pyopengl Ошибка на glVertexAttribPointer () - PullRequest
2 голосов
/ 29 апреля 2020

Я получил ошибку на glVertexAttribPointer, может быть, это потому, что значение или что-то (?) Кто-нибудь знает, как это исправить?

import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy as np
from PIL import Image


def main():
    if not glfw.init():
        return

    window = glfw.create_window(720, 720, "08_A_xxx: PyOpengl dan tekstur", None, None)

    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)


                   #posisi          warna               koordinat tekstur
    rectangle = [-0.5, -0.5, 0.0,   1.0, 0.0, 0.0,          0.0, 0.0,
            0.5, -0.5, 0.0,         0.0, 1.0, 0.0,          1.0, 0.0,
            0.5, 0.5, 0.0,          0.0, 0.0, 1.0,          1.0, 1.0,
            -0.5, 0.5, 0.0,         1.0, 1.0, 1.0,           0.0, 1.0]


    # ubah ke 32 bit (float)

    rectangle = np.array(rectangle, dtype=np.float32)


    indices = [0,1,2,
              2,3,0]

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

    VERTEX_SHADER = """

           #version 330

           in vec3 position;
           in vec3 color;
           in vec2 InTexCoords;

           out vec3 newColor;
           out vec2 OutTexCoords;

           void main() {

            gl_Position = vec4(position, 1.0);
            newColor = color;
            OutTexCoords = InTexCoords;

             }


       """

    FRAGMENT_SHADER = """
        #version 330

         in vec3 newColor;
         in vec2 OutTexCoords;

         out vec4 outColor;
         uniform sampler2D samplerTex;

        void main() {

           outColor = texture(samplerTex, OutTexCoords);

        }

    """

    # Kompilasi program dan shaders

    shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER),
                                              OpenGL.GL.shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER))

    # Buat objek buffer dalam gpu
    VBO = glGenBuffers(1)
    # Bind the buffer
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 128, rectangle, GL_STATIC_DRAW)


    # Buat EBO
    EBO = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)



    # mendapatkan posisi dari shader
    position = glGetAttribLocation(shader, 'position')
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
    glEnableVertexAttribArray(position)

    # mendapatkan warna dari  shader
    color = glGetAttribLocation(shader, 'color')
    glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(color)

    texCoords = glGetAttribLocation(shader, "InTexCoords")
    glVertexAttribPointer(texCoords,2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
    glEnableVertexAttribArray(texCoords)

    # Buat Tekstur
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    # texture wrapping params
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    # texture filtering params
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    image = Image.open("hello.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)


    glUseProgram(shader)

    glClearColor(0.0, 0.0, 0.0, 1.0)

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

        glClear(GL_COLOR_BUFFER_BIT)

        # Gambar segiempat

        glDrawElements(GL_TRIANGLES,6, GL_UNSIGNED_INT,  None)

        glfw.swap_buffers(window)

    glfw.terminate()


if __name__ == "__main__":
    main()

1 Ответ

0 голосов
/ 29 апреля 2020

Атрибут color не является активным программным ресурсом, поскольку атрибут не «используется» в шейдерной программе. Атрибут передается из вершины в фрагментный шейдер, но фрагментный шейдер игнорирует входную переменную newColor. Алгоритм оптимизации сортирует атрибут color.
Следовательно, glGetAttribLocation возвращает -1 и, наконец, glVertexAttribPointer не выполняется.

Нет необходимости указывать массив данных атрибута вершины для атрибута color, потому что это совсем не нужно. Оцените, если glGetAttribLocation возвращает значение, большее или равное 0, для решения проблемы:

color = glGetAttribLocation(shader, 'color')
if color >= 0:
    glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(color)
...