glGetAttribLocation вызывает недопустимую операцию - PullRequest
0 голосов
/ 11 июня 2018

Я пытался сделать модель / симуляцию луны, используя python от pyopengl и pygame.Я использовал 3d модель луны с открытым исходным кодом в файле .obj и попытался объединить ее в своем коде.Но по какой-то причине возникает ошибка с тегом

OpenGL.error.GLError: GLError (err = 1282, description = b'invalid operation ', baseOperation = glGetAttribLocation, cArguments = (6,b'position \ x00 ')

Моя реализация разделена на разные классы (например, ООП), но основные, т. е. шейдер, класс луны и класс, в котором я использую эту программу, перечислены ниже.Загрузчик OBJ прямо с официального сайта Pygame.

Vertex Shader

#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 newColor;
layout (location = 2) in vec2 verTexCoord;
out vec3 color;
out vec2 fragTexCoord;
// other methods like scaling, rotation
void main(){
    vec4 pos = vec4(position, 1.0);
    // apply translation, rotation and scaling 
    gl_Position = pos;
    fragTexCoord = verTexCoord;
    color = newColor;
}

Фрагментный шейдер

#version 330
in vec3 color;
in vec2 fragCoord;
out vec4 outColor;
uniform sampler2D ourTexture;
void main(){
    outColor = texture2D(ourTexture, fragCoord);
}

Луна

from objloader import *
class Moon(Shape):
    def __init__(self):
        Shape.__init__(self)
        self.obj = OBJ("Moon\moon.obj", swapyz=True)
        self.drawing_type = GL_POLYGON
        self.setup_shaders()
        self.setup_buffers()
    def setup_shaders(self):
        # Get and Compile the shaders here
        self.program = glCreateProgram()
        glAttachShader(self.program, vertexShader)
        glAttachShader(self.program, fragmentShader)
        glLinkProgram(self.program)

    def setup_buffers(self):
        self.vao = glGenVertexArrays(1)
        self.vbo = glGenBuffers(1)
        v = []
        # buildlist will give a list that contains the moons vertices including the texture coordinates. 
        v = self.buildList(self.obj)
        self.vertexes = np.stack(v)
        self.vertex_length = len(self.vertexes)
        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
        glBufferData(GL_ARRAY_BUFFER, self.vertexes.nbytes, self.vertexes, GL_STATIC_DRAW)
        glBindVertexArray(self.vao)
        # This is the line the error occurs at.
        positionLocation = glGetAttribLocation(self.program, "position")

Ненеобходимо, но здесь есть класс Shape и функция, в которой помещается текст для рисования (он находится в классе, отличном от Shape).

class Shape():
    def __init__(self):
        self.vao = None
        self.vbo = None
        self.program = None
        self.vertexes = None
        self.drawing_type = None
        self.vertex_length = None

Функция рисования

def draw(self):
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    for shape in self.shapes:
        glUseProgram(shape.program)
        glBindVertexArray(shape.vao)
        glDrawArrays(shape.drawing_type, 0, shape.vertex_length)
        glBindVertexArray(0)

1 Ответ

0 голосов
/ 11 июня 2018

glGetAttribLocation выдает недопустимую ошибку операции, поскольку программный объект self.program неправильно связан.

Программа не связана, поскольку выходные переменные вершинного шейдеране соответствует входным переменным фрагментного шейдера.

Вершинный шейдер:

out vec3 color;
out vec2 fragTexCoord;

Фрагментный шейдер:

in vec3 color;
in vec2 fragCoord;

Чтобы решить проблему, измените фрагментный шейдер следующим образом:

#version 330

in vec3 color;
in vec2 fragTexCoord; // "fragTexCoord" insted of "fragCoord"

out vec4 outColor;
uniform sampler2D ourTexture;
void main(){
    outColor = texture2D(ourTexture, fragTexCoord); 
}

Обратите внимание, что если программный объект был успешно связан, можно проверить с помощью glGetProgramiv( self.program, GL_LINK_STATUS ):

glLinkProgram( self.program )
if not glGetProgramiv( self.__prog, GL_LINK_STATUS ):
    print( 'link error:' )
    print( glGetProgramInfoLog( self.__prog ) )

Для полноты картины, если шейдерный объект был успешно скомпилирован, можно проверить с помощью glGetShaderiv( shaderObj, GL_COMPILE_STATUS ):

glCompileShader( shaderObj )
if not glGetShaderiv( shaderObj, GL_COMPILE_STATUS ):
    print( 'compile error:' )
    print( glGetShaderInfoLog( shaderObj ) )
...