OpenGL为什么无法加载纹理(通用图像)?

huangapple go评论73阅读模式
英文:

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&#39;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(&quot;Name must be a string.&quot;)
        if not isinstance(block_id, int):
            raise TypeError(&quot;Block Id must be an integer.&quot;)
        if not isinstance(texture, list) or len(texture) != 3:
            raise ValueError(&quot;Texture must be a list of 3 elements.&quot;)
        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, &quot;RGBA&quot;, 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(&quot;Invalid texture file path.&quot;)
            texture_file, texture_ext = os.path.splitext(texture)
            if texture_ext.lower() not in [&#39;.png&#39;, &#39;.jpg&#39;, &#39;.jpeg&#39;]:
                raise ValueError(&quot;Invalid texture file type.&quot;)
            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=&quot;grass_block&quot;,
        block_id=1,
        texture=[
           &quot;grass_block_top16x16.png&quot;,
           &quot;grass_block_side16x16.png&quot;,
           &quot;grass_block_bottom16x16.png&quot;
        ])

    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)).

huangapple
  • 本文由 发表于 2023年4月17日 07:53:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76030891.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定