如何为三角形添加纹理?
How to add texture to a triangle?
我正在尝试为三角形添加木质纹理。代码仅适用于三角形。但是在我尝试添加纹理时会引发错误。我认为问题出在 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.0,0.0,
0.5, -0.5, 0.0, 1.0,0.0,
0.0, 0.5, 0.0, 0.5,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, GL_FLOAT, GL_FALSE, 24, 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_REPEAT)
glTexParameteri(GL_TEXTURE_2D, 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, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
def render(window):
global shaderProgram
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shaderProgram)
glDrawElements(GL_TRIANGLES, 3, 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
的 stride 参数指定连续通用顶点属性之间的字节偏移量。您的属性由具有 3 个分量的顶点坐标和具有 2 个分量的纹理坐标组成。因此,您的步幅参数必须为 20(5 * 4 字节)而不是 24:
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0))
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 20, ctypes.c_void_p(0))
glVertexAttribPointer(texCoords,2, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12))
glVertexAttribPointer(texCoords,2, GL_FLOAT, GL_FALSE, 20, 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)
必须在链接程序之前(glLinkProgram
之前)将通用顶点属性索引与命名属性变量 (glBindAttribLocation
) 相关联。
我建议通过 Layout Qualifier:
设置属性索引
layout (location = 0) in vec4 position;
layout (location = 1) in vec2 InTexCoords;
我正在尝试为三角形添加木质纹理。代码仅适用于三角形。但是在我尝试添加纹理时会引发错误。我认为问题出在 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.0,0.0,
0.5, -0.5, 0.0, 1.0,0.0,
0.0, 0.5, 0.0, 0.5,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, GL_FLOAT, GL_FALSE, 24, 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_REPEAT)
glTexParameteri(GL_TEXTURE_2D, 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, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
def render(window):
global shaderProgram
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shaderProgram)
glDrawElements(GL_TRIANGLES, 3, 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
的 stride 参数指定连续通用顶点属性之间的字节偏移量。您的属性由具有 3 个分量的顶点坐标和具有 2 个分量的纹理坐标组成。因此,您的步幅参数必须为 20(5 * 4 字节)而不是 24:
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0))
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 20, ctypes.c_void_p(0))
glVertexAttribPointer(texCoords,2, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12))
glVertexAttribPointer(texCoords,2, GL_FLOAT, GL_FALSE, 20, 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)
必须在链接程序之前(glLinkProgram
之前)将通用顶点属性索引与命名属性变量 (glBindAttribLocation
) 相关联。
我建议通过 Layout Qualifier:
layout (location = 0) in vec4 position;
layout (location = 1) in vec2 InTexCoords;