无法让 glVertexAttribPointer 从着色器渲染颜色
Can't get glVertexAttribPointer to render colour from shaders
我正在尝试使用单个 VBO 和着色器渲染具有不同颜色的 3 个点。我将位置和颜色值传递给单个 VBO:
vertices = np.array([[0, 0.1, 0.6, 1, 1, 0], [0.3, 0.1, 0, 0, 1, 1], [0.8, 0.5, 0, 0, 1, 0]], dtype='f')
然后我试图读入我的着色器。我在片段着色器中添加了 alpha。我使用 glVertexAttribPointer
来区分我的 x、y、z 和我的 r、g、b、a。我能够渲染我的 x,y,z:
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "position"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "position"), 3, GL_FLOAT, False, 6*4, None)
我无法使用 glVertexAttribPointer
加载我的 r、g、b、a,正如我从文档中了解到的那样:
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "color"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "color"), 3, GL_FLOAT, False, 6*4, 3*4)
这不会渲染任何可见点。我的着色器确实在工作,就像我将指针的字节偏移量更改为 None:
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "color")) glVertexAttribPointer(glGetAttribLocation(shader_program, "color"), 3, GL_FLOAT, False, 6*4, None)
我的点根据我的标准化 x、y、z 坐标着色(即 glVertexAttribPointer
将我的 x 坐标解释为 r,y 坐标解释为 g,z 坐标解释为 b),这作为字节有意义偏移量为0。字节偏移量肯定应该是3 * 4吗?我的两个想法是我要么
- 误解了
glVertexAttribPointer
或 的最后一个参数
- 以某种方式使顶点透明
但我尝试过更改颜色的顺序、向原始数据集添加 alpha 等,但都没有成功。任何帮助表示赞赏。
完整代码:
from OpenGL.arrays import vbo
import pygame
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
def getFileContent(file):
content = open(file, 'r').read()
return content
def run():
pygame.init()
screen = pygame.display.set_mode((800,600), pygame.OPENGL | pygame.DOUBLEBUF)
vertices = np.array([[0, 0.1, 0.6, 1, 1, 0], [0.3, 0.1, 0, 0, 1, 1], [0.8, 0.5, 0, 0, 1, 0]], dtype='f')
vertexPositions = vbo.VBO(vertices)
indices = np.array([[0,1,2]], dtype=np.int32)
indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)
shader_program = glCreateProgram()
vertex_source = compileShader(getFileContent("testing_vert_shader.vert"), GL_VERTEX_SHADER)
fragment_source = compileShader(getFileContent("testing_frag_shader.frag"), GL_FRAGMENT_SHADER)
glAttachShader(shader_program, vertex_source)
glAttachShader(shader_program, fragment_source)
glBindAttribLocation(shader_program, 0, "position")
glBindAttribLocation(shader_program, 1, "color")
glLinkProgram(shader_program)
print(glGetProgramiv(shader_program, GL_LINK_STATUS)) # shader linked == 1
while True:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shader_program)
indexPositions.bind()
vertexPositions.bind()
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "position"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "position"), 3, GL_FLOAT, False, 6*4, None)
# red vertices rendered if these two lines are commented out
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "color"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "color"), 3, GL_FLOAT, False, 6*4, None) # changing last argument of glVertexAttribPointer to None results in x,y,z being read as colours
glDrawElements(GL_POINTS, 3, GL_UNSIGNED_INT, None)
# Show the screen
pygame.display.flip()
run()
顶点着色器:
#version 330 core
in vec3 position;
in vec3 color;
out vec3 vColor;
void main()
{
gl_Position = vec4(position, 1.0);
vColor = vec3(color);
}
片段着色器:
#version 330 core
in vec3 vColor;
out vec4 outcolor;
void main()
{
outcolor = vec4(vColor, 1.0f);
}
如果绑定了命名缓冲区对象,则 glVertexAttribPointer
的第 5 个参数被视为缓冲区对象数据存储中的字节偏移量。但是,参数的类型仍然是指针(c_void_p
)。
因此必须使用 c_void_p
来转换偏移量。如果偏移量为 0,则第 5 个参数可以是 None
或 c_void_p(0)
:
loc_col = glGetAttribLocation(shader_program, "color")
glVertexAttribPointer(loc_col, 3, GL_FLOAT, False, 6*4, ctypes.c_void_p(3*4))
我正在尝试使用单个 VBO 和着色器渲染具有不同颜色的 3 个点。我将位置和颜色值传递给单个 VBO:
vertices = np.array([[0, 0.1, 0.6, 1, 1, 0], [0.3, 0.1, 0, 0, 1, 1], [0.8, 0.5, 0, 0, 1, 0]], dtype='f')
然后我试图读入我的着色器。我在片段着色器中添加了 alpha。我使用 glVertexAttribPointer
来区分我的 x、y、z 和我的 r、g、b、a。我能够渲染我的 x,y,z:
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "position"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "position"), 3, GL_FLOAT, False, 6*4, None)
我无法使用 glVertexAttribPointer
加载我的 r、g、b、a,正如我从文档中了解到的那样:
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "color"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "color"), 3, GL_FLOAT, False, 6*4, 3*4)
这不会渲染任何可见点。我的着色器确实在工作,就像我将指针的字节偏移量更改为 None:
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "color")) glVertexAttribPointer(glGetAttribLocation(shader_program, "color"), 3, GL_FLOAT, False, 6*4, None)
我的点根据我的标准化 x、y、z 坐标着色(即 glVertexAttribPointer
将我的 x 坐标解释为 r,y 坐标解释为 g,z 坐标解释为 b),这作为字节有意义偏移量为0。字节偏移量肯定应该是3 * 4吗?我的两个想法是我要么
- 误解了
glVertexAttribPointer
或 的最后一个参数
- 以某种方式使顶点透明
但我尝试过更改颜色的顺序、向原始数据集添加 alpha 等,但都没有成功。任何帮助表示赞赏。
完整代码:
from OpenGL.arrays import vbo
import pygame
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
def getFileContent(file):
content = open(file, 'r').read()
return content
def run():
pygame.init()
screen = pygame.display.set_mode((800,600), pygame.OPENGL | pygame.DOUBLEBUF)
vertices = np.array([[0, 0.1, 0.6, 1, 1, 0], [0.3, 0.1, 0, 0, 1, 1], [0.8, 0.5, 0, 0, 1, 0]], dtype='f')
vertexPositions = vbo.VBO(vertices)
indices = np.array([[0,1,2]], dtype=np.int32)
indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)
shader_program = glCreateProgram()
vertex_source = compileShader(getFileContent("testing_vert_shader.vert"), GL_VERTEX_SHADER)
fragment_source = compileShader(getFileContent("testing_frag_shader.frag"), GL_FRAGMENT_SHADER)
glAttachShader(shader_program, vertex_source)
glAttachShader(shader_program, fragment_source)
glBindAttribLocation(shader_program, 0, "position")
glBindAttribLocation(shader_program, 1, "color")
glLinkProgram(shader_program)
print(glGetProgramiv(shader_program, GL_LINK_STATUS)) # shader linked == 1
while True:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shader_program)
indexPositions.bind()
vertexPositions.bind()
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "position"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "position"), 3, GL_FLOAT, False, 6*4, None)
# red vertices rendered if these two lines are commented out
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "color"))
glVertexAttribPointer(glGetAttribLocation(shader_program, "color"), 3, GL_FLOAT, False, 6*4, None) # changing last argument of glVertexAttribPointer to None results in x,y,z being read as colours
glDrawElements(GL_POINTS, 3, GL_UNSIGNED_INT, None)
# Show the screen
pygame.display.flip()
run()
顶点着色器:
#version 330 core
in vec3 position;
in vec3 color;
out vec3 vColor;
void main()
{
gl_Position = vec4(position, 1.0);
vColor = vec3(color);
}
片段着色器:
#version 330 core
in vec3 vColor;
out vec4 outcolor;
void main()
{
outcolor = vec4(vColor, 1.0f);
}
如果绑定了命名缓冲区对象,则 glVertexAttribPointer
的第 5 个参数被视为缓冲区对象数据存储中的字节偏移量。但是,参数的类型仍然是指针(c_void_p
)。
因此必须使用 c_void_p
来转换偏移量。如果偏移量为 0,则第 5 个参数可以是 None
或 c_void_p(0)
:
loc_col = glGetAttribLocation(shader_program, "color")
glVertexAttribPointer(loc_col, 3, GL_FLOAT, False, 6*4, ctypes.c_void_p(3*4))