如何将顶点位置传递到顶点着色器。我写了一个没有在屏幕上绘制任何内容的着色器

时间:2016-04-03 16:13:12

标签: c++ c++11 opengl shader fragment-shader

我写了一个没有在屏幕上绘制任何东西的着色器程序,我认为这是因为我可能会错过一些东西,我不知道如何将顶点位置传递给它。

我的顶点着色器是:

#version 130

in vec2 vertexPosition;

void main()
{
    gl_Position.xy=vertexPosition;
    gl_Position.z=-1.0;
    gl_Position.w=1.0;
}

我的片段着色器是:

#version 130

out vec3 color;

void main()
{
    color=vec3(1.0,0.0,0.0);
}

这是代码:

 GLfloat triangle []
    {
        200,200,
        400,200,
        400,400
    };
    //translating the coordinates
    glViewport(0,0,640,480);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,640,0,480,0,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


    GLuint triangleBufferID;//store the identifier of this buffer
    glGenBuffers(1, &triangleBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, triangleBufferID); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW); //describe the data in the buffer
    glEnableVertexAttribArray(0); //enable the buffer
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); //Get the pointer for the buffer.

    //SECOND SHADER TYPE (READ FROM FILE):
    const GLchar* vertexshaderPath = "vertexshader.vsh";
    const GLchar* fragmentshaderPath = "fragmentshader.fsh";
    string vertexshaderSource = ""; //getting a string to store the source code of vertexshader.vsh
    string fragmentshaderSource = ""; //getting a string to store the source code of fragmentshader.fsh
    ifstream vertexfile; //getting a file pointer for vertexshader.vsh;
    ifstream fragmentfile; //getting a file pointer for fragmentshader.fsh;
    vertexfile.exceptions (ifstream::badbit); //add exceptions to the file pointer;
    fragmentfile.exceptions (ifstream::badbit); //add exceptions to the file pointer;
    try 
    {
        vertexfile.open(vertexshaderPath); //open vertexshader.vsh
        fragmentfile.open(fragmentshaderPath); //open fragmentshader.fsh
        stringstream vfstream, ffstream; //get two stringstream object;
        vfstream << vertexfile.rdbuf(); //get the content of vertexshader.vsh into a stringstream;
        ffstream << fragmentfile.rdbuf(); //get the content of fragmentshader.fsh into a stringstream;
        vertexfile.close(); //close the file;
        fragmentfile.close(); //close the file;
        vertexshaderSource=vfstream.str(); //copy the string from stringstream into vertexshaderSource;
        fragmentshaderSource=ffstream.str(); //copy the string from stringstream into fragmentshaderSource;
    }
    catch (ifstream::failure e) //if failure caught...
    {
        cout << "Error, file is unreadable!" << endl;
    }
    const GLchar* vscode = vertexshaderSource.c_str();
    //converted into c_str();
    const GLchar* fscode = fragmentshaderSource.c_str(); 
    //converted into c_str();

    //THIS PART FOR ALL WAYS:
    GLuint vertexshaderID=glCreateShader(GL_VERTEX_SHADER); //create a shader
    glShaderSource(vertexshaderID,1,&vscode,nullptr);
    glCompileShader(vertexshaderID); //compile shader;
    GLint success;
    GLchar infolog[512];
    glGetShaderiv(vertexshaderID, GL_COMPILE_STATUS, &success);
    if(!success) //check the compilation results
    {
        glGetShaderInfoLog(vertexshaderID,512,0,infolog);
        cout << "Error vertex shader's compilation failed" << endl;
        cout << infolog << endl;
    }
    GLuint fragmentshaderID=glCreateShader(GL_FRAGMENT_SHADER); //create a shader
    glShaderSource(fragmentshaderID,1,&fscode, nullptr);
    glCompileShader(fragmentshaderID); //compile shader
    glGetShaderiv(fragmentshaderID,GL_COMPILE_STATUS,&success);
    if(!success) //check the compilation results
    {
        glGetShaderInfoLog(fragmentshaderID,512,0,infolog);
        cout << "Error fragment shader's compilation failed" << endl;
        cout << infolog << endl;
    }
    GLuint programID = glCreateProgram(); //create a program;
    glAttachShader(programID, vertexshaderID); //attach vertexshader to the program;
    glAttachShader(programID, fragmentshaderID); //attach fragmentshader to the program;

    glBindAttribLocation(programID, 0, "vertexPosition");
    glUniform3f(glGetUniformLocation(programID, "color"),1.0,0.0,0.0);

    glLinkProgram(programID); //link the pieces of the program;
    glGetProgramiv(programID, GL_LINK_STATUS, &success);
    if(!success) //check the link status;
    {
        glGetProgramInfoLog(programID,512,0,infolog);
        cout << "Error linking the program" << endl;
        cout << infolog << endl;
    }
  //  glDeleteShader(vertexshaderID);
//    glDeleteShader(fragmentshaderID);

    glUseProgram(programID); //use the program;
    glDrawArrays(GL_TRIANGLES, 0, 3);
    SDL_GL_SwapWindow(window);

1 个答案:

答案 0 :(得分:0)

代码有几个问题:

用于初始化缓冲区和着色器的代码与必须在每个帧中调用的代码混合在一起。例如,着色器加载肯定只能进行一次,但是绘制调用必须每帧都进行。

然后,您将固定功能代码(glMatrixMode和相关功能)与核心配置文件代码混合在一起。最可能的问题是,此处应用的所有转换都未使用(因为在使用着色器的核心配置文件中工作时不使用矩阵堆栈)。因此,使用的坐标(从200到400)在默认视锥体之外(范围从-1到1)。您必须在着色器中的某处实现转换,以便将您的点正确投影到NDC。

轻微:无法保证vertexPosition位于0位置(尽管可能是这种情况)。