通过opengl来实现yuv的显示
来源:互联网 发布:2017音乐软件市场份额 编辑:程序博客网 时间:2024/05/17 18:49
文章转载自:http://blog.csdn.net/eastlhu/article/details/9382431
// OpenGL ES 2.0 code #include "Shader.vert" #include "Shader.frag" #include <jni.h> #include <android/log.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <stdio.h> #include <stdlib.h> #include <math.h> enum { ATTRIB_VERTEX, ATTRIB_TEXTURE, }; static GLuint g_texYId; static GLuint g_texUId; static GLuint g_texVId; static GLuint simpleProgram; static char * g_buffer = NULL; static int g_width = 0; static int g_height = 0; static void checkGlError(const char* op) { GLint error; for (error = glGetError(); error; error = glGetError()) { log("error::after %s() glError (0x%x)\n", op, error); } } static GLuint bindTexture(GLuint texture, const char *buffer, GLuint w , GLuint h) { // GLuint texture; // glGenTextures ( 1, &texture ); checkGlError("glGenTextures"); glBindTexture ( GL_TEXTURE_2D, texture ); checkGlError("glBindTexture"); glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer); checkGlError("glTexImage2D"); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); checkGlError("glTexParameteri"); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); checkGlError("glTexParameteri"); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); checkGlError("glTexParameteri"); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); checkGlError("glTexParameteri"); //glBindTexture(GL_TEXTURE_2D, 0); return texture; } static void renderFrame() { #if 0 // Galaxy Nexus 4.2.2 static GLfloat squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; static GLfloat coordVertices[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; #else // HUAWEIG510-0010 4.1.1 static GLfloat squareVertices[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, }; static GLfloat coordVertices[] = { -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, }; #endif glClearColor(0.5f, 0.5f, 0.5f, 1); checkGlError("glClearColor"); glClear(GL_COLOR_BUFFER_BIT); checkGlError("glClear"); //PRINTF("setsampler %d %d %d", g_texYId, g_texUId, g_texVId); GLint tex_y = glGetUniformLocation(simpleProgram, "SamplerY"); checkGlError("glGetUniformLocation"); GLint tex_u = glGetUniformLocation(simpleProgram, "SamplerU"); checkGlError("glGetUniformLocation"); GLint tex_v = glGetUniformLocation(simpleProgram, "SamplerV"); checkGlError("glGetUniformLocation"); glBindAttribLocation(simpleProgram, ATTRIB_VERTEX, "vPosition"); checkGlError("glBindAttribLocation"); glBindAttribLocation(simpleProgram, ATTRIB_TEXTURE, "a_texCoord"); checkGlError("glBindAttribLocation"); glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); checkGlError("glVertexAttribPointer"); glEnableVertexAttribArray(ATTRIB_VERTEX); checkGlError("glEnableVertexAttribArray"); glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, 0, 0, coordVertices); checkGlError("glVertexAttribPointer"); glEnableVertexAttribArray(ATTRIB_TEXTURE); checkGlError("glEnableVertexAttribArray"); glActiveTexture(GL_TEXTURE0); checkGlError("glActiveTexture"); glBindTexture(GL_TEXTURE_2D, g_texYId); checkGlError("glBindTexture"); glUniform1i(tex_y, 0); checkGlError("glUniform1i"); glActiveTexture(GL_TEXTURE1); checkGlError("glActiveTexture"); glBindTexture(GL_TEXTURE_2D, g_texUId); checkGlError("glBindTexture"); glUniform1i(tex_u, 1); checkGlError("glUniform1i"); glActiveTexture(GL_TEXTURE2); checkGlError("glActiveTexture"); glBindTexture(GL_TEXTURE_2D, g_texVId); checkGlError("glBindTexture"); glUniform1i(tex_v, 2); checkGlError("glUniform1i"); //glEnable(GL_TEXTURE_2D); //checkGlError("glEnable"); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); checkGlError("glDrawArrays"); } static GLuint buildShader(const char* source, GLenum shaderType) { GLuint shaderHandle = glCreateShader(shaderType); if (shaderHandle) { glShaderSource(shaderHandle, 1, &source, 0); glCompileShader(shaderHandle); GLint compiled = 0; glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* buf = (char*) malloc(infoLen); if (buf) { glGetShaderInfoLog(shaderHandle, infoLen, NULL, buf); log_easy("error::Could not compile shader %d:\n%s\n", shaderType, buf); free(buf); } glDeleteShader(shaderHandle); shaderHandle = 0; } } } return shaderHandle; } static GLuint buildProgram(const char* vertexShaderSource, const char* fragmentShaderSource) { GLuint vertexShader = buildShader(vertexShaderSource, GL_VERTEX_SHADER); GLuint fragmentShader = buildShader(fragmentShaderSource, GL_FRAGMENT_SHADER); GLuint programHandle = glCreateProgram(); if (programHandle) { glAttachShader(programHandle, vertexShader); checkGlError("glAttachShader"); glAttachShader(programHandle, fragmentShader); checkGlError("glAttachShader"); glLinkProgram(programHandle); GLint linkStatus = GL_FALSE; glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = (char*) malloc(bufLength); if (buf) { glGetProgramInfoLog(programHandle, bufLength, NULL, buf); log_easy("error::Could not link program:\n%s\n", buf); free(buf); } } glDeleteProgram(programHandle); programHandle = 0; } } return programHandle; } static unsigned char * readYUV(const char *path) { FILE *fp; unsigned char * buffer; long size = 1280 * 720 * 3 / 2; if((fp=fopen(path,"rb"))==NULL) { log("cant open the file"); exit(0); } buffer = (unsigned char *)malloc(size); memset(buffer,'\0',size); long len = fread(buffer,1,size,fp); //PRINTF("read data size:%ld", len); fclose(fp); return buffer; } void gl_initialize() { g_buffer = NULL; simpleProgram = buildProgram(VERTEX_SHADER, FRAG_SHADER); glUseProgram(simpleProgram); glGenTextures(1, &g_texYId); glGenTextures(1, &g_texUId); glGenTextures(1, &g_texVId); } void gl_uninitialize() { g_width = 0; g_height = 0; if (g_buffer) { free(g_buffer); g_buffer = NULL; } } //设置图像数据 void gl_set_framebuffer(const char* buffer, int buffersize, int width, int height) { if (g_width != width || g_height != height) { if (g_buffer) free(g_buffer); g_width = width; g_height = height; g_buffer = (char *)malloc(buffersize); } if (g_buffer) memcpy(g_buffer, buffer, buffersize); } //画屏 void gl_render_frame() { if (0 == g_width || 0 == g_height) return; #if 0 int width = 448; int height = 336; static unsigned char *buffer = NULL; if (NULL == buffer) { char filename[128] = {0}; strcpy(filename, "/sdcard/yuv_448_336.yuv"); buffer = readYUV(filename); } #else const char *buffer = g_buffer; int width = g_width; int height = g_height; #endif glViewport(0, 0, width, height); bindTexture(g_texYId, buffer, width, height); bindTexture(g_texUId, buffer + width * height, width/2, height/2); bindTexture(g_texVId, buffer + width * height * 5 / 4, width/2, height/2); renderFrame(); } //如果设置图像数据和画屏是两个线程的话,记住要加锁。
Shader.vext:
//Shader.vert文件内容 static const char* VERTEX_SHADER = "attribute vec4 vPosition; \n" "attribute vec2 a_texCoord; \n" "varying vec2 tc; \n" "void main() \n" "{ \n" " gl_Position = vPosition; \n" " tc = a_texCoord; \n" "} \n";
Shader.frag:
//Shader.frag文件内容 static const char* FRAG_SHADER = "varying lowp vec2 tc;\n" "uniform sampler2D SamplerY;\n" "uniform sampler2D SamplerU;\n" "uniform sampler2D SamplerV;\n" "void main(void)\n" "{\n" "mediump vec3 yuv;\n" "lowp vec3 rgb;\n" "yuv.x = texture2D(SamplerY, tc).r;\n" "yuv.y = texture2D(SamplerU, tc).r - 0.5;\n" "yuv.z = texture2D(SamplerV, tc).r - 0.5;\n" "rgb = mat3( 1, 1, 1,\n" "0, -0.39465, 2.03211,\n" "1.13983, -0.58060, 0) * yuv;\n" "gl_FragColor = vec4(rgb, 1);\n" "}\n";
阅读全文
0 0
- 通过opengl来实现yuv的显示
- 通过opengl es 2.0来实现yuv的显示
- 通过opengl es 2.0来实现yuv(NV21)的显示
- OpenGL显示YUV视频
- c++ OpenGL显示YUV数据
- 通过原生的方法 来实现 隐藏显示
- 通过cocos2d-x的CCGLProgram和CCShaderCache的实现来分析OpenGL ES中的Shader编程
- 通过cocos2d-x的CCGLProgram和CCShaderCache的实现来分析OpenGL
- qt采用opengl显示yuv视频数据
- Android Opengl ES2.0 -实现RGB-YUV互转并显示到屏幕
- OpenGL ES总结(三)OpenGL通过计算纹理坐标来显示一张图片
- 通过鼠标的移动来实现层的隐藏与显示
- Java 通过 list 和 对象数组 来实现 简单的 分页显示
- JS通过操作Element的Css来实现隐藏和显示(本示例只有隐藏)
- 通过jq来监听input的输入状态,实现角标的显示/隐藏
- OpenGL: OpenGL实现立体显示
- 通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸
- 用jni实现基于opengl的yuv格式的视频渲染
- 配置Windows下工作环境
- Eclipse 使用maven jar包出错 Download不下来jar包
- maven scope含义的说明
- [Leetcode] 554. Brick Wall 解题报告
- C++程序发开特点
- 通过opengl来实现yuv的显示
- shell脚本密码输入
- leetcode 695. Max Area of Island 深度优先遍历DFS
- Comparable与Comparator的具体应用场景
- RMI简单示例
- 【LDA】LDA主题模型
- 发布uap项目
- 3年工作经验的程序员应该具备的技能
- leetcode 696. Count Binary Substrings