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 public:
30 /// Set up a new window, default depth of colorbuffer and depthbuffer
31 Cubemania(const char* title, bool fullscreen, int width, int height)
32 : GLWindow(fullscreen, title, width, height) {}
33
34 /// override window initialization
35 virtual void init();
36 /// draw a frame
37 virtual void redraw();
38 /// recompute viewport
39 virtual void resize(int newWidth, int newHeight);
40 };
41
42
43
44 /// override window initialization
45 /** Called by the baseclass GLWindow during window construction
**/
46 void Cubemania::init()
47 {
48 // Gouraud shading
49 glShadeModel(GL_SMOOTH);
50 // black background
51 glClearColor(0,0,0, 1);
52
53 // z-buffer
54 glEnable(GL_DEPTH_TEST);
55 glDepthFunc(GL_LEQUAL);
56
57 // recommended by NeHe but I can't tell a difference ...
58 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
59
60 // backface culling, it's a bit faster
61 glEnable(GL_CULL_FACE);
62
63 // initial window size
64 resize(width, height);
65 }
66
67
68 /// draw a frame
69 /** Called by the baseclass GLWindow during window construction
**/
70 void Cubemania::resize(int newWidth, int newHeight)
71 {
72 // prepare resize
73 GLWindow::resize(newWidth, newHeight);
74
75 // perspective view
76 glMatrixMode(GL_PROJECTION);
77 glLoadIdentity();
78 gluPerspective(60, // field-of-view
79 newWidth/(float)newHeight, // aspect-ratio
80 1, // front-z-plane
81 -1); // back-z-plane
82
83 // set camera
84 glMatrixMode(GL_MODELVIEW);
85 glLoadIdentity();
86 gluLookAt(0, 0, 2, // from (0,0,2)
87 0, 0, 0, // to (0,0,0)
88 0, 1, 0); // up
89 }
90
91
92 /// draw a frame
93 void Cubemania::redraw()
94 {
95 // clear color and depth buffer
96 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
97
98 // safe current model-view matrix
99 glPushMatrix();
100
101 // slow rotation depending on timestamp
102 glRotatef(seconds() * 30, 0, 1, 1);
103
104 // all 8 vertices of a cube organised as [x1,y1,z1], [x2,y2,yz], ...
105 static GLfloat vertices[] = { 0,0,0,
106 0,0,1,
107 0,1,0,
108 0,1,1,
109 1,0,0,
110 1,0,1,
111 1,1,0,
112 1,1,1 };
113
114 // 6 sides refering to the vertices defined above
115 static GLubyte indices[] = { 0,2,3,1,
116 4,5,7,6,
117 0,1,5,4,
118 2,6,7,3,
119 0,4,6,2,
120 1,3,7,5 };
121
122 // initiate vertex array
123 glEnableClientState(GL_VERTEX_ARRAY);
124 // 3 dimensions (x,y,z), data type float, densely packed
125 glVertexPointer(3, GL_FLOAT, 0, vertices);
126
127 // translate cubes from [0,1]^3 to [-.5,+.5]^3
128 glTranslatef(-0.5f, -0.5f, -0.5f);
129
130 // number and size of cubes ... just modify to get even more cubes !
131 const int cubes = 10;
132 const float gridsize = 1.0f / cubes;
133 const float length = 0.3f * gridsize;
134
135 // generate all these funky cubes ...
136 for (float x = 0; x < 1; x += gridsize)
137 for (float y = 0; y < 1; y += gridsize)
138 for (float z = 0; z < 1; z += gridsize)
139 {
140 // save current model-view matrix
141 glPushMatrix();
142
143 // color is derived from position
144 glColor3f(x,y,z);
145 // place cube
146 glTranslatef(x,y,z);
147 glScalef(length,length,length);
148 // and draw it
149 glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, indices);
150
151 // restore model-view matrix
152 glPopMatrix();
153 }
154
155 // finished drawing
156 glDisableClientState(GL_VERTEX_ARRAY);
157 glPopMatrix();
158 }
159
160
161
162 // here we go ;-)
163 int __cdecl main(int argc, char *argv[])
164 {
165 // windowed mode, 512x512 pixels
166 Cubemania opengl("Stephan's Cubemania", false, 512, 512);
167 opengl.init();
168 return opengl.run();
169 }
170
171
172 #ifdef _VERY_SMALL_EXE_
173 /* 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.
*/
174 #pragma comment(lib, "msvcrt_vc6.lib")
175 #pragma comment(linker, "/NODEFAULTLIB:libc.lib")
176 #pragma comment(exestr, "(C) http://www.stephan-brumme.com, " __DATE__ " @" __TIME__)
177 #endif
178