现代opengl python程序有立方体,但没有纹理
下面的最新代码是Superbible OpenGL第7版程序的移植python程序 立方体将显示,但纹理不会显示。也应该有轻微的向隧道移动,但这也没有发生。你知道这是什么原因吗 更新:多亏了Rabbi76,纹理现在出现了,并且渲染正确现代opengl python程序有立方体,但没有纹理,python,python-3.x,opengl,glut,texture-mapping,Python,Python 3.x,Opengl,Glut,Texture Mapping,下面的最新代码是Superbible OpenGL第7版程序的移植python程序 立方体将显示,但纹理不会显示。也应该有轻微的向隧道移动,但这也没有发生。你知道这是什么原因吗 更新:多亏了Rabbi76,纹理现在出现了,并且渲染正确 #!/usr/bin/python3 import sys import time sys.path.append("./shared") #from sbmloader import SBMObject # location of sbm file
#!/usr/bin/python3
import sys
import time
sys.path.append("./shared")
#from sbmloader import SBMObject # location of sbm file format loader
from ktxloader import KTXObject # location of ktx file format loader
from sbmath import m3dDegToRad, m3dRadToDeg, m3dTranslateMatrix44, m3dRotationMatrix44, m3dMultiply, m3dOrtho, m3dPerspective, rotation_matrix, translate, m3dScaleMatrix44
fullscreen = True
#import numpy.matlib
#import numpy as np
try:
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray
except:
print ('''
ERROR: PyOpenGL not installed properly.
''')
sys.exit()
identityMatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
render_prog = GLuint(0)
render_vao = GLuint(0)
class uniforms:
mvp = GLint
offset = GLint
tex_wall = GLuint(0)
tex_ceiling = GLuint(0)
tex_floor = GLuint(0)
uniform = uniforms()
class Scene:
def __init__(self, width, height):
global render_prog
global render_vao
global uniform
global tex_wall, tex_ceiling, tex_floor
self.width = width
self.height = height
vs = GLuint(0)
fs = GLuint(0)
vs_source = '''
#version 420 core
out VS_OUT
{
vec2 tc;
} vs_out;
uniform mat4 mvp;
uniform float offset;
void main(void)
{
const vec2[4] position = vec2[4](vec2(-0.5, -0.5),
vec2( 0.5, -0.5),
vec2(-0.5, 0.5),
vec2( 0.5, 0.5));
vs_out.tc = (position[gl_VertexID].xy + vec2(offset, 0.5)) * vec2(30.0, 1.0);
gl_Position = mvp * vec4(position[gl_VertexID], 0.0, 1.0);
}
'''
fs_source = '''
#version 420 core
layout (location = 0) out vec4 color;
in VS_OUT
{
vec2 tc;
} fs_in;
layout (binding = 0) uniform sampler2D tex;
void main(void)
{
color = texture(tex, fs_in.tc);
}
'''
vs = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vs, vs_source)
glCompileShader(vs)
glGetShaderInfoLog(vs)
fs = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fs, fs_source)
glCompileShader(fs)
glGetShaderInfoLog(vs)
render_prog = glCreateProgram()
glAttachShader(render_prog, vs)
glAttachShader(render_prog, fs)
glLinkProgram(render_prog)
glDeleteShader(vs)
glDeleteShader(fs)
glGetProgramInfoLog(render_prog)
uniform.mvp = glGetUniformLocation(render_prog, "mvp")
uniform.offset = glGetUniformLocation(render_prog, "offset")
glGenVertexArrays(1, render_vao)
glBindVertexArray(render_vao)
ktxobj = KTXObject()
tex_wall = ktxobj.ktx_load("brick.ktx")
tex_ceiling = ktxobj.ktx_load("ceiling.ktx")
tex_floor = ktxobj.ktx_load("floor.ktx")
textures = [ tex_floor, tex_wall, tex_ceiling ]
for i in range (0, 3):
glBindTexture(GL_TEXTURE_2D, textures[i])
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glBindVertexArray(render_vao)
def display(self):
green = [ 0.0, 0.1, 0.0, 0.0 ]
currentTime = time.time()
glViewport(0, 0, self.width, self.height)
glClearBufferfv(GL_COLOR, 0, green)
glUseProgram(render_prog)
proj_matrix = (GLfloat * 16)(*identityMatrix)
proj_matrix = m3dPerspective(m3dDegToRad(60.0), float(self.width) / float(self.height), 0.1, 100.0)
glUniform1f(uniform.offset, -(currentTime * 0.03) % 1) # negative sign to postive changes direction
textures = [ tex_wall, tex_ceiling, tex_wall, tex_floor ]
for i in range(0, 4):
RZ = (GLfloat * 16)(*identityMatrix)
m3dRotationMatrix44(RZ, i * m3dDegToRad(90.0), 0.0, 0.0, 1.0)
T = (GLfloat * 16)(*identityMatrix)
m3dTranslateMatrix44(T, -5, 0, -10)
RY = (GLfloat * 16)(*identityMatrix)
m3dRotationMatrix44(RY, m3dDegToRad(90.0), 0.0, 1.0, 0.0)
S = (GLfloat * 16)(*identityMatrix)
m3dScaleMatrix44(S, 300.0, 10.0, 1.0)
mv_matrix = (GLfloat * 16)(*identityMatrix)
mv_matrix = m3dMultiply(RZ, m3dMultiply(T, m3dMultiply(RY, S)))
mvp = (GLfloat * 16)(*identityMatrix)
mvp = m3dMultiply(proj_matrix , mv_matrix )
glUniformMatrix4fv(uniform.mvp, 1, GL_FALSE, mvp)
glBindTexture(GL_TEXTURE_2D, textures[i]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glutSwapBuffers()
def reshape(self, width, height):
self.width = width
self.height = height
def keyboard(self, key, x, y ):
global fullscreen
print ('key:' , key)
if key == b'\x1b': # ESC
sys.exit()
elif key == b'f' or key == b'F': #fullscreen toggle
if (fullscreen == True):
glutReshapeWindow(512, 512)
glutPositionWindow(int((1360/2)-(512/2)), int((768/2)-(512/2)))
fullscreen = False
else:
glutFullScreen()
fullscreen = True
print('done')
def init(self):
pass
def timer(self, blah):
glutPostRedisplay()
glutTimerFunc( int(1/60), self.timer, 0)
time.sleep(1/60.0)
if __name__ == '__main__':
start = time.time()
glutInit()
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(512, 512)
w1 = glutCreateWindow('OpenGL SuperBible - Tunnel')
glutInitWindowPosition(int((1360/2)-(512/2)), int((768/2)-(512/2)))
fullscreen = False
many_cubes = False
#glutFullScreen()
scene = Scene(512,512)
glutReshapeFunc(scene.reshape)
glutDisplayFunc(scene.display)
glutKeyboardFunc(scene.keyboard)
glutIdleFunc(scene.display)
#glutTimerFunc( int(1/60), scene.timer, 0)
scene.init()
glutMainLoop()
该程序应显示为:
更新:有了Rabbid76的惊人代码和洞察,输出现在可以正确呈现。下面是输出的动画gif
依赖项文件:,
在“共享”文件夹中,您必须使用在场景的构造函数中设置全局命名空间中的变量tex_wall、tex_天花板、tex_floor:
课堂场景:
定义初始自身、宽度、高度:
全球tex_墙、tex_天花板、tex_地板
[...]
tex_wall=ktxobj.ktx_loadbrick.ktx
tex_天花板=ktxobj.ktx_load天花.ktx
tex_floor=ktxobj.ktx_loadfloor.ktx
[...]
此外,设置模型矩阵时还存在一些问题。y比例必须为10.0,以将墙缩放到适当的高度和宽度:
m3dScaleMatrix44S、30.0、1.0、1.0
m3dScaleMatrix44S、300.0、10.0、1.0
平移必须在围绕z轴旋转之前完成,因为墙壁、地板和天花板应旋转或移位。必须首先进行缩放:
mv_矩阵=m3dMultiplyT,m3dMultiplyRZ,m3dMultiply,RY
mv_矩阵=m3dMultiplyRZ,m3dMultiplyT,m3dMultiplyRY,S
在ktxloader模块中,当从位图读取数据字节时,使用ptr:
因此,ptr必须由h.keypairbyte增加:
数据_start=ptr+h.keypairbytes
dt=数据[数据开始:]
ptr+=h.keypairbytes
地板和天花板已交换:
纹理=[tex_墙、tex_地板、tex_墙、tex_天花板]
纹理=[tex_墙、tex_天花板、tex_墙、tex_地板]
在设置纹理偏移量均匀浮点偏移量之前,必须使用%modulo运算符,因为currentTime中的值很大,不适合单精度32位浮点值。由于纹理坐标在[0.0,1.0]范围内,因此偏移的分数部分可以通过%1计算。e、 g:
glUniform1funiform.offset,currentTime*-0.03%1
我已合并您的更改,并更新了输出屏幕截图。尽管可能是由于纹理关闭,ktxloader.py无法正常工作。也许你可以看看,并做一些面向对象的代码编写魔术。多谢各位@斯坦。是的,纹理没有正确读取form.kxt。“我现在很忙,但我稍后再试。”斯坦说。我的答案中有一个拼写错误:全球特克斯墙,特克斯天花板,特克斯福尔必须是全球特克斯墙,特克斯天花板,特克斯地板。必须缩放几何体的两个维度:m3dScaleMatrix44S、300.0、10.0、1.0使用%1解决方案解决纹理问题的难以置信的代码。这是一个非常好的发现,解释是完美的。我永远也想不到,我一直在怀疑加载器,尽管加载器在alienrain.py程序中正确地加载了一个外星人,所以有点奇怪,并且该程序中的4行仍然是一个谜。同样,在这个程序中,我注意到将符号改为负数会改变立方体的方向。glUniform1funiform.offset,-currentTime*0.03%1感谢您提供的loader和%1 tunnel.py解决方案。太棒了!
glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, width, height, h.glformat, h.gltype, data[ptr:])