openg离线包_OpenGL离线渲染和缓冲区对象

理论

OpenGLl离线渲染就是通过OpenGL将绘制结果渲染到显存中的一张图片上,通过gl接口函数可以从显存读取到内存中。基于OpenGL的离线渲染机制,可以快速实现一个渲染器:

输入:图像,点,线。。。

输出:图像

实现方案

从一般到特殊:

1. 不支持FBO

主要介绍PC上,移动设备如果不支持FBO要实现离线渲染那就实在没辙了。

glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); 设置读写时后缓存区。 一般pc都支持双缓冲机制,如果没有GL_BACK就没辙了。

glDrawPixels 更新颜色缓冲区。

调用opengl绘制函数在GL_BACK绘制。

完成后glReadPixels将颜色缓冲区以从显存调入内存。 该函数会导致gpu阻塞,效率不高。

2. PC支持FBO

opengl支持多种缓冲区对象:

缓冲区对象说白了就是 显存中一块缓存区。OpenGL是业界渲染标准,具体接口功能由显卡驱动实现,OpenGL客户端是使用OpeGL的应用程序,OpenGL服务器可以理解成GPU,如果没有GPU就是OS内核中的一个模块,缓冲区对象定义在服务器端,减少客户端每次渲染时数据传输开销。每个缓冲区对象有唯一的ID,类似handle概念,客户端通过BufferId管理缓冲区对象。

1)纹理对象,最常见的从gl1.0就开始支持,基本操作指令:glGenTextures, glBindTextures, glDeleteTextures,后续有多重纹理增加新的指令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 OpenGL ES 在 Android 平台上渲染 NV12 格式数据的 C 代码示例: ```c #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> // 初始化 OpenGL ES 上下文和纹理 GLuint textureId; GLuint program; GLint textureUniform; void initOpenGLContextAndTexture() { // 创建 OpenGL ES 上下文 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLint major, minor; eglInitialize(display, &major, &minor); EGLConfig config; EGLint numConfigs; static const EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; eglChooseConfig(display, configAttribs, &config, 1, &numConfigs); 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); eglMakeCurrent(display, surface, surface, context); // 生成纹理 glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // 编译着色器程序 static const char* vertexShaderCode = "attribute vec4 position;\n" "attribute vec2 texCoord;\n" "varying vec2 v_texCoord;\n" "void main() {\n" " gl_Position = position;\n" " v_texCoord = texCoord;\n" "}\n"; static const char* fragmentShaderCode = "#extension GL_OES_EGL_image_external : require\n" "precision mediump float;\n" "uniform samplerExternalOES texture;\n" "varying vec2 v_texCoord;\n" "void main() {\n" " gl_FragColor = texture2D(texture, v_texCoord);\n" "}\n"; GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderCode, NULL); glCompileShader(vertexShader); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderCode, NULL); glCompileShader(fragmentShader); program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); textureUniform = glGetUniformLocation(program, "texture"); } // 渲染 NV12 数据 void renderNV12Data(unsigned char* data, int width, int height) { // 绑定纹理 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); glTexImage2D(GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)data); // 渲染纹理 glUseProgram(program); glUniform1i(textureUniform, 0); static const GLfloat vertexData[] = { -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, }; static const GLfloat texCoordData[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, vertexData); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texCoordData); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); } ``` 以上代码中,`initOpenGLContextAndTexture` 函数用于初始化 OpenGL ES 上下文和纹理,`renderNV12Data` 函数用于渲染 NV12 数据。在 `renderNV12Data` 函数中,首先将 NV12 数据转换成 EGLImageOES 对象,并绑定到纹理上,然后使用着色器程序渲染纹理。其中,顶点着色器将顶点位置和纹理坐标传递给片段着色器,片段着色器从外部纹理中采样颜色并输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值