我在尝试绑定(bind)统一的 4x4 矩阵时运气不佳。我的目标是使用这个程序的 OpenGL 3.3,但我的环境是 OpenGL 4.2。我有一个函数可以简单地将单位矩阵绑定(bind)到我的顶点着色器中的制服,但是对 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 有几个原因:
对于上下文,调用此函数的对象有一个名为 active_program 的参数,该参数存储当前激活的 GLSL 程序的编号。 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.
类型8b5c当然是GL_FLOAT_MAT4,大小当然是1,所以看不出是哪个无效操作条件在咬我!
编辑:
这是调用 UseProgram 和此函数的 main 循环:
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 的有效性并更新对象的 active_program 参数。
编辑 2: 感谢 luke将我指向 gDEBugger,它也检测到了 GL 错误。在 gDEBugger 的调用信息中,我注意到只列出了三个参数。虽然我认为这可能是因为第四个是指向数组的指针(它是否驻留在客户端,还是每次调用 glUniform 时它都会传递给服务器端?),但它让我想到了还有什么可能是原因。
如果可以证明的话,glUniformMatrix4fv 当然实际上是一个获取其地址的函数指针,如下所示:
声明:
PFNGLUNIFORMMATRIX4FV glUniformMatrix4fv;
作业:
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glXGetProcAddress((const GLubyte*)"glUniform4fv");
这是我出于学术原因避免使用 GLEW。然而,当我浏览 gext.h 时,我注意到还有一个 PFNGLUNIFORMMATRIX4FVARBPROC,我认为它只是用于在此函数被采用到核心之前编写的代码库.如果不是这样,请告诉我。
最佳答案
看看你的 glXGetProcAddress 调用:
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glXGetProcAddress((const GLubyte*)"glUniform4fv");
您请求的是 glUniform4fv 而不是 glUniformMatrix4fv !
我知道你说过你没有出于学术原因使用扩展包装库,但我仍然强烈推荐它们。
关于c++ - glUniformMatrix4fv 失败,错误代码为 GL_INVALID_OPERATION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9661049/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t
我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat
这是我在ChefRecipe中的一blockRuby:#ifdatadirdoesn'texist,moveoverthedefaultoneif!File.exist?("/vol/postgres/data")execute"mv/var/lib/postgresql/9.1/main/vol/postgres/data"end结果是:Executingmv/var/lib/postgresql/9.1/main/vol/postgres/datamv:inter-devicemovefailed:`/var/lib/postgresql/9.1/main'to`/vol/post
我刚刚开始从Ruby1.8.7升级到Ruby1.9.2(使用RVM)。我的所有应用程序都使用“脚本/服务器”(或“rails服务器”)和1.9.2运行,但是,只有Rails3.0.0RC应用程序可以与Passenger一起使用。Rails2.3.8应用给出的错误信息是:invalidbytesequenceinUS-ASCII我猜这是一个Passenger问题。我使用找到的RVM指南安装了Passenger2.2.15here.任何想法如何修复这个错误?谢谢。我已更新以包含堆栈跟踪:/Users/kevin/.rvm/gems/ruby-1.9.2-p0/gems/actionpack