python - 如何为三角形添加纹理?
问题描述
我正在尝试为三角形添加木质纹理。代码仅适用于三角形。但是在我尝试添加纹理时会引发错误。我认为问题在于 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()
我试图按照本教程学习opengl。但是本教程是用 C++ 编写的。此外,我的方法略有不同。我没有在顶点中添加颜色代码。但我不认为这是添加纹理方式的问题。
解决方案
stride 参数glVertexAttribPointer
指定连续通用顶点属性之间的字节偏移量。您的属性由具有 3 个组件的顶点坐标和具有 2 个组件的纹理坐标组成。因此,您的 stride 参数必须为 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)
glBindAttribLocation
必须在程序链接之前(之前)将通用顶点属性索引与命名属性变量( )相关联glLinkProgram
。
我建议通过Layout Qualifier设置属性索引:
layout (location = 0) in vec4 position;
layout (location = 1) in vec2 InTexCoords;
推荐阅读
- javascript - Javascript 中的 click 函数出错
- c# - Azure Functions 3.0 部署时随机抛出运行时错误
- javascript - 在 JavaScript 中过滤嵌套对象
- python - 尝试开发二十一点游戏的计分系统
- c# - .NET Core 3.1/IHostBuilder 的 UseUrls 等效项
- firebase - 向“Xamarin.Android.Crashlytics”添加引用会导致多个编译时错误
- operating-system - 操作系统中的文件系统和文件管理有什么区别?
- ios - NSMutableAttributedString 添加隐藏文本的多个属性
- node.js - Discord.js 音乐机器人无法在 Linux 上运行(但在 Windows 上运行)
- excel - VBA 错误“对象变量或未设置块变量”