Почему мой Flatten Shader (из учебника Lighthouse3d) не работает? - PullRequest
1 голос
/ 16 июня 2011

Я новичок в GLSL. Итак, я прохожу учебник в Интернете .

В учебном примере есть пример, называемый Flatten Shader, который отображает чайник GLUT в виде чайника Flatten. Вот ссылка на Flatten Shader .

Я сделал все точно так же, как шаги, упомянутые в учебнике, но мой чайник не плоский, как выглядит чайник в учебнике. Это выглядит как обычный чайник.

Вот код для вершинного шейдера:

  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);

Я не знаю, что пошло не так. Пожалуйста, помогите!

Ответы [ 2 ]

5 голосов
/ 16 июня 2011

Несколько вещей:

  1. Вы неправильно связываете свои шейдеры. Ваша функция createProgram должна связать фрагментный шейдер и вершинный шейдер вместе. Вы должны заменить его кодом, который выглядит следующим образом:

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

    }

  2. И, соответственно, вы должны изменить свой последний фрагмент, чтобы он выглядел так:

    GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
    GLuint shaderProgram = createProgram(fragmentShader, vertexShader);
    glUseProgram(shaderProgram);
    
  3. Также могут возникнуть другие проблемы. Вы должны использовать glGet (Shader | Program) InfoLog для отладки ваших шейдеров, а также вызывать glGetError, чтобы помочь диагностировать, где произошла ошибка вашей программы.

  4. Наконец, я не могу ручаться за достоверность этого ответа об обмене стека, но, очевидно, в некоторых более старых реализациях ATi gl_Color - это vec3, а не vec4, и поэтому вам необходимо привести его перед назначением. См. Следующее обсуждение: Синтаксическая ошибка шейдерного фрагмента GLSL

0 голосов
/ 17 июня 2011

В дополнение к ответу Миколы, вам не нужно каждый раз проверять информационный журнал;вы можете проверить, правильно ли скомпилированы ваши шейдеры и правильно ли связана ваша программа, и вызывать glGetShaderInfoLog и glGetProgramInfoLog, если произошла ошибка.

Вот код, который делает именно это (в 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)
...