加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

基于Cocos2d-x学习OpenGL ES 2.0之多纹理

发布时间:2020-12-14 17:28:43 所属栏目:百科 来源:网络整理
导读:没想到原文出了那么多错别字,实在对不起观众了。介绍opengl es 2.0的不多。相信介绍基于Cocos2d-x学习OpenGL ES 2.0之多纹理的,我是独此一家吧。~~ 子龙山人出了一个系列:基于Cocos2d-x学习OpenGL ES 2.0。弄c++来搞cocos2dx的可以看看。 教程是参考iphon

没想到原文出了那么多错别字,实在对不起观众了。介绍opengl es 2.0的不多。相信介绍基于Cocos2d-x学习OpenGL ES 2.0之多纹理的,我是独此一家吧。~~

子龙山人出了一个系列:基于Cocos2d-x学习OpenGL ES 2.0。弄c++来搞cocos2dx的可以看看。

教程是参考iphone的教程来写的,坑点也有不少,最主要的坑点还是在版本。所以还是弄个cocos2dx 3.2比较好。前两天辉辉说cocos2dx 3.2也很操蛋,.h里声明的返回值在源码实现的时候返回类型竟然变了。不得不吐槽一下~

子龙山人的教程只能教你照葫芦画瓢,什么原理的东西是压根就没涉及,有的还因为cocos2dx的封装过度会产生一些误导。

cocos2dx对opengl es封装的有点让人恶心,如果想学习opengl es是不建议在cocos2dx下进行学习的。

废话少说吧,开始正文。

根据子龙山人的教程,弄出了立方体纹理贴图,但是假如想在同一个面上贴多个纹理呢?该怎么实现?

本文提到两个方法,第一就是获取两个纹理,分别画图贴纹理,意思就是装顶点,装索引,绑定纹理,画图一。装顶点,装纹理,画图二。此时用到的都是GL_TEXTURE0,在frag文件中,只需要一个采样器就ok。

第二中方法就是用两个sampler,装顶点,装索引,绑定纹理一,绑定纹理二,画图。就OK了。

说起来比较简单,真要自己动手做,对于一个新手来说,过程还是有点小郁闷的。

下面就上源码了,对于步骤和方法的含义,此处不作介绍。相信强大的google和百度可以发挥巨大的作用。

第一种是立方体六个面贴上纹理,其中一个面再次贴上第二个纹理。

所用到的shader文件:

 1 attribute vec4 a_position; // 1
 2 attribute vec4 a_color;  2
 3 attribute vec2 TextureCoord;
 4 
 5 varying vec4 DestinationColor;  3
 6 varying vec2 v_texCoord;
 7 
 8 
 9 void main(void) {  4
10     DestinationColor = a_color;  5
11     v_texCoord = TextureCoord;
12     gl_Position = CC_MVPMatrix * a_position;  6
13 }
1 varying vec4 DestinationColor; 2 varying vec2 v_texCoord; 3 4 5 6 gl_FragColor = DestinationColor * texture2D(CC_Texture0,v_texCoord) ; 7 }

所用到的两张图

头文件:

#ifndef _CubeTexture_H__
#define _CubeTexture_H__

#include "cocos2d.h"

using namespace cocos2d;

class CubeTexture : public cocos2d::Layer
{
public:
     there's no 'id' in cpp,so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

     Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    void draw(Renderer *renderer,const Mat4 &transform,uint32_t transformUpdated) override;
    we call our actual opengl commands here
    void onDraw();

     implement the "static create()" method manually
    CREATE_FUNC(CubeTexture);

private:
    Mat4 _modelViewMV;
    CustomCommand _customCommand;

    GLProgram *mShaderProgram;
    GLint _colorLocation;
    GLint _positionLocation;
    GLint _textureLocation;

    GLuint _textureUniform;

    GLuint _textureID;
    GLuint _textureID2;

    GLuint vertexBuffer;
    GLuint indexBuffer;
    
    GLuint _vertexBuffer2;
    GLuint _indexBuffer2;

};

#endif  __HELLOWORLD_SCENE_H__
1 #include CubeTexture.h" 2 namespace GL; 3 4 cocos2d::Scene* CubeTexture::createScene() 5 { 6 auto scene = Scene::create(); 7 auto layer = CubeTexture::create(); 8 scene->addChild(layer); 9 return scene; 10 } 11 12 bool CubeTexture::init() 13 { 14 if ( Layer::init() ) 15 { 16 mShaderProgram = new GLProgram; 17 mShaderProgram->initWithFilenames(myshader.vert",myshader.frag"); 18 mShaderProgram->link(); 19 mShaderProgram->updateUniforms(); 20 21 _textureID = Director::getInstance()->getTextureCache()->addImage( HelloWorld.png" )->getName(); 22 _textureID2 = Director::getInstance()->getTextureCache()->addImage(item_powerup_fish.png")->getName(); 23 glGenBuffers( 1,&vertexBuffer ); 24 glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer ); 25 26 glGenBuffers( indexBuffer ); 27 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBuffer ); 28 29 return true; 30 } 31 false; 32 } 33 34 void CubeTexture::draw( Renderer *renderer,255);line-height:1.5;">const Mat4 &transform,uint32_t transformUpdated ) 35 { 36 Layer::draw(renderer,transform,transformUpdated); 37 38 _customCommand.init(_globalZOrder); 39 _customCommand.func = CC_CALLBACK_0(CubeTexture::onDraw,255);line-height:1.5;">this); 40 renderer->addCommand(&_customCommand); 41 } 42 43 void CubeTexture::onDraw() 44 { 45 Director::getInstance()->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 46 Director::getInstance()->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 47 Director::getInstance()->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 48 Director::getInstance()->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 49 50 Mat4 modelViewMatrix; 51 Mat4::createLookAt(Vec3(0,128);line-height:1.5;">5),Vec3(0),-modelViewMatrix); 52 modelViewMatrix.translate(0 ); 53 54 static float rotation = 20; 55 modelViewMatrix.rotate(Vec3(0),CC_DEGREES_TO_RADIANS(rotation)); 56 57 Mat4 projectionMatrix; 58 Mat4::createPerspective(60,128);line-height:1.5;">480/320,128);line-height:1.5;">1.0,128);line-height:1.5;">42,&projectionMatrix); 59 Director::getInstance()->multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION,projectionMatrix); 60 Director::getInstance()->multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW,modelViewMatrix); 61 62 typedef struct { 63 float Position[3]; 64 float Color[4]; 65 float TexCoord[2]; 66 } Vertex; 67 #define TEX_COORD_MAX 1 68 69 Vertex Vertices[] = { 70 Front 71 {{0},{1},{TEX_COORD_MAX,128);line-height:1.5;">0}}, 72 {{1},TEX_COORD_MAX}},128);line-height:1.5;"> 73 {{-0,128);line-height:1.5;"> 74 {{- 75 Back 76 {{2},128);line-height:1.5;"> 77 {{- 78 {{ 79 {{- 80 Left 81 {{- 82 {{- 83 {{- 84 {{- 85 Right 86 {{ 87 {{ 88 {{ 89 {{ 90 Top 91 {{ 92 {{ 93 {{- 94 {{- 95 Bottom 96 {{ 97 {{ 98 {{- 99 {{-0}} 100 }; 101 int vertexCount = sizeof(Vertices) / sizeof(Vertices[0]); 102 103 GLubyte Indices[] = { 104 105 2,128);line-height:1.5;">106 2,128);line-height:1.5;">3,128);line-height:1.5;">107 108 4,128);line-height:1.5;">5,128);line-height:1.5;">6,128);line-height:1.5;">109 7,128);line-height:1.5;">110 111 8,128);line-height:1.5;">9,128);line-height:1.5;">10,128);line-height:1.5;">112 10,128);line-height:1.5;">11,128);line-height:1.5;">8,128);line-height:1.5;">113 114 12,128);line-height:1.5;">13,128);line-height:1.5;">14,128);line-height:1.5;">115 14,128);line-height:1.5;">15,128);line-height:1.5;">12,128);line-height:1.5;">116 117 16,128);line-height:1.5;">17,128);line-height:1.5;">18,128);line-height:1.5;">118 18,128);line-height:1.5;">19,128);line-height:1.5;">16,128);line-height:1.5;">119 120 20,128);line-height:1.5;">21,128);line-height:1.5;">22,128);line-height:1.5;">121 22,128);line-height:1.5;">23,128);line-height:1.5;">20 122 }; 123 124 1) Add to top of file 125 const Vertex Vertices2[] = { 126 {{0.5,128);line-height:1.5;">0.01},128);line-height:1.5;">1}},128);line-height:1.5;">127 {{128 {{-129 {{-130 }; 131 132 const GLubyte Indices2[] = { 133 3 134 }; 135 136 glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer); 137 glBufferData(GL_ARRAY_BUFFER,255);line-height:1.5;">sizeof(Vertices),Vertices,GL_STATIC_DRAW); 138 139 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBuffer); 140 glBufferData(GL_ELEMENT_ARRAY_BUFFER,255);line-height:1.5;">sizeof(Indices),Indices,128);line-height:1.5;">141 142 143 _positionLocation = glGetAttribLocation(mShaderProgram->getProgram(),0);line-height:1.5;">a_position144 _colorLocation = glGetAttribLocation(mShaderProgram->getProgram(),0);line-height:1.5;">a_color145 146 _textureLocation = glGetAttribLocation(mShaderProgram->getProgram(),0);line-height:1.5;">TextureCoord147 _textureUniform = glGetUniformLocation(mShaderProgram->getProgram(),0);line-height:1.5;">CC_Texture0148 149 mShaderProgram->use(); 150 mShaderProgram->setUniformsForBuiltins(); 151 152 glEnableVertexAttribArray(_positionLocation); 153 glEnableVertexAttribArray(_colorLocation); 154 glEnableVertexAttribArray(_textureLocation); 155 156 glVertexAttribPointer(_positionLocation,GL_FLOAT,GL_FALSE,255);line-height:1.5;">sizeof(Vertex),(GLvoid*)offsetof(Vertex,Position)); 157 158 glVertexAttribPointer(_colorLocation,Color)); 159 160 glVertexAttribPointer(_textureLocation,255);line-height:1.5;">sizeof(Vertex),128);line-height:1.5;">161 (GLvoid*)offsetof(Vertex,TexCoord)); 162 // 163 ////set sampler 164 GL::bindTexture2DN(165 glActiveTexture( GL_TEXTURE0 ); 166 glBindTexture(GL_TEXTURE_2D,_textureID); 167 glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); 168 glEnable(GL_BLEND); 169 glEnable(GL_DEPTH_TEST); 170 glDrawElements(GL_TRIANGLES,128);line-height:1.5;">36,GL_UNSIGNED_BYTE,128);line-height:1.5;">0); 171 glUniform1i(_textureUniform,128);line-height:1.5;">0); unnecc in practice 172 173 glGenBuffers(_vertexBuffer2); 174 glBindBuffer(GL_ARRAY_BUFFER,_vertexBuffer2); 175 glBufferData(GL_ARRAY_BUFFER,255);line-height:1.5;">sizeof(Vertices2),Vertices2,128);line-height:1.5;">176 177 glGenBuffers(_indexBuffer2); 178 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_indexBuffer2); 179 glBufferData(GL_ELEMENT_ARRAY_BUFFER,255);line-height:1.5;">sizeof(Indices2),Indices2,128);line-height:1.5;">180 181 glBindBuffer(GL_ARRAY_BUFFER,128);line-height:1.5;">182 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,128);line-height:1.5;">183 184 GL::bindTexture2DN(185 glUniform1i(_textureUniform,128);line-height:1.5;">186 187 glVertexAttribPointer(_positionLocation,128);line-height:1.5;">188 glVertexAttribPointer(_colorLocation,(GLvoid*) (sizeof(float) * 3)); 189 glVertexAttribPointer(_textureLocation,128);line-height:1.5;">7)); 190 191 glDrawElements(GL_TRIANGLE_STRIP,255);line-height:1.5;">sizeof(Indices2)/sizeof(Indices2[0]),128);line-height:1.5;">192 193 CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,vertexCount); 194 195 CHECK_GL_ERROR_DEBUG(); 196 glDisable(GL_DEPTH_TEST); 197 198 Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 199 Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 200 }

运行结果:

方法二,所需要的shader文件:

1 attribute vec4 a_position; 2 attribute vec2 a_texCoord; 4 varying vec2 v_texCoord; 6 void) { 7 gl_Position = CC_MVPMatrix * a_position; 8 v_texCoord = a_texCoord; 9 }
1 precision mediump float; 2 varying vec2 v_texCoord; 3 uniform sampler2D s_lightMap; 4 uniform sampler2D s_baseMap; 5 6 7 8 vec4 baseColor; 9 vec4 lightColor; 10 baseColor = texture2D( s_baseMap,v_texCoord); 11 lightColor = texture2D( s_lightMap,v_texCoord ); 12 baseColor = texture2D( CC_Texture0,128);line-height:1.5;">13 lightColor = texture2D( CC_Texture1,v_texCoord ); 14 gl_FragColor = baseColor * ( lightColor + 0.25 ); 15 }

所需要的图

头文件

MultiTexture.h

源文件

MultiTexture.h 2 3 cocos2d::Scene* MultiTexture::createScene() 4 { 5 auto scene = Scene::create(); 6 auto layer = MultiTexture::create(); 7 scene->addChild(layer); 8 9 } 10 11 bool MultiTexture::init() 12 { 13 14 { 15 mShaderProgram = 16 mShaderProgram->initWithFilenames(multiTexture.vertmultiTexture.frag 17 mShaderProgram->link(); 18 mShaderProgram->updateUniforms(); 19 20 _baseMapTexId = Director::getInstance()->getTextureCache()->addImage( 21 _lightMapTexId = Director::getInstance()->getTextureCache()->addImage(crate.jpg 22 glGenVertexArrays(VAO); 23 glBindVertexArray(VAO); 24 25 glGenBuffers( 26 glBindBuffer(GL_ARRAY_BUFFER,128);line-height:1.5;"> 27 28 glGenBuffers( 29 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,128);line-height:1.5;"> 30 31 32 } 33 34 } 35 36 void MultiTexture::draw( Renderer *renderer,128);line-height:1.5;"> 37 { 38 Layer::draw(renderer,128);line-height:1.5;"> 39 40 _customCommand.init(_globalZOrder); 41 _customCommand.func = CC_CALLBACK_0(MultiTexture::onDraw,128);line-height:1.5;"> 42 renderer->addCommand(&_customCommand); 43 } 44 45 void MultiTexture::onDraw() 46 { 47 Director::getInstance()->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 48 Director::getInstance()->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 49 Director::getInstance()->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 50 Director::getInstance()->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 51 52 typedef 53 54 55 } Vertex; 56 57 58 Vertex Vertices[] = { 59 60 {{- 61 {{- 62 {{0},{ TEX_COORD_MAX,128);line-height:1.5;"> 63 {{ 64 65 }; 66 67 68 GLubyte Indices[] = { 69 70 71 }; 72 73 glBindBuffer(GL_ARRAY_BUFFER,128);line-height:1.5;"> 74 glBufferData(GL_ARRAY_BUFFER,128);line-height:1.5;"> 75 76 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,128);line-height:1.5;"> 77 glBufferData(GL_ELEMENT_ARRAY_BUFFER,128);line-height:1.5;"> 78 79 _positionLoc = glGetAttribLocation(mShaderProgram->getProgram(),128);line-height:1.5;"> 80 _texCoordLoc = glGetAttribLocation(mShaderProgram->getProgram(),0);line-height:1.5;">a_texCoord 81 _baseMapLoc = glGetUniformLocation(mShaderProgram->getProgram(),"s_baseMap"); 82 _lightMapLoc = glGetUniformLocation(mShaderProgram->getProgram(),"s_lightMap"); 83 _baseMapLoc = glGetUniformLocation(mShaderProgram->getProgram(),128);line-height:1.5;"> 84 _lightMapLoc = glGetUniformLocation(mShaderProgram->getProgram(),0);line-height:1.5;">CC_Texture1 85 86 glEnableVertexAttribArray(_positionLoc); 87 glEnableVertexAttribArray(_texCoordLoc); 88 89 glVertexAttribPointer(_positionLoc,128);line-height:1.5;"> 90 glVertexAttribPointer(_texCoordLoc,128);line-height:1.5;"> 91 (GLvoid*)offsetof(Vertex,128);line-height:1.5;"> 92 93 mShaderProgram->use(); 94 mShaderProgram->setUniformsForBuiltins(); 95 96 glEnable(GL_DEPTH_TEST); 97 glBindVertexArray(VAO); 98 99 GL::bindTexture2DN(100 glUniform1i(_lightMapLoc,128);line-height:1.5;">0 ); 101 102 GL::bindTexture2DN(103 glUniform1i(_baseMapLoc,128);line-height:1.5;">1); 104 105 glDrawElements(GL_TRIANGLES,128);line-height:1.5;">6,128);line-height:1.5;">106 107 glBindVertexArray(108 CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(6); 109 110 CHECK_GL_ERROR_DEBUG(); 111 glDisable(GL_DEPTH_TEST); 112 113 Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 114 Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 115 }

运行效果:

第二种方法中,

cpp内的:

//_baseMapLoc =glGetUniformLocation(mShaderProgram->getProgram(),"s_baseMap");

//_lightMapLoc = glGetUniformLocation(mShaderProgram->getProgram(),"s_lightMap");
_baseMapLoc = glGetUniformLocation(mShaderProgram->getProgram(),"CC_Texture0");
_lightMapLoc = glGetUniformLocation(mShaderProgram->getProgram(),"CC_Texture1");

和shader内的

//baseColor = texture2D( s_baseMap,v_texCoord);
//lightColor = texture2D( s_lightMap,v_texCoord );
baseColor = texture2D( CC_Texture0,v_texCoord);
lightColor = texture2D( CC_Texture1,v_texCoord );

将注释解开,把下面两行注掉。同样可以。这说明了,cocos2dx在进行编译shader的时候内置了多个uniform值。大家可以看一下,其中就包括CC_Texture0系列。

其实用起来不算方便了,而不注意的人,可能会声明和内置变量相同的名字,此时,咳咳咳咳咳~ shader编译的时候就会出错了。不知道为啥cocos2dx要多次一举。

还有一点:

////set sampler
GL::bindTexture2DN(0,_textureID);
//glActiveTexture( GL_TEXTURE0 );
//glBindTexture(GL_TEXTURE_2D,_textureID);

我使用了GL::bindTexture2DN 方法,而并没有使用opengl es原装的 glActiveTexture 和glBindTexture这两个方法。其实GL::bindTexture2DN 内部就调用了后面的两个方法,那为何不直接用后面的两个方法呢?

原因是,直接用opengl es的方法,会出错!!!尼玛 这才是坑点。跟踪后发现,cocos2dx给GL相关的东西添加了一个StateCache的东西,当activeTexture时,需要更改cache内的东西。直接调用glActiveTexture的方法,就略去了往cache内塞东西的步骤,这样就出错了。

猜测是cocos2dx进行渲染的时候,调用了cache内的什么东西。尼玛,你还能封装的再恶心一点么?

所以说,不喜欢cocos2dx这种处理问题的方法的,可以完全抛开cocos2dx了。

(原文:https://www.cnblogs.com/slysky/p/3981210.html)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读