cocos2dx-x-3.13.1
代码:
新建cocos2dx项目,具体操作官网有教程。新建好后,
新建Test.cpp,代码如下:
// // Test.cpp // MutilTextures // // Created by zhufu on 2017/3/28. // // #include "Test.h" Test* Test::create() { Test* test = new(std::nothrow) Test(); if(test && test->init()) { test->autorelease(); return test; } else { delete test; test = nullptr; return nullptr; } } bool Test::init() { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); initCommand(); loadShader(); loadTexture(); loadRectangle(); return true; } void Test::flipVertical(int width, int height, unsigned char* arr) { int index = 0, f_index, cycle=height/2; char buf; for (int i = 0; i < cycle; i++) { for (int j = 0; j < width*Test::Format_RGBA; j++) { //当前像素 index = i*width*Test::Format_RGBA + j; //需要交换的像素 f_index = (height - 1 - i)*width*Test::Format_RGBA + j; //缓存当前像素 buf = arr[index]; //交换像素 arr[index] = arr[f_index]; //交换回像素 arr[f_index] = buf; } } } void Test::loadShader() { _glProgram = new GLProgram(); _glProgram->initWithFilenames("shader/myVertexShader.vsh", "shader/myFragmentShader.fsh"); _glProgram->link(); } void Test::loadTexture() { Image *image1 = new Image; std::string imagePath1 = FileUtils::getInstance()->fullPathForFilename("boy.png"); image1->initWithImageFile(imagePath1); unsigned char *imageData1 = image1->getData(); int width1 = image1->getWidth(); int height1 = image1->getHeight(); flipVertical(width1, height1, imageData1); //别忘了释放image内存 // CC_SAFE_DELETE(image); glGenTextures(1, &textureID1); glBindTexture(GL_TEXTURE_2D, textureID1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width1, height1, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData1); Image *image2 = new Image; std::string imagePath2 = FileUtils::getInstance()->fullPathForFilename("girl.png"); image2->initWithImageFile(imagePath2); unsigned char *imageData2 = image2->getData(); int width2 = image2->getWidth(); int height2 = image2->getHeight(); flipVertical(width2, height2, imageData2); glGenTextures(1, &textureID2); glBindTexture(GL_TEXTURE_2D, textureID2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData2); glBindTexture(GL_TEXTURE_2D, 0); } void Test::loadRectangle() { glGenVertexArrays(1, &_vao); glBindVertexArray(_vao); //make and bind VBO; GLuint vbo = 0; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); //put the rectangle vertices(XYZ) and texture coordinates (UV) into the vbo GLfloat textureData[] = { // X Y Z U V -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f,-1.0f, 0.0f, 0.0f, 0.0f, 1.0f,-1.0f , 0.0f, 1.0f, 0.0f, }; glBufferData(GL_ARRAY_BUFFER, sizeof(textureData), textureData, GL_STATIC_DRAW); //connect the xyz to the "vert" arrribute of the vertex shader glEnableVertexAttribArray(_glProgram->getAttribLocation("vert")); glVertexAttribPointer(_glProgram->getAttribLocation("vert"), 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(_glProgram->getAttribLocation("vertTexCoord")); glVertexAttribPointer(_glProgram->getAttribLocation("vertTexCoord"), 2, GL_FLOAT, GL_TRUE, 5 * sizeof(GLfloat), (const GLvoid*)(3*sizeof(GLfloat))); } void Test::initCommand() { _command.init(getLocalZOrder()); _command.func = CC_CALLBACK_0(Test::onDraw, this); } void Test::draw(Renderer *renderer, const Mat4 &transform, uint32_t platform) { onDraw(); } void Test::onDraw() { //clear everything glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); //bind the program (the shaders) _glProgram->use(); //bind the texture and set the "tex" uniform in the fragment shader // glActiveTexture(GL_TEXTURE0); // glBindTexture(GL_TEXTURE_2D, textureID1); GL::bindTexture2DN(0, textureID1); GLuint tex1 = glGetUniformLocation(_glProgram->getProgram(), "texture1"); glUniform1i(tex1, 0); // glActiveTexture(GL_TEXTURE1); // glBindTexture(GL_TEXTURE_2D, textureID2); GL::bindTexture2DN(1, textureID2); GLuint tex2 =glGetUniformLocation(_glProgram->getProgram(), "texture2"); glUniform1i(tex2, 1); //bind the vao glBindVertexArray(_vao); //draw the vao glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }
新建Test.h,代码如下:
// // Test.h // MutilTextures // // Created by zhufu on 2017/3/28. // // #ifndef Test_h #define Test_h #include USING_NS_CC; class Test : public Node { public: enum Format { Format_Grayscale = 1, /**< one channel: grayscale */ Format_GrayscaleAlpha = 2, /**< two channels: grayscale and alpha */ Format_RGB = 3, /**< three channels: red, green, blue */ Format_RGBA = 4 /**< four channels: red, green, blue, alpha */ }; static Test* create(); virtual bool init() override; virtual void draw(Renderer* renderer, const Mat4 &transform, uint32_t platform) override; void onDraw(); void loadShader(); void loadTexture(); void loadRectangle(); void initCommand(); void flipVertical(int width, int height, unsigned char* arr); private: GLuint textureID1; GLuint textureID2; GLProgram* _glProgram; GLuint _vao; CustomCommand _command; }; #endif /* Test_h */
如图:
修改HelloWorldScene.cpp,
先
include "Test.h"
再修改CreateScene方法:
Scene* HelloWorld::createScene() { // 'scene' is an autorelease object auto scene = Scene::create(); auto test = Test::create(); scene->addChild(test); // 'layer' is an autorelease object auto layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } 如图:
在Resources方位夹下新建shader文件夹,再在shader新建myVertexShader.vsh和myFragmentShader.fsh文件。
如图:
myVertexShader.vsh
attribute vec3 vert; attribute vec2 vertTexCoord;
varying vec2 textureOut;
void main() { // Pass the tex coord straight through to the fragment shader textureOut = vertTexCoord; gl_Position = vec4(vert, 1); }
myFragmentShader.fsh
uniform sampler2D texture1; uniform sampler2D texture2;
varying vec2 textureOut;
void main() { vec4 col1 = texture2D(texture1, textureOut); vec4 col2 = texture2D(texture2, textureOut); gl_FragColor = mix(col1, col2, 0.5); }
还有,最后一人是修改cocos2dx的适配模式,就是修改AppDelegate.cpp文件,如图:
修改成:
还有,这次的图片要自己去找了。
接下来,可以开心地运行程序了。
运行效果: