2017-03-26 12 views
0

私はすべてを試しましたが、まだ私はエラーが表示されません。私は球体にテクスチャをつけようとしています。なぜ私のテクスチャが表示されないのですか?PyOpenGL

""" 
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() 

これは、このコードの結果であり、このような単純な緑色の球:

enter image description here

しかし、これは私の期待する結果ではありません。私は単純に球の表面にこのテクスチャmars.pngを表示したい:

enter image description here

私はそれはそう自分でこの問題を解決することはできませんこれで私を助けて。

答えて

0

read_texture()テクスチャ名を生成した後、バインドしません。したがって、その後のテクスチャ関連の呼び出しは、既定のテクスチャに移動し、新しく作成されたテクスチャには移動しません。

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

また、あなたの画像はPNG画像です。 list(img.getdata())は、(R, G, B, A)を含むタプルのリストになります。したがって、glTexImage2Dに電話するときは、データがGL_RGBAで、GL_RGBではないことを知らせる必要があります。

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

自動化することもできます。

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) 

また、アルファチャンネルを持たないように変換することもできます。もちろんimg.getdata()を呼び出す前に実行する必要がある

img = img.convert("RGB") 

今、あなたは次のように表示されます

また重要な注意。 read_texture()draw_sphere()に呼び出しています。つまり、draw_sphere()が呼び出されるたびに、イメージがロードされ、新しいテクスチャが作成されます。あなたは本当にそれをしたくありません。その代わりに、glutMainLoop()を呼び出してread_texture()と呼び出し、結果をグローバル名として保存してください。