英文:
Why is OpenGL not loading textures (generic images)?
问题
I am having trouble loading images into OpenGL. I am attempting to put the images onto a Block (3D generated cube with OpenGL), but all I am getting is a blank Block. I'm not sure what I did wrong, as I followed the usual steps for loading textures in OpenGL. Can anyone provide some guidance on what might be causing this issue?
from OpenGL.GLU import *
from OpenGL.GL import *
import os
class BlockTexture:
def __init__(self, name: str, block_id: int, texture: list):
if not isinstance(name, str):
raise TypeError("Name must be a string.")
if not isinstance(block_id, int):
raise TypeError("Block Id must be an integer.")
if not isinstance(texture, list) or len(texture) != 3:
raise ValueError("Texture must be a list of 3 elements.")
self.name = name
self.block_id = block_id
self.texture = texture
def load_texture(self, filepath):
textureSurface = pygame.image.load(filepath)
textureData = pygame.image.tostring(textureSurface, "RGBA", 1)
width = textureSurface.get_width()
height = textureSurface.get_height()
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData)
return texture
def test_texture_file(self):
texture_ids = []
for texture in self.texture:
if not self.test_texture_filepath(texture):
raise ValueError("Invalid texture file path.")
texture_file, texture_ext = os.path.splitext(texture)
if texture_ext.lower() not in ['.png', '.jpg', '.jpeg']:
raise ValueError("Invalid texture file type.")
texture_ids.append(self.load_texture(texture))
return texture_ids
def test_texture_filepath(self, filepath):
if not isinstance(filepath, str):
return False
if not os.path.isfile(filepath):
return False
return True
class Block(BlockTexture):
def __init__(self, name, block_id, texture):
super().__init__(name, block_id, texture)
self.texture_ids = self.test_texture_file()
def draw(self, x, y, z):
# Top Face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[0])
glBegin(GL_QUADS)
glTexCoord2f(0, 1)
glVertex3f(x, y + 1, z)
glTexCoord2f(1, 1)
glVertex3f(x + 1, y + 1, z)
glTexCoord2f(1, 0)
glVertex3f(x + 1, y + 1, z + 1)
glTexCoord2f(0, 0)
glVertex3f(x, y + 1, z + 1)
glEnd()
# Front Face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(0, 1)
glVertex3f(x + 1, y + 1, z + 1)
glTexCoord2f(1, 1)
glVertex3f(x, y + 1, z + 1)
glTexCoord2f(1, 0)
glVertex3f(x, y, z + 1)
glTexCoord2f(0, 0)
glVertex3f(x + 1, y, z + 1)
glEnd()
# Back Face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(1, 1)
glVertex3f(x, y + 1, z)
glTexCoord2f(0, 1)
glVertex3f(x + 1, y + 1, z)
glTexCoord2f(0, 0)
glVertex3f(x + 1, y, z)
glTexCoord2f(1, 0)
glVertex3f(x, y, z)
glEnd()
# Left face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(0, 1)
glVertex3f(x, y + 1, z + 1)
glTexCoord2f(1, 1)
glVertex3f(x, y + 1, z)
glTexCoord2f(1, 0)
glVertex3f(x, y, z)
glTexCoord2f(0, 0)
glVertex3f(x, y, z + 1)
glEnd()
# Right face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(1, 1)
glVertex3f(x + 1, y + 1, z)
glTexCoord2f(0, 1)
glVertex3f(x + 1, y + 1, z + 1)
glTexCoord2f(0, 0)
glVertex3f(x + 1, y, z + 1)
glTexCoord2f(1, 0)
glVertex3f(x + 1, y, z)
glEnd()
# Bottom face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[0])
glBegin(GL_QUADS)
glTexCoord2f(0, 0)
glVertex3f(x, y, z + 1)
glTexCoord2f(1, 0)
glVertex3f(x + 1, y, z + 1)
glTexCoord2f(1, 1)
glVertex3f(x + 1, y, z)
glTexCoord2f(0, 1)
glVertex3f(x, y, z)
glEnd()
After trying to load the rotation cube into a pygame window and encountering issues, I attempted to use other frameworks and also changed the image size to something other than 16x16. However, these attempts did not resolve the problem and I am still unable to get the image to display properly. At this point, I am unsure of the reason for this issue. I've tried testing different image formats and setting them as the background. Which worked stupendously. But I can't figure out why it doesn't put the images inside the Block. Here is the initializing pygame window:
```py
import pygame
from pygame.locals import *
def test_pygame_opengl():
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glTranslatef(0.0, 0.0, -5)
GrassBlock = Block(
name="grass_block",
block_id=1,
texture=[
"grass_block_top16x16
<details>
<summary>英文:</summary>
I am having trouble loading images into OpenGL. I am attempting to put the images onto a Block (3D generated cube with OpenGL), but all I am getting is a blank Block. I'm not sure what I did wrong, as I followed the usual steps for loading textures in OpenGL. Can anyone provide some guidance on what might be causing this issue?
````py
from OpenGL.GLU import *
from OpenGL.GL import *
import os
class BlockTexture:
def __init__(self, name: str, block_id: int, texture: list):
if not isinstance(name, str):
raise TypeError("Name must be a string.")
if not isinstance(block_id, int):
raise TypeError("Block Id must be an integer.")
if not isinstance(texture, list) or len(texture) != 3:
raise ValueError("Texture must be a list of 3 elements.")
self.name = name
self.block_id = block_id
self.texture = texture
def load_texture(self, filepath):
textureSurface = pygame.image.load(filepath)
textureData = pygame.image.tostring(textureSurface, "RGBA", 1)
width = textureSurface.get_width()
height = textureSurface.get_height()
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData)
return texture
def test_texture_file(self):
texture_ids = []
for texture in self.texture:
if not self.test_texture_filepath(texture):
raise ValueError("Invalid texture file path.")
texture_file, texture_ext = os.path.splitext(texture)
if texture_ext.lower() not in ['.png', '.jpg', '.jpeg']:
raise ValueError("Invalid texture file type.")
texture_ids.append(self.load_texture(texture))
return texture_ids
def test_texture_filepath(self, filepath):
if not isinstance(filepath, str):
return False
if not os.path.isfile(filepath):
return False
return True
class Block(BlockTexture):
def __init__(self, name, block_id, texture):
super().__init__(name, block_id, texture)
self.texture_ids = self.test_texture_file()
def draw(self, x, y, z):
# Top Face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[0])
glBegin(GL_QUADS)
glTexCoord2f(0, 1)
glVertex3f(x, y + 1, z)
glTexCoord2f(1, 1)
glVertex3f(x + 1, y + 1, z)
glTexCoord2f(1, 0)
glVertex3f(x + 1, y + 1, z + 1)
glTexCoord2f(0, 0)
glVertex3f(x, y + 1, z + 1)
glEnd()
# Front Face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(0, 1)
glVertex3f(x + 1, y + 1, z + 1)
glTexCoord2f(1, 1)
glVertex3f(x, y + 1, z + 1)
glTexCoord2f(1, 0)
glVertex3f(x, y, z + 1)
glTexCoord2f(0, 0)
glVertex3f(x + 1, y, z + 1)
glEnd()
# Back Face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(1, 1)
glVertex3f(x, y + 1, z)
glTexCoord2f(0, 1)
glVertex3f(x + 1, y + 1, z)
glTexCoord2f(0, 0)
glVertex3f(x + 1, y, z)
glTexCoord2f(1, 0)
glVertex3f(x, y, z)
glEnd()
# Left face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(0, 1)
glVertex3f(x, y + 1, z + 1)
glTexCoord2f(1, 1)
glVertex3f(x, y + 1, z)
glTexCoord2f(1, 0)
glVertex3f(x, y, z)
glTexCoord2f(0, 0)
glVertex3f(x, y, z + 1)
glEnd()
# Right face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[1])
glBegin(GL_QUADS)
glTexCoord2f(1, 1)
glVertex3f(x + 1, y + 1, z)
glTexCoord2f(0, 1)
glVertex3f(x + 1, y + 1, z + 1)
glTexCoord2f(0, 0)
glVertex3f(x + 1, y, z + 1)
glTexCoord2f(1, 0)
glVertex3f(x + 1, y, z)
glEnd()
# Bottom face
glBindTexture(GL_TEXTURE_2D, self.texture_ids[0])
glBegin(GL_QUADS)
glTexCoord2f(0, 0)
glVertex3f(x, y, z + 1)
glTexCoord2f(1, 0)
glVertex3f(x + 1, y, z + 1)
glTexCoord2f(1, 1)
glVertex3f(x + 1, y, z)
glTexCoord2f(0, 1)
glVertex3f(x, y, z)
glEnd()
After trying to load the rotation cube into a pygame window and encountering issues, I attempted to use other frameworks and also changed the image size to something other than 16x16. However, these attempts did not resolve the problem and I am still unable to get the image to display properly. At this point, I am unsure of the reason for this issue. I've tried testing different image formats and setting them as the background. Which worked stupendously. But I can't figure out why it doesn't put the images inside the Block. Here is the initializing pygame window:
import pygame
from pygame.locals import *
def test_pygame_opengl():
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glTranslatef(0.0, 0.0, -5)
GrassBlock = Block(
name="grass_block",
block_id=1,
texture=[
"grass_block_top16x16.png",
"grass_block_side16x16.png",
"grass_block_bottom16x16.png"
])
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glRotatef(1, 3, 1, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
GrassBlock.draw(0, 0, 0)
pygame.display.flip()
pygame.time.wait(10)
test_pygame_opengl()
答案1
得分: 0
二维纹理映射必须启用,请参阅glEnable
。在绘制几何图形之前(在glBegin
之前)启用纹理映射:
glEnable(GL_TEXTURE_2D)
由于OpenGL是一个状态引擎,如果要在没有纹理的情况下绘制几何图形,必须再次禁用纹理映射(glDisable(GL_TEXTURE_2D)
)。
英文:
Two-dimensional texturing has to be enabled, see glEnable
. Enable texturing before drawing the geometry (before glBegin
):
glEnable(GL_TEXTURE_2D)
Since OpenGL is a state engine, you must disable texturing again if you want to draw geometry without texture (glDisable(GL_TEXTURE_2D)
).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论