内容简介:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010339039/article/details/88595059
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010339039/article/details/88595059
首先来看看渲染效果
我们先来看看关于纹理的坐标:
他是如下图:
顶点着色器代码:texture_vertext_shader_java_1.glsl
attribute vec4 a_Position; attribute vec2 a_TextureCoordinates; varying vec2 v_TextureCoordinates; void main() { v_TextureCoordinates = a_TextureCoordinates; gl_Position = a_Position; }
a_Position:是顶点的坐标
a_TextureCoordinates:是用来接收的纹理坐标的属性。
v_TextureCoordinates:这个是用来将坐标传递给片段着色器。
片段着色器代码:texture_frament_shader_java_1.glsl
precision mediump float ; uniform sampler2D u_TextureUnit; varying vec2 v_TextureCoordinates; void main() { gl_FragColor = texture2D(u_TextureUnit , v_TextureCoordinates); }
u_TextureUnit:这是用来接收纹理数据的数组。
v_TextureCoordinates:是从顶点着色器传递过来的纹理坐标
texture2D方法:他会读入特定坐标的颜色值,然后传递给gl_FragColor
现在来看看 java 上的代码:
这些都是加载代码,然后编译,连接,然后使用,和上篇渲染三角形是一样的。
String vertexShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.texture_vertext_shader_java_1); String frgShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.texture_frament_shader_java_1); int vertextShader = ShaderHelper.compileVertextShader(vertexShaderSource); int fragmentShader = ShaderHelper.compileFragmentShader(frgShaderSource); program = ShaderHelper.linkProgram(vertextShader, fragmentShader); ShaderHelper.validatePrograme(program); glUseProgram(program);
下面是获取三个变量的地址:
uTextureUnitL = glGetUniformLocation(program, "u_TextureUnit"); aPositionL = glGetAttribLocation(program, "a_Position"); aTextureCoordinatesL = glGetAttribLocation(program, "a_TextureCoordinates");
接下来我们着重看下加载纹理的地方:loadTexture
先创建一个纹理对象:
final int[] textureObjectIds = new int[1]; glGenTextures(1,textureObjectIds , 0); if(textureObjectIds[0] == 0){ Log.e("xhc" , "cant open opengl texture object !"); return 0; }
//然后将图片加载成一个bitmap final BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources() , resourceId , options); if(bitmap == null){ Log.e("xhc" , "bitmap create faild "); glDeleteTextures(1, textureObjectIds , 0); return 0; }
//在使用这个新生成的纹理之前,我们需要告诉opengl纹理调用应该应用于这个纹理对象 //第一个参数GL_TEXTURE_2D 告诉这个纹理是个二维的纹理,对应的id是 textureObjectIds[0] glBindTexture(GL_TEXTURE_2D , textureObjectIds[0]);
/** * 设置过滤器GL_TEXTURE_MIN_FILTER指缩小的情况选择GL_LINEAR_MIPMAP_LINEAR说明缩小使用三线性过滤 * GL_TEXTURE_MAG_FILTER 指放大的情况GL_LINEAR使用双线性过滤 */ glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR);
我们简单来看看过滤方式:
//加载位图数据到opengl中 texImage2D(GL_TEXTURE_2D , 0 , bitmap,0); //释放位图,节约内存 bitmap.recycle(); //生成mip贴图 glGenerateMipmap(GL_TEXTURE_2D); //解除纹理绑定,这里不是把纹理数据和纹理id解除绑定,只是为了让后面的操作不要操作到此纹理,如果就是想操作,再从新绑定即可 glBindTexture(GL_TEXTURE_2D , 0);
//我们再来看看坐标,顶点坐标和纹理坐标都放在一起 //注意顶点和纹理的坐标做好对应 float[] tableVerticesTexture = { //x, y , s , t 0f, 0f, 0.5f, 0.5f, -1f, -1f, 0f, 1f, 1f, -1f, 1f, 1f, 1f, 1f, 1f, 0f, -1f, 1f, 0f, 0f, -1f, -1f, 0f, 1f, };
将坐标数据传入对应的opengl中,并使能。
private void setVertexAttribPointer(int dataOffset, int attributeLocation, int componetCount, int stride) { vertexData.position(dataOffset); glVertexAttribPointer(attributeLocation, componetCount, GL_FLOAT, false, stride, vertexData); glEnableVertexAttribArray(attributeLocation); vertexData.position(0); }
最后绘制:
//通过 glActiveTexture(GL_TEXTURE0);把活动的纹理单元设置成纹理单元0, //然后通过glBindTextture()把纹理绑定到这个单元。通过调用 //glUniformli(uTextureUnitLocation ,0)把被选定的纹理单元传递给片段着色器中。 @Override public void onDrawFrame(GL10 gl10) { glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); //drawtexture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texttureId); glUniform1i(uTextureUnitL, 0); glDrawArrays(GL_TRIANGLE_FAN, 0, 6); }
以上所述就是小编给大家介绍的《音视频之opengl渲染图片》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 音视频之渲染yuv图片
- iOS 图片压缩、滤镜、剪切、渲染等解析
- iOS开发 - 图片的解压缩到渲染过程
- OpenGL ES 入门之旅(15)--分屏滤镜渲染图片
- OpenGL/OpenGL ES入门: 使用OpenGL ES 渲染图片
- Octane渲染入门-渲染设置图文版
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。