使用glBindTextu获取错误纹理

2024-09-30 16:36:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个.png格式的纹理(地板和墙),我在初始化时加载它们,并在渲染之前选择glBindTexture,但是我得到了: screen_shot_1 而不是这样: screen_shot_2 初始化:

def __init__(self, screen_info, wall_number):
    self.screen = screen_info
    self.inscription = font.Font(get_path([RES_PATH[0], 'font', 'main.ttf']), 12)
    self.path = get_path([RES_PATH[0], RES_PATH[1], ''])
    self.sprite_list = {}
    self.tex_list = {}
    self.generate_list()
    self.wall_coordinates = []
    self.wall_number = wall_number
    self.wall_counter = 0

    glClearColor(*BACKGROUND_COLOR)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(FOV, self.screen.current_w / self.screen.current_h, DISTANCE_NEAR, DISTANCE_FAR)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glEnable(GL_DEPTH_TEST)
    glEnable(GL_TEXTURE_2D)
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

主回路:

^{pr2}$

纹理加载程序:

def load_tex(self, filename, rotate=False, text_render=False, text=''):
    if not text_render:
        surface = image.load(filename)

        if rotate:
            surface = transform.rotate(surface, 180)

    else:
        surface = self.inscription.render(str(text), 1, (255, 255, 255), (0, 0, 0))
        surface = transform.scale(surface, (64, 64))
        surface = transform.rotate(surface, 180)

    size = surface.get_size()
    surface = image.tostring(surface, 'RGB', True)
    texture = glGenTextures(1)

    glBindTexture(GL_TEXTURE_2D, texture)
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    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, 3, size[0], size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, surface)

    return texture

初始化期间加载纹理:

def generate_list(self):
    for filename in listdir(self.path):
        self.tex_list[filename] = self.load_tex(get_path([RES_PATH[0], RES_PATH[1], filename]))

绘图地:

def draw_ground(self, x, z, length=50):
    glBindTexture(GL_TEXTURE_2D, self.tex_list['floor.png'])
    # glBindTexture(GL_TEXTURE_2D, self.load_tex(get_path([RES_PATH[0], RES_PATH[1], 'floor.png'])))
    glBegin(GL_QUADS)

    glTexCoord2f(0, length)
    glVertex3f(x - length, -0.5, z + length)
    glTexCoord2f(length, length)
    glVertex3f(x + length, -0.5, z + length)
    glTexCoord2f(length, 0)
    glVertex3f(x + length, -0.5, z - length)
    glTexCoord2f(0, 0)
    glVertex3f(x - length, -0.5, z - length)

    glEnd()

绘制墙:

def draw_square(self, x, y, z, length=2, rot=False):
    glBindTexture(GL_TEXTURE_2D, self.tex_list['wall.png'])
    # glBindTexture(GL_TEXTURE_2D, self.load_tex(get_path([RES_PATH[0], RES_PATH[1], 'wall.png'])))
    glBegin(GL_QUADS)

    glTexCoord2f(0, 1)
    glVertex3f(x, y, z)
    glTexCoord2f(1, 1)

    if not rot:
        glVertex3f(x + length, y, z)
        glTexCoord2f(1, 0)
        glVertex3f(x + length, y - length, z)

    else:
        glVertex3f(x, y, z + length)
        glTexCoord2f(1, 0)
        glVertex3f(x, y - length, z + length)

    glTexCoord2f(0, 0)
    glVertex3f(x, y - length, z)

    glEnd()

那么问题是什么呢?在


Tags: pathselfresscreensurfacelengthlisttex
1条回答
网友
1楼 · 发布于 2024-09-30 16:36:29

我在你的代码中注意到了一些可能与你的纹理问题无关的事情:

  • 对于你的glTexParameterf调用,我看到你最近用的是GL。这将导致像素化纹理。如果不使用pixel art,您可能需要考虑将GL峎LINEAR作为最终参数,因为这将执行双线性插值,从而删除显著的像素化。在
  • 我不认为你需要glTexEnvf和glPixelStorei电话。在
  • 作为一个好习惯,一旦你使用完一个纹理,你应该通过调用glBindTexture(GL_texture_0,0)来解除绑定。OpenGL是关于状态的,所以在你完成后把事情恢复到原来的状态是个好主意,这样你以后就不会对奇怪的行为感到惊讶了。我的猜测是您没有正确绑定第二个纹理(检查纹理ID),导致第一个纹理用于所有调用。尝试重新排序绘图调用,看看纹理是否发生变化。这只是猜测,因为我无法运行您的示例代码。在
  • glTexImage2D的参数看起来很奇怪。您可能想看看opengl docs以及它们的python等价物。我个人喜欢使用GL_gba这样的枚举来表示格式,以使代码更清晰。在

下面是我用pyopengl和pygame制作的一个简单的演示。它渲染两个二维正方形,每个具有不同的纹理。结构和U是重要的功能部件,而载荷是主要部件:

import pygame
from pygame.locals import *
from OpenGL.GL import *
import sys

def init_gl():
    window_size = width, height = (550, 400)
    pygame.init()
    pygame.display.set_mode(window_size, OPENGL | DOUBLEBUF)
    glEnable(GL_TEXTURE_2D)
    glMatrixMode(GL_PROJECTION)
    glOrtho(0, width, height, 0, -1, 1)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

def load_texture(texture_url):
    tex_id = glGenTextures(1)
    tex = pygame.image.load(texture_url)
    tex_surface = pygame.image.tostring(tex, 'RGBA')
    tex_width, tex_height = tex.get_size()
    glBindTexture(GL_TEXTURE_2D, tex_id)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_surface)
    glBindTexture(GL_TEXTURE_2D, 0)
    return tex_id

if __name__ == "__main__":
    init_gl()
    texture1 = load_texture("texture1.png")
    texture2 = load_texture("texture2.png")

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        glClear(GL_COLOR_BUFFER_BIT)
        glBindTexture(GL_TEXTURE_2D, texture1)
        glBegin(GL_QUADS)
        glTexCoord(0, 0)
        glVertex(50, 50, 0)
        glTexCoord(0, 1)
        glVertex(50, 100, 0)
        glTexCoord(1, 1)
        glVertex(100, 100, 0)
        glTexCoord(1, 0)
        glVertex(100, 50, 0)
        glEnd()
        glBindTexture(GL_TEXTURE_2D, 0)

        glBindTexture(GL_TEXTURE_2D, texture2)
        glBegin(GL_QUADS)
        glTexCoord(0, 0)
        glVertex(450, 300, 0)
        glTexCoord(0, 1)
        glVertex(450, 350, 0)
        glTexCoord(1, 1)
        glVertex(500, 350, 0)
        glTexCoord(1, 0)
        glVertex(500, 300, 0)
        glEnd()
        glBindTexture(GL_TEXTURE_2D, 0)

        pygame.display.flip()

顺便说一句,您的代码和我发布的演示代码在现代OpenGL中都是不推荐使用的,它不支持glBegin和glEnd这样的慢速即时模式调用。如果以后遇到性能问题,可能需要考虑重构以使用更现代的技术,如vbo(顶点缓冲对象)。但对于简单的应用程序,这应该不是一个太大的问题。让我知道如果这有帮助!在

相关问题 更多 >