OpenGL总结11-模型矩阵模式与纹理矩阵模式的差异

在使用OpenGL进行三维纹理渲染的时候,因为使用了混合和透明度,光使用透明度图像会比较难看,所以添加了混合,但是使用混合之后就不能使用深度测试,如果想使用深度测试有一种方法叫顺序无关的渲染,因为渲染顺序对混合有影响,所以要是用深度无关的渲染方法避免这个问题。

但我之前为了避免这个问题,采用了一种比较取巧的办法,原本控制模型旋转是在GL_MODELVIEW下进行的,此时必然要使用深度测试,否则像素的显示是错误的,因为混合在深度测试的后面,而深度测试是不考虑透明的,所以即使是透明的图像也会遮挡后面的图像(我的图像是有一半的模型,旋转过某个角度的时候会变暗),此时图像旋转是正确的,但是显示的颜色就出现了问题。

我为了避免这种情况试了好多方法,还是不行,但是之后发现在纹理矩阵模式下的时候就不会出现这个问题,在GL_TEXTURE模式的时候,旋转模型不会出现模型显示错误,或者背面变暗的情况。

注意,虽然显示是正确的,但是后来发现两种模式下的旋转机制可能不同。简单的说模型矩阵下GL_MODELVIEW,利用glRotate进行旋转,坐标轴是会跟随旋转的,当多个方向旋转是就会出现万向锁。但是在纹理矩阵模式下GL_TEXTURE,我发现当绕多个轴进行旋转的时候,纹理坐标轴是没有跟随旋转的,因为同样的代码,在两种模式下是不同的表现。观察之后发现,模型矩阵绕x,y轴旋转,始终是绕着模型本身固定的轴在旋转,而纹理矩阵模式的坐标轴不变,也就是说每次都是屏幕上显示的x,y轴旋转,所以可以达到自由旋转的目的,也就是说没有产生万向锁。

以上内容仅供记录参考。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将纹理矩阵转换为Bitmap,可以使用OpenGL ES将纹理渲染到一个Framebuffer对象中,并使用glReadPixels()方法将像素数据读回到一个ByteBuffer中。然后,可以使用BitmapFactory的decodeByteArray()方法将ByteBuffer中的像素数据解码为Bitmap。 以下是将纹理矩阵转换为Bitmap的代码示例: ```java // 创建一个Framebuffer对象 int[] framebuffers = new int[1]; GLES20.glGenFramebuffers(1, framebuffers, 0); int framebufferId = framebuffers[0]; GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferId); // 创建一个纹理并将其附加到Framebuffer对象上 int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); int textureId = textures[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, textureId, 0); // 检查Framebuffer是否完整 int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) { throw new RuntimeException("Framebuffer is not complete"); } // 绑定Framebuffer并渲染纹理 GLES20.glViewport(0, 0, width, height); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferId); GLES20.glUseProgram(program); GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, texCoordBuffer); GLES20.glUniformMatrix4fv(mtxHandle, 1, false, mtx, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glUniform1i(texSamplerHandle, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); // 读取像素数据并创建一个Bitmap ByteBuffer buffer = ByteBuffer.allocateDirect(width * height * 4); buffer.order(ByteOrder.nativeOrder()); GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); // 解绑纹理和Framebuffer并删除它们 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glDeleteTextures(1, textures, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glDeleteFramebuffers(1, framebuffers, 0); ``` 需要注意的是,这个代码示例假设当前上下文中存在一个有效的OpenGL ES程序,并且已经获得了程序中各个属性和uniform变量的句柄。如果您需要更详细的代码示例,请告诉我您正在使用的平台和开发环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值