来来来,说到做到,解密我的天空盒:882:
对于GL高手来说,这个东西根本不叫东西,呵呵。不过几个月前这个东西是cocos根本没有的东西,写出来再完成调试可是耗了个把星期的时间的。Cocos应该是也快出天空盒了,到时比较比较哈
skybox.cpp:
#include "SkyBox.h"
SkyBox* SkyBox::loadme(float pSize, std::string pSkyID){
auto o = new SkyBox();
o->init(pSize, pSkyID);
return o;
}
bool SkyBox::init(float pSize, std::string pSkyID){
BoxID = pSkyID;//天空盒编号,可用于适配多套天空盒
BoxSize = pSize;//天空盒尺寸
log("hahahaha skybox init......................................................");
if ( !Node::init() ){return false;}
mShaderProgram = new GLProgram;
mShaderProgram->initWithFilenames("skybox/myshader.vert", "skybox/myshader.frag");//vert和frag文件放于resources/skybox目录下
//mShaderProgram->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
//mShaderProgram->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
mShaderProgram->link();
mShaderProgram->updateUniforms();
_textureB = Director::getInstance()->getTextureCache()->addImage("skybox/" + BoxID + "/back.jpg")->getName();//back面纹理图片
_textureF = Director::getInstance()->getTextureCache()->addImage("skybox/" + BoxID + "/front.jpg")->getName();//front面纹理图片
_textureD = Director::getInstance()->getTextureCache()->addImage("skybox/" + BoxID + "/down.jpg")->getName();//down面纹理图片
_textureU = Director::getInstance()->getTextureCache()->addImage("skybox/" + BoxID + "/up.jpg")->getName();//up面纹理图片
_textureL = Director::getInstance()->getTextureCache()->addImage("skybox/" + BoxID + "/left.jpg")->getName();//left面纹理图片
_textureR = Director::getInstance()->getTextureCache()->addImage("skybox/" + BoxID + "/right.jpg")->getName();//right面纹理图片
glGenBuffers(1, &skyboxVertexBuffer);//顶点数据缓存
glBindBuffer(GL_ARRAY_BUFFER, skyboxVertexBuffer);
glGenBuffers(1, &skyboxIndexBuffer);//索引数据缓存
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skyboxIndexBuffer);
return true;
}
void SkyBox::draw(cocos2d::Renderer *renderer, const Mat4 &transform, uint32_t transformUpdated){
Node::draw(renderer, transform, transformUpdated);
onDraw();
}
void SkyBox::onDraw(){
typedef struct {
float Position;
float TexCoord;
} Vertex;
Vertex Vertices] = {//正方形顶点数组
{ { 1, 1, 1 }, { 1, 0 } }, { { 1, -1, 1 }, { 1, 1 } }, { { -1, -1, 1 }, { 0, 1 } }, { { -1, 1, 1 }, { 0, 0 } },// Front
{ { -1, -1, -1 }, { 1, 1 } }, { { 1, 1, -1 }, { 0, 0 } }, { { -1, 1, -1 }, { 1, 0 } }, { { 1, -1, -1 }, { 0, 1 } },// Back
{ { -1, 1, 1 }, { 1, 0 } }, { { -1, -1, 1 }, { 1, 1 } }, { { -1, -1, -1 }, { 0, 1 } }, { { -1, 1, -1 }, { 0, 0 } },// Left
{ { 1, 1, -1 }, { 1, 0 } }, { { 1, -1, -1 }, { 1, 1 } }, { { 1, -1, 1 }, { 0, 1 } }, { { 1, 1, 1 }, { 0, 0 } },// Right
{ { 1, 1, -1 }, { 1, 0 } }, { { -1, 1, -1 }, { 0, 0 } }, { { -1, 1, 1 }, { 0, 1 } }, { { 1, 1, 1 }, { 1, 1 } },// Top
{ { 1, -1, 1 }, { 1, 0 } }, { { -1, -1, 1 }, { 0, 0 } }, { { -1, -1, -1 }, { 0, 1 } }, { { 1, -1, -1 }, { 1, 1 } }// Bottom
};
int vertexCount = sizeof(Vertices) / sizeof(Vertices);
GLubyte Indices] = {//指定三角形的索引
0, 1, 2, 2, 3, 0// Front
,4, 5, 6, 4, 5, 7// Back
,8, 9, 10, 10, 11, 8// Left
,12, 13, 14, 14, 15, 12// Right
,16, 17, 18, 18, 19, 16// Top
,20, 21, 22, 22, 23, 20// Bottom
};
//创建索引缓冲区并绑定索引数据到缓冲区
glBindBuffer(GL_ARRAY_BUFFER, skyboxVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skyboxIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
_positionLocation = glGetAttribLocation(mShaderProgram->getProgram(), "Position");//从着色器源程序中获取Position存储位置
_modelViewUniform = glGetUniformLocation(mShaderProgram->getProgram(), "Modelview");//从着色器源程序中获取Modelview存储位置
_textureLocation = glGetAttribLocation(mShaderProgram->getProgram(), "TextureCoord");//从着色器源程序中获取TextureCoord存储位置
_textureUniform = glGetUniformLocation(mShaderProgram->getProgram(), "CC_Texture0");//从着色器源程序中获取CC_Texture0存储位置
Mat4 modelView = this->getNodeToWorldTransform();//获取视口矩阵
modelView.scale(BoxSize);//矩阵按BoxSize缩放
mShaderProgram->use();// Use the program object
mShaderProgram->setUniformsForBuiltins();//更新CC_MVPMatrix
mShaderProgram->setUniformLocationWithMatrix4fv(_modelViewUniform, modelView.m, 1);//设置modelView到_modelViewUniform,传值给.vert
glEnableVertexAttribArray(_positionLocation);//开启顶点属性数组
glEnableVertexAttribArray(_textureLocation);//开启顶点属性数组
glVertexAttribPointer(_positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Position));//位置信息赋值(1..顶点着色器位置属性;2..每一个顶点信息由几个值组成;3..顶点信息的数据类型;4..不要将数据类型标准化;5..数组中每个元素的长度;6..数组的首地址)
glVertexAttribPointer(_textureLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, TexCoord));//颜色信息赋值(1..顶点着色器位置属性;2..每一个顶点信息由几个值组成;3..顶点信息的数据类型;4..不要将数据类型标准化;5..数组中每个元素的长度;6..数组的首地址)
//CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, vertexCount);//统计显示的顶点数
GL::bindTexture2D(_textureB);//绑定back面纹理
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (GLvoid*)0);//基本图元的类型/顶点数/索引数据类型/索引数据在缓冲区的偏移(0)
GL::bindTexture2D(_textureF);//绑定front面纹理
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (GLvoid*)6);//基本图元的类型/顶点数/索引数据类型/索引数据在缓冲区的偏移(6)
GL::bindTexture2D(_textureL);//绑定left面纹理
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (GLvoid*)12);//基本图元的类型/顶点数/索引数据类型/索引数据在缓冲区的偏移(12)
GL::bindTexture2D(_textureR);//绑定right面纹理
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (GLvoid*)18);//基本图元的类型/顶点数/索引数据类型/索引数据在缓冲区的偏移(18)
GL::bindTexture2D(_textureU);//绑定up面纹理
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (GLvoid*)24);//基本图元的类型/顶点数/索引数据类型/索引数据在缓冲区的偏移(24)
GL::bindTexture2D(_textureD);//绑定down面纹理
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (GLvoid*)30);//基本图元的类型/顶点数/索引数据类型/索引数据在缓冲区的偏移(30)
mShaderProgram->setUniformLocationWith1i(_textureUniform, 0);//向着色器设置一致变量_textureUniform的值
CHECK_GL_ERROR_DEBUG();
}
```
skybox.h:
#ifndef __SKYBOX_H__
#define __SKYBOX_H__
#include "cocos2d.h"
USING_NS_CC;
class SkyBox : public cocos2d::Node{
public:
static SkyBox* loadme(float pSize, std::string pSkyID);
virtual bool init(float pSize, std::string pSkyID);
private:
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t transformUpdated) override;
void onDraw();
Camera*_Camera;
float BoxSize;
std::string BoxID;
Mat4 _modelViewMV;
CustomCommand _customCommand;
GLProgram *mShaderProgram;
GLint _positionLocation;
GLint _textureLocation;
GLuint _modelViewUniform;
GLuint _textureUniform;
GLuint _textureU;
GLuint _textureD;
GLuint _textureF;
GLuint _textureB;
GLuint _textureL;
GLuint _textureR;
GLuint skyboxVertexBuffer;
GLuint skyboxIndexBuffer;
};
#endif
```
myshader.vert
attribute vec4 Position;
attribute vec2 TextureCoord;
uniform mat4 Modelview;
varying vec2 v_texCoord;
void main(void) {
v_texCoord = TextureCoord;
gl_Position = CC_PMatrix * Modelview * Position;
}
```
myshader.frag
//varying vec4 DestinationColor;
//uniform sampler2D CC_Texture0;
varying vec2 v_texCoord;
void main(void) {
//gl_FragColor = DestinationColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor = texture2D(CC_Texture0, v_texCoord);
}
```
在场景中添加天空盒的代码:
auto skybox = SkyBox::loadme(100000, "12");//创建SKYBOX,图片目录为resources/skybox/12
addChild(skybox, -10000);
```
简单吧,嘿嘿,注释成那样,要是还要写什么说明,那也就醉了吧,嘿嘿
附上像素非常低的图片一套,拿去玩吧,什么什么?要高清图片?我也要。。。。。能给我几套不?
