glGetAttribLocation вызывает недопустимую операцию
Я пытался сделать модель / симуляцию луны, используя python от pyopengl и pygame. Я использовал 3d модель луны с открытым исходным кодом в файле.obj и попытался объединить ее в своем коде. Но по какой-то причине возникает ошибка с тегом
OpenGL.error.GLError: GLError(err = 1282,description = b'недопустимая операция',baseOperation = glGetAttribLocation,cArguments = (6, b'position\x00')
Моя реализация разделена на разные классы (например, ООП), но основные, то есть шейдер, класс Луны и класс, в котором я использую эту программу, перечислены ниже. Загрузчик OBJ прямо с официального сайта Pygame.
Вершинный шейдер
#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 ответ
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 ) )