Python에서 OpenGL로 텍스처를 렌더링하는 것은 (Rendering a texture with OpenGL in Python is not)


문제 설명

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ñosRabbid76)

참조 문서

  1. Rendering a texture with OpenGL in Python is not (CC BY‑SA 2.5/3.0/4.0)

#Python #opengl-compat #textures #opengl #pyopengl






관련 질문

Python - 파일 이름에 특수 문자가 있는 파일의 이름을 바꿀 수 없습니다. (Python - Unable to rename a file with special characters in the file name)

구조화된 배열의 dtype을 변경하면 문자열 데이터가 0이 됩니다. (Changing dtype of structured array zeros out string data)

목록 목록의 효과적인 구현 (Effective implementation of list of lists)

for 루프를 중단하지 않고 if 문을 중지하고 다른 if에 영향을 줍니다. (Stop if statement without breaking for loop and affect other ifs)

기본 숫자를 10 ^ 9 이상으로 늘리면 코드가 작동하지 않습니다. (Code fails to work when i increase the base numbers to anything over 10 ^ 9)

사용자 지정 대화 상자 PyQT5를 닫고 데이터 가져오기 (Close and get data from a custom dialog PyQT5)

Enthought Canopy의 Python: csv 파일 조작 (Python in Enthought Canopy: manipulating csv files)

학생의 이름을 인쇄하려고 하는 것이 잘못된 것은 무엇입니까? (What is wrong with trying to print the name of the student?)

다단계 열 테이블에 부분합 열 추가 (Adding a subtotal column to a multilevel column table)

여러 함수의 변수를 다른 함수로 사용 (Use variables from multiple functions into another function)

리프 텐서의 값을 업데이트하는 적절한 방법은 무엇입니까(예: 경사하강법 업데이트 단계 중) (What's the proper way to update a leaf tensor's values (e.g. during the update step of gradient descent))

Boto3: 조직 단위의 AMI에 시작 권한을 추가하려고 하면 ParamValidationError가 발생합니다. (Boto3: trying to add launch permission to AMI for an organizational unit raises ParamValidationError)







코멘트