// ////////////////////////////////////////////////////////// // Cubemania.cpp // Copyright (c) 2004 Stephan Brumme. All rights reserved. // // just can't live without Windows ... #include // ... and OpenGL ! #include #include // my OpenGL window wrapper #include "GLWindow.h" /* 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. */ // target Windows #pragma comment (linker, "/SUBSYSTEM:WINDOWS") #pragma comment (linker, "/ENTRY:mainCRTStartup") // link required libraries #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glu32.lib") /// Draw 10x10x10 = 1,000 spinning cubes /** \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 **/ class Cubemania : public GLWindow { public: /// Set up a new window, default depth of colorbuffer and depthbuffer Cubemania(const char* title, bool fullscreen, int width, int height) : GLWindow(fullscreen, title, width, height) {} /// override window initialization virtual void init(); /// draw a frame virtual void redraw(); /// recompute viewport virtual void resize(int newWidth, int newHeight); }; /// override window initialization /** Called by the baseclass GLWindow during window construction **/ void Cubemania::init() { // Gouraud shading glShadeModel(GL_SMOOTH); // black background glClearColor(0,0,0, 1); // z-buffer glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); // recommended by NeHe but I can't tell a difference ... glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // backface culling, it's a bit faster glEnable(GL_CULL_FACE); // initial window size resize(width, height); } /// draw a frame /** Called by the baseclass GLWindow during window construction **/ void Cubemania::resize(int newWidth, int newHeight) { // prepare resize GLWindow::resize(newWidth, newHeight); // perspective view glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, // field-of-view newWidth/(float)newHeight, // aspect-ratio 1, // front-z-plane -1); // back-z-plane // set camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, 2, // from (0,0,2) 0, 0, 0, // to (0,0,0) 0, 1, 0); // up } /// draw a frame void Cubemania::redraw() { // clear color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // safe current model-view matrix glPushMatrix(); // slow rotation depending on timestamp glRotatef(seconds() * 30, 0, 1, 1); // all 8 vertices of a cube organised as [x1,y1,z1], [x2,y2,yz], ... static GLfloat vertices[] = { 0,0,0, 0,0,1, 0,1,0, 0,1,1, 1,0,0, 1,0,1, 1,1,0, 1,1,1 }; // 6 sides refering to the vertices defined above static GLubyte indices[] = { 0,2,3,1, 4,5,7,6, 0,1,5,4, 2,6,7,3, 0,4,6,2, 1,3,7,5 }; // initiate vertex array glEnableClientState(GL_VERTEX_ARRAY); // 3 dimensions (x,y,z), data type float, densely packed glVertexPointer(3, GL_FLOAT, 0, vertices); // translate cubes from [0,1]^3 to [-.5,+.5]^3 glTranslatef(-0.5f, -0.5f, -0.5f); // number and size of cubes ... just modify to get even more cubes ! const int cubes = 10; const float gridsize = 1.0f / cubes; const float length = 0.3f * gridsize; // generate all these funky cubes ... for (float x = 0; x < 1; x += gridsize) for (float y = 0; y < 1; y += gridsize) for (float z = 0; z < 1; z += gridsize) { // save current model-view matrix glPushMatrix(); // color is derived from position glColor3f(x,y,z); // place cube glTranslatef(x,y,z); glScalef(length,length,length); // and draw it glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, indices); // restore model-view matrix glPopMatrix(); } // finished drawing glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); } // here we go ;-) int __cdecl main(int argc, char *argv[]) { // windowed mode, 512x512 pixels Cubemania opengl("Stephan's Cubemania", false, 512, 512); opengl.init(); return opengl.run(); } #ifdef _VERY_SMALL_EXE_ /* 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. */ #pragma comment(lib, "msvcrt_vc6.lib") #pragma comment(linker, "/NODEFAULTLIB:libc.lib") #pragma comment(exestr, "(C) http://www.stephan-brumme.com, " __DATE__ " @" __TIME__) #endif