1 // //////////////////////////////////////////////////////////
2 // Cubemania.cpp
3 // Copyright (c) 2004 Stephan Brumme. All rights reserved.
4 //
5
6 // just can't live without Windows ...
7 #include <windows.h>
8 // ... and OpenGL !
9 #include <gl/gl.h>
10 #include <gl/glu.h>
11
12 // my OpenGL window wrapper
13 #include "GLWindow.h"
14
15
16 /* of course the following 4 settings can be done in the project settings
but I like to use #pragmas since I always keep on forgetting to set them
in the Visual Studio project settings. I am getting older. */
17 // target Windows
18 #pragma comment (linker, "/SUBSYSTEM:WINDOWS")
19 #pragma comment (linker, "/ENTRY:mainCRTStartup")
20 // link required libraries
21 #pragma comment(lib, "opengl32.lib")
22 #pragma comment(lib, "glu32.lib")
23
24
25
26 /// Draw 10x10x10 = 1,000 spinning cubes
27 /**
\class Cubemania
\author Stephan Brumme, games@stephan-brumme.com
\version 1.1: August 11, 2004
- Code cleanup
- added lots of comments
\version 1.0: August 9, 2004
- Initial release
**/
28 class Cubemania : public GLWindow
29 {
30 public:
31 /// Set up a new window, default depth of colorbuffer and depthbuffer
32 Cubemania(const char* title, bool fullscreen, int width, int height)
33 : GLWindow(fullscreen, title, width, height) {}
34
35 /// override window initialization
36 virtual void init();
37 /// draw a frame
38 virtual void redraw();
39 /// recompute viewport
40 virtual void resize(int newWidth, int newHeight);
41 };
42
43
44
45 /// override window initialization
46 /** Called by the baseclass GLWindow during window construction
**/
47 void Cubemania::init()
48 {
49 // Gouraud shading
50 glShadeModel(GL_SMOOTH);
51 // black background
52 glClearColor(0,0,0, 1);
53
54 // z-buffer
55 glEnable(GL_DEPTH_TEST);
56 glDepthFunc(GL_LEQUAL);
57
58 // recommended by NeHe but I can't tell a difference ...
59 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
60
61 // backface culling, it's a bit faster
62 glEnable(GL_CULL_FACE);
63
64 // initial window size
65 resize(width, height);
66 }
67
68
69 /// draw a frame
70 /** Called by the baseclass GLWindow during window construction
**/
71 void Cubemania::resize(int newWidth, int newHeight)
72 {
73 // prepare resize
74 GLWindow::resize(newWidth, newHeight);
75
76 // perspective view
77 glMatrixMode(GL_PROJECTION);
78 glLoadIdentity();
79 gluPerspective(60, // field-of-view
80 newWidth/(float)newHeight, // aspect-ratio
81 1, // front-z-plane
82 -1); // back-z-plane
83
84 // set camera
85 glMatrixMode(GL_MODELVIEW);
86 glLoadIdentity();
87 gluLookAt(0, 0, 2, // from (0,0,2)
88 0, 0, 0, // to (0,0,0)
89 0, 1, 0); // up
90 }
91
92
93 /// draw a frame
94 void Cubemania::redraw()
95 {
96 // clear color and depth buffer
97 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
98
99 // safe current model-view matrix
100 glPushMatrix();
101
102 // slow rotation depending on timestamp
103 glRotatef(seconds() * 30, 0, 1, 1);
104
105 // all 8 vertices of a cube organised as [x1,y1,z1], [x2,y2,yz], ...
106 static GLfloat vertices[] = { 0,0,0,
107 0,0,1,
108 0,1,0,
109 0,1,1,
110 1,0,0,
111 1,0,1,
112 1,1,0,
113 1,1,1 };
114
115 // 6 sides refering to the vertices defined above
116 static GLubyte indices[] = { 0,2,3,1,
117 4,5,7,6,
118 0,1,5,4,
119 2,6,7,3,
120 0,4,6,2,
121 1,3,7,5 };
122
123 // initiate vertex array
124 glEnableClientState(GL_VERTEX_ARRAY);
125 // 3 dimensions (x,y,z), data type float, densely packed
126 glVertexPointer(3, GL_FLOAT, 0, vertices);
127
128 // translate cubes from [0,1]^3 to [-.5,+.5]^3
129 glTranslatef(-0.5f, -0.5f, -0.5f);
130
131 // number and size of cubes ... just modify to get even more cubes !
132 const int cubes = 10;
133 const float gridsize = 1.0f / cubes;
134 const float length = 0.3f * gridsize;
135
136 // generate all these funky cubes ...
137 for (float x = 0; x < 1; x += gridsize)
138 for (float y = 0; y < 1; y += gridsize)
139 for (float z = 0; z < 1; z += gridsize)
140 {
141 // save current model-view matrix
142 glPushMatrix();
143
144 // color is derived from position
145 glColor3f(x,y,z);
146 // place cube
147 glTranslatef(x,y,z);
148 glScalef(length,length,length);
149 // and draw it
150 glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, indices);
151
152 // restore model-view matrix
153 glPopMatrix();
154 }
155
156 // finished drawing
157 glDisableClientState(GL_VERTEX_ARRAY);
158 glPopMatrix();
159 }
160
161
162
163 // here we go ;-)
164 int __cdecl main(int argc, char *argv[])
165 {
166 // windowed mode, 512x512 pixels
167 Cubemania opengl("Stephan's Cubemania", false, 512, 512);
168 opengl.init();
169 return opengl.run();
170 }
171
172
173 #ifdef _VERY_SMALL_EXE_
174 /* JUST DELETE THE FIRST 2 #PRAGMAS SINCE THEY ARE ONLY USEFUL TO PRODUCE
A VERY SMALL EXECUTABLE (6K WITH VS.NET 2003) AND ARE CONSIDERED
VERRRRRY DIRRRRRTY CODING STYLE !!!
Linking against a VC6 lib in VS.NET 2003 (first #pragma) may lead to
INSECURE, INSTABLE and CRASHING programs. But they are smaller ;-)
Btw, if you compile on VS.NET 2003 and use the default system libraries
(=> you removed the #pragmas) make sure to find MSVCR71.DLL on the
target system. For VS7 this DLL is called somehow similar.
These DLLs come usually with the Windows Service Packs but are not guaranteed
to be installed on every system since they were not part of the original
plain-vanilla Windows 98/XP+. On the other hand, VC6's MSVCRT.DLL always exists
on any Windows 98/XP+ based computer.
*/
175 #pragma comment(lib, "msvcrt_vc6.lib")
176 #pragma comment(linker, "/NODEFAULTLIB:libc.lib")
177 #pragma comment(exestr, "(C) http://www.stephan-brumme.com, " __DATE__ " @" __TIME__)
178 #endif
179