unsigned int 向量的差异,解释为有符号并转换为未正确呈现的浮点向量
Posted
技术标签:
【中文标题】unsigned int 向量的差异,解释为有符号并转换为未正确呈现的浮点向量【英文标题】:Difference of unsigned int vectors, interpreted as signed and casted to a float vector not rendering properly 【发布时间】:2012-12-10 18:30:39 【问题描述】:如果我在我的 c++ 代码中取两个 uint 向量的差异,转换为 int,转换为 float,然后传递给 GLSL,它会呈现正常。但是当我尝试让 GLSL 发挥作用并进行投射时,它会以几乎均匀的阴影覆盖屏幕,就好像我要绘制的正方形真的被放大了一样。是的,我真的很想在 GLSL 中做到这一点,如果只是看看如何。此外,我的矩阵和向量在 Eigen 对象中,虽然我不确定这是否重要。
无论如何,为了确保清楚,我的 projviewMatrix(在两种情况下都相同)在给定应该是相同的浮点向量相乘时工作得非常好。所以我很确定问题出在 GLSL 中的 uint 向量减法上。我在 c++ 中执行了与在着色器中完全相同的操作(uint 向量减法、转换为 int 和转换为浮点数),但一个有效,一个无效。
这是我目前正在尝试的顶点着色器。我尝试将向量视为有符号整数并进行减法,因为运算应该相同......我认为。行为没有变化。
#version 150 core
uniform mat4 projviewMatrix;
uniform ivec3 camera;
in ivec3 in_Position;
in vec3 in_Color;
out vec3 pass_Color;
void main()
gl_Position = projviewMatrix * vec4(in_Position - camera, 1.0);
pass_Color = in_Color;
我尝试将 in_Position
和 camera
传递为 uvec3s,然后进行 ivec4(in_Position - camera, 1)
和其他各种愚蠢的重新排列,但无济于事。还尝试将camera
重命名为in_Camera
。我承认,那是绝望的。
我的制服传递的东西。当我传入工作浮点向量时,我只需注释掉 2 条相机线。
GLint viewLoc = glGetUniformLocation(shader.id(), "projviewMatrix"); //this is an ortho projection with 1/2 scaling, no rotation or translation
GLint cameraLoc = glGetUniformLocation(shader.id(), "camera");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, projview.data());
glUniform3uiv(cameraLoc, 1, camera.pos.data());
这就是我将 VBO 绑定到 VAO 的方式。
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLint), 0, GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_INT, false, 0, 0);
这是工作的浮点向量输入 GLSL。 in_Position
是上面的 in_Position
减去 camera
并转换为 int 然后在我的 c++ 代码中浮动。
#version 150 core
uniform mat4 projviewMatrix;
in vec3 in_Position;
in vec3 in_Color;
out vec3 pass_Color;
void main()
gl_Position = projviewMatrix * vec4(in_Position, 1.0);
pass_Color = in_Color;
我的 projviewMatrix 只做两件事:正射投影和 1/2 缩放。没有平移或旋转,或其他任何东西。它的正交部分是用这些参数生成的,width/height就是窗口的宽/高。
proj = orthoProj(-width, width, -height, height, -4, 4);
编辑:应 Alf 的要求:
这发生在我绑定我的制服后:
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]);
int* buffer = (int*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
static const int width = 1000;
TestObject& test = game.test;
buffer[0] = test.pos[0] - width;
buffer[1] = test.pos[1] - width;
buffer[2] = 0;
我不断地像这样手动填写buffer
。 test.pos
是正方形的中心,当前等于 camera.pos
xy 坐标 (1
buffer[0] -= camera.pos[0];
buffer[1] -= camera.pos[1];
buffer[2] -= camera.pos[2];
无论哪种方式,我都将数据作为整数传递。除了相机统一绑定和 GLSL 代码差异之外,上述块(发生在每个 buffer
顶点)是我的“GLSL 减法”和“C++ 减法”内容之间的唯一区别。
test.pos
和 camera.pos
都是 Eigen::Vector3ui
对象,所以 uint 向量 3s。
edit2:
我认为还值得注意的是,我有调试输出打印着色器中的任何错误,但没有。另外,如果我将in_Position
和camera
更改为vec3
,则结果是与其他任何东西相同的蓝绿色阴影。
如果我在顶点着色器中创建自己的 ivec3 并使用它来代替 camera
,我可以更改“相机”值并移动我现在可以确认的是超级膨胀的正方形,大致从 0 到1
编辑 3:
使用glVertexAttribIPointer()
将数据放入in_Position
已解决部分问题,这显然是OpenGL 在我的GLSL 代码执行之前进行了额外的强制转换以浮动。然而,camera
向量仍然以同样的方式出现错误,除了我目前使用的glUniform3uiv
之外,我不知道我能做些什么。我尝试使用 glUniform3ui
并输入它的 3 个值,但这也没有用。
【问题讨论】:
你能展示一些C++代码吗 @Cheersandhth.-Alf 好的,发布所有相关内容(我认为)。提前感谢您查看此内容 1.发送整数时,请尝试 glVertexAttribIPointer() 而不是 glVertexAttribPointer()。 @OlegTitov 啊,成功了!当我在我的着色器中创建一个“假”相机ivec3
并在其中硬编码值,并按照您的建议将 glVertexAttribIPointer() 传入我的 VBO 时,它工作得很好。但是使用我真正的uniform ivec3 camera
仍然会产生不正确的输出。所以类似的问题也困扰着我的相机矢量,但我没有看到类似的解决方案......
@user173342 因此,如果您将相机更改为 uvec 并仅在着色器中为相机添加从 uvec 到 ivec 的额外投射,您仍然会得到错误的结果?
【参考方案1】:
有 2 个问题。
-
应该使用
glVertexAttribIPointer()
设置指向整数属性的指针,因为glVertexAttribPointer()
会导致openGL 执行一些额外的float 类型转换。
ivec3
制服是用glUniform3uiv()
设置的,这也可能导致意外的演员阵容。正确的解决方案是使用 unsinged uniform 并在着色器中执行投射。
【讨论】:
以上是关于unsigned int 向量的差异,解释为有符号并转换为未正确呈现的浮点向量的主要内容,如果未能解决你的问题,请参考以下文章
unsigned char 与 char 有啥却别?何时适用
X86 架构 - 使用 unsigned long long 设置向量大小
为什么C或C ++标准没有明确地将char定义为signed或unsigned?
将 unsigned int + 字符串转换为 unsigned char 向量