上一篇讲述了OpenGL相关的基本概念,下面开始通过实例描述opengl的使用。
triangle.cpp
1 #include <GL/glew.h>
2 #include <GL/freeglut.h>
3 #include <iostream>
4
5 #define BUFFER_OFFSET(x) ((const void*) (x))
6
7 enum VAO_IDs {Triangles, NumVAOs};
8 enum Buffer_IDs {ArrayBuffer, NumBuffers};
9 enum Attrib_IDs {vPosition = 0};
10
11 GLuint VAOs[NumVAOs];
12 GLuint Buffers[NumBuffers];
13 GLuint program;
14
15 const GLchar* vertex_shader = "#version 430 core \n"
16 "layout(location = 0)\n"
17 "in vec4 vPosition;\n"
18 "void main()\n"
19 "{\n"
20 "gl_Position = vPosition;\n"
21 "}\n";
22
23 const GLchar* fragment_shader = "#version 430 core \n"
24 "uniform vec4 color;\n"
25 "out vec4 fColor;\n"
26 "void main()\n"
27 "{\n"
28 "fColor = color;\n"
29 "}\n";
30 void init_shader()
31 {
32 // vertex shader
33 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
34 glShaderSource(vertexShader, 1, &vertex_shader, NULL);
35 glCompileShader(vertexShader);
36 // check vertex shader compiling status
37 GLint compiled;
38 GLchar log[256];
39 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compiled);
40 if (!compiled)
41 {
42 glGetShaderInfoLog(vertexShader, 256, NULL, log);
43 std::cerr << "vertex shader compile failed" << log << std::endl;
44 }
45
46 // fragment shader
47 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
48 glShaderSource(fragmentShader, 1, &fragment_shader, NULL);
49 glCompileShader(fragmentShader);
50 // check fragment shader compiling status
51 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compiled);
52 if (!compiled)
53 {
54 glGetShaderInfoLog(fragmentShader, 256, NULL, log);
55 std::cerr << "fragment shader compile failed" << log << std::endl;
56 }
57
58 // link shaders
59 program = glCreateProgram();
60 glAttachShader(program, vertexShader);
61 glAttachShader(program, fragmentShader);
62 glLinkProgram(program);
63 //check link status
64 GLint linked;
65 glGetProgramiv(program, GL_LINK_STATUS, &linked);
66 if (!linked)
67 {
68 glGetProgramInfoLog(program, 256, NULL, log);
69 std::cerr << "shader linking failed" << log << std::endl;
70 }
71 // delete shader
72 glDeleteShader(vertexShader);
73 glDeleteShader(fragmentShader);
74 }
75
76 void init_data()
77 {
78 glClearColor(1, 1, 1, 0);
79 glClear(GL_COLOR_BUFFER_BIT);
80
81 glGenVertexArrays(NumVAOs, VAOs);
82 glBindVertexArray(VAOs[Triangles]);
83
84 GLfloat vertices[3][2] = {
85 { -0.8, -0.9 },
86 { 0.8, -0.9 },
87 { 0, 0.9 },
88 };
89
90 glGenBuffers(NumBuffers, Buffers);
91 glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
92 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
93
94 glUseProgram(program);
95 // control fragment color
96 GLint loc = glGetUniformLocation(program, "color");
97 glUniform4f(loc, 1.0f, 0.0f, 0.0f, 1.0f);
98 glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
99 glEnableVertexAttribArray(vPosition);
100
101 }
102
103 void display()
104 {
105 glClear(GL_COLOR_BUFFER_BIT);
106
107 glBindVertexArray(VAOs[Triangles]);
108 glDrawArrays(GL_TRIANGLES, 0, 3);
109 glFlush();
110 }
111
112 int main(int argc, char* argv[])
113 {
114 glutInit(&argc, argv);
115 glutInitDisplayMode(GLUT_RGBA);
116 glutInitWindowSize(300 ,300);
117 glutInitWindowPosition(100, 100);
118 glutCreateWindow("Learn opengl: first triangle");
119
120 glewExperimental = GL_TRUE;
121 if(glewInit())
122 {
123 std::cout << "Unable to Initialize" << std::endl;
124 exit(1);
125 }
126 init_shader();
127 init_data();
128 glutDisplayFunc(display);
129 glutMainLoop();
130 }
在Ubuntu上运行: g++ triangle.cpp -lGL -lGLU -lglut -lGLEW
即可得到下图所示的三角形: