PyOpenGL纹理闪烁和跳跃

时间:2020-06-08 05:13:07

标签: python opengl graphics 3d pyopengl

我试图弄清楚为什么会出现闪烁和纹理移位。在阅读了一些教程之后,我基本上只是在第一次尝试PyOpenGL,而我只是想制作一个简单的旋转地球球。

作为测试,在while循环(第42行及以后)中,我将框架设置为围绕主旋转轴[1,1,1]以0.5的速度旋转。但是,根据下面的屏幕截图,关于地球的纹理(或者也许是地球模型本身?)开始跳跃。

Screenshot from PyGame Window of a texture jump and flicker

原始的“ earth.bmp”文件是从3D地球投影的2D地图。

enter image description here

我不知道如何开始进行故障排除。有谁知道出什么问题了吗?下面的代码主要包含三个功能:主循环,创建Earth sphere和读取纹理的功能。

# Import PyGame, PyOpenGL and other public libraries.
import pygame
import numpy as np
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from PIL import Image as Image

def main():

    # Initialise PyGame.
    pygame.init()
    display = (600,450)

    # We need to inform PyGame that we are using OpenGL
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

    # gluPerspective( FOV (deg), aspect ratio, z-near, z-far)
    # Aspect ratio = (width / height)
    # z-near and z-far refer to clipping ranges (when images disappear)
    gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)

    # For moving about the object: X, Y, Z (we want to zoom out on Z)
    glTranslatef(0.0, 0.0, -5.0)

    # Rotation matrix (velocity, X, Y, Z of principal rotation axis)
    glRotate(0, 0, 0, 0)

    # Now we want to import the Earth's texture.
    texture_earth = Read_Texture('earth.bmp')

    # This section runs the main loop of the code.
    # In essence, it has the following structure within a while loop:
    #
    # handleEvents()
    # glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    # doTransformationsAndDrawing()
    # pygame.display.flip()
    # pygame.time.wait(1)

    while True:

        # Standard PyGame handling code to kill the application if it closes.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()


        # Pygame is just showing you the frame.
        # We actually need to clear the frame between each frame!
        # Then we draw on top of the empty cleared frame again.
        # Inputs are two constants telling OpenGL specifically what to clear.
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

        # glRotate(angular velocity, X, Y, Z of principal rotation axis)
        glRotate(0.5,1,1,1)

        # Brew up the code into OpenGL
        #gen_cubesat.CubeSat()
        Body_Earth(texture_earth)

        # Update the PyGame frame
        pygame.display.flip()
        pygame.time.wait(5)

# Function that generates the Earth sphere (to be called in main loop)
def Body_Earth(texture):

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    # OpenGL keeps a stack of matrices to apply and remove transformations.
    # glPushMatrix copies the top matrix and pushes it onto the stack.
    # glPopMatrix pops the top matrix off the stack.
    # All transformation functions (glScaled, etc.) apply on the top matrix.
    # The top matrix is what all rendering commands use to transform the data.

    # By pushing and popping matrices, you can control what transformations
    # apply to which objects, as well as apply transformations to groups of
    # objects, and easily reverse the transformations so that they don't
    # affect other objects.

    glPushMatrix()

    # State machine for glEnable?
    glEnable(GL_TEXTURE_2D)

    earth_sphere = gluNewQuadric()
    gluQuadricTexture(earth_sphere, GL_TRUE)
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, texture)
    gluSphere(earth_sphere, 1, 50, 50)
    gluDeleteQuadric(earth_sphere)
    glDisable(GL_TEXTURE_2D)

    # Explain pop matrix here?
    glPopMatrix()

# Generic function from that allows OpenGL objects to read textures.
def Read_Texture(filename):
    img = Image.open(filename)
    img_data = np.array(list(img.getdata()), np.int8)
    texture_id = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture_id)
    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__':
    main()

0 个答案:

没有答案