使用 glvertex4i 传递网格面索引时的顶点着色器错误

Vertex Shader error while Passing mesh face index using glvertex4i

本文关键字:顶点 错误 索引 glvertex4i 网格 使用      更新时间:2023-10-16

正在初始化GL_List进行处理。

glBegin(GL_POINTS); 
for (i = 0; i < faceNum; i++)
{
mesh->GetFaceNodes(i + 1, ver[0], ver[1], ver[2], ver[3]);
**glVertex4i(ver[0] - 1, ver[1] - 1, ver[2] - 1, i+1);**
}
glEnd();    
glEndList();

顶点着色器给了我一个编译错误,不知道为什么。

顶点着色器:

varying out float final;
void main( void )
{
final = float(gl_Vertex.w);       // want to pass this face index on to 
}

几何着色器:

varying in float final[];
varying out float final_tofrag;
final_tofrag=final[0];

//Doing other calculations here they are totally different 

片段着色器:

varying in float final_tofrag;
void main( void )
{
if (color.z<0.0)
gl_FragData[0] = vec4(float(final_frag),float(final_frag), -(gl_FragCoord.z), 0); // want to check that value of the final(gl_vertex.w) is being passed from vertex shader to fragment shader or not. Its giving me 0.00000;
else
gl_FragData[0] = vec4(float(final_frag), float(final_frag), gl_FragCoord.z, 0);
}

如果您实际上在问题中发布了编译错误,这将有所帮助,否则我们不知道您的错误是什么。

所以,由于我在黑暗中随机猜测,我将在这里进行一些猜测。

  1. 您正在为整数分配浮点数,这可能会给您带来转换错误。
// this might now compile, but it will probably only ever give you
// zero or one. Was that the intent?
final = int(gl_Vertex.w); 
  1. 您没有在顶点着色器中写入gl_Position。如果不写入该值,OpenGL 将无法执行顶点着色器。

  2. 在片段着色器中,您正在检查值color.z,但尚未将颜色声明为统一、着色器输入或常量。

  3. 虽然这不会导致编译错误,但将 final(值为 1 或 0?的整数(除以整数值 100 或 1000 只会得到零或一。是否打算使用 final 作为浮点数而不是整数?

  4. 您在片段着色器的 vec4 声明中混合整数和浮点数。这可能会导致编译器崩溃。

不幸的是,如果无法访问 GLSL 错误日志,除了我上面列出的内容之外,任何人都无法采取任何措施来识别您的问题。

由于着色器不包含任何版本信息,因此它是 OpenGL 着色语言 1.10 规范着色器。

在 GLSL 1.10 中,不允许varyingint类型的变量,并且不支持从intfloat的隐式强制转换。 glsl 1.10 没有inout变量。间歇变量的关键字是varying

此外,变量color未定义 int eh 片段着色器。

varying float final;
void main( void )
{
final = gl_Vertex.w;
// [...]
}
varying float final_tofrag;
void main( void )
{
if (final_tofrag < 0.0) // ?
gl_FragData[0] = vec4(final_tofrag, final_tofrag, -gl_FragCoord.z, 0.0);
else
gl_FragData[0] = vec4(final_tofrag, final_tofrag, gl_FragCoord.z, 0.0);
}

我建议检查着色器编译是否成功以及程序对象是否成功链接。

如果着色器的编译成功可以通过glGetShaderiv和参数GL_COMPILE_STATUS. 检查,例如:

#include <iostream>
#include <vector>
bool CompileStatus( GLuint shader )
{
GLint status = GL_TRUE;
glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
if (status == GL_FALSE)
{
GLint logLen;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( shader, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
return status != GL_FALSE;
}

如果程序链接成功,可以通过glGetProgramiv和参数GL_LINK_STATUS来检查。 例如:

bool LinkStatus( GLuint program )
{
GLint status = GL_TRUE;
glGetProgramiv( program, GL_LINK_STATUS, &status );
if (status == GL_FALSE)
{
GLint logLen;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( program, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
}
return status != GL_FALSE;
}

问题中的代码没有任何意义。之所以选择 GLSL 关键字varying,是因为它旨在反映由于基元之间的自动插值而导致每个片段的数据将不同的属性。这仅在 rasrerizer 之前的最后一个可编程着色器阶段和片段着色器之间发生。

一开始,只有顶点着色器和片段着色器。VS 将获得attributes 作为输入,输出为varyings,这将是插值并成为 FS 的输入。

随着GL 3.0/GLSL 1.30中几何着色器的引入,这个方案不再有意义。VS的输出将不再插值,而是成为GS的直接输入。结果,关键字attributevaryingGLSL中删除,并替换为更通用的in/out方案。

因此,具有varying的 GS 不存在。您要么使用不支持几何着色器的旧版 GLSL,要么使用带有in/out的较新的 GLSL。