简体   繁体   English

谁能向我解释为什么纹理不显示? [PyOpenGL]

[英]May anyone explain to me why the texture doesn't show? [PyOpenGL]

The relevant methods to see are: init , genTexture, onDisplayEvent and table_leg_model. 要查看的相关方法是: init ,genTexture,onDisplayEvent和table_leg_model。

The 'wood1.png' is a 64x64 image. “ wood1.png”是64x64的图片。

Code : 代码:

import Image

from math import cos
from math import pi
from math import sin
from numpy import array
from numpy import uint8
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from sys import argv

# Classes ----------------------------------------------------------------------
class AppGL(object):
    def __init__(self, title, position=(100, 100), size=(400, 400)):
        # Properties -----------------------------------------------------------
        self.angle_delta = 4.0
        self.position = position
        self.rotateX = [0, 1.0, 0.0, 0.0]
        self.rotateY = [0, 0.0, 1.0, 0.0]
        self.size = size
        self.translate = [0.0, 0.0, 0.0]

        self.textures_index = {
            'wood1': 0,
        }
        self.textures = array([0] * len(self.textures_index), uint8)
        #-----------------------------------------------------------------------

        # General initialization
        glClearColor(0.0, 0.0, 0.0, 1.0)

        glEnable(GL_DEPTH_TEST)
        glEnable(GL_TEXTURE_2D)

        glGenTextures(len(self.textures), self.textures)
        self.genTexture('wood1', 'textures/wood1.png')
        #-----------------------------------------------------------------------

        # GLUT initialization --------------------------------------------------
        glutInit(argv)
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
        glutInitWindowPosition(*self.position)
        glutInitWindowSize(*self.size)
        glutCreateWindow(title)
        #-----------------------------------------------------------------------

        # Callbacks ------------------------------------------------------------
        glutDisplayFunc(self.onDisplayEvent)
        glutKeyboardFunc(self.onKeyEvent)
        glutMotionFunc(self.onMouseMotionEvent)
        glutMouseFunc(self.onMouseButtonEvent)
        glutReshapeFunc(self.onReshapeEvent)
        glutSpecialFunc(self.onSpecialKeyEvent)
        #-----------------------------------------------------------------------

        # Arrays ---------------------------------------------------------------
        data = []
        #data.extend(table_model(0.4, 40))
        data.extend(table_leg_model())
        #data.extend(table_model(0.2, 40))

        glInterleavedArrays(GL_T2F_V3F, 0, array(data, "f"))
        #-----------------------------------------------------------------------

    def genTexture(self, index, path):
        img = Image.open(path)
        texture_data = array(list(img.getdata()), uint8)

        glBindTexture(GL_TEXTURE_2D, self.textures[self.textures_index[index]])
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data)

    def onDisplayEvent(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glLoadIdentity()
        gluLookAt(0, 0, 4, 0, 0, -1, 0, 1, 0)

        glTranslatef(*self.translate)
        glRotatef(*self.rotateX)
        glRotatef(*self.rotateY)

        # Visual scene ---------------------------------------------------------
        glPushMatrix()

        # Table -----------------------~
        #glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(0, 80, 2), "d"))
        #glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(1, 80, 2), "d"))
        #glDrawElements(GL_QUAD_STRIP, 80, GL_UNSIGNED_INT, array(xrange(0, 80), "d"))

        getMatrixHead()
        glTranslatef(-0.1, -0.1, 0)
        #glDrawElements(GL_QUAD_STRIP, 10, GL_UNSIGNED_INT, array(xrange(80, 90), "d"))
        glDrawElements(GL_QUAD_STRIP, 10, GL_UNSIGNED_INT, array(xrange(0, 10), "d"))

        #getMatrixHead()
        #glTranslatef(0, 0, 1)
        #glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(90, 170, 2), "d"))
        #glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(91, 170, 2), "d"))
        #glDrawElements(GL_QUAD_STRIP, 80, GL_UNSIGNED_INT, array(xrange(90, 170), "d"))

        glPopMatrix()
        #-----------------------------------------------------------------------

        glutSwapBuffers()

    def onKeyEvent(self, key, x, y):
        change = True

        if key == 'a':
            self.translate[0] += 1

        elif key == 'd':
            self.translate[0] -= 1

        elif key == 's':
            self.translate[1] += 1

        elif key == 'w':
            self.translate[1] -= 1

        elif key == 'q':
            self.translate[2] += 1

        elif key == 'e':
            self.translate[2] -= 1

        else:
            change = False

        if change: glutPostRedisplay()

    def onMouseMotionEvent(self, x, y):
        pass

    def onMouseButtonEvent(self, button, state, x, y):
        pass

    def onReshapeEvent(self, width, height):
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(60.0, width / height, 1.0, 100.0)
        glMatrixMode(GL_MODELVIEW)

    def onSpecialKeyEvent(self, key, x, y):
        change = True

        if key == GLUT_KEY_UP:
            self.rotateX[0] += self.angle_delta

        elif key == GLUT_KEY_DOWN:
            self.rotateX[0] -= self.angle_delta

        elif key == GLUT_KEY_LEFT:
            self.rotateY[0] += self.angle_delta

        elif key == GLUT_KEY_RIGHT:
            self.rotateY[0] -= self.angle_delta

        else:
            change = False

        if change: glutPostRedisplay()

    def run(self):
        glutMainLoop()
#-------------------------------------------------------------------------------

# Functions --------------------------------------------------------------------
def getMatrixHead():
    glPopMatrix()
    glPushMatrix()

def table_model(radius, number_of_points):
    delta = 2 * pi / (number_of_points - 1)
    points = []

    for i in xrange(number_of_points):
        points.extend((radius * cos(i * delta), radius * sin(i * delta), 0.05))
        points.extend((radius * cos(i * delta), radius * sin(i * delta), 0))

    return points

def table_leg_model():
    return (
        0, 0,   0, 0.2, 0,
        0, 1,   0, 0.2, 1.0,
        1, 0,   0, 0, 0,
        1, 1,   0, 0, 1.0,
        #0, 0,   0.2, 0, 0,
        #0, 1,   0.2, 0, 1.0,
        #1, 0,   0.2, 0.2, 0,
        #1, 1,   0.2, 0.2, 1.0,
        #0, 0,   0, 0.2, 0,
        #0, 1,   0, 0.2, 1.0,
    )
#-------------------------------------------------------------------------------

# Main -------------------------------------------------------------------------
if __name__ == '__main__':
    AppGL("Moe's Tavern", (300, 100), (800, 600)).run()
#-------------------------------------------------------------------------------

The source code can also be found here ~> https://github.com/EPadronU/TavernGL/blob/master/appgl.py 也可以在这里找到源代码〜> https://github.com/EPadronU/TavernGL/blob/master/appgl.py

I'll just run down the list of what stroke me curious: 我只列出我好奇的中风清单:

The function getMatrixHead makes no sense, at least the naming. 函数getMatrixHead至少在命名上没有意义。 At best it will just drop what's been on the stack and make a copy of what's below. 充其量,它只会丢弃堆栈中的内容并复制下面的内容。

Then you make the typical newbie error of trying to "initialize" OpenGL. 然后,您会遇到尝试“初始化” OpenGL的典型新手错误。 Don't do that. 不要那样做 Except for loading textures or VBO data make OpenGL calls only from the display function and nowhere else. 除了加载纹理或VBO数据外,仅从显示功能进行OpenGL调用,而其他任何地方都不能进行。 If you made a backtrace whenever a OpenGL function is called it should only happen because ultimately because display was called. 如果每当调用OpenGL函数时都进行了回溯,则应仅由于最终由于调用了display而发生。 If you had done it that way you'd not have made OpenGL called before there was an actual OpenGL context: Only after a OpenGL context has been created OpenGL calls have an effect. 如果您以这种方式完成操作,则不会在存在实际的OpenGL上下文之前调用OpenGL:仅创建OpenGL上下文之后, OpenGL调用才会生效。 If using GLUT that's after calling glutCreateWindow 如果调用glutCreateWindow 之后使用GLUT

Now look at that code: 现在看一下该代码:

    glEnable(GL_DEPTH_TEST)
    glEnable(GL_TEXTURE_2D)

    glGenTextures(len(self.textures), self.textures)
    self.genTexture('wood1', 'textures/wood1.png')
    #-----------------------------------------------------------------------

    # GLUT initialization --------------------------------------------------
    glutInit(argv)
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowPosition(*self.position)
    glutInitWindowSize(*self.size)
    glutCreateWindow(title)

You're making OpenGL calls before there is a context. 您需要在没有上下文的情况下进行OpenGL调用。 If you had written it in the following way it would have worked (I also took the liberty at giving it a nice informative loading screen) 如果您以下面的方式编写它,那么它可能会起作用(我也很乐意为它提供一个很好的信息加载屏幕)

import Image

from math import cos
from math import pi
from math import sin
from numpy import array
from numpy import uint8
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from sys import argv

# Classes ----------------------------------------------------------------------
class AppGL(object):
    def __init__(self, title, position=(100, 100), size=(400, 400)):
        # Properties -----------------------------------------------------------
        self.angle_delta = 4.0
        self.position = position
        self.rotateX = [0, 1.0, 0.0, 0.0]
        self.rotateY = [0, 0.0, 1.0, 0.0]
        self.size = size
        self.translate = [0.0, 0.0, 0.0]
        self.textures = dict()

        #-----------------------------------------------------------------------

        # GLUT initialization --------------------------------------------------
        glutInit(argv)
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
        glutInitWindowPosition(*self.position)
        glutInitWindowSize(*self.size)
        glutCreateWindow(title)
        #-----------------------------------------------------------------------

        # Callbacks ------------------------------------------------------------
        glutDisplayFunc(self.onDisplayEvent)
        glutKeyboardFunc(self.onKeyEvent)
        glutMotionFunc(self.onMouseMotionEvent)
        glutMouseFunc(self.onMouseButtonEvent)
        glutReshapeFunc(self.onReshapeEvent)
        glutSpecialFunc(self.onSpecialKeyEvent)
        #-----------------------------------------------------------------------

        # Arrays ---------------------------------------------------------------
        self.tablelegmodel = array( list(table_leg_model()), "f")

        #-----------------------------------------------------------------------

    def loadTexture(self, path):
        if path in self.textures.keys():
            glBindTexture(GL_TEXTURE_2D, self.textures[path])
            return

        glDrawBuffer(GL_FRONT)
        glClearColor(0.25, 0.25, 0.75, 1.)
        glClear(GL_COLOR_BUFFER_BIT)

        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glLoadIdentity()

        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()

        glRasterPos3f(-0.9, 0.9, 0)
        glDisable(GL_TEXTURE_2D)
        glDisable(GL_LIGHTING)
        glutBitmapString(GLUT_BITMAP_HELVETICA_18, "Loading Texture " + path)
        glFinish()
        glDrawBuffer(GL_BACK)

        glMatrixMode(GL_PROJECTION)
        glPopMatrix()
        glMatrixMode(GL_MODELVIEW)
        glPopMatrix()

        img = Image.open(path)
        texture_data = array(list(img.getdata()), uint8)

        texID = array([0], uint8)
        glGenTextures(1, texID)
        texID = texID[0]

        self.textures[path] = texID
        glBindTexture(GL_TEXTURE_2D, texID)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data)

    def onDisplayEvent(self):
        width, height = self.size
        aspect = float(width) / float(height)

        glClearColor(0.0, 0.0, 0.0, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glViewport(0, 0, width, height)

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(60.0, aspect, 1.0, 100.0)

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        gluLookAt(0, 0, 4, 0, 0, -1, 0, 1, 0)

        glTranslatef(*self.translate)
        glRotatef(*self.rotateX)
        glRotatef(*self.rotateY)

        # Visual scene ---------------------------------------------------------
        glEnable(GL_DEPTH_TEST)

        glPushMatrix()
        glTranslatef(-0.1, -0.1, 0)

        self.loadTexture('textures/wood1.png')

        glEnable(GL_TEXTURE_2D)

        glInterleavedArrays(GL_T2F_V3F, 0, self.tablelegmodel)
        glDrawElements(GL_QUAD_STRIP, 10, GL_UNSIGNED_INT, array(xrange(0, 10), "d"))

        glPopMatrix()
        #-----------------------------------------------------------------------

        glutSwapBuffers()

    def onKeyEvent(self, key, x, y):
        if key == 'a':
            self.translate[0] += 1

        elif key == 'd':
            self.translate[0] -= 1

        elif key == 's':
            self.translate[1] += 1

        elif key == 'w':
            self.translate[1] -= 1

        elif key == 'q':
            self.translate[2] += 1

        elif key == 'e':
            self.translate[2] -= 1

        else:
            return

        glutPostRedisplay()

    def onMouseMotionEvent(self, x, y):
        pass

    def onMouseButtonEvent(self, button, state, x, y):
        pass

    def onReshapeEvent(self, width, height):
        self.size = width, height
        glutPostRedisplay()

    def onSpecialKeyEvent(self, key, x, y):
        if key == GLUT_KEY_UP:
            self.rotateX[0] += self.angle_delta

        elif key == GLUT_KEY_DOWN:
            self.rotateX[0] -= self.angle_delta

        elif key == GLUT_KEY_LEFT:
            self.rotateY[0] += self.angle_delta

        elif key == GLUT_KEY_RIGHT:
            self.rotateY[0] -= self.angle_delta

        else:
            return

        glutPostRedisplay()

    def run(self):
        glutMainLoop()
#-------------------------------------------------------------------------------

def table_model(radius, number_of_points):
    delta = 2 * pi / (number_of_points - 1)
    points = []

    for i in xrange(number_of_points):
        points.append((radius * cos(i * delta), radius * sin(i * delta), 0.05))
        points.append((radius * cos(i * delta), radius * sin(i * delta), 0))

    return points

def table_leg_model():
    return (
        0, 0,   0, 0.2, 0,
        0, 1,   0, 0.2, 1.0,
        1, 0,   0, 0, 0,
        1, 1,   0, 0, 1.0,
        #0, 0,   0.2, 0, 0,
        #0, 1,   0.2, 0, 1.0,
        #1, 0,   0.2, 0.2, 0,
        #1, 1,   0.2, 0.2, 1.0,
        #0, 0,   0, 0.2, 0,
        #0, 1,   0, 0.2, 1.0,
    )
#-------------------------------------------------------------------------------

# Main -------------------------------------------------------------------------
if __name__ == '__main__':
    AppGL("Moe's Tavern", (300, 100), (800, 600)).run()
#-------------------------------------------------------------------------------

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM