2
votes

I got an error on glVertexAttribPointer maybe it because the value or anything (?) does anyone know how to fix this?

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
this if color >= 0: statement got error, i don't know how to fix it. so i change with a different code, and it's done. thanks for you help anywayuser13429071

1 Answers

0
votes

The attribute color is not an active program resource, because the attribute is not "used" in the shader program. The attribute is passed from the vertex to the fragment shader, but the fragment shader ignores the input variable newColor. The optimization algorithm sorts out the attribute color.
Hence glGetAttribLocation returns -1 and finally glVertexAttribPointer fails.

It is not necessary to specify the array of vertex attribute data for the attribute color, because it is not needed at all. Evaluate if glGetAttribLocation returns a value greater or equal 0, to solve the issue:

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