我试图弄清楚为什么会出现闪烁和纹理移位。在阅读了一些教程之后,我基本上只是在第一次尝试PyOpenGL,而我只是想制作一个简单的旋转地球球。
作为测试,在while循环(第42行及以后)中,我将框架设置为围绕主旋转轴[1,1,1]以0.5的速度旋转。但是,根据下面的屏幕截图,关于地球的纹理(或者也许是地球模型本身?)开始跳跃。
原始的“ earth.bmp”文件是从3D地球投影的2D地图。
我不知道如何开始进行故障排除。有谁知道出什么问题了吗?下面的代码主要包含三个功能:主循环,创建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()