cocos2dx opengl入门系列五-显示多纹理

运行环境:

mac 10.12.2

xcode Version 8.2.1

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 */


如图:

cocos2dx opengl入门系列五-显示多纹理_第1张图片

修改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;
}
如图:

cocos2dx opengl入门系列五-显示多纹理_第2张图片

在Resources方位夹下新建shader文件夹,再在shader新建myVertexShader.vsh和myFragmentShader.fsh文件。

如图:

cocos2dx opengl入门系列五-显示多纹理_第3张图片


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文件,如图:


修改成:


还有,这次的图片要自己去找了。

cocos2dx opengl入门系列五-显示多纹理_第4张图片


cocos2dx opengl入门系列五-显示多纹理_第5张图片

接下来,可以开心地运行程序了。

运行效果:

cocos2dx opengl入门系列五-显示多纹理_第6张图片

你可能感兴趣的:(c++,cocos2dx,opengl)