這幾天在看子龍山人的關於OpenGL的文章,先依葫蘆畫瓢,能看到些東西,才能慢慢深刻了解,當入門文章不錯,可是其中遇到的一些問題,折騰了一些時間,爲了方便和我同樣的小白們,在這篇文章中進行寫補充。html
OpenGL ES2.0教程:編寫本身的shader(2)--子龍山人windows
文章中關於VBO和VAO部分的代碼的寫法,我進行了些修改,將重複使用的變量定義全局變量,並修改初始化數據位置,防止在onDraw方法中重複的Malloc,導致內存泄露,具體的修改在代碼註釋中會說明。ide
HelloWorldScene.hui
1 #include "cocos2d.h" 2 3 USING_NS_CC; 4 5 class HelloWorld : public cocos2d::Layer 6 7 { 8 9 public: 10 11 static cocos2d::Scene* createScene(); 12 13 virtual bool init() override; 14 15 CREATE_FUNC(HelloWorld); 16 17 virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) override; 18 19 void onDraw(); 20 21 private: 22 23 CustomCommand _command; 24 25 float _position[16]; 26 27 float _color[12]; 28 29 GLProgram* glProgram; 30 31 GLuint vao;//定義VAO緩衝 32 33 GLuint positionVBO; 34 35 GLuint colorVBO; 36 37 GLuint positionLocation; 38 39 GLuint colorLocation; 40 41 };
1 #include "HelloWorldScene.h" 2 3 Scene* HelloWorld::createScene() 4 { 5 auto scene = Scene::create(); 6 7 auto layer = HelloWorld::create(); 8 9 scene->addChild(layer); 10 11 return scene; 12 } 13 14 void HelloWorld::visit(Renderer *renderer, const Mat4 &transform,uint32_t parentFlags) 15 { 16 Layer::visit(renderer, transform, parentFlags); 17 _command.init(_globalZOrder); 18 _command.func = CC_CALLBACK_0(HelloWorld::onDraw, this); 19 Director::getInstance()->getRenderer()->addCommand(&_command); 20 } 21 22 void HelloWorld::onDraw() 23 { 24 //使用已經在init中初始化的glProgram 25 glProgram->use(); 26 glProgram->setUniformsForBuiltins(); 27 28 //獲取VAO(OSX和ISO中默認開啓,windows中默認不開啓) 29 glBindVertexArray(vao); 30 31 //獲取VBO 32 glBindBuffer(GL_ARRAY_BUFFER, positionVBO); 33 //填充座標數據 34 glBufferData(GL_ARRAY_BUFFER, sizeof(_position), _position, GL_STATIC_DRAW); 35 positionLocation = glGetAttribLocation(glProgram->getProgram(), "a_position"); 36 glEnableVertexAttribArray(positionLocation); 37 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 38 39 //獲取VBO 40 glBindBuffer(GL_ARRAY_BUFFER, colorVBO); 41 //填充顏色數據 42 glBufferData(GL_ARRAY_BUFFER, sizeof(_color), _color, GL_STATIC_DRAW); 43 colorLocation = glGetAttribLocation(glProgram->getProgram(), "a_color"); 44 glEnableVertexAttribArray(colorLocation); 45 glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 46 47 //使用VAO 48 glBindVertexArray(vao); 49 //渲染 50 glDrawArrays(GL_TRIANGLES, 0, 3); 51 //清空VAO 52 glBindVertexArray(0); 53 54 CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 3); 55 CHECK_GL_ERROR_DEBUG(); 56 } 57 58 bool HelloWorld::init() 59 { 60 if ( !Layer::init() ) 61 { 62 return false; 63 } 64 65 //準備數據 66 auto size = Director::getInstance()->getWinSize(); 67 float position[] = { 0, 0, size.width, 0, size.width / 2, size.height}; 68 float color[] = { 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1}; 69 for (int i = 0; i < sizeof(position); i++) { 70 _position[i] = position[i]; 71 } 72 for (int i = 0; i < sizeof(color); i++) { 73 _color[i] = color[i]; 74 } 75 76 //vert和frag文件和原文同樣,直接放在Classes目錄就能夠讀取到(環境:XCode) 77 glProgram = new GLProgram; 78 glProgram->initWithFilenames("myVertextShader.vert","myFragmentShader.frag"); 79 glProgram->link(); 80 glProgram->updateUniforms(); 81 this->setGLProgram(glProgram); 82 83 //glGen的系列方法會不斷的Malloc內存空間,寫在onDraw中會致使內存泄漏 84 glGenVertexArrays(1, &vao); 85 glGenBuffers(1, &positionVBO); 86 glGenBuffers(1, &colorVBO); 87 return true; 88 }