如何为三角形添加纹理?

问题描述

我正在尝试将木质纹理添加到三角形中。代码仅适用于三角形。但是在尝试添加纹理时会引发错误。我认为问题出在GLSL或创建EBO / VBO(不确定)中。整个屏幕保持黑色。

这是完整的代码。我在这里做什么错了?

from OpenGL.GL import *
from OpenGL.glu import *
from OpenGL.GL import shaders

import glfw
import numpy as np
from PIL import Image

VERTEX_SHADER = """
#version 330
    layout (location = 0) in vec4 position;

    in vec2 InTexCoords;
    out vec2 OutTexCoords;
    
    void main(){
    gl_Position = position;
    OutTexCoords = InTexCoords;
    }
"""

FRAGMENT_SHADER = """
#version 330
    out vec4 FragColor;
    uniform vec4 triangleColor;
    
    in vec2 OutTexCoords;
    uniform sampler2D sampleTex;

    void main() {
    FragColor = texture(sampleTex,OutTexCoords);
    }
"""
shaderProgram = None

def initialize():
    global VERTEXT_SHADER
    global FRAGMENT_SHADER
    global shaderProgram

    #compiling shaders
    vertexshader = shaders.compileShader(VERTEX_SHADER,GL_VERTEX_SHADER)
    fragmentshader = shaders.compileShader(FRAGMENT_SHADER,GL_FRAGMENT_SHADER)

    #creating shaderProgram
    shaderProgram = shaders.compileProgram(vertexshader,fragmentshader)

    #vertex and indices data
                #triangle          #texture
    vertices = [-0.5,-0.5,0.0,0.5,1.0,1.0]
    
    indices = [0,1,2]

    vertices = np.array(vertices,dtype=np.float32)
    indices = np.array(vertices,dtype=np.float32)

    #add vertices to buffer
    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER,VBO)
    glBufferData(GL_ARRAY_BUFFER,vertices.nbytes,vertices,GL_STATIC_DRAW)

    #add indices to buffer
    EBO = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices,GL_STATIC_DRAW)
  
    position = 0
    glVertexAttribPointer(position,3,GL_FLOAT,GL_FALSE,24,ctypes.c_void_p(0))
    glEnabLevertexAttribArray(position)

    texCoords = 1
    glBindAttribLocation( shaderProgram,texCoords,'InTexCoords')
    glVertexAttribPointer(texCoords,2,ctypes.c_void_p(12))
    glEnabLevertexAttribArray(texCoords)

    #creating texture
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D,texture)
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)

    image = Image.open("wood.jpg")
    img_data = np.array(list(image.getdata()),np.uint8)
    glTexImage2D(GL_TEXTURE_2D,GL_RGB,512,GL_UNSIGNED_BYTE,img_data)
    
    
def render(window):
    global shaderProgram
  
    glClearColor(0,1)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  
    gluseProgram(shaderProgram)

    glDrawElements(GL_TRIANGLES,GL_UNSIGNED_INT,None)

     
    gluseProgram(0)
    glfw.swap_buffers(window)

def main():
    glfw.init()
    window = glfw.create_window(640,640,"EXAMPLE PROGRAM",None,None)
    glfw.make_context_current(window)
    initialize()

    while not glfw.window_should_close(window):
        glfw.poll_events()
        render(window)
            
    glfw.terminate()


if __name__ == '__main__':
    main()

我试图遵循本教程learnopengl。但是本教程使用C ++。此外,我的方法略有不同。我不在顶点添加颜色代码。但我认为这不是添加纹理的问题。

解决方法

glVertexAttribPointer的跨度参数指定连续的通用顶点属性之间的字节偏移。您的属性由具有3个分量的顶点坐标和具有2个分量的纹理坐标组成。因此,您的跨步参数必须为20(5 * 4个字节),而不是24:

glVertexAttribPointer(position,3,GL_FLOAT,GL_FALSE,24,ctypes.c_void_p(0))

glVertexAttribPointer(position,20,ctypes.c_void_p(0))

glVertexAttribPointer(texCoords,2,ctypes.c_void_p(12))

glVertexAttribPointer(texCoords,ctypes.c_void_p(12))

索引的数据类型必须是整数。绘图调用(glDrawElements(...,...,GL_UNSIGNED_INT,...))中的类型必须与此类型匹配。使用uint32而不是float(和vertices-> indices):

indices = np.array(vertices,dtype=np.float32)

indices = np.array(indices,dtype=np.uint32)

必须在链接程序之前(在glBindAttribLocation之前)将通用顶点属性索引与命名属性变量(glLinkProgram)关联。
我建议通过Layout Qualifier设置属性索引:

layout (location = 0) in vec4 position;
layout (location = 1) in vec2 InTexCoords;