12 HINSTANCE hInstance
; // Holds The Instance Of The Application
14 GLuint texture
[3]; //stores texture objects and display list
16 LPCTSTR registryPath
= _T("Software\\Microsoft\\ScreenSavers\\Butterflies");
20 struct object
// Create A Structure Called Object
22 int tex
; // Integer Used To Select Our Texture
23 float x
; // X Position
24 float y
; // Y Position
25 float z
; // Z Position
26 float yi
; // Y Increase Speed (Fall Speed)
27 float spinz
; // Z Axis Spin
28 float spinzi
; // Z Axis Spin Speed
29 float flap
; // Flapping Triangles :)
30 float fi
; // Flap Direction (Increase Value)
33 struct object obj
[50];
34 //object obj[50]; // Create 50 Objects Using The Object Structure
44 DWORD valtype
, valsize
, val
;
48 result
= RegOpenKeyEx(HKEY_CURRENT_USER
, registryPath
, 0, KEY_READ
, &skey
);
49 if(result
!= ERROR_SUCCESS
)
54 result
= RegQueryValueEx(skey
, _T("Rotate"), 0, &valtype
, (LPBYTE
)&val
, &valsize
);
55 if(result
== ERROR_SUCCESS
)
65 result
= RegCreateKeyEx(HKEY_CURRENT_USER
, registryPath
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &skey
, &disp
);
66 if(result
!= ERROR_SUCCESS
)
70 RegSetValueEx(skey
, _T("Rotate"), 0, REG_DWORD
, (CONST BYTE
*)&val
, sizeof(val
));
75 void SetObject(int loop
) // Sets The Initial Value Of Each Object (Random)
77 obj
[loop
].tex
=rand()%3; // Texture Can Be One Of 3 Textures
78 obj
[loop
].x
=rand()%34-17.0f
; // Random x Value From -17.0f To 17.0f
79 obj
[loop
].y
=18.0f
; // Set y Position To 18 (Off Top Of Screen)
80 obj
[loop
].z
=-((rand()%30000/1000.0f
)+10.0f
); // z Is A Random Value From -10.0f To -40.0f
81 obj
[loop
].spinzi
=(rand()%10000)/5000.0f
-1.0f
; // spinzi Is A Random Value From -1.0f To 1.0f
82 obj
[loop
].flap
=0.0f
; // flap Starts Off At 0.0f;
83 obj
[loop
].fi
=0.05f
+(rand()%100)/1000.0f
; // fi Is A Random Value From 0.05f To 0.15f
84 obj
[loop
].yi
=0.001f
+(rand()%1000)/10000.0f
; // yi Is A Random Value From 0.001f To 0.101f
87 void LoadGLTextures() // Creates Textures From Bitmaps In The Resource File
89 HBITMAP hBMP
; // Handle Of The Bitmap
90 BITMAP BMP
; // Bitmap Structure
93 // The ID Of The 3 Bitmap Images We Want To Load From The Resource File
94 byte Texture
[]={ IDB_BUTTERFLY1
, IDB_BUTTERFLY2
, IDB_BUTTERFLY3
};
96 glGenTextures(sizeof(Texture
), &texture
[0]); // Generate 3 Textures (sizeof(Texture)=3 ID's)
97 for (loop
=0; loop
<sizeof(Texture
); loop
++) // Loop Through All The ID's (Bitmap Images)
99 hBMP
=(HBITMAP
)LoadImage(GetModuleHandle(NULL
),MAKEINTRESOURCE(Texture
[loop
]), IMAGE_BITMAP
, 0, 0, LR_CREATEDIBSECTION
);
100 if (hBMP
) // Does The Bitmap Exist?
102 GetObject(hBMP
,sizeof(BMP
), &BMP
); // Get The Object
103 // hBMP: Handle To Graphics Object
104 // sizeof(BMP): Size Of Buffer For Object Information
105 // Buffer For Object Information
106 glPixelStorei(GL_UNPACK_ALIGNMENT
,4); // Pixel Storage Mode (Word Alignment / 4 Bytes)
107 glBindTexture(GL_TEXTURE_2D
, texture
[loop
]); // Bind Our Texture
108 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_LINEAR
); // Linear Filtering
109 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_LINEAR_MIPMAP_LINEAR
); // Mipmap Linear Filtering
111 // Generate Mipmapped Texture (3 Bytes, Width, Height And Data From The BMP)
112 gluBuild2DMipmaps(GL_TEXTURE_2D
, 3, BMP
.bmWidth
, BMP
.bmHeight
, GL_BGR_EXT
, GL_UNSIGNED_BYTE
, BMP
.bmBits
);
117 HGLRC
InitOGLWindow(HWND hWnd
)
119 HDC hDC
= GetDC(hWnd
);
121 PIXELFORMATDESCRIPTOR pfd
;
124 ZeroMemory(&pfd
, sizeof(PIXELFORMATDESCRIPTOR
));
126 pfd
.nSize
= sizeof(PIXELFORMATDESCRIPTOR
);
128 pfd
.dwFlags
= PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_WINDOW
| PFD_DOUBLEBUFFER
;
132 nFormat
= ChoosePixelFormat(hDC
, &pfd
);
133 DescribePixelFormat(hDC
, nFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
134 SetPixelFormat(hDC
, nFormat
, &pfd
);
136 hRC
= wglCreateContext(hDC
);
137 wglMakeCurrent(hDC
, hRC
);
139 ReleaseDC(hWnd
, hDC
);
144 void InitOpenGL(GLsizei width
, GLsizei height
)
148 if (height
==0) // Prevent A Divide By Zero By
150 height
=1; // Making Height Equal One
153 glViewport(0,0,width
,height
); // Reset The Current Viewport
155 glMatrixMode(GL_PROJECTION
); // Select The Projection Matrix
156 glLoadIdentity(); // Reset The Projection Matrix
158 // Calculate The Aspect Ratio Of The Window
159 gluPerspective (45.0f
, (GLfloat
)(width
)/(GLfloat
)(height
),1.0f
, 1000.0f
);
161 glMatrixMode(GL_MODELVIEW
); // Select The Modelview Matrix
163 // Start Of User Initialization
164 LoadGLTextures(); // Load The Textures From Our Resource File
166 glClearColor (0.0f
, 0.0f
, 0.0f
, 0.5f
); // Black Background
167 glClearDepth (1.0f
); // Depth Buffer Setup
168 glDepthFunc (GL_LEQUAL
); // The Type Of Depth Testing (Less Or Equal)
169 glDisable(GL_DEPTH_TEST
); // Disable Depth Testing
170 glShadeModel (GL_SMOOTH
); // Select Smooth Shading
171 glHint (GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
); // Set Perspective Calculations To Most Accurate
172 glEnable(GL_TEXTURE_2D
); // Enable Texture Mapping
173 glBlendFunc(GL_ONE
,GL_SRC_ALPHA
); // Set Blending Mode (Cheap / Quick)
177 for (loop
=0; loop
<50; loop
++) // Loop To Initialize 50 Objects
179 SetObject(loop
); // Call SetObject To Assign New Random Values
187 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
); // Clear Screen And Depth Buffer
189 for (loop
=0; loop
<50; loop
++) // Loop Of 50 (Draw 50 Objects)
191 glLoadIdentity (); // Reset The Modelview Matrix
192 glBindTexture(GL_TEXTURE_2D
, texture
[obj
[loop
].tex
]); // Bind Our Texture
193 glTranslatef(obj
[loop
].x
,obj
[loop
].y
,obj
[loop
].z
); // Position The Object
194 glRotatef(45.0f
,1.0f
,0.0f
,0.0f
); // Rotate On The X-Axis
197 glRotatef((obj
[loop
].spinz
),0.0f
,0.0f
,1.0f
); // Spin On The Z-Axis
199 glBegin(GL_TRIANGLES
); // Begin Drawing Triangles
200 // First Triangle _____
201 glTexCoord2f(1.0f
,1.0f
); glVertex3f( 1.0f
, 1.0f
, 0.0f
); // (2)| / (1)
202 glTexCoord2f(0.0f
,1.0f
); glVertex3f(-1.0f
, 1.0f
, obj
[loop
].flap
); // | /
203 glTexCoord2f(0.0f
,0.0f
); glVertex3f(-1.0f
,-1.0f
, 0.0f
); // (3)|/
206 glTexCoord2f(1.0f
,1.0f
); glVertex3f( 1.0f
, 1.0f
, 0.0f
); // /|(1)
207 glTexCoord2f(0.0f
,0.0f
); glVertex3f(-1.0f
,-1.0f
, 0.0f
); // / |
208 glTexCoord2f(1.0f
,0.0f
); glVertex3f( 1.0f
,-1.0f
, obj
[loop
].flap
); // (2)/____|(3)
210 glEnd(); // Done Drawing Triangles
212 obj
[loop
].y
-=obj
[loop
].yi
; // Move Object Down The Screen
213 obj
[loop
].spinz
+=obj
[loop
].spinzi
; // Increase Z Rotation By spinzi
214 obj
[loop
].flap
+=obj
[loop
].fi
; // Increase flap Value By fi
216 if (obj
[loop
].y
<-18.0f
) // Is Object Off The Screen?
218 SetObject(loop
); // If So, Reassign New Values
221 if ((obj
[loop
].flap
>1.0f
) || (obj
[loop
].flap
<-1.0f
)) // Time To Change Flap Direction?
223 obj
[loop
].fi
=-obj
[loop
].fi
; // Change Direction By Making fi = -fi
227 Sleep(15); // Create A Short Delay (15 Milliseconds)
233 BOOL
AboutProc(HWND hdlg
, UINT msg
, WPARAM wpm
, LPARAM lpm
){
236 case WM_CTLCOLORSTATIC
:
237 if(((HWND
)lpm
== GetDlgItem(hdlg
, WEBPAGE1
)) || ((HWND
)lpm
== GetDlgItem(hdlg
, WEBPAGE2
)))
239 SetTextColor((HDC
)wpm
, RGB(0,0,255));
240 SetBkColor((HDC
)wpm
, (COLORREF
)GetSysColor(COLOR_3DFACE
));
241 return(HandleToLong(GetSysColorBrush(COLOR_3DFACE
)));
247 EndDialog(hdlg
, LOWORD(wpm
));
250 ShellExecute(NULL
, _T("open"), _T("http://nehe.gamedev.net"), NULL
, NULL
, SW_SHOWNORMAL
);
253 ShellExecute(NULL
, _T("open"), _T("http://www.thaputer.com"), NULL
, NULL
, SW_SHOWNORMAL
);
260 LRESULT WINAPI
ScreenSaverProc(HWND hWnd
, UINT message
,
261 WPARAM wParam
, LPARAM lParam
)
264 static DWORD timer
= 1;
274 hRC
= InitOGLWindow(hWnd
);
275 GetClientRect (hWnd
, &WindowRect
);
276 width
= WindowRect
.right
- WindowRect
.left
;
277 height
= WindowRect
.bottom
- WindowRect
.top
;
278 InitOpenGL(width
,height
);
279 SetTimer(hWnd
, timer
, 5, NULL
);
285 ReleaseDC(hWnd
, hDC
);
288 wglMakeCurrent(NULL
, NULL
);
289 wglDeleteContext(hRC
);
293 return DefScreenSaverProc(hWnd
, message
, wParam
, lParam
);
296 BOOL WINAPI
ScreenSaverConfigureDialog(HWND hDlg
, UINT message
,
297 WPARAM wParam
, LPARAM lParam
)
303 CheckDlgButton(hDlg
, ROTATE
, dRotate
);
306 switch (LOWORD(wParam
))
309 dRotate
= (IsDlgButtonChecked(hDlg
, ROTATE
) == BST_CHECKED
);
311 EndDialog(hDlg
, TRUE
);
314 EndDialog(hDlg
, TRUE
);
317 DialogBox(hInstance
, MAKEINTRESOURCE(IDD_DLG_ABOUT
), hDlg
, (DLGPROC
)AboutProc
);
325 BOOL WINAPI
RegisterDialogClasses(HANDLE hInst
)