균일 한 4x4 행렬을 바인딩하려는 불운이 있습니다. 이 프로그램으로 OpenGL 3.3을 대상으로하고 있지만 OpenGL 4.2 환경입니다. 내 정점 쉐이더에서 단위 행렬을 유니폼에 단순히 바인딩하는 함수가 있지만 glUniformMatrix4fv에 대한 호출이 GL_INVALID_OPERATION으로 실패합니다.glUniformMatrix4fv가 GL_INVALID_OPERATION의 오류 코드와 함께 실패합니다.
여기 내 버텍스 쉐이더입니다 :
#version 330
in vec4 in_vertex;
uniform mat4 mvMatrix;
void main(void) {
gl_Position = mvMatrix * in_vertex;
}
내가 매트릭스 전위 왼쪽/오른쪽 곱셈의 함정 알고 있어요,하지만 난 그게 내가 실제로 균일 한 매트릭스를 통과 할 때의 전투의 그림.
여기는 문제가있는 기능에서 참조되는 간단한 함수입니다. 나는 오류가 발생한 곳을 찾아 내려고 고정하기 위해서만 이것을 사용하고있다.
: glUniformMatrix4fv의 평가는 모든 서버 측에 있기 때문에, 나는 등inline void die_on_gl_error(const char* location) {
GLenum error = GL_NO_ERROR;
error = glGetError();
if (GL_NO_ERROR != error) {
printf("GL Error %x encountered in %s.\n", error, location);
exit(1);
}
}
SDK docs는 glMatrixUniform4fv가 GL_INVALID_OPERATION을 설정할 수있는 몇 가지 이유가 있다고 중단 점을 사용하는 방법을 가지고 있지 않습니다
- 현재 프로그램 개체가 없으면 GL_INVALID_OPERATION이 생성됩니다.
- GL_INVALID_OPERATION은 셰이더에서 선언 된 균일 변수의 크기가 glUniform 명령에서 지정한 크기와 일치하지 않으면 생성됩니다.
- GL_INVALID_OPERATION은이 함수의 정수 변형 중 하나가 float, vec2, vec3, vec4 또는 이들의 배열의 균일 변수를로드하는 데 사용되거나이 함수의 부동 소수점 변형 중 하나 ivec2, ivec3 또는 ivec4 유형의 균일 변수 또는 이들의 배열을로드하는 데 사용됩니다.
- GL_INVALID_OPERATION은 location이 현재 프로그램 객체의 유효하지 않은 균일 한 위치이고 location이 -1과 같지 않은 경우에 생성됩니다.
- count가 1보다 크고 표시된 균일 변수가 배열 변수가 아니면 GL_INVALID_OPERATION이 생성됩니다.
- GLUINiform1i 및 glUniform1iv 이외의 명령을 사용하여 샘플러를로드하면 GL_INVALID_OPERATION이 생성됩니다.
- GL_INVALID_OPERATION은 glBegin 실행과 glEnd 실행 사이에 glUniform이 실행되면 생성됩니다.
이 함수가 호출되는 객체에는 현재 활성화 된 GLSL 프로그램의 번호를 저장하는 active_program이라는 매개 변수가 있습니다. identity_matrix과 같이 선언 :
float identity_matrix[16];
다음과 같이 정의 : 속히없이
identity_matrix = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
, 여기 나에게 문제를주고 무엇을 모든 그 후
void VSGL::load_identity_matrix() {
// GL_INVALID_OPERATION is generated if there is no current program object.
if (!glIsProgram(active_program)) {
printf("Active program is not valid.\n");
exit(1);
}
// ... active_program is a program, but is it valid?
GLint program_valid = 0;
glValidateProgram(active_program);
glGetProgramiv(active_program, GL_VALIDATE_STATUS, &program_valid);
if (GL_TRUE != program_valid) {
printf("Program validation failed.\n");
exit(1);
}
die_on_gl_error("GetProgram (Validate Status)");
// ... makes sure there is a program active, and the current program matches
// the value stored in active_program.
GLint current_program = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program);
if (0 == current_program) {
printf("Error, no current program is set.\n");
exit(1);
} else if (current_program != active_program) {
printf("Error, current program doesn't match active_program!\n");
}
die_on_gl_error("GetInteger");
// ... ensures the program actually has an active uniform, as the docs
// say that uniforms can be optimized out if they don't contribute to
// out results.
GLint num_active_uniforms = 0;
glGetProgramiv(active_program, GL_ACTIVE_UNIFORMS, &num_active_uniforms);
if (0 == num_active_uniforms) {
printf("There are 0 uniforms active in program %d.\n", active_program);
exit(1);
} else {
printf("There are %d uniform(s) active in program %d.\n", num_active_uniforms, active_program);
}
die_on_gl_error("GetProgram (Active Uniforms)");
// GL_INVALID_OPERATION is generated if the size of the uniform variable
// declared in the shader does not match the size indicated by the glUniform
// command.
// GL_INVALID_OPERATION is generated if location is an invalid uniform location
// for the current program object and location is not equal to -1.
// ... gets some basic information about the active uniforms, of which there
// should be only one, a FLOAT_MAT4 of size 1.
const GLchar *uniform_name = "mvMatrix";
GLint location = glGetUniformLocation(active_program, uniform_name);
die_on_gl_error("GetUniformLocation");
GLchar *message;
GLint max_uniform_length;
glGetProgramiv(active_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_length);
message = new GLchar[max_uniform_length];
GLint size;
GLenum type;
glGetActiveUniform(active_program, location, max_uniform_length, NULL, &size, &type, message);
printf("Uniform %s:\tType:%x\tSize:%d\n", message, type, size);
if (GL_FLOAT_MAT4 != type) {
printf("Active uniform at location is not a 4x4 float matrix.\n");
}
die_on_gl_error("GetActiveUniform");
// GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated
// uniform variable is not an array variable.
// GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than
// glUniform1i and glUniform1iv.
// GL_INVALID_OPERATION is generated if glUniform is executed between the execution
// of glBegin and the corresponding execution of glEnd.
// None of the above are true, and yet the following dies with GL_INVALID_OPERATION?
glUniformMatrix4fv(location, 1, false, identity_matrix);
die_on_gl_error("UniformMatrix4f");
}
을, 여기에 출력입니다 :
There are 1 uniform(s) active in program 3.
Uniform mvMatrix: Type:8b5c Size:1
GL Error 502 encountered in UniformMatrix4f.
Type 8b5c는 물론 GL_FLOAT_MAT4이고 크기는 1입니다. 그래서 어떤 잘못된 작동 조건이 나를 물어 뜯는 지 알 수 없습니다!
편집 :
while (wm->update()) {
wm->poll_input();
handle_input(viewingmatrix);
if (!gl->use_program(program))
exit(-1);
gl->load_identity_matrix();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, bananaNumVerts);
glFlush();
usleep(16667);
}
gl->use_program(program)
이와 업데이트 전달 INT의 유효성을 검사 단지 래퍼입니다 :
여기 UseProgram이 함수가 호출되는 주에있는 루프의 객체의 active_program 매개 변수
편집 2 :뿐만 아니라 GL 오류를 감지 gDEBugger를, 나를 가리키는위한 luke에 감사를드립니다. gDEBugger의 호출 정보에서 필자는 세 가지 인수 만 나열되었음을 지적했습니다. 이것은 4 번째가 배열에 대한 포인터 였기 때문에 (클라이언트 측에 존재합니까, 아니면 glUniform가 호출 될 때마다 서버 측에 전달됩니까?), 다른 생각이 들었습니다. 원인.
가선언 :
가PFNGLUNIFORMMATRIX4FV glUniformMatrix4fv;
할당은 :
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glXGetProcAddress((const GLubyte*)"glUniform4fv");
이것은 경우
는 glUniformMatrix4fv은 물론과 같이 자신의 어드레스를 취득 실제로 함수 포인터, 시험하는이야 나는 학구적 이유로 GLEW를 피했다. 그러나 glext.h
을보고있을 때 도 PFNGLUNIFORMMATRIX4FVARBPROC인데,이 기능이 코어에 적용되기 전에 작성된 코드베이스에 대한 것입니다. 그렇지 않은 경우 알려 주시기 바랍니다.
나는이 질문이 4000+ 리뷰에 국한되어 있지 않다고 생각합니다. –