为什么我的 Flatten Shader(来自 Lighthouse3d 教程)无法工作?

发布于 2024-11-15 13:29:05 字数 2336 浏览 2 评论 0原文

教程有一个名为“Flatten Shader”的示例,它将 GLUT 茶壶显示为扁平茶壶。 这里是扁平化着色器的链接

我已经按照教程中提到的步骤完成了所有操作,但是我的茶壶并不像教程中的茶壶那样平坦。它看起来就像一个普通的茶壶。

这是顶点着色器的代码:

  void main()
  {
     vec4 v = vec4(gl_Vertex);
     v.z = 0.0;
     gl_Position = gl_ModelViewProjectionMatrix * v;
  }

这是我的片段着色器:

 void main()
 {
    gl_FragColor = gl_Color;
 }

这是我绘制茶壶的方式:

 void display ( void )
{   
    glClearDepth(1.0);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode( GL_MODELVIEW );

    glLoadIdentity();

    gluLookAt( 0.0, 0.0, 2.0,
           0.0, 0.0, 0.0,
           0.0, 1.0, 0.0
             );

    glMultMatrixd(trackball->getRotation());

    const GLfloat diffuseIntensity[] = { 0.8, 0.4, 0.4, 1.0 };
    const GLfloat specularIntensity[] = { 0.5, 0.5, 0.5, 1.0 };

    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuseIntensity);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularIntensity);
    glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 5.0 );

    glutSolidTeapot(1.0);

    glutSwapBuffers();
}

虽然它应该是“平坦的”,但显示的茶壶就像一个普通的茶壶。如果您认为我错过了一些初始配置/设置步骤,那么请不要这样做,因为我已经完成了它们:

GLuint createShader ( const GLchar* const source, GLenum type )
{
     GLuint shader = glCreateShader( type );
     glShaderSource( shader, 1, const_cast<const GLchar**>(&source), 0 );
     glCompileShader( shader );

     return shader;
}

并且:

GLuint createProgram ( const GLuint shader )
{
     GLuint program = glCreateProgram();
     glAttachShader(program, shader);
     glLinkProgram(program);

     return program;
}

这是所有内容都聚集在一起的地方:

    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);

    GLuint vertexShaderProgram = createProgram(vertexShader);
    GLuint fragmentShaderProgram = createProgram(fragmentShader);

    glUseProgram(vertexShaderProgram);
    glUseProgram(fragmentShaderProgram);

我哪里出错了?

The tutorial has an example called the Flatten Shader, which displays the GLUT teapot as a flatten teapot. Here is the link to the Flatten Shader.

I have done everything exactly like the steps mentioned in the tutorial, but my teapot is not flat like how the teapot in the tutorial looks like. It just looks like a normal teapot.

Here is the code for the vertex shader:

  void main()
  {
     vec4 v = vec4(gl_Vertex);
     v.z = 0.0;
     gl_Position = gl_ModelViewProjectionMatrix * v;
  }

Here is my fragment shader:

 void main()
 {
    gl_FragColor = gl_Color;
 }

And here is how I draw the Teapot:

 void display ( void )
{   
    glClearDepth(1.0);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode( GL_MODELVIEW );

    glLoadIdentity();

    gluLookAt( 0.0, 0.0, 2.0,
           0.0, 0.0, 0.0,
           0.0, 1.0, 0.0
             );

    glMultMatrixd(trackball->getRotation());

    const GLfloat diffuseIntensity[] = { 0.8, 0.4, 0.4, 1.0 };
    const GLfloat specularIntensity[] = { 0.5, 0.5, 0.5, 1.0 };

    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuseIntensity);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularIntensity);
    glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 5.0 );

    glutSolidTeapot(1.0);

    glutSwapBuffers();
}

While it is supposed to be "Flat", the Teapot that gets displayed is like a normal teapot. If you think that I missed some initial configurations / setup steps, then don't because I already did them:

GLuint createShader ( const GLchar* const source, GLenum type )
{
     GLuint shader = glCreateShader( type );
     glShaderSource( shader, 1, const_cast<const GLchar**>(&source), 0 );
     glCompileShader( shader );

     return shader;
}

and:

GLuint createProgram ( const GLuint shader )
{
     GLuint program = glCreateProgram();
     glAttachShader(program, shader);
     glLinkProgram(program);

     return program;
}

And here is where everything gets together:

    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);

    GLuint vertexShaderProgram = createProgram(vertexShader);
    GLuint fragmentShaderProgram = createProgram(fragmentShader);

    glUseProgram(vertexShaderProgram);
    glUseProgram(fragmentShaderProgram);

Where am I going wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ζ澈沫 2024-11-22 13:29:05

有几点:

  1. 您没有正确绑定着色器。您的 createProgram 函数需要将片段着色器和顶点着色器绑定在一起。您应该将其替换为如下所示的代码:

    GLuint createProgram ( const GLuint fshader, const GLuint vshader )
    {
         GLuint 程序 = glCreateProgram();
         glAttachShader(程序, fshader);
         glAttachShader(程序,vshader);       
         glLinkProgram(程序);
         退货计划;
    

    }

  2. 相应地,您应该将最后一个代码段修改为如下所示:

    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
    GLuint shaderProgram = createProgram(fragmentShader, vertexShader);
    glUseProgram(着色器程序);
    
  3. 此外,可能还有其他问题。您应该使用 glGet(Shader|Program)InfoLog 来帮助调试着色器,并调用 glGetError 来帮助诊断程序失败的位置。

  4. 最后,我不能保证这个堆栈交换答案的可信度,但显然在一些较旧的 ATi 实现上,gl_Color 是 vec3,而不是 vec4,因此您需要在分配之前对其进行转换。请参阅以下讨论: GLSL 片段着色器语法错误

A few things:

  1. You are not binding your shaders correctly. Your createProgram function needs to bind both the fragment shader and the vertex shader together. You should replace it with code that looks like this:

    GLuint createProgram ( const GLuint fshader, const GLuint vshader )
    {
         GLuint program = glCreateProgram();
         glAttachShader(program, fshader);
         glAttachShader(program, vshader);       
         glLinkProgram(program);
         return program;
    

    }

  2. And correspondingly, you should modify your last snippet to look like this:

    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
    GLuint shaderProgram = createProgram(fragmentShader, vertexShader);
    glUseProgram(shaderProgram);
    
  3. Also, there could be other issues. You should use glGet(Shader|Program)InfoLog to help debug your shaders, and also make calls to glGetError to help diagnose where your program failed.

  4. Finally, I can't vouch for the credibility of this stack exchange answer, but apparently on some older ATi implementations gl_Color is a vec3, not a vec4, and so you need to cast it before assigning. See the following discussion: GLSL fragment shader syntax error

信仰 2024-11-22 13:29:05

作为对 Mikola 答案的补充,您不需要每次都检查信息日志;您可以检查着色器是否正确编译以及程序是否正确链接,并且仅在发生错误时调用 glGetShaderInfoLogglGetProgramInfoLog

这里有一些代码可以做到这一点(在 Python 中,但转换为 C++ 很简单):

# create your vertex shader, attach its source, etc.
glCompileShader(vertex_shader)
rc_compile = GLint()
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, rc_compile)
if rc_compile.value == GL_FALSE: # shader compilation failed
  info = create_string_buffer(1024)
  glGetShaderInfoLog(vertex_shader, 1024, None, info)
  glDeleteShader(vertex_shader)
  raise Exception(info.value)

# do the same thing for a fragment shader and create a program to link the two
glAttachShader(program, vertex_shader)
glAttachShader(program, fragment_shader)
rc_link = GLint()
glGetProgramiv(program, GL_LINK_STATUS, rc_link)
if rc_link.value == GL_FALSE: # program link failed
  info = create_string_buffer(1024)
  glGetProgramInfoLog(program, 1024, None, info)
  glDeleteProgram(program)
  raise Exception(info.value)

As an addition to Mikola's answer, you don't need to check the info log every time; you can check if your shaders compiled correctly and if your program linked correctly and only call glGetShaderInfoLog and glGetProgramInfoLog if an error occurred.

Here's some code to do just that (in Python but translation to C++ is trivial):

# create your vertex shader, attach its source, etc.
glCompileShader(vertex_shader)
rc_compile = GLint()
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, rc_compile)
if rc_compile.value == GL_FALSE: # shader compilation failed
  info = create_string_buffer(1024)
  glGetShaderInfoLog(vertex_shader, 1024, None, info)
  glDeleteShader(vertex_shader)
  raise Exception(info.value)

# do the same thing for a fragment shader and create a program to link the two
glAttachShader(program, vertex_shader)
glAttachShader(program, fragment_shader)
rc_link = GLint()
glGetProgramiv(program, GL_LINK_STATUS, rc_link)
if rc_link.value == GL_FALSE: # program link failed
  info = create_string_buffer(1024)
  glGetProgramInfoLog(program, 1024, None, info)
  glDeleteProgram(program)
  raise Exception(info.value)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文