2012-05-11 10 views
0

私はこのチュートリアルからOpenGLを学んでいます:http://openglbook.com/the-book/。私はシェイダーに問題があります。シェーダのコンパイル/リンク時にエラーが発生しますが、私が間違っていることはわかりません。OpenGL - シェーダ、シンボルは、vとfの2つの異なるタイプで定義されています。シェーダ

エラー:

Symbol ex_Color is defined with 2 different types in vertex and fragment shaders.

シェーダ(私は理由GLSLバージョンのそれらを少し修正):

const GLchar* VertexShader = 
{ 
    "#version 130\n"\ 

    "in vec4 in_Position;\n"\ 
    "in vec4 in_Color;\n"\ 

    "out vec4 ex_Color;\n"\ 

    "void main(void)\n"\ 
    "{\n"\ 
    "  gl_Position = in_Position;\n"\ 
    "  ex_Color = in_Color;\n"\ 
    "}\n" 
}; 

const GLchar* FragmentShader = 
{ 
    "#version 130\n"\ 

    "precision mediump float;\n"\ 

    "in vec4 ex_Color;\n"\ 

    "out vec4 out_Color;\n"\ 

    "void main(void)\n"\ 
    "{\n"\ 
    "  out_Color = ex_Color;\n"\ 
    "}\n" 
}; 

ソースコード:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <GL/glew.h> 
#include <GL/freeglut.h> 
#define WINDOW_TITLE_PREFIX "Chapter 2" 

int CurrentWidth = 800, 
    CurrentHeight = 600, 
    WindowHandle = 0; 

unsigned FrameCount = 0; 

GLuint 
    VertexShaderId, 
    FragmentShaderId, 
    ProgramId, 
    VaoId, 
    VboId, 
    ColorBufferId; 

    const GLchar* VertexShader = 
    { 
      "#version 130\n"\ 

      "in vec4 in_Position;\n"\ 
      "in vec4 in_Color;\n"\ 

      "out vec4 ex_Color;\n"\ 

      "void main(void)\n"\ 
      "{\n"\ 
      "  gl_Position = in_Position;\n"\ 
      "  ex_Color = in_Color;\n"\ 
      "}\n" 
    }; 

    const GLchar* FragmentShader = 
    { 
      "#version 130\n"\ 

      "precision mediump float;\n"\ 

      "in vec4 ex_Color;\n"\ 

      "out vec4 out_Color;\n"\ 

      "void main(void)\n"\ 
      "{\n"\ 
      "  out_Color = ex_Color;\n"\ 
      "}\n" 
    }; 

void Initialize(int, char*[]); 
void InitWindow(int, char*[]); 
void ResizeFunction(int, int); 
void RenderFunction(void); 
void TimerFunction(int); 
void IdleFunction(void); 
void Cleanup(void); 
void CreateVBO(void); 
void DestroyVBO(void); 
void CreateShaders(void); 
void DestroyShaders(void); 

int main(int argc, char* argv[]) 
{ 
    Initialize(argc, argv); 

    glutMainLoop(); 

    exit(EXIT_SUCCESS); 
} 

void Initialize(int argc, char* argv[]) 
{ 
    GLenum GlewInitResult; 

    InitWindow(argc, argv); 

    glewExperimental = GL_TRUE; 
    GlewInitResult = glewInit(); 

    if (GLEW_OK != GlewInitResult) { 
     fprintf(
      stderr, 
      "ERROR: %s\n", 
      glewGetErrorString(GlewInitResult) 
     ); 
     exit(EXIT_FAILURE); 
    } 

    fprintf(
     stdout, 
     "INFO: OpenGL Version: %s (GLSL = %s)\n", 
     glGetString(GL_VERSION), 
     glGetString(GL_SHADING_LANGUAGE_VERSION) 
    ); 

    CreateShaders(); 
    CreateVBO(); 

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
} 

void InitWindow(int argc, char* argv[]) 
{ 
    glutInit(&argc, argv); 

    glutInitContextVersion(3, 1); 
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); 
    glutInitContextProfile(GLUT_CORE_PROFILE); 

    glutSetOption(
     GLUT_ACTION_ON_WINDOW_CLOSE, 
     GLUT_ACTION_GLUTMAINLOOP_RETURNS 
    ); 

    glutInitWindowSize(CurrentWidth, CurrentHeight); 

    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); 

    WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX); 

    if(WindowHandle < 1) { 
     fprintf(
      stderr, 
      "ERROR: Could not create a new rendering window.\n" 
     ); 
     exit(EXIT_FAILURE); 
    } 

    glutReshapeFunc(ResizeFunction); 
    glutDisplayFunc(RenderFunction); 
    glutIdleFunc(IdleFunction); 
    glutTimerFunc(0, TimerFunction, 0); 
    glutCloseFunc(Cleanup); 
} 

void ResizeFunction(int Width, int Height) 
{ 
    CurrentWidth = Width; 
    CurrentHeight = Height; 
    glViewport(0, 0, CurrentWidth, CurrentHeight); 
} 

void RenderFunction(void) 
{ 
    ++FrameCount; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glDrawArrays(GL_TRIANGLES, 0, 3); 

    glutSwapBuffers(); 
    glutPostRedisplay(); 
} 

void IdleFunction(void) 
{ 
    glutPostRedisplay(); 
} 

void TimerFunction(int Value) 
{ 
    if (0 != Value) { 
     char* TempString = (char*) 
      malloc(512 + strlen(WINDOW_TITLE_PREFIX)); 

     sprintf(
      TempString, 
      "%s: %d Frames Per Second @ %d x %d", 
      WINDOW_TITLE_PREFIX, 
      FrameCount * 4, 
      CurrentWidth, 
      CurrentHeight 
     ); 

     glutSetWindowTitle(TempString); 
     free(TempString); 
    } 

    FrameCount = 0; 
    glutTimerFunc(250, TimerFunction, 1); 
} 

void Cleanup(void) 
{ 
    DestroyShaders(); 
    DestroyVBO(); 
} 

void CreateVBO(void) 
{ 
    GLfloat Vertices[] = { 
     -0.8f, -0.8f, 0.0f, 1.0f, 
     0.0f, 0.8f, 0.0f, 1.0f, 
     0.8f, -0.8f, 0.0f, 1.0f 
    }; 

    GLfloat Colors[] = { 
     1.0f, 0.0f, 0.0f, 1.0f, 
     0.0f, 1.0f, 0.0f, 1.0f, 
     0.0f, 0.0f, 1.0f, 1.0f 
    }; 

    GLenum ErrorCheckValue = glGetError(); 

    glGenVertexArrays(1, &VaoId); 
    glBindVertexArray(VaoId); 

    glGenBuffers(1, &VboId); 
    glBindBuffer(GL_ARRAY_BUFFER, VboId); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 
    glEnableVertexAttribArray(0); 

    glGenBuffers(1, &ColorBufferId); 
    glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); 
    glEnableVertexAttribArray(1); 

    ErrorCheckValue = glGetError(); 
    if (ErrorCheckValue != GL_NO_ERROR) 
    { 
     fprintf(
      stderr, 
      "ERROR: Could not create a VBO: %s \n", 
      gluErrorString(ErrorCheckValue) 
     ); 

     exit(-1); 
    } 
} 

void DestroyVBO(void) 
{ 
    GLenum ErrorCheckValue = glGetError(); 

    glDisableVertexAttribArray(1); 
    glDisableVertexAttribArray(0); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    glDeleteBuffers(1, &ColorBufferId); 
    glDeleteBuffers(1, &VboId); 

    glBindVertexArray(0); 
    glDeleteVertexArrays(1, &VaoId); 

    ErrorCheckValue = glGetError(); 
    if (ErrorCheckValue != GL_NO_ERROR) 
    { 
     fprintf(
      stderr, 
      "ERROR: Could not destroy the VBO: %s \n", 
      gluErrorString(ErrorCheckValue) 
     ); 

     exit(-1); 
    } 
} 

void CreateShaders(void) 
{ 
    GLenum ErrorCheckValue = glGetError(); 

    VertexShaderId = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(VertexShaderId, 1, &VertexShader, NULL); 
    glCompileShader(VertexShaderId); 

    GLint vertex_shader_status; 
    glGetShaderiv(FragmentShaderId, GL_COMPILE_STATUS, &vertex_shader_status); 
    if (vertex_shader_status == 0) 
    { 
     GLint logLength; 

     glGetShaderiv(FragmentShaderId, GL_INFO_LOG_LENGTH, &logLength); 
     if (logLength > 0) 
     { 
      GLchar *log = (GLchar *)malloc(logLength); 
      glGetShaderInfoLog(FragmentShaderId, logLength, &logLength, log); 
      fprintf(
       stderr, 
       "ERROR: Could not create the vertex shader: %s \n", 
       log 
      ); 
      free(log); 
     } 
     glDeleteShader(FragmentShaderId); 

    } 

    FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL); 
    glCompileShader(FragmentShaderId); 

    ProgramId = glCreateProgram(); 
     glAttachShader(ProgramId, VertexShaderId); 
     glAttachShader(ProgramId, FragmentShaderId); 
     glBindAttribLocation(ProgramId, 0, "in_Position"); 
     glBindAttribLocation(ProgramId, 1, "in_Color"); 
    glLinkProgram(ProgramId); 
    glUseProgram(ProgramId); 

    GLint logLength, status; 

    glValidateProgram(ProgramId); 
    glGetProgramiv(ProgramId, GL_INFO_LOG_LENGTH, &logLength); 
    if (logLength > 0) 
    { 
     GLchar *log = (GLchar *)malloc(logLength); 
     glGetProgramInfoLog(ProgramId, logLength, &logLength, log); 
     fprintf(
       stderr, 
       "ERROR: Could not create the program: %s \n", 
       log 
      ); 
     free(log); 
    } 

    glGetProgramiv(ProgramId, GL_VALIDATE_STATUS, &status); 
    if (status == 0) { 
     fprintf(
       stderr, 
       "ERROR: Could not create the program: \n" 
      ); 
    } 

    ErrorCheckValue = glGetError(); 
    if (ErrorCheckValue != GL_NO_ERROR) 
    { 
     fprintf(
      stderr, 
      "ERROR: Could not create the shaders: %s \n", 
      gluErrorString(ErrorCheckValue) 
     ); 
     exit(-1); 
    } 
} 

void DestroyShaders(void) 
{ 
    GLenum ErrorCheckValue = glGetError(); 

    glUseProgram(0); 

    glDetachShader(ProgramId, VertexShaderId); 
    glDetachShader(ProgramId, FragmentShaderId); 

    glDeleteShader(FragmentShaderId); 
    glDeleteShader(VertexShaderId); 

    glDeleteProgram(ProgramId); 

    ErrorCheckValue = glGetError(); 
    if (ErrorCheckValue != GL_NO_ERROR) 
    { 
     fprintf(
      stderr, 
      "ERROR: Could not destroy the shaders: %s \n", 
      gluErrorString(ErrorCheckValue) 
     ); 
     exit(-1); 
    } 
} 

私はモビリティのRadeon HD4570グラフィックスカードを持っています(OpenGL 3.1、GLSL 1.30)。

答えて

1

私が間違っていない場合、浮動小数点はデフォルトでhighpの精度を頂点シェーダに持っています。頂点シェーダでmediumpout vec ex_Colorを追加してください。

+0

'out mediump vec4 ex_Color;'が機能します! – Ziem

2

"precision mediump float;"そのシェーダで定義されているすべての浮動体のタイプを変更します。その宣言を使用している理由はありますか?仕様ごとのGLSLは意味を一切持たないことに注意してください。 GLESとの互換性のために追加されました。

+0

'precision mediump float;がありませんエラーが発生しました:_Declarationに精度修飾子を含めるか、または既定の精度が以前に宣言されている必要があります。 – Ziem

+0

シェーダコンパイラはありますか?これがOpenGL ES(またはESのみであるWebGL)でない限り、これらの精度修飾子はオプションです。 –

関連する問題