[√]OpenGL绘制图片

简介: [√]OpenGL绘制图片

最简单的图片绘制程序

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();

image.png

动态合图原理分析

image.png

如果多个图片一个drawCall完成绘制,其原理就是将要绘制的图片,统一绘制到一张大纹理(RenderTexture),实现细节为通过glTexSubImage2D可以修改纹理的部分区域。

需要将不同格式(RGB888、RGBA8888等)的纹理数据转换为RenderTexture的纹理格式。

在提交顶点数据时,注意映射好每张图片的纹理坐标,即可。

image.png

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位:

image.png

目录
相关文章
四、 OpenGL ES GLSL图片倒置的翻转解决方案(6种)
OpenGL ES GLSL图片倒置的翻转解决方案(6种)
724 0
四、 OpenGL ES GLSL图片倒置的翻转解决方案(6种)
OpenGL ES 图片的解压缩
在Mac开发的环境中.jpg .png结尾的图片都可以当做纹理数据源, 但是在使用的时候需要解压缩, 以下方法就是通过图片名来获取最终需要的
144 0
|
敏捷开发
OpenGL ES 纹理图片解析第一波 - 无耐地放弃重写这一部分
OpenGL ES 纹理图片解析第一波 - 无耐地放弃重写这一部分 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
1218 0
|
Android开发 HTML5 移动开发
OpenGL ES 贴图图片是否有 Alpha 通道以及图片大小导致无法显示帖图的原因分析
OpenGL ES 贴图图片是否有 Alpha 通道以及图片大小导致无法显示帖图的原因分析 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
1160 0
|
缓存 Windows 编解码
NeHe的OpenGL教程6(Bang翻译Delphi版)-如何用图片进行纹理映射
NeHe的OpenGL教程6(Bang翻译Delphi版)-如何用图片进行纹理映射 在这一课里,我将教会你如何把纹理映射到立方体的六个面,如下图: 将下图放在应用程序data目录下,起名NeHe.
1063 0
|
7月前
|
XML 小程序 Java
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
145 0
|
缓存 C++
Opengl ES之FBO
Opengl ES连载系列
158 0