Не удается получить glVertexAttribPointer для отображения цвета из шейдеров - PullRequest
1 голос
/ 24 января 2020

Я пытаюсь отрисовать 3 точки разными цветами, используя один VBO и шейдеры. Я передаю значения местоположения и цвета одному 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')

, который я затем пытаюсь прочитать в мои шейдеры. Я добавляю альфа в фрагментный шейдер. Я использую 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)

Я не могу загрузить свои r, g, b, a, используя glVertexAttribPointer, как я понимаю из документов:

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? Мои две мысли заключались в том, что я либо

  1. неправильно понял последний аргумент glVertexAttribPointer, либо
  2. , так или иначе сделав вершины прозрачными

, но я ' мы попытались изменить порядок моих цветов, добавив альфа к исходному набору данных et c, но безуспешно. Любая помощь приветствуется.

Полный код:

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);
}

1 Ответ

2 голосов
/ 24 января 2020

Если указанный буферный объект связан, то 6-й параметр glVertexAttribPointer обрабатывается как смещение байта в хранилище данных буферного объекта. Но тип параметра в любом случае является указателем (c_void_p).

Таким образом, если смещение равно 0, то 5-й параметр может быть либо None, либо c_void_p(0), иначе смещение должно быть приведено к c_void_p:

loc_col = glGetAttribLocation(shader_program, "color")
glVertexAttribPointer(loc_col, 3, GL_FLOAT, False, 6*4, ctypes.c_void_p(3*4))
...