1 //
2 // Tiny OpenGL v3 + glut demo program for the Fast Light Tool Kit (FLTK).
3 //
4 // Copyright 1998-2021 by Bill Spitzak and others.
5 //
6 // This library is free software. Distribution and use rights are outlined in
7 // the file "COPYING" which should have been included with this file. If this
8 // file is missing or damaged, see the license at:
9 //
10 // https://www.fltk.org/COPYING.php
11 //
12 // Please see the following page on how to report bugs and issues:
13 //
14 // https://www.fltk.org/bugs.php
15 //
16
17 #include <stdio.h>
18 #if defined(__APPLE__)
19 # define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED 1
20 # include <OpenGL/gl3.h> // defines OpenGL 3.0+ functions
21 #else
22 # if defined(_WIN32)
23 # define GLEW_STATIC 1
24 # endif
25 # include <GL/glew.h>
26 #endif
27 #include <FL/glut.H>
28
29
30 // Globals
31 // Real programs don't use globals :-D
32 // Data would normally be read from files
33 GLfloat vertices[] = { -1.0f,0.0f,0.0f,
34 0.0f,1.0f,0.0f,
35 0.0f,0.0f,0.0f };
36 GLfloat colours[] = { 1.0f, 0.0f, 0.0f,
37 0.0f, 1.0f, 0.0f,
38 0.0f, 0.0f, 1.0f };
39 GLfloat vertices2[] = { 0.0f,0.0f,0.0f,
40 0.0f,-1.0f,0.0f,
41 1.0f,0.0f,0.0f };
42
43 // two vertex array objects, one for each object drawn
44 unsigned int vertexArrayObjID[2];
45 // three vertex buffer objects in this example
46 unsigned int vertexBufferObjID[3];
47
48
printShaderInfoLog(GLint shader)49 void printShaderInfoLog(GLint shader)
50 {
51 int infoLogLen = 0;
52 GLchar *infoLog;
53
54 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
55 if (infoLogLen > 0)
56 {
57 infoLog = new GLchar[infoLogLen];
58 // error check for fail to allocate memory omitted
59 glGetShaderInfoLog(shader,infoLogLen, NULL, infoLog);
60 fprintf(stderr, "InfoLog:\n%s\n", infoLog);
61 delete [] infoLog;
62 }
63 }
64
65
init(void)66 void init(void)
67 {
68 // Would load objects from file here - but using globals in this example
69
70 // Allocate Vertex Array Objects
71 glGenVertexArrays(2, &vertexArrayObjID[0]);
72 // Setup first Vertex Array Object
73 glBindVertexArray(vertexArrayObjID[0]);
74 glGenBuffers(2, vertexBufferObjID);
75
76 // VBO for vertex data
77 glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[0]);
78 glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
79 glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
80 glEnableVertexAttribArray(0);
81
82 // VBO for colour data
83 glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[1]);
84 glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), colours, GL_STATIC_DRAW);
85 glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0);
86 glEnableVertexAttribArray(1);
87
88 // Setup second Vertex Array Object
89 glBindVertexArray(vertexArrayObjID[1]);
90 glGenBuffers(1, &vertexBufferObjID[2]);
91
92 // VBO for vertex data
93 glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[2]);
94 glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices2, GL_STATIC_DRAW);
95 glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
96 glEnableVertexAttribArray(0);
97
98 glBindVertexArray(0);
99 }
100
101
initShaders(void)102 void initShaders(void)
103 {
104 GLuint p, f, v;
105 glClearColor (1.0, 1.0, 1.0, 0.0);
106
107 v = glCreateShader(GL_VERTEX_SHADER);
108 f = glCreateShader(GL_FRAGMENT_SHADER);
109
110 #ifdef __APPLE__
111 #define SHADING_LANG_VERS "140"
112 #else
113 #define SHADING_LANG_VERS "130"
114 #endif
115 // load shaders
116 const char *vv = "#version " SHADING_LANG_VERS "\n\
117 in vec3 in_Position;\
118 in vec3 in_Color;\
119 out vec3 ex_Color;\
120 void main(void)\
121 {\
122 ex_Color = in_Color;\
123 gl_Position = vec4(in_Position, 1.0);\
124 }";
125
126 const char *ff = "#version " SHADING_LANG_VERS "\n\
127 precision highp float;\
128 in vec3 ex_Color;\
129 out vec4 out_Color;\
130 void main(void)\
131 {\
132 out_Color = vec4(ex_Color,1.0);\
133 }";
134
135 glShaderSource(v, 1, &vv,NULL);
136 glShaderSource(f, 1, &ff,NULL);
137
138 GLint compiled;
139
140 glCompileShader(v);
141 glGetShaderiv(v, GL_COMPILE_STATUS, &compiled);
142 if (!compiled)
143 {
144 fprintf(stderr, "Vertex shader not compiled.\n");
145 printShaderInfoLog(v);
146 }
147
148 glCompileShader(f);
149 glGetShaderiv(f, GL_COMPILE_STATUS, &compiled);
150 if (!compiled)
151 {
152 fprintf(stderr, "Fragment shader not compiled.\n");
153 printShaderInfoLog(f);
154 }
155
156 p = glCreateProgram();
157
158 glAttachShader(p,v);
159 glAttachShader(p,f);
160 glBindAttribLocation(p,0, "in_Position");
161 glBindAttribLocation(p,1, "in_Color");
162
163 glLinkProgram(p);
164 glGetProgramiv(p, GL_LINK_STATUS, &compiled);
165 if (compiled != GL_TRUE) {
166 GLchar *infoLog; GLint length;
167 glGetProgramiv(p, GL_INFO_LOG_LENGTH, &length);
168 infoLog = new GLchar[length];
169 glGetProgramInfoLog(p, length, NULL, infoLog);
170 fprintf(stderr, "Link log=%s\n", infoLog);
171 delete[] infoLog;
172 }
173 glUseProgram(p);
174 }
175
176
display(void)177 void display(void)
178 {
179 // clear the screen
180 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
181
182 glBindVertexArray(vertexArrayObjID[0]); // First VAO
183 glDrawArrays(GL_TRIANGLES, 0, 3); // draw first object
184
185 glBindVertexArray(vertexArrayObjID[1]); // select second VAO
186 glVertexAttrib3f((GLuint)1, 1.0, 0.0, 0.0); // set constant color attribute
187 glDrawArrays(GL_TRIANGLES, 0, 3); // draw second object
188 }
189
190 const int fullscreen = 0; // TEST (set to 1 to enable fullscreen mode)
191
main(int argc,char * argv[])192 int main (int argc, char* argv[])
193 {
194 Fl::use_high_res_GL(true);
195 glutInit(&argc, argv);
196 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | FL_OPENGL3);
197 glutInitWindowSize(400, 400);
198 glutCreateWindow("Triangle Test");
199 #ifndef __APPLE__
200 GLenum err = glewInit(); // defines pters to functions of OpenGL V 1.2 and above
201 if (err) Fl::error("glewInit() failed returning %u", err);
202 fprintf(stderr, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
203 #endif
204 int gl_version_major;
205 const char *glv = (const char*)glGetString(GL_VERSION);
206 fprintf(stderr, "OpenGL version %s supported\n", glv);
207 sscanf(glv, "%d", &gl_version_major);
208 if (gl_version_major < 3) {
209 fprintf(stderr, "\nThis platform does not support OpenGL V3\n\n");
210 exit(1);
211 }
212 initShaders();
213 init();
214 glutDisplayFunc(display);
215 if (fullscreen) Fl::first_window()->fullscreen();
216 glutMainLoop();
217 return 0;
218 }
219