You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Pygame与OpenGL环境下为三个立方体分别加载不同纹理的问题求助

解决多立方体绑定不同纹理的问题

嘿,我明白你的困扰了——你想让三个立方体各用独立的纹理,但现在它们都显示同一张图,问题主要出在纹理加载和绑定的逻辑上,咱们一步步来改:

问题分析

  1. pygame.image.load()的用法错误:这个函数一次只能加载单张图片,你传多个路径的话,它只会处理第一个,后面的参数会被忽略,所以你实际上只加载了image1.bmp这一张图。
  2. 只生成了一个纹理ID:当前代码里glGenTextures(1)只创建了一个纹理对象,三个立方体都用这个,自然显示一样的纹理。
  3. 没有为每个立方体绑定对应纹理:绘制立方体前没有切换到对应的纹理,所以不管画多少个,用的都是最后绑定的那个纹理。

解决方案步骤

  • 重构loadTexture函数,让它接收单个图片路径,返回对应的纹理ID
  • 预先加载三张图片,得到三个独立的纹理ID
  • 绘制每个立方体前,先绑定对应的纹理ID

修改后的完整代码

#import
import pygame
import sys
from OpenGL.GL import *
from OpenGL.GLU import *

display = (800,600)
vertices = [
    (-0.5, -0.5, 0.5),
    (0.5, -0.5, 0.5),
    (0.5, 0.5, 0.5),
    (-0.5, 0.5, 0.5),
    (-0.5, -0.5, -0.5),
    (0.5, -0.5, -0.5),
    (0.5, 0.5, -0.5),
    (-0.5, 0.5, -0.5)
]
edges = [
    (0,1), (1,2), (2,3), (3,0),
    (4,5), (5,6), (6,7), (7,4),
    (0,4), (1,5), (2,6), (3,7)
]

# 重构加载纹理的函数:接收单个图片路径,返回纹理ID
def loadTexture(img_path):
    textureSurface = pygame.image.load(img_path)
    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 initialitation():
    glClearColor(1.0, 1.0, 1.0, 1.0) #Warna latar belakang putih
    glViewport(0,0,display[0],display[1])
    gluPerspective(45, display[0]/display[1],0.1,50.0)
    # 预先加载三张纹理,得到三个纹理ID
    global tex1, tex2, tex3
    tex1 = loadTexture('image1.bmp')
    tex2 = loadTexture('images2.bmp') # 修正拼写错误:iamges -> images
    tex3 = loadTexture('images3.bmp')

def cube_image(lines=False):
    if lines:
        glBegin(GL_LINES)
        for edge in edges:
            glColor3fv((1, 1, 1))
            for vertex in edge:
                glVertex3fv(vertices[vertex])
        glEnd()
    else:
        #front
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -0.5, 0.5);
        glTexCoord2f(1.0, 1.0); glVertex3f( 0.5, -0.5, 0.5);
        glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, 0.5, 0.5);
        glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, 0.5, 0.5);
        glEnd();
        #back
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -0.5, -0.5);
        glTexCoord2f(1.0, 1.0); glVertex3f(-0.5, 0.5, -0.5);
        glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, 0.5, -0.5);
        glTexCoord2f(0.0, 0.0); glVertex3f( 0.5, -0.5, -0.5);
        glEnd();
        #left
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -0.5, 0.5);
        glTexCoord2f(1.0, 1.0); glVertex3f(-0.5, 0.5, 0.5);
        glTexCoord2f(1.0, 0.0); glVertex3f(-0.5, 0.5, -0.5);
        glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, -0.5, -0.5);
        glEnd();
        #right
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 1.0); glVertex3f( 0.5, -0.5, -0.5);
        glTexCoord2f(1.0, 1.0); glVertex3f( 0.5, 0.5, -0.5);
        glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, 0.5, 0.5);
        glTexCoord2f(0.0, 0.0); glVertex3f( 0.5, -0.5, 0.5);
        glEnd();
        #upper
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5);
        glTexCoord2f(1.0, 1.0); glVertex3f( 0.5, 0.5, 0.5);
        glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, 0.5, -0.5);
        glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, 0.5, -0.5);
        glEnd();
        #below
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -0.5, 0.5);
        glTexCoord2f(1.0, 1.0); glVertex3f(-0.5, -0.5, -0.5);
        glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, -0.5, -0.5);
        glTexCoord2f(0.0, 0.0); glVertex3f( 0.5, -0.5, 0.5);
        glEnd();

def myImage():
    # 第一个立方体:绑定tex1
    glBindTexture(GL_TEXTURE_2D, tex1)
    glPushMatrix()
    glTranslated(1,0,0)
    cube_image(0)
    glPopMatrix()
    
    # 第二个立方体:绑定tex2
    glBindTexture(GL_TEXTURE_2D, tex2)
    glPushMatrix()
    glTranslated(-1,0,0)
    cube_image(0)
    glPopMatrix()
    
    # 第三个立方体:绑定tex3
    glBindTexture(GL_TEXTURE_2D, tex3)
    glPushMatrix()
    glTranslated(0,0,0)
    cube_image(0)
    glPopMatrix()

def main():
    pygame.init()
    pygame.display.set_mode(display, pygame.OPENGL|pygame.DOUBLEBUF)
    pygame.display.set_caption('Cube and Texture')
    initialitation()
    glTranslatef(0.0,0.0,-5)
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        #glRotatef(1, 0, 0, 1)
        glEnable( GL_TEXTURE_2D )
        glEnable( GL_DEPTH_TEST )
        glPushMatrix()
        glRotatef(30, 1, 1, 0)
        myImage()
        glPopMatrix()
        pygame.display.flip()
        pygame.time.wait(10)

#if python says run, let's run!
if __name__ == '__main__':
    main()

关键修改点说明

  1. 修复纹理加载函数:loadTexture现在接收单个图片路径,每次调用生成一个独立的纹理ID,确保每张图对应自己的纹理对象。
  2. 预加载三张纹理:在初始化时加载好三张图的纹理ID,存在全局变量里方便后续使用。
  3. 绘制前绑定对应纹理:在绘制每个立方体前,调用glBindTexture(GL_TEXTURE_2D, texId)切换到对应的纹理,这样每个立方体就会使用自己的纹理了。
  4. 修复拼写错误:你之前代码里把images2.bmp写成了iamges2.bmp,这里已经修正,避免加载失败。
  5. 添加退出事件处理:原来的代码没有处理窗口关闭事件,现在加上了,方便正常退出程序。

内容的提问来源于stack exchange,提问作者Hoeskiee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:27:27