我试图用Python,OpenGL和GLFW绘制一个有纹理的正方形。 这是我要给你看的全部images。在
很抱歉发布图片的方式,但我没有足够的声誉发布超过2个链接(我甚至不能发布照片)。在
我得到了这个: [专辑中的第二张图片]
而不是: [专辑中的第一张图片]
但是如果我使用一些不同的jpg文件:
其中一些显示正确,
在我将它们旋转90度(我的意思是在带有RGB组件的阵列上使用numpy rot90函数)并将它们发送到GPU之前,它们都会正常显示。看起来是这样的(颜色不变,我只得到一些失真):
旋转前: [专辑中的第三张图片]
旋转后: [专辑中的第四张图片]
这完全取决于一个文件。 有人知道我做错了什么吗?或者看到我看不到的东西?在
代码:
首先,我要初始化glfw,创建一个窗口,等等
if __name__ == '__main__':
import sys
import glfw
import OpenGL.GL as gl
import numpy as np
from square import square
from imio import imread,rgb_flag,swap_rb
from txio import tx2gpu,txrefer
glfw.glfwInit()
win =glfw.glfwCreateWindow(800,800,"Hello")
glfw.glfwMakeContextCurrent(win)
glfw.glfwSwapInterval(1)
gl.glClearColor(0.75,0.75,0.75,1.0)
然后,我使用OpenCV imread函数加载一个图像,我记得用蓝色替换红色。然后我将图像发送到gpu-我将在一分钟内描述tx2gpu。在
^{pr2}$swap_rb()函数(在其他文件中定义,已导入):
def swap_rb(mat):
X = mat[:,:,2].copy()
mat[:,:,2] = mat[:,:,0]
mat[:,:,0] = X
return mat
然后是主循环(稍后我将介绍txrefer和square):
while not glfw.glfwWindowShouldClose(win):
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
txrefer(tx_id); square(2); txrefer(0)
glfw.glfwSwapBuffers(win)
glfw.glfwPollEvents()
主要功能结束:
glfw.glfwDestroyWindow(win)
glfw.glfwTerminate()
现在重要的事情:
定义正方形的函数如下所示:
def square(scale=1.0,color=None,solid=True):
s = scale*.5
if type(color)!=type(None):
if solid:
gl.glBegin(gl.GL_TRIANGLE_FAN)
else:
gl.glBegin(gl.GL_LINE_LOOP)
gl.glColor3f(*color[0][:3]); gl.glVertex3f(-s,-s,0)
gl.glColor3f(*color[1][:3]); gl.glVertex3f(-s,s,0)
gl.glColor3f(*color[2][:3]); gl.glVertex3f(s,s,0)
gl.glColor3f(*color[3][:3]); gl.glVertex3f(s,-s,0)
else:
if solid:
gl.glBegin(gl.GL_TRIANGLE_FAN)
else:
gl.glBegin(gl.GL_LINE_LOOP)
gl.glTexCoord2f(0,0); gl.glVertex3f(-s,-s,0)
gl.glTexCoord2f(0,1); gl.glVertex3f(-s,s,0)
gl.glTexCoord2f(1,1); gl.glVertex3f(s,s,0)
gl.glTexCoord2f(1,0); gl.glVertex3f(s,-s,0)
gl.glEnd()
纹理功能是这样的:
import OpenGL.GL as gl
unit_symbols = [
gl.GL_TEXTURE0,gl.GL_TEXTURE1,gl.GL_TEXTURE2,
gl.GL_TEXTURE3,gl.GL_TEXTURE4,
gl.GL_TEXTURE5,gl.GL_TEXTURE6,gl.GL_TEXTURE7,
gl.GL_TEXTURE8,gl.GL_TEXTURE9,
gl.GL_TEXTURE10,gl.GL_TEXTURE11,gl.GL_TEXTURE12,
gl.GL_TEXTURE13,gl.GL_TEXTURE14,
gl.GL_TEXTURE15,gl.GL_TEXTURE16,gl.GL_TEXTURE17,
gl.GL_TEXTURE18,gl.GL_TEXTURE19,
gl.GL_TEXTURE20,gl.GL_TEXTURE21,gl.GL_TEXTURE22,
gl.GL_TEXTURE23,gl.GL_TEXTURE24,
gl.GL_TEXTURE25,gl.GL_TEXTURE26,gl.GL_TEXTURE27,
gl.GL_TEXTURE28,gl.GL_TEXTURE29,
gl.GL_TEXTURE30,gl.GL_TEXTURE31]
def tx2gpu(image,flip=True,unit=0):
gl.glActiveTexture(unit_symbols[unit])
texture_id = gl.glGenTextures(1)
gl.glBindTexture(gl.GL_TEXTURE_2D,texture_id)
gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_WRAP_S,gl.GL_REPEAT)
gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_WRAP_T,gl.GL_REPEAT)
gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR)
gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MIN_FILTER,gl.GL_LINEAR)
yres,xres,cres = image.shape
from numpy import flipud
gl.glTexImage2D(gl.GL_TEXTURE_2D,0,gl.GL_RGB,xres,yres,0,gl.GL_RGB,gl.GL_UNSIGNED_BYTE,flipud(image))
gl.glBindTexture(gl.GL_TEXTURE_2D,0)
return texture_id
def txrefer(tex_id,unit=0):
gl.glColor4f(1,1,1,1);
gl.glActiveTexture(unit_symbols[unit])
if tex_id!=0:
gl.glEnable(gl.GL_TEXTURE_2D)
gl.glBindTexture(gl.GL_TEXTURE_2D,tex_id)
else:
gl.glBindTexture(gl.GL_TEXTURE_2D,0)
gl.glDisable(gl.GL_TEXTURE_2D)
你遇到的问题是对齐问题。OpenGL对“解包”图像的初始对齐设置是每行从4字节边界开始。如果图像宽度不是4的倍数或每个像素没有4个字节,则会发生这种情况。但要改变这一点很容易:
可能对你有好处。在
glTex[Sub]Image
之前调用它。在另一件事:你的
unit_symbols
列表完全没有必要。OpenGL规范明确指出GL_TEXTUREn
=GL_TEXTURE0 + n
。你只需做glActiveTexture(GL_TEXTURE0 + n)
。然而,加载纹理图像时,该单元是完全不相关的;唯一重要的是,加载纹理时只绑定一个纹理,这发生在纹理单元中;一个纹理可以绑定到任何所需的纹理单元中。在就我个人而言,我使用最高的纹理单位来加载图像,以避免意外地破坏所需的状态。在
相关问题 更多 >
编程相关推荐