comparison glxdragon.cpp @ 0:3d74a9dd96e4

Initial import of Thomas Trummer's original code.
author Thomas Trummer
date Sun, 27 Oct 2019 15:57:55 +0200
parents
children b45d8958e5a6
comparison
equal deleted inserted replaced
-1:000000000000 0:3d74a9dd96e4
1
2 // Copyright (c) 2009, Thomas Trummer
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the <organization> nor the
13 // names of its contributors may be used to endorse or promote products
14 // derived from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY Thomas Trummer ''AS IS'' AND ANY
17 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
20 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27
28 #include <SDL.h>
29 #include <SDL_opengl.h>
30
31 #include <iostream>
32 #include <sstream>
33 #include <fstream>
34 #include <stdexcept>
35 #include <string>
36 #include <vector>
37 #include <algorithm>
38 #include <cstdio>
39 #include <ctime>
40
41
42 struct Mesh
43 {
44 std::vector<float> vertices;
45 std::vector<unsigned> faces;
46 }
47 dragonMesh;
48
49
50 void init(const int windowWidth, const int windowHeight, const std::string& windowTitle)
51 {
52 std::stringstream ss;
53
54
55 if (SDL_Init(SDL_INIT_VIDEO) != 0)
56 {
57 ss << "Unable to initialize SDL: " << SDL_GetError() << '\n';
58
59 throw std::runtime_error(ss.str());
60 }
61
62
63 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
64 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
65 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
66 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
67 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
68
69
70 SDL_WM_SetCaption(windowTitle.c_str(), 0);
71
72
73 if ((SDL_SetVideoMode(windowWidth, windowHeight, 0, SDL_OPENGL)) == NULL)
74 {
75 ss << "Couldn't set GL mode: " << SDL_GetError() << '\n';
76
77 throw std::runtime_error(ss.str());
78 }
79
80
81 std::cout << "GL_VENDOR : " << glGetString(GL_VENDOR) << std::endl;
82 std::cout << "GL_RENDERER : " << glGetString(GL_RENDERER) << std::endl;
83 std::cout << "GL_VERSION : " << glGetString(GL_VERSION) << std::endl;
84
85 std::cout << std::endl;
86
87
88 // Setup the window and view port
89 glViewport(0, 0, windowWidth, windowHeight);
90
91 glMatrixMode(GL_PROJECTION);
92 glLoadIdentity();
93
94 gluPerspective(45.0f, GLfloat(windowWidth) / GLfloat(windowHeight), 0.1f, 1000.0f);
95
96 glMatrixMode(GL_MODELVIEW);
97 glLoadIdentity();
98
99
100 // Enable back face culling
101 glEnable(GL_CULL_FACE);
102
103 // Enable smooth shading
104 glShadeModel(GL_SMOOTH);
105
106 // Enable the depth buffer
107 glEnable(GL_DEPTH_TEST);
108
109 // Setup depth buffer
110 glClearDepth(1.0f);
111
112 // Set the depth buffer function
113 glDepthFunc(GL_LEQUAL);
114
115 // Enable vertex and and normal arrays
116 glEnableClientState(GL_VERTEX_ARRAY);
117 glEnableClientState(GL_NORMAL_ARRAY);
118
119 // Set correct perspective correction
120 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
121 }
122
123
124 void initScene()
125 {
126 glEnable(GL_COLOR_MATERIAL);
127
128 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
129 glMateriali(GL_FRONT, GL_SHININESS, 96);
130
131 float specReflection[] = { 0.8f, 0.8f, 0.8f, 1.0f };
132 glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
133
134
135 glEnable(GL_LIGHT0);
136
137 // Define the light components and position
138 GLfloat ambient [] = { 0.2f, 0.2f, 0.2f, 1.0f };
139 GLfloat diffuse [] = { 0.8f, 0.8f, 0.8f, 1.0f };
140 GLfloat specular[] = { 0.5f, 0.5f, 0.5f, 1.0f };
141 GLfloat position[] = { 10.0f, 10.0f, 0.0f, 0.0f };
142
143 // Define the light components and position
144 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
145 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
146 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
147 glLightfv(GL_LIGHT0, GL_POSITION, position);
148
149 // Define the camera
150 gluLookAt(0, 0.12, 0.24, 0, 0.12, 0, 0, 1, 0);
151 }
152
153
154 void done()
155 {
156 SDL_Quit();
157 }
158
159
160 void drawModelVA(const Mesh& mesh)
161 {
162 int maxIndices;
163
164 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices);
165
166
167 glVertexPointer(3, GL_FLOAT, 24, &mesh.vertices[0]);
168 glNormalPointer( GL_FLOAT, 24, &mesh.vertices[3]);
169
170
171 for(size_t n = 0; n < mesh.faces.size() / 3; n += maxIndices)
172 {
173 const int count = std::min(maxIndices, int(mesh.faces.size() / 3 - n));
174
175 glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_INT, &dragonMesh.faces[n * 3]);
176 }
177 }
178
179
180 bool paintGL()
181 {
182 glClear(GL_DEPTH_BUFFER_BIT);
183
184
185 glMatrixMode(GL_PROJECTION);
186 glPushMatrix();
187 glLoadIdentity();
188
189 glOrtho(0.0, 1.0, 0.0, 1.0, -1, 1);
190
191 glMatrixMode(GL_MODELVIEW);
192 glPushMatrix();
193 glLoadIdentity();
194
195
196 glDisable(GL_DEPTH_TEST);
197 glDisable(GL_LIGHTING);
198
199 // Draw the background gradient
200 glBegin(GL_QUADS);
201 {
202 glColor3ub(0x3B, 0x3B, 0x75);
203 glVertex2f(0.0f, 0.0f);
204 glVertex2f(1.0f, 0.0f);
205
206 glColor3ub(0x00, 0x00, 0x00);
207 glVertex2f(1.0f, 1.0f);
208 glVertex2f(0.0f, 1.0f);
209 }
210 glEnd();
211
212
213 // Restore the 3D projection
214 glMatrixMode(GL_PROJECTION);
215 glPopMatrix();
216
217 glMatrixMode(GL_MODELVIEW);
218 glPopMatrix();
219
220
221 glEnable(GL_DEPTH_TEST);
222 glEnable(GL_LIGHTING);
223
224
225 // Set the color of the model
226 glColor3ub(0x90, 0x80, 0x90);
227
228 // Draw the model using vertex arrays
229 drawModelVA(dragonMesh);
230
231 // Draw the current frame
232 SDL_GL_SwapBuffers();
233
234
235
236 static int steps = 0;
237
238 // Rotate for 2 degrees
239 glRotatef(2.0f, 0, 1, 0);
240
241 // Return true if a full rotation was done
242 return (steps++ == 180) ? (steps = 0, true) : false;
243 }
244
245
246 void runEventLoop()
247 {
248 static std::clock_t startTime = std::clock();
249
250 while (true)
251 {
252 SDL_Event event;
253
254 if (SDL_PollEvent(&event))
255 {
256 if (event.type == SDL_QUIT)
257 break;
258 }
259 else
260 {
261 // Render the next frame and test if a full turn was completed
262 if (paintGL())
263 {
264 // Get the time it took to render a full turn
265 double time = double(std::clock() - startTime) / CLOCKS_PER_SEC;
266
267 // Print the current frames per second
268 std::printf("%.1lf seconds for 180 frames = %.1lf FPS\n", time, 180 / time);
269
270 // Restart the timer
271 startTime = std::clock();
272 }
273 }
274 }
275 }
276
277
278 void loadMesh(const std::string& fileName, Mesh& mesh)
279 {
280 std::ifstream in(fileName.c_str(), std::ios::binary);
281
282
283 if (!in.is_open())
284 {
285 std::stringstream ss;
286
287 ss << "Unable to open file: " << fileName << '\n';
288
289 throw std::runtime_error(ss.str());
290
291 }
292
293
294 mesh.vertices.resize(100139 * 6);
295
296 in.read(reinterpret_cast<char*>(&mesh.vertices[0]), 100139 * 6 * 4);
297
298
299 mesh.faces.resize(200198 * 3);
300
301
302 for(unsigned i = 0; i < 200198; i++)
303 {
304 in.seekg(1, std::ios::cur);
305
306 in.read(reinterpret_cast<char*>(&mesh.faces[i*3]), 3 * 4);
307 }
308 }
309
310
311 int main()
312 {
313 try
314 {
315 loadMesh("dragon.mesh", dragonMesh);
316
317 init(640, 480, "glxdragon");
318
319 initScene();
320
321 runEventLoop();
322 }
323 catch(std::runtime_error& e)
324 {
325 std::cerr << e.what();
326 }
327
328 done();
329 }