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