如何在openGL中设置着色器

时间:2019-03-27 04:36:21

标签: c++ opengl

我正在使用OpenGL开发代码,并且正在完成其中一节教程。但是,我完成的代码并未为三角形着色。根据本教程,我的三角形应该显示为绿色,但它始终变成白色。我认为我的着色器的代码中有错误,但我似乎找不到该错误。

我尝试过几次修改代码,甚至还进入了下一个教程,该教程为每个顶点着色。但是,我的三角形仍然显示为白色。

#include <iostream> //Includes C++ i/o stream
#include <GL/glew.h> //Includes glew header
#include <GL/freeglut.h> //Includes freeglut header

using namespace std; //Uses the standard namespace

#define WINDOW_TITLE "Modern OpenGL" //Macro for window title

//Vertex and Fragment Shader Source Macro
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif

//Variables for window width and height
int WindowWidth = 800, WindowHeight = 600;

/* User-defined Function prototypes to:
 * initialize the program, set the window size,
 * redraw graphics on the window when resized,
 * and render graphics on the screen
 * */
void UInitialize(int, char*[]);
void UInitWindow(int, char*[]);
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateVBO(void);  //This step is missing from Tutorial 3-3
void UCreateShaders(void);

/*Vertex Shader Program Source Code*/
const GLchar * VertexShader = GLSL(440,
        in layout(location=0) vec4 vertex_Position; //Receive vertex coordinates from attribute 0. i.e. 2
            void main(){
                gl_Position = vertex_Position; //Sends vertex positions to gl_position vec 4
            }
);

/*Fragment Shader Program Source Code*/
const GLchar * FragmentShader = GLSL(440,
        void main(){
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); //Sets the pixels / fragments of the triangle to green
    }
);

//main function. Entry point to the OpenGL Program
int main(int argc, char* argv[])
{
    UInitialize(argc, argv); //Initialize the OpenGL program
    glutMainLoop(); // Starts the Open GL loop in the background
    exit(EXIT_SUCCESS); //Terminates the program successfully
}


//Implements the UInitialize function
void UInitialize(int argc, char* argv[])
{
    //glew status variable
    GLenum GlewInitResult;

    UInitWindow(argc, argv); //Creates the window

    //Checks glew status
    GlewInitResult = glewInit();

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

    //Displays GPU OpenGL version
    fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));

    UCreateVBO(); //Calls the function to create the Vertex Buffer Object

    UCreateShaders(); //Calls the function to create the Shader Program

    //Sets the background color of the window to black. Optional
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

}

//Implements the UInitWindow function
void UInitWindow(int argc, char* argv[])
{
    //Initializes freeglut
    glutInit(&argc, argv);

    //Sets the window size
    glutInitWindowSize(WindowWidth, WindowHeight);

    //Memory buffer setup for display
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

    //Creates a window with the macro placeholder title
    glutCreateWindow(WINDOW_TITLE);

    glutReshapeFunc(UResizeWindow); //Called when the window is resized
    glutDisplayFunc(URenderGraphics); //Renders graphics on the screen

}

//Implements the UResizeWindow function
void UResizeWindow(int Width, int Height)
{
    glViewport(0,0, Width, Height);
}

//Implements the URenderGraphics function
void URenderGraphics(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clears the screen

    /*Creates the triangle*/
    GLuint totalVertices = 3; //Specifies the number of vertices for the triangle i.e. 3
    glDrawArrays(GL_TRIANGLES, 0, totalVertices); //Draws the triangle

    glutSwapBuffers(); //Flips the back buffer with the front buffer every frame. Similar to GL Flush

}

//Implements the CreateVBO function
void UCreateVBO(void)
{
    //Specifies coordinates for triangle vertices on x and y
    GLfloat verts[] =
    {
            0.0f, 1.0f, //top-center of the screen
            -1.0f, -1.0f, //bottom-left of the screen
            1.0f, -1.0f //bottom-right of the screen
    };

    //Stores the size of the verts array / number of the coordinates needed for the triangle i.e. 6
    float numVertices = sizeof(verts);

    GLuint myBufferID; //Variable for vertex buffer object id
    glGenBuffers(1, &myBufferID); //Creates 1 buffer
    glBindBuffer(GL_ARRAY_BUFFER, myBufferID); //Activates the buffer
    glBufferData(GL_ARRAY_BUFFER, numVertices, verts, GL_STATIC_DRAW); //Sends vertex or coordinate data to GPU

    /*Creates the Vertex Attribute Pointer*/
    GLuint floatsPerVertex = 2; //Number of coordinates per vertex
    glEnableVertexAttribArray(0); //Specifies the initial position of the coordinates in the buffer
    /*Instructs the GPU on how to handle the vertex bugger object data.
     * Parameters: attribPointerPosition | coordinates per vertex | data type | deactivate normalization | 0 strides | 0 offset
     */
    glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, 0, 0);
}

//Implements the UCreateShaders function
void UCreateShaders(void)
{
    //Create a shader program object
    GLuint ProgramId = glCreateProgram();

    GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER); //Create a Vertex Shader Object
    GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); //Create a Fragment Shader Object

    glShaderSource(vertexShaderId, 1, &VertexShader, NULL); //Retrieves the vertex shader source code
    glShaderSource(fragmentShaderId, 1, &FragmentShader, NULL); //Retrieves the fragment shader source code

    glCompileShader(vertexShaderId); //Compile the vertex shader
    glCompileShader(fragmentShaderId); //Compile the fragment shader

    //Attaches the vertex and fragment shaders to the shader program
    glAttachShader(ProgramId, vertexShaderId);
    glAttachShader(ProgramId, fragmentShaderId);

    glLinkProgram(ProgramId); //Links the shader program
    glUseProgram(ProgramId); //Uses the shader program
}

正确完成后,代码应产生一个纯绿色三角形。

1 个答案:

答案 0 :(得分:3)

由于已弃用变量public class Store { private Stock<Food> foodStock; private Stock<Drink> drinkStock; public Store() { this.foodStock = new Stock<>(); this.drinkStock = new Stock<>(); } public Store(Stock<Food> foodStock, Stock<Drink> drinkStock) { this.foodStock = foodStock; this.drinkStock = drinkStock; } public void addItemToStock(AbstractEdible product) { if (product instanceof Food) { this.foodStock.addItem((Food) product); } else if (product instanceof Drink) { this.drinkStock.addItem((Drink) product); } } } 在GLSL 4.4核心配置文件中不可用。因为您未指定gl_FragColor配置文件,所以假定使用默认的compatibility。可以使用

core

对于您的着色器,或者甚至更好的是,使用GLSL 4.4及更高版本的方法:

#version 440 compatibility