Por qué mi textura no muestra PyOpenGL

Lo intenté todo pero aún no me sale mi error. Estoy tratando de poner una textura en el objeto de mi esfera.

""" Minimal texture on sphere demo This is demo for showing how to put image on sphere as texture in PyOpenGL. """ from OpenGL.GLUT import * from OpenGL.GLU import * from OpenGL.GL import * from PIL import Image import numpy def run_scene(): glutInit() glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) glutCreateWindow("Minimal sphere OpenGL") lightning() glutDisplayFunc(draw_sphere) glMatrixMode(GL_PROJECTION) gluPerspective(40, 1, 1, 40) glMatrixMode(GL_MODELVIEW) gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0) glPushMatrix() glutMainLoop() return def lightning(): glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_BLEND) glLightfv(GL_LIGHT0, GL_POSITION, [10, 4, 10, 1]) glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 1, 0.8, 1]) glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1) glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05) glEnable(GL_LIGHT0) return def draw_sphere(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glPushMatrix() texture_id = read_texture('mars.png') glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, texture_id) glEnable(GL_TEXTURE_GEN_S) glEnable(GL_TEXTURE_GEN_T) glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) glutSolidSphere(1, 50, 50) glDisable(GL_TEXTURE_2D) glPopMatrix() glutSwapBuffers() return def read_texture(filename): img = Image.open(filename) img_data = numpy.array(list(img.getdata()), numpy.int8) texture_id = glGenTextures(1) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data) return texture_id if __name__ == '__main__': run_scene() 

Este es el resultado de este código, simple esfera verde como esta:

introduzca la descripción de la imagen aquí

Pero este no es mi resultado esperado. Quiero simplemente mostrar esta textura mars.png en la superficie de la esfera:

introduzca la descripción de la imagen aquí

Ayúdame con esto, no puedo resolver esto por mi cuenta, parece.

En read_texture() después de generar un nombre de textura, no lo vinculas. Por lo tanto, las siguientes llamadas relacionadas con la textura irán a la textura predeterminada y no a la textura recién creada.

 texture_id = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texture_id) # This is what's missing 

También ya que su imagen es una imagen PNG. Entonces list(img.getdata()) será una lista de tuplas que contienen (R, G, B, A) . Por eso, cuando llame a glTexImage2D , debe saber que sus datos son GL_RGBA y no GL_RGB .

 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data) 

También puedes automatizarlo.

 format = GL_RGB if img.mode == "RGB" else GL_RGBA glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, format, GL_UNSIGNED_BYTE, img_data) 

También puedes convertirlo para no tener un canal alfa.

 img = img.convert("RGB") 

Lo que, por supuesto, debe hacerse antes de llamar a img.getdata() .

Ahora deberías ver lo siguiente:

También una nota importante. Estás llamando a read_texture() en draw_sphere() . Esto significa que cada vez que se llama a draw_sphere() , la imagen se carga y se crea una nueva textura. Realmente no quieres hacer eso. En su lugar, antes de llamar a glutMainLoop() llame a read_texture() y almacene el resultado como un nombre global.