Description
从外部文件加载 shader,绘制 1 个 triangle
Project structure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Project Root ================ │ 02_load-simple-shaders.cpp │ makefile ├───include │ ├───GL │ │ eglew.h │ │ glew.h │ │ glxew.h │ │ wglew.h │ └───GLFW │ glfw3.h │ glfw3native.h ├───lib │ glew32d.dll │ glfw3.dll └───shaders 02_load-simple-shaders.frag 02_load-simple-shaders.vert |
Codes
makefile
1 2 3 4 5 6 7 8 9 |
CC = g++ INCFLAGS = -I include LDFLAGS = -L lib -lglfw3 -lglew32d -lopengl32 all: $(CC) 02_load-simple-shaders.cpp -o 02_load-simple-shaders $(INCFLAGS) $(LDFLAGS) clean: @del *.o *.exe |
02_load-simple-shaders.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
#include <GL/glew.h> #include <GLFW/glfw3.h> #include <math.h> #include <iostream> GLuint rendering_program; GLuint vertex_array_object; static const GLchar* load_shader( const char* filename ) { FILE* infile = fopen( filename, "rb" ); if(!infile) return NULL; fseek( infile, 0, SEEK_END ); int size = ftell( infile ); rewind( infile ); GLchar* src = new GLchar[size+1]; fread( src, sizeof(GLchar), size, infile ); fclose( infile ); src[size] = 0; return const_cast<const GLchar*>(src); } void display(){ double curTime = glfwGetTime(); const GLfloat color[] = { (float)sin(curTime)*0.5f + 0.5f, (float)cos(curTime)*0.5f + 0.5f, 0.0f, 1.0f }; glClearBufferfv(GL_COLOR, 0, color); // Use the program object we created earlier for rendering glUseProgram(rendering_program); glDrawArrays(GL_TRIANGLES, 0, 3); } void compile_shaders() { GLuint vertex_shader; GLuint fragment_shader; // Source code for vertex shader static const GLchar * vertex_shader_source = load_shader("shaders/05_draw-triangle.vert"); // Source code for fragment shader static const GLchar * fragment_shader_source = load_shader("shaders/05_draw-triangle.frag"); // Create and compile vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL); glCompileShader(vertex_shader); // Create and compile fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); glCompileShader(fragment_shader); // Create program, attach shaders to it, and link it rendering_program = glCreateProgram(); glAttachShader(rendering_program, vertex_shader); glAttachShader(rendering_program, fragment_shader); glLinkProgram(rendering_program); // Delete the shaders as the program has them now glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glCreateVertexArrays(1, &vertex_array_object); glBindVertexArray(vertex_array_object); } void shutdown() { glDeleteVertexArrays(1, &vertex_array_object); glDeleteProgram(rendering_program); glDeleteVertexArrays(1, &vertex_array_object); } int main() { GLFWwindow* window; glfwInit(); window = glfwCreateWindow(800, 600, "Hello, World!", NULL, NULL); glfwMakeContextCurrent(window); glewInit(); // startup compile_shaders(); while (!glfwWindowShouldClose(window)) { display(); glfwSwapBuffers(window); glfwPollEvents(); } shutdown(); glfwTerminate(); return 0; } |
02_load-simple-shaders.vert
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#version 450 core void main(void) { // Declare a hard-coded array of positions const vec4 vertices[3] = vec4[3]( vec4(0.25, -0.25, 0.5, 1.0), vec4(-0.25, -0.25, 0.5, 1.0), vec4(0.25, 0.25, 0.5, 1.0) ); // Index into our array using gl_VertexID gl_Position = vertices[gl_VertexID]; } |
02_load-simple-shaders.frag
1 2 3 4 5 6 7 8 |
#version 450 core out vec4 color; void main(void) { color = vec4(0.2, 0.2, 1.0, 1.0); } |