#include #include #include //GLM MAth Header inclusions #include #include #include using namespace std; //Standard name space #define WINDOW_TITLE "Modern OpenGL" // Window title macro /* Shader program */ #ifndef GLSL #define GLSL(Version, Source) "#version " #Version "\n" #Source #endif /*Variable declaration for shader, window size initialization, buffer and array objects*/ GLint shaderProgram, WindowWidth = 800, WindowHeight = 600; GLuint VBO, VAO, EBO, texture; /*Function prototypes */ void UResizeWindow(int, int); void URenderGraphics(); void UCreateShader(); void UCreateBuffers(); /* Vertex Shader source code */ const GLchar* vertexShaderSource = GLSL(330, layout(location = 0) in vec3 position; //vertex data from vertex attrib pointer 0 layout(location = 1) in vec3 color;// color data from vertex attrib pointer 1 out vec3 mobileColor; //Global variables for the transform matrices uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { gl_position = projection * view * model * vec4(position, 1.0f); // transform vertices to clip coordinates mobileColor = color; // references incoming color data } ); /*Fragment shader source*/ const GLchar* fragmentShaderSource = GLSL(330, in vec3 mobileColor;//variable to hold incoming color data from vertex shader out vec4 gpuColor; //variable to pass color data to the GPU void main() { gpuColor = vec4(mobileColor, 1.0); // sends color data to the GPU for rendering } ); /*Main Program*/ int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow(WINDOW_TITLE); glutReshapeFunc(UResizeWindow); glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; return -1; } UCreateShader(); UCreateBuffers(); // use the shader program glUseProgram(shaderProgram); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // sets background color //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glutDisplayFunc(URenderGraphics); glutMainLoop(); // Destroys buffer objects once used glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); return 0; } /* Resize the window */ void UResizeWindow(int w, int h) { WindowWidth = w; WindowHeight = h; glViewport(0, 0, WindowWidth, WindowHeight); } /* Render graphics */ void URenderGraphics() { glEnable(GL_DEPTH_TEST); // enabled z depth glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArray(VAO); // activate the vertex aray object before rendering and transforming them //transform the object glm::mat4 model; model = glm::translate(model, glm::vec3(0.5f, 0.0f, 0.0f)); //place the object at the center of the viewport //rotate the cube every second by 0.0005f degrees in xyz model = glm::rotate(model, glutGet(GLUT_ELAPSED_TIME) * -0.0005f, glm::vec3(0.0, 1.0f, 0.0f)); model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); // increase the object size by the scale of 2 // toggle the camera glm::mat4 view; view = glm::translate(view, glm::vec3(0.0f, 0.0f, -5.0f)); //moves the world backwards -5 units in the z away from the camera // creates perspectives projection glm::mat4 projection; projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f); // retrieves and passed transform matrices to the shader program GLint modelLoc = glGetUniformLocation(shaderProgram, "model"); GLint viewLoc = glGetUniformLocation(shaderProgram, "view"); GLint projLoc = glGetUniformLocation(shaderProgram, "projection"); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glutPostRedisplay(); //Draws triangles glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); glBindVertexArray(0); //deactivates the vertes array objects glutSwapBuffers(); // flips the back buffer with the front buffer every frame } void UCreateShader() { //vertex shader GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // creates the vertex shader glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // Attaches the vertex shader to the source glCompileShader(vertexShader); // compiles vertex shader //fragment shader GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //creates the fragment shader glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); //attaches the fragment shader to the source glCompileShader(fragmentShader); //compile the fragment shader //shader program shaderProgram = glCreateProgram(); //creates the shader program and return an id glAttachShader(shaderProgram, vertexShader); //Attached the vertex shader to the shader program glAttachShader(shaderProgram, fragmentShader); // Attached the fragment shader to the shader program glLinkProgram(shaderProgram); //Link the vertex and fragment shader to the shader program //Delete the vertex and fragment shader once linked glDeleteShader(vertexShader); glDeleteShader(fragmentShader); } /*Create the Buffer and array objects*/ void UCreateBuffers() { //Position and color data GLfloat vertices[] = { //vertex Position // Colors 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, //Top right vertex 0 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom right vertex 1 -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, //Bottom left vertex 2 -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //Top left vertex 3 0.5f, -0.5f, -1.0f, 0.5f, 0.5f, 1.0f, //4br right 0.5f, 0.5f, -1.0f, 1.0f, 1.0f, 0.5f, //5tl right -0.5f, 0.5f, -1.0f, 0.2f, 0.2f, 0.5f, //6tl top -0.5f, -0.5f, -1.0f, 1.0, 0.0f, 1.0f //7bl block }; GLuint indices[] = { 0,1,3, // triangle 1 1,2,3, // triangle 2 0,1,4, //triangle 3 0,4,5, //triangle 4 0,5,6, //triangle 5 0,3,6, // triangle 6 4,5,6, // triangle 7 4,6,7, //triangle 8 2,3,6, //triangle 9 2,6,7, //triangle 10 1,4,7, //triangle 11 1,2,7 //triangle12 }; //Generate buffer ids glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); //Activates the vertex array object before binding and setting any VBOs and vertex attributes pointers glBindVertexArray(VAO); //Activates VBO glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO //Activates the Element buffers object / indicers glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //Copy indices to EBO //Set attribute pointer 0 to hold position data glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); //Enables vertex attribute //set attribute pointer 1 to hold color data glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); //Enables vertex attribute glBindVertexArray(0); }