-
-
Save Pandinosaurus/fadad1efebd9032f761d991382b1d861 to your computer and use it in GitHub Desktop.
OpenGL draw cube and triangle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define GLEW_STATIC | |
| #include<stdio.h> | |
| #include<stdlib.h> | |
| #include<GL\glew.h> | |
| #include<GL\GL.h> | |
| #include<GLFW\glfw3.h> | |
| #include<glm.hpp> | |
| #include<gtx\transform.hpp> | |
| #include<string> | |
| #include<vector> | |
| #include<fstream> | |
| #include<time.h> | |
| using namespace glm; | |
| GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path); | |
| int main(int argc, char** argv) | |
| { | |
| glfwInit(); // one of two windows that were set up as if(!glfwInit()) cout << error; Deprecated? | |
| glfwWindowHint(GLFW_SAMPLES, 4); //4x AA | |
| glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // sets the first part of the version [3].3 | |
| glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // sets the second part of the version 3.[3] | |
| glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
| GLFWwindow* window = glfwCreateWindow(1024,768,"OpenGL", nullptr, nullptr); | |
| glfwMakeContextCurrent(window); | |
| // Initialize GLEW | |
| glewExperimental = GL_TRUE; // needed in core profile | |
| glewInit(); // two of two windows that were set up as if(!glewInit()) cout << error; Deprecated? | |
| // glfwSetWindowTitle( window, "Tutorial 04" ); | |
| // Ensure we can capture the escape key being pressed below | |
| //glfwEnable( GLFW_STICKY_KEYS ); | |
| // Dark blue background | |
| glClearColor(0.0f, 0.0f, 0.4f, 0.0f); | |
| // Enable depth test | |
| glEnable(GL_DEPTH_TEST); | |
| // Accept fragment if it closer to the camera than the former one | |
| glDepthFunc(GL_LESS); | |
| GLuint VertexArrayID; | |
| glGenVertexArrays(1, &VertexArrayID); | |
| glBindVertexArray(VertexArrayID); | |
| // Create and compile our GLSL program from the shaders | |
| GLuint programID = LoadShaders( "first.vs", "first.fs" ); | |
| // Get a handle for our "MVP" uniform | |
| GLuint MatrixID = glGetUniformLocation(programID, "MVP"); | |
| // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units | |
| mat4 Projection = perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); | |
| // Camera matrix | |
| mat4 View = lookAt( | |
| vec3(4,3,-3), // Camera is at (4,3,-3), in World Space | |
| vec3(0,0,0), // and looks at the origin | |
| vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down) | |
| ); | |
| // Model matrix : an identity matrix (model will be at the origin) | |
| mat4 Model = mat4(1.0f); | |
| // Our ModelViewProjection : multiplication of our 3 matrices | |
| mat4 MVP = Projection * View * Model; // Remember, matrix multiplication is the other way around | |
| // Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle. | |
| // A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices | |
| static const GLfloat g_vertex_buffer_data[] = { | |
| -1.0f,-1.0f,-1.0f, | |
| -1.0f,-1.0f, 1.0f, | |
| -1.0f, 1.0f, 1.0f, | |
| 1.0f, 1.0f,-1.0f, | |
| -1.0f,-1.0f,-1.0f, | |
| -1.0f, 1.0f,-1.0f, | |
| 1.0f,-1.0f, 1.0f, | |
| -1.0f,-1.0f,-1.0f, | |
| 1.0f,-1.0f,-1.0f, | |
| 1.0f, 1.0f,-1.0f, | |
| 1.0f,-1.0f,-1.0f, | |
| -1.0f,-1.0f,-1.0f, | |
| -1.0f,-1.0f,-1.0f, | |
| -1.0f, 1.0f, 1.0f, | |
| -1.0f, 1.0f,-1.0f, | |
| 1.0f,-1.0f, 1.0f, | |
| -1.0f,-1.0f, 1.0f, | |
| -1.0f,-1.0f,-1.0f, | |
| -1.0f, 1.0f, 1.0f, | |
| -1.0f,-1.0f, 1.0f, | |
| 1.0f,-1.0f, 1.0f, | |
| 1.0f, 1.0f, 1.0f, | |
| 1.0f,-1.0f,-1.0f, | |
| 1.0f, 1.0f,-1.0f, | |
| 1.0f,-1.0f,-1.0f, | |
| 1.0f, 1.0f, 1.0f, | |
| 1.0f,-1.0f, 1.0f, | |
| 1.0f, 1.0f, 1.0f, | |
| 1.0f, 1.0f,-1.0f, | |
| -1.0f, 1.0f,-1.0f, | |
| 1.0f, 1.0f, 1.0f, | |
| -1.0f, 1.0f,-1.0f, | |
| -1.0f, 1.0f, 1.0f, | |
| 1.0f, 1.0f, 1.0f, | |
| -1.0f, 1.0f, 1.0f, | |
| 1.0f,-1.0f, 1.0f | |
| }; | |
| static const GLfloat triangle_buffer_data[] = { 2.0f, 0.5f, 0.0f, | |
| 1.5, 0.5, 0.0f, | |
| 2.0f, 1.0f, 0.0f}; | |
| srand(time(NULL)); | |
| static GLfloat g_color_buffer_data[12*3*3]; | |
| for(int v = 0; v < 12*3; v++) | |
| { | |
| g_color_buffer_data[3*v+0] = 1.0f; //1/(rand() % 10 +1);//red; | |
| g_color_buffer_data[3*v+1] = 1.0f; //1/(rand() % 10 +1);//green; | |
| g_color_buffer_data[3*v+2] = 1.0f; //1/(rand() % 10 +1);//blue; | |
| } | |
| static GLfloat triangle_color_buffer_data[3*3]; | |
| for (int i = 0; i < 3*3; i++) | |
| { | |
| triangle_color_buffer_data[3*i+0] = 1/(rand() % 5 + 1); | |
| triangle_color_buffer_data[3*i+1] = 1/(rand() % 5 + 1); | |
| triangle_color_buffer_data[3*i+2] = 1/(rand() % 5 + 1); | |
| } | |
| GLuint vertexbuffer; | |
| glGenBuffers(1, &vertexbuffer); | |
| glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); | |
| glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); | |
| GLuint colorbuffer; | |
| glGenBuffers(1, &colorbuffer); | |
| glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); | |
| glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW); | |
| GLuint trianglebuff; | |
| glGenBuffers(1, &trianglebuff); | |
| glBindBuffer(GL_ARRAY_BUFFER, trianglebuff); | |
| glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_buffer_data), triangle_buffer_data, GL_STATIC_DRAW); | |
| GLuint trianglecolorbuff; | |
| glGenBuffers(1, &trianglecolorbuff); | |
| glBindBuffer(GL_ARRAY_BUFFER, trianglecolorbuff); | |
| glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_color_buffer_data), triangle_color_buffer_data, GL_STATIC_DRAW); | |
| while (!glfwWindowShouldClose(window)) | |
| { | |
| glfwPollEvents(); | |
| if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) | |
| glfwSetWindowShouldClose(window, GL_TRUE); | |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| for(int v = 0; v < 12*3; v++) | |
| { | |
| g_color_buffer_data[3*v+0] = 0.1f + 1/(rand() % 10 +1);//red; | |
| g_color_buffer_data[3*v+1] = 0.1f + 1/(rand() % 10 +1);//green; | |
| g_color_buffer_data[3*v+2] = 0.1f + 1/(rand() % 10 +1);//blue; | |
| } | |
| for(int v = 0; v < 3*3; v++) | |
| { | |
| triangle_color_buffer_data[3*v+0] = 0.1f + 1/(rand() % 10 +1);//red; | |
| triangle_color_buffer_data[3*v+1] = 0.1f + 1/(rand() % 10 +1);//green; | |
| triangle_color_buffer_data[3*v+2] = 0.1f + 1/(rand() % 10 +1);//blue; | |
| } | |
| glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); | |
| glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW); | |
| glUseProgram(programID); | |
| // Send our transformation to the currently bound shader, | |
| // in the "MVP" uniform | |
| glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); | |
| // 1rst attribute buffer : vertices | |
| glEnableVertexAttribArray(0); | |
| glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); | |
| glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); | |
| // 2nd attribute buffer : colors | |
| glEnableVertexAttribArray(1); | |
| glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); | |
| glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0); | |
| // Draw the triangles ! | |
| glDrawArrays(GL_TRIANGLES, 0, 36); // 12*3 indices starting at 0 -> 12 triangles | |
| //glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); | |
| glBindBuffer(GL_ARRAY_BUFFER,trianglebuff); //bind the new buffers | |
| glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); // Send in the new data | |
| glBindBuffer(GL_ARRAY_BUFFER, trianglecolorbuff); | |
| glBufferData(GL_ARRAY_BUFFER,sizeof(triangle_color_buffer_data), triangle_color_buffer_data, GL_STATIC_DRAW); | |
| glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0); | |
| glDrawArrays(GL_TRIANGLES,0,9); | |
| glDisableVertexAttribArray(0); | |
| glDisableVertexAttribArray(1); | |
| glfwSwapBuffers(window); | |
| } | |
| glDeleteBuffers(1, &vertexbuffer); | |
| glDeleteBuffers(1, &colorbuffer); | |
| glDeleteProgram(programID); | |
| glDeleteVertexArrays(1, &VertexArrayID); | |
| glfwTerminate(); | |
| //system("pause"); | |
| } | |
| GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) | |
| { | |
| GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); | |
| GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); | |
| // Read the vertex Shader code from the file | |
| std::string VertexShaderCode; | |
| std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); | |
| if(VertexShaderStream.is_open()) | |
| { | |
| std::string Line = ""; | |
| while(getline(VertexShaderStream, Line)) | |
| VertexShaderCode +="\n" + Line; | |
| VertexShaderStream.close(); | |
| } | |
| // Read the Fragment Shader code from the file | |
| std::string FragmentShaderCode; | |
| std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); | |
| if(FragmentShaderStream.is_open()) | |
| { | |
| std::string Line = ""; | |
| while(getline(FragmentShaderStream, Line)) | |
| FragmentShaderCode +="\n" + Line; | |
| FragmentShaderStream.close(); | |
| } | |
| GLint Result = GL_FALSE; | |
| int InfoLogLength; | |
| // Compile Vertex Shader | |
| printf("Compiling shader : %s\n", vertex_file_path); | |
| char const * VertexSourcePointer = VertexShaderCode.c_str(); | |
| glShaderSource(VertexShaderID,1,&VertexSourcePointer, NULL); | |
| glCompileShader(VertexShaderID); | |
| // Check Vertex Shader | |
| glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); | |
| glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | |
| if(InfoLogLength > 0) | |
| { | |
| std::vector<char> VertexShaderErrorMessage(InfoLogLength); | |
| glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); | |
| printf("%s\n", &VertexShaderErrorMessage[0]); | |
| } | |
| // Compile Fragment Shader | |
| printf("Compiling shader : %s\n", fragment_file_path); | |
| char const * FragmentSourcePointer = FragmentShaderCode.c_str(); | |
| glShaderSource(FragmentShaderID,1,&FragmentSourcePointer, NULL); | |
| glCompileShader(FragmentShaderID); | |
| // Check Fragment Shader | |
| glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); | |
| glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | |
| if(InfoLogLength > 0) | |
| { | |
| std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); | |
| glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); | |
| printf("%s\n", &FragmentShaderErrorMessage[0]); | |
| } | |
| // Link the program | |
| printf("Linking program\n"); | |
| GLuint ProgramID = glCreateProgram(); | |
| glAttachShader(ProgramID, VertexShaderID); | |
| glAttachShader(ProgramID, FragmentShaderID); | |
| glLinkProgram(ProgramID); | |
| // Check the Program | |
| glGetProgramiv(ProgramID, GL_COMPILE_STATUS, &Result); | |
| glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); | |
| std::vector<char> ProgramErrorMessage(max(InfoLogLength, int(1))); | |
| printf("%s\n", &ProgramErrorMessage[0]); | |
| glDeleteShader(VertexShaderID); | |
| glDeleteShader(FragmentShaderID); | |
| return ProgramID; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment