为什么我的纹理没有显示PyOpenGL

发布于 2021-01-29 17:29:35

我什么都试过了,但还是没有错。我正试着把
球体对象上的纹理。

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

帮我个忙我自己解决不了这个问题。

关注者
0
被浏览
138
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    在“read\u 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\u RGBA”而不是“GL\u RGB”。

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

    You can also automate it.

    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)
    

    You can also convert it to not have an alpha channel.

    img = img.convert("RGB")
    

    当然,在打电话之前需要做些什么img.getdata获取数据().

    也是一个重要的注意事项。您正在“draw\u sphere()”中调用“read\u texture()”。
    这意味着每次调用“draw\u sphere()”时,都会加载图像并
    将创建新纹理。你真的不想那么做。而不是以前
    调用glutMainLoop()callread\u texture()并将结果存储为
    全局名称。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看