如何将顶点位置传递给顶点着色器.我写了一个着色器,它不会在屏幕上绘制任何内容

How can I pass the vertices position to my vertex shader. I wrote a shader that is not drawing anything to the screen

本文关键字:顶点 一个 任何内 绘制 屏幕 位置      更新时间:2023-10-16

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

我的顶点着色器是:

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

代码有几个问题:

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

然后,将固定函数代码(glMatrixMode和相关函数)与核心配置文件代码混合。最有可能的问题是,这里应用的所有变换都没有使用(因为在使用着色器的核心配置文件中工作时不使用矩阵堆栈)。因此,使用的坐标(从200到400)在默认视图截头体之外(从-1到1)。您必须在着色器中的某个位置实现转换,才能将点正确投影到NDC。

次要:不能保证vertexPosition会在位置0上(尽管可能是这种情况)