最简单的图片绘制程序
float vertices[] = { //-- 位置 ---- -- 纹理坐标-- 400, 400, 0.0f, 1.0f, 1.0f, // 右上 400, 0, 0.0f, 1.0f, 0.0f, // 右下 0, 0, 0.0f, 0.0f, 0.0f, // 左下 0 , 400, 0.0f, 0.0f, 1.0f // 左上 }; // 顺时针 // 3 -- 0 // | \ | // 2 -- 1 unsigned int indices[] = { // 注意索引从0开始! 0, 1, 3, // 第一个三角形 1, 2 ,3, // 第二个三角形 }; GLuint vbo, ebo, texture; glGenBuffers(1, &vbo); glGenBuffers(1, &ebo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glEnableVertexAttribArray(_attribPosition); glVertexAttribPointer(_attribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (GLvoid*)0); glEnableVertexAttribArray(_aTexCoord); glVertexAttribPointer(_aTexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (GLvoid*)(sizeof(float) * 3)); Image img; img.initWithImageFile("./vx.png"); int width = img.getWidth(); int height = img.getHeight(); glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0); // 在绑定纹理之前先激活纹理单元 glBindTexture(GL_TEXTURE_2D, texture);// 绑定纹理到激活的纹理单元 glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // png使用GL_RGBA, jpg使用GL_RGB glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.getData()); glGenerateMipmap(GL_TEXTURE_2D); _ourTexture=glGetUniformLocation(ourShader.ID, "texture1"); glUniform1i(_ourTexture, 0);// 设置每个采样器属于哪个纹理单元 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); CHECK_GL_ERROR_DEBUG();
动态合图原理分析
如果多个图片一个drawCall完成绘制,其原理就是将要绘制的图片,统一绘制到一张大纹理(RenderTexture),实现细节为通过glTexSubImage2D可以修改纹理的部分区域。
需要将不同格式(RGB888、RGBA8888等)的纹理数据转换为RenderTexture的纹理格式。
在提交顶点数据时,注意映射好每张图片的纹理坐标,即可。
cocos2dx生成material的规则:
void TrianglesCommand::generateMaterialID() { // glProgramState is hashed because it contains: // * uniforms/values // * glProgram // // we safely can when the same glProgramState is being used then they share those states // if they don't have the same glProgramState, they might still have the same // uniforms/values and glProgram, but it would be too expensive to check the uniforms. struct { GLuint textureId; GLenum blendSrc; GLenum blendDst; void* glProgramState; } hashMe; hashMe.textureId = _textureID; hashMe.blendSrc = _blendType.src; hashMe.blendDst = _blendType.dst; hashMe.glProgramState = _glProgramState; _materialID = XXH32((const void*)&hashMe, sizeof(hashMe), 0); }
TriangleCommand只使用了quadIndices前6位: