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_Positioncamera 传递为 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;

我不断地像这样手动填写buffertest.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.poscamera.pos 都是 Eigen::Vector3ui 对象,所以 uint 向量 3s。

edit2:

我认为还值得注意的是,我有调试输出打印着色器中的任何错误,但没有。另外,如果我将in_Positioncamera 更改为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 向量

使用 192/256 位整数对无符号 64 位整数向量的点积求和的最快方法?

为啥无符号短(乘)无符号短转换为有符号整数? [复制]