문제 설명
Python에서 OpenGL로 텍스처를 렌더링하는 것은 (Rendering a texture with OpenGL in Python is not)
다음 코드를 사용하여 텍스처(.png 사용)를 렌더링하고 싶습니다.
object_cube.loadTextures()
# Execute with Python 3
import pygame
import random
import math
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
camera_x = 0
camera_z = 0
camera_y = 0
x = 0
Vertices = [
[1, ‑1, 1],
[‑1, ‑1, 1],
[‑1, ‑1, ‑1],
[1, ‑1, ‑1],
[1, 1, ‑1],
[‑1, 1, ‑1],
[‑1, 1, 1],
[1, 1, 1]
]
class Ground:
global camera_z
def __init__(self):
self.ground_vertices = (
(‑11, ‑2.01, 20),
(11, ‑2.01, 20),
(11, ‑2.01, ‑300),
(‑11, ‑2.01, ‑300)
)
def draw(self):
glPushMatrix()
glTranslatef(0, 0, camera_z)
glBegin(GL_QUADS)
for vertex in self.ground_vertices:
glColor3fv((0, 0.5, 0.5))
glVertex3fv(vertex)
glEnd()
glPopMatrix()
class Cube:
def __init__(self, v=False):
self.vertices = [
[1, ‑1, 1],
[‑1, ‑1, 1],
[‑1, ‑1, ‑1],
[1, ‑1, ‑1],
[1, 1, ‑1],
[‑1, 1, ‑1],
[‑1, 1, 1],
[1, 1, 1]
]
self.surfaces = (
(0, 1, 6, 7),
(0, 1, 2, 3),
(0, 3, 4, 7),
(1, 2, 6, 5),
(2, 3, 4, 5),
(4, 5, 6, 7)
)
self.colors = (
(105 / 255, 210 / 255, 231 / 255),
(167 / 255, 219 / 255, 216 / 255),
(224 / 255, 228 / 255, 204 / 255),
(243 / 255, 134 / 255, 48 / 255)
)
self.colors2 = (
(0.91, 0.31, 0.47),
(0.84, 0.51, 0.54),
(0.78, 0.64, 0.6),
(0.78, 0.9, 0.85)
)
self.vertices_texture = (
(0.0, 0.0),
(1.0, 0.0),
(1.0, 1.0),
(0.0, 1.0),
)
self.v = v
self.center = [0, 0, 0]
def draw(self):
glBegin(GL_QUADS)
if not self.v:
for surface in self.surfaces:
x = 0
for vertex in surface:
glColor3fv(self.colors2[x])
# glTexCoord2f(self.vertices_texture[x])
glVertex3fv(self.vertices[vertex])
x += 1
else:
for surface in self.surfaces:
x = 0
for vertex in surface:
glColor3fv(self.colors[x])
glTexCoord2fv(self.vertices_texture[x])
glVertex3fv(self.vertices[vertex])
x += 1
glEnd()
def set_vertices(self, max_distance, min_distance=‑40):
x_value_change = random.randrange(‑10, 10)
y_value_change = ‑1
z_value_change = random.randrange(‑1 * max_distance, min_distance)
new_vertices = []
for vertex in Vertices:
new_vertex = []
new_x = vertex[0] + x_value_change
new_y = vertex[1] + y_value_change
new_z = vertex[2] + z_value_change
new_vertex.append(new_x)
new_vertex.append(new_y)
new_vertex.append(new_z)
new_vertices.append(new_vertex)
self.vertices = new_vertices
self.center = [
(self.vertices[2][0]+self.vertices[7][0])/2,
(self.vertices[2][1]+self.vertices[7][1])/2,
(self.vertices[2][2]+self.vertices[7][2])/2
]
def rotate(self):
glPushMatrix()
glRotatef(25, 1, 0, 0)
glPopMatrix()
def loadTexture(self):
textureSurface = pygame.image.load('./textures/ursa.png')
textureData = pygame.image.tostring(textureSurface, "RGBA", 1)
width = textureSurface.get_width()
height = textureSurface.get_height()
glEnable(GL_TEXTURE_2D)
texid = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texid)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData)
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)
# return texid
def movInverse(event):
global x
y = 0
if event.type == pygame.KEYDOWN:
if(math.fabs(x) < 11):
if event.key == pygame.K_LEFT:
x ‑= 1
if event.key == pygame.K_RIGHT:
x += 1
else:
if(x < 0):
if event.key == pygame.K_RIGHT:
x += 1
else:
if event.key == pygame.K_LEFT:
x ‑= 1
if event.key == pygame.K_UP:
y += 1
if event.key == pygame.K_DOWN:
y ‑= 1
glTranslatef(0, y, 0)
def leave(event):
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
quit()
def main():
global camera_x, camera_y, camera_z, x
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL | OPENGLBLIT)
max_distance = 300
gluPerspective(45, (display[0] / display[1]), 0.1, max_distance)
glEnable(GL_DEPTH_TEST)
glTranslatef(0, ‑10 / 2.4, ‑50)
ground = Ground()
cube = Cube(True)
# cube.loadTexture()
# I want to render the texture here, but when I do it, everything get screwed.
my_cubes = []
for i in range(50):
tmp_cube = Cube()
# tmp_cube.loadTexture()
# I also tried to render it here, but I got the same result
tmp_cube.set_vertices(max_distance)
my_cubes.append(tmp_cube)
while True:
for event in pygame.event.get():
leave(event)
movInverse(event)
M = glGetDoublev(GL_MODELVIEW_MATRIX)
# print(M)
camera_x = M[3][0]
camera_y = M[3][1]
camera_z = M[3][2]
glTranslatef(0, 0, 1.5)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
ground.draw()
glPushMatrix()
if(math.fabs(x) < 11):
glTranslatef(x, ‑1.5, camera_z‑20)
glScalef(1 / 2, 1 / 2, 0)
cube.draw()
glPopMatrix()
for tmp_cube in my_cubes:
tmp_cube.draw()
tmp_cube.center[2] += camera_z
print(tmp_cube.center)
for tmp_cube in my_cubes:
if camera_z <= tmp_cube.vertices[0][2]:
new_max = int(‑1 * (camera_z ‑ max_distance * 2))
tmp_cube.set_vertices(new_max, int(camera_z ‑ max_distance))
pygame.display.flip()
if __name__ == '__main__':
main()
주석을 제거하기 전까지는 모든 것이 잘 진행됩니다. 내가 가진 주요 문제는 렌더링된 이미지에 작은 큐브가 표시되지만 나머지는 검은색이라는 것입니다. 그려야 할 나머지 요소는 어떻게 되는지 모르겠습니다.
참조 솔루션
방법 1:
If texturing is enabled, then by default the color of the texel is multiplied by the current color, because by default the texture environment mode (GL_TEXTURE_ENV_MODE
) is GL_MODULATE
. See glTexEnv
.
This causes that the color of the texels of the texture is "mixed" by the last color which you have set by glColor3fv
.</p>
Set a "white" color before you render the textured objects:
glColor3f(1, 1, 1)
Two‑dimensional texturing is enabled by glEnable(GL_TEXTURE_2D)
and can be disabled by glDisable(GL_TEXTURE_2D)
. If texturing is enables then the texture wich is currently bound when the geometry is drawn by the glBegin
/glEnd
sequence is applied.
If you've want to draw objects which are textured, and other objects which are not, then you've to enable texturing before the object is drawn and to disable it after:
class Cube:
# [...]
def draw(self):
if self.v:
glEnable(GL_TEXTURE_2D)
glColor3f(1, 1, 1)
glBegin(GL_QUADS)
if not self.v:
for surface in self.surfaces:
for x, vertex in enumerate(surface):
glColor3fv(self.colors2[x])
glVertex3fv(self.vertices[vertex])
else:
for surface in self.surfaces:
for x, vertex in enumerate(surface):
glTexCoord2fv(self.vertices_texture[x])
glVertex3fv(self.vertices[vertex])
glEnd()
if self.v:
glDisable(GL_TEXTURE_2D)
(by Anthony Luzquiños、Rabbid76)