Как настроить шейдеры в openGL - PullRequest
0 голосов
/ 27 марта 2019

Я работаю над разработкой кода в 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 Ответ

3 голосов
/ 27 марта 2019

Переменная gl_FragColor недоступна в профиле ядра GLSL 4.4, поскольку она устарела. Поскольку вы не указываете профиль compatibility, предполагается значение по умолчанию core. Либо использовать

#version 440 compatibility

для ваших шейдеров, или, что еще лучше, используйте подход GLSL 4.4 и выше:

#version 440 core
layout(location = 0) out vec4 OUT;
void main(){
    OUT = vec4(0.0, 1.0, 0.0, 1.0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...