OpenGL ES 绘制流程

ChatGPT 3.5 国内中文镜像站免费使用啦

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  >> OpenGL ES 特效

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  >> OpenGL ES 转场

零基础 OpenGL ES 学习路线推荐 :  OpenGL ES 学习目录 >> OpenGL ES 函数

零基础 OpenGL ES 学习路线推荐 :  OpenGL ES 学习目录 >> OpenGL ES GPUImage 使用

零基础 OpenGL ES 学习路线推荐 :  OpenGL ES 学习目录 >> OpenGL ES GLSL 编程


一.前言

OpenGL ES 是一种在嵌入式设备上运行的专门的 OpenGL 版本,它提供了强大的图形渲染功能,支持2D和3D图形的绘制。下面是使用C语言编写 OpenGL ES 绘制流程的一个简单示例


二.初始化 OpenGL ES

在使用 OpenGL ES 之前,需要先初始化 OpenGL ES 环境,以便后续的 OpenGL ES 函数可以正确地执行。通常,初始化 OpenGL ES 需要做以下几件事情:

  • 1.创建一个 EGL 窗口
  • 2.创建一个 OpenGL ES 上下文
  • 3.置视口和投影矩阵
/*******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:OpenGL ES 绘制流程
//@Time:2023/03/11 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/*******************************************************************************************/ 



#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <stdio.h>

EGLDisplay display;
EGLSurface surface;
EGLContext context;
GLuint program;

void initOpenGL() {
    // 创建EGL窗口,并设置相关参数
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    EGLint major, minor;
    eglInitialize(display, &major, &minor);

    EGLConfig config;
    EGLint numConfigs;
    EGLint attribs[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
                        EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE};
    eglChooseConfig(display, attribs, &config, 1, &numConfigs);

    EGLint format;
    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);

    // 创建OpenGL ES 上下文
    EGLSurface surface = eglCreateWindowSurface(display, config, window, NULL);
    EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
    EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);

    // 设置视口和投影矩阵
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, width, 0, height, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

三.编译和链接着色器程序

OpenGL ES 使用着色器程序来进行图形渲染。着色器程序由一个顶点着色器和一个片段着色器组成。其中,顶点着色器用于处理顶点属性,片段着色器用于处理像素颜色。编译和链接着色器程序需要做以下几件事情:

  • 1.创建顶点着色器和片段着色器
  • 2.编译着色器程序,并将编译错误输出到控制台
  • 3.将顶点着色器和片段着色器链接到着色器程序中
  • 4.检查链接错误,并将错误输出到控制台
/*******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:OpenGL ES 绘制流程
//@Time:2023/03/11 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/*******************************************************************************************/

const char *vertexShaderSource = "attribute vec4 a_Position;\n"
                                 "attribute vec4 a_Color;\n"
                                 "varying vec4 v_Color;\n"
                                 "void main() {\n"
                                 "  gl_Position = a_Position;\n"
                                 "  v_Color = a_Color;\n"
                                 "}\n";

const char *fragmentShaderSource = "precision mediump float;\n"
                                   "varying vec4 v_Color;\n"
                                   "void main() {\n"
                                   "  gl_FragColor = v_Color;\n"
                                   "}\n";

GLuint vertexShader;
GLuint fragmentShader;

void initShaders() {
    // 创建顶点着色器并编译
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    // 检查编译错误
    GLint compiled;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compiled);
    if (!compiled) {
        GLsizei len;
        glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len);
        char *log = (char *) malloc(len);
        glGetShaderInfoLog(vertexShader, len, &len, log);
        fprintf(stderr, "vertex shader compile error: %s\n", log);
        free(log);
    }

    // 创建片段着色器并编译
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    // 检查编译错误
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compiled);
    if (!compiled) {
        GLsizei len;
        glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &len);
        char *log = (char *) malloc(len);
        glGetShaderInfoLog(fragmentShader, len, &len, log);
        fprintf(stderr, "fragment shader compile error: %s\n", log);
        free(log);
    }

    // 创建着色器程序并链接
    program = glCreateProgram();
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glLinkProgram(program);

    // 检查链接错误
    GLint linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (!linked) {
       GLsizei len;
       glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
       char *log = (char *) malloc(len);
       glGetProgramInfoLog(program, len, &len, log);
       fprintf(stderr, "shader program link error: %s\n", log);
       free(log);
    }
}

四. 准备顶点数据

OpenGL ES 中,绘制图形需要指定顶点数据。通常,顶点数据包括顶点坐标、颜色、法线和纹理坐标等。准备顶点数据需要将顶点数据存储在一个缓冲区对象中,并使用 glVertexAttribPointer 函数指定顶点属性。

/*******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:OpenGL ES 绘制流程
//@Time:2023/03/11 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/*******************************************************************************************/


GLfloat vertices[] = {
    -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下角,红色
    0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 右下角,绿色
    0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 上方,蓝色
};

GLuint vbo;

void initVertices() {
    // 创建缓冲区对象
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    // 将顶点数据存储在缓冲区对象中
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // 指定顶点属性,并启用顶点属性
    GLint positionLoc = glGetAttribLocation(program, "a_Position");
    GLint colorLoc = glGetAttribLocation(program, "a_Color");

    glEnableVertexAttribArray(positionLoc);
    glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);

    glEnableVertexAttribArray(colorLoc);
    glVertexAttribPointer(colorLoc, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

准备好顶点数据后,即可使用 glDrawArrays glDrawElements 函数绘制图形。其中,glDrawArrays 函数是按顺序绘制顶点,而 glDrawElements 函数则是按索引绘制顶点。


五.渲染图形

准备好顶点数据后,即可使用 glDrawArrays 或 glDrawElements 函数绘制图形。其中,glDrawArrays 函数是按顺序绘制顶点,而 glDrawElements 函数则是按索引绘制顶点。

/*******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:OpenGL ES 绘制流程
//@Time:2023/03/11 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/*******************************************************************************************/

void render() {
    // 清除颜色缓冲区和深度缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // 使用着色器程序
    glUseProgram(program);

    // 绑定缓冲区对象
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    // 绘制图形
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // 解绑缓冲区对象
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // 交换前后缓冲区
    eglSwapBuffers(display, surface);
}

六.清理OpenGL ES

在使用完 OpenGL ES 后,需要清理 OpenGL ES 环境,以释放资源。

/*******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:OpenGL ES 绘制流程
//@Time:2023/03/11 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/*******************************************************************************************/


void cleanup() {
    // 删除着色器程序
    glDeleteProgram(program);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // 删除缓冲区对象
    glDeleteBuffers(1, &vbo);

    // 删除EGL上下文和窗口
    eglDestroyContext(display, context);
    eglDestroySurface(display, surface);
    eglTerminate(display);
}

综上所述,这是一个简单的 OpenGL ES 绘制流程的例子,其中包括了初始化 OpenGL ES、编译和链接着色器程序、准备顶点数据、渲染图形和清理 OpenGL ES 等步骤。在实际应用中,可能还需要进行更多的操作,例如纹理加载、深度测试和光照计算等。


七.OpenGL ES 实战演示

1.Windows OpenGL ES 图像 lookup 色彩调整:源码下载

图片[1]-OpenGL ES 绘制流程 - 猿说编程

2.Windows OpenGL ES 色阶调节:源码下载

Windows OpenGL ES 图像色阶

八.猜你喜欢

  1. OpenGL ES 简介
  2. OpenGL ES 版本介绍
  3. OpenGL ES 2.0 和 3.0区别
  4. OpenGL ES 名词解释(一)
  5. OpenGL ES 名词解释(二)
  6. OpenGL ES GLSL 着色器使用过程
  7. OpenGL ES EGL 简介
  8. OpenGL ES EGL 名词解释
  9. OpenGL ES EGL eglGetDisplay
  10. OpenGL ES EGL eglInitialize
  11. OpenGL ES EGL eglGetConfigs
  12. OpenGL ES EGL eglChooseConfig
  13. OpenGL ES EGL eglGetError
  14. OpenGL ES EGL eglCreateContext
  15. OpenGL ES EGL eglCreateWindowSurface
  16. OpenGL ES EGL eglCreatePbufferSurface
  17. OpenGL ES EGL eglMakeCurrent
  18. OpenGL ES EGL eglSwapBuffer
  19. OpenGL ES EGL eglDestroySurface
  20. OpenGL ES EGL eglDestroyContext
  21. OpenGL ES EGL eglQueryContext
  22. OpenGL ES EAGLContext 和 EGLContext
  23. OpenGL ES OpenGL WebGL EGL WGL 区别
  24. OpenGL ES freeglut 下载和使用
  25. OpenGL ES glew 下载和使用
  26. OpenGL ES glut 下载和使用
  27. OpenGL ES glfw 下载和使用
  28. OpenGL ES glad 下载和使用
  29. OpenGL ES glut glew glfw glad freeglut
  30. OpenGL ES google angle
  31. OpenGL Windows 搭建环境(MFC版本)
  32. OpenGL ES Windows 搭建环境(MFC版本)
  33. OpenGL ES 版本检测
  34. OpenGL GLES 和 GLSL
  35. OpenGL ES 获取最大纹理尺寸 GL_MAX_TEXTURE_SIZE
  36. OpenGL ES 获取最多纹理单元数量 GL_MAX_TEXTURE_IMAGE_UNITS
  37. OpenGL ES 纹理采样的数量限制
  38. OpenGL ES 视口宽高限制 GL_MAX_VIEWPORT_DIMS
  39. OpenGL ES 笛卡尔坐标系之纹理坐标和顶点坐标
  40. OpenGL ES 查看显卡信息
  41. OpenGL ES 正交投影和透视投影
  42. OpenGL ES GLSL 简介
  43. OpenGL ES GLSL 编译
  44. OpenGL ES glDrawArrays 函数
  45. OpenGL ES glDrawArrays 崩溃
  46. OpenGL ES glDrawArray 和 glDrawElements 用法区别
  47. OpenGL 绘制流程
  48. OpenGL ES 绘制流程
ChatGPT 3.5 国内中文镜像站免费使用啦
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容