Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我的展平着色器(来自Lighthouse 3D教程)不工作?_C++_Opengl_Glsl_Shader_Glut - Fatal编程技术网

C++ 为什么我的展平着色器(来自Lighthouse 3D教程)不工作?

C++ 为什么我的展平着色器(来自Lighthouse 3D教程)不工作?,c++,opengl,glsl,shader,glut,C++,Opengl,Glsl,Shader,Glut,有一个称为展平着色器的示例,它将GLUT茶壶显示为展平茶壶 我所做的一切都与教程中提到的步骤一模一样,但我的茶壶并不像教程中的茶壶那样扁平。它看起来就像一个普通的茶壶 以下是顶点着色器的代码: void main() { vec4 v = vec4(gl_Vertex); v.z = 0.0; gl_Position = gl_ModelViewProjectionMatrix * v; } 这是我的片段着色器: void main() {

有一个称为展平着色器的示例,它将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 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);
我哪里出错了?

有几件事:

  • 未正确绑定着色器。createProgram函数需要将片段着色器和顶点着色器绑定在一起。您应该将其替换为如下代码:

    GLuint createProgram ( const GLuint fshader, const GLuint vshader )
    {
         GLuint program = glCreateProgram();
         glAttachShader(program, fshader);
         glAttachShader(program, vshader);       
         glLinkProgram(program);
         return program;
    
    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
    GLuint shaderProgram = createProgram(fragmentShader, vertexShader);
    glUseProgram(shaderProgram);
    
    }

  • 相应地,您应该修改最后一个代码段,使其如下所示:

    GLuint createProgram ( const GLuint fshader, const GLuint vshader )
    {
         GLuint program = glCreateProgram();
         glAttachShader(program, fshader);
         glAttachShader(program, vshader);       
         glLinkProgram(program);
         return program;
    
    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
    GLuint shaderProgram = createProgram(fragmentShader, vertexShader);
    glUseProgram(shaderProgram);
    
  • 此外,可能还有其他问题。您应该使用glGet(Shader | Program)InfoLog来帮助调试着色器,还应该调用glGetError来帮助诊断程序失败的地方

  • 最后,我不能保证这个堆栈交换答案的可信度,但显然在一些较旧的ATi实现中,gl_颜色是vec3,而不是vec4,因此您需要在分配之前强制转换它。见以下讨论:

  • 有几件事:

  • 未正确绑定着色器。createProgram函数需要将片段着色器和顶点着色器绑定在一起。您应该将其替换为如下代码:

    GLuint createProgram ( const GLuint fshader, const GLuint vshader )
    {
         GLuint program = glCreateProgram();
         glAttachShader(program, fshader);
         glAttachShader(program, vshader);       
         glLinkProgram(program);
         return program;
    
    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
    GLuint shaderProgram = createProgram(fragmentShader, vertexShader);
    glUseProgram(shaderProgram);
    
    }

  • 相应地,您应该修改最后一个代码段,使其如下所示:

    GLuint createProgram ( const GLuint fshader, const GLuint vshader )
    {
         GLuint program = glCreateProgram();
         glAttachShader(program, fshader);
         glAttachShader(program, vshader);       
         glLinkProgram(program);
         return program;
    
    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
    GLuint shaderProgram = createProgram(fragmentShader, vertexShader);
    glUseProgram(shaderProgram);
    
  • 此外,可能还有其他问题。您应该使用glGet(Shader | Program)InfoLog来帮助调试着色器,还应该调用glGetError来帮助诊断程序失败的地方

  • 最后,我不能保证这个堆栈交换答案的可信度,但显然在一些较旧的ATi实现中,gl_颜色是vec3,而不是vec4,因此您需要在分配之前强制转换它。见以下讨论:


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

    这里有一些代码可以做(在Python中,但是对C++的翻译是微不足道的):


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

    这里有一些代码可以做(在Python中,但是对C++的翻译是微不足道的):