This shows you how to create the main window with the book’s application framework and how to render simple graphics into it.
In shaders,we use #version430 core to tell the shader compiler that we intend to use version 4.3 of the shading language.The keyword core to indicate that we only intend to use features from the core profile of OpenGL.
The main function is where the shader starts executing.
gl_Position is part of the plumbing that connects the shader to the rest of OpenGL.All variables that start with gl_ are part of OpenGL and connect shaders to each other or to the various parts of fixed functionality in OpenGL.In the vertex shader,gl_Position represents the output position of the vertex.
1 #version 420 core 2 void main(void) 3 { 4 gl_Position = vec4(0.0, 0.0, 0.0, 1.0); 5 }
Using the keyword "out" to declares "color" as a output variable.In fragment shaders, the value of out put variables will be sent to window or screen.
If we want to draw anything when our pipeline does not contain a vertex shader,the results will be undefined and almost certainly not what you were hoping for.So we should have both a vertex and a feagment shader at least.
Next we will compile and link them so that we can run the OpenGL application.
1 GLuint compile_shaders(void) 2 { 3 GLuint vertex_shader; 4 GLuint fragment_shader; 5 GLuint program; 6 // Source code for vertex shader 7 static const GLchar * vertex_shader_source[] = 8 { 9 "#version 430 core " 10 " " 11 "void main(void) " 12 "{ " 13 " gl_Position = vec4(0.0, 0.0, 0.5, 1.0); " 14 "} " 15 }; 16 // Source code for fragment shader 17 static const GLchar * fragment_shader_source[] = 18 { 19 "#version 430 core " 20 " " 21 "out vec4 color; " 22 " " 23 "void main(void) " 24 "{ " 25 " color = vec4(0.0, 0.8, 1.0, 1.0); " 26 "} " 27 }; 28 // Create and compile vertex shader 29 vertex_shader = glCreateShader(GL_VERTEX_SHADER); 30 glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); 31 glCompileShader(vertex_shader); 32 // Create and compile fragment shader 33 fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 34 glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); 35 glCompileShader(fragment_shader); 36 // Create program, attach shaders to it, and link it 37 program = glCreateProgram(); 38 glAttachShader(program, vertex_shader); 39 glAttachShader(program, fragment_shader); 40 glLinkProgram(program); 41 // Delete the shaders as the program has them now 42 glDeleteShader(vertex_shader); 43 glDeleteShader(fragment_shader); 44 return program; 45 }
glCreateShader() creates an empty shader object, ready to accept source code and be compiled.
glShaderSource() hands shader source code to the shader object so that it can keep a copy of it.
glCompileShader() compiles whatever source code is contained in the shader object.
glCreateProgram() creates a program object to which you can attach shader objects.
glAttachShader() attaches a shader object to a program object.
glLinkProgram() links all of the shader objects attached to a program object together.
glDeleteShader() deletes a shader object. Once a shader has been linked into a program object, the program contains the binary code and the shader is no longer needed.
Fortunately, GLSL includes a special input to the vertex shader called gl_VertexID, which is the index of the vertex that is being processed at the time. The gl_VertexID input starts counting from the value given by the first parameter of glDrawArrays() and counts upwards one vertex at a time for count vertices (the third parameter of glDrawArrays()).
Example code:
1 #include <sb6.h> 2 3 class singlepoint_app : public sb6::application 4 { 5 void init() 6 { 7 static const char title[] = "OpenGL SuperBible - Single Triangle"; 8 9 sb6::application::init(); 10 11 memcpy(info.title, title, sizeof(title)); 12 } 13 14 virtual void startup() 15 { 16 static const char * vs_source[] = 17 { 18 "#version 420 core " 19 " " 20 "void main(void) " 21 "{ " 22 " const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0), " 23 " vec4(-0.25, -0.25, 0.5, 1.0), " 24 " vec4( 0.0, 0.0, 0.5, 1.0)); " 25 " " 26 " gl_Position = vertices[gl_VertexID]; " 27 "} " 28 }; 29 30 static const char * fs_source[] = 31 { 32 "#version 420 core " 33 " " 34 "out vec4 color; " 35 " " 36 "void main(void) " 37 "{ " 38 " color = vec4(0.0, 0.8, 1.0, 1.0); " 39 "} " 40 }; 41 42 program = glCreateProgram(); 43 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); 44 glShaderSource(fs, 1, fs_source, NULL); 45 glCompileShader(fs); 46 47 GLuint vs = glCreateShader(GL_VERTEX_SHADER); 48 glShaderSource(vs, 1, vs_source, NULL); 49 glCompileShader(vs); 50 51 glAttachShader(program, vs); 52 glAttachShader(program, fs); 53 54 glLinkProgram(program); 55 56 glGenVertexArrays(1, &vao); 57 glBindVertexArray(vao); 58 } 59 60 virtual void render(double currentTime) 61 { 62 static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f }; 63 glClearBufferfv(GL_COLOR, 0, green); 64 65 glUseProgram(program); 66 glDrawArrays(GL_LINES, 0, 3); 67 } 68 69 virtual void shutdown() 70 { 71 glDeleteVertexArrays(1, &vao); 72 glDeleteProgram(program); 73 } 74 75 private: 76 GLuint program; 77 GLuint vao; 78 }; 79 80 DECLARE_MAIN(singlepoint_app)