cbbb45f167bf71897ff8a2434c50afeeea4c7053
[reactos.git] / rosapps / applications / screensavers / butterflies / butterflies.c
1 #include <windows.h>
2 #include <scrnsave.h>
3 #include <math.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <GL/gl.h>
7 #include <GL/glu.h>
8 #include "resource.h"
9
10 /* missing declare from gl.h */
11 #define GL_BGR_EXT 0x80E0
12
13 HINSTANCE hInstance; // Holds The Instance Of The Application
14
15 GLuint texture[3]; //stores texture objects and display list
16
17 LPCTSTR registryPath = ("Software\\tHaPuTeRProductions\\Lesson38Saver");
18 BOOL dRotate;
19
20
21 struct object // Create A Structure Called Object
22 {
23 int tex; // Integer Used To Select Our Texture
24 float x; // X Position
25 float y; // Y Position
26 float z; // Z Position
27 float yi; // Y Increase Speed (Fall Speed)
28 float spinz; // Z Axis Spin
29 float spinzi; // Z Axis Spin Speed
30 float flap; // Flapping Triangles :)
31 float fi; // Flap Direction (Increase Value)
32 };
33
34 struct object obj[50];
35 //object obj[50]; // Create 50 Objects Using The Object Structure
36
37 void SetDefaults()
38 {
39 dRotate = TRUE;
40 }
41
42 void ReadRegistry(){
43 LONG result;
44 HKEY skey;
45 DWORD valtype, valsize, val;
46
47 SetDefaults();
48
49 result = RegOpenKeyEx(HKEY_CURRENT_USER, registryPath, 0, KEY_READ, &skey);
50 if(result != ERROR_SUCCESS)
51 return;
52
53 valsize=sizeof(val);
54
55 result = RegQueryValueEx(skey, "Rotate", 0, &valtype, (LPBYTE)&val, &valsize);
56 if(result == ERROR_SUCCESS)
57 dRotate = val;
58 RegCloseKey(skey);
59 }
60
61 void WriteRegistry(){
62 LONG result;
63 HKEY skey;
64 DWORD val, disp;
65
66 result = RegCreateKeyEx(HKEY_CURRENT_USER, registryPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey, &disp);
67 if(result != ERROR_SUCCESS)
68 return;
69
70 val = dRotate;
71 RegSetValueEx(skey, "Rotate", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val));
72
73 RegCloseKey(skey);
74 }
75
76 void SetObject(int loop) // Sets The Initial Value Of Each Object (Random)
77 {
78 obj[loop].tex=rand()%3; // Texture Can Be One Of 3 Textures
79 obj[loop].x=rand()%34-17.0f; // Random x Value From -17.0f To 17.0f
80 obj[loop].y=18.0f; // Set y Position To 18 (Off Top Of Screen)
81 obj[loop].z=-((rand()%30000/1000.0f)+10.0f); // z Is A Random Value From -10.0f To -40.0f
82 obj[loop].spinzi=(rand()%10000)/5000.0f-1.0f; // spinzi Is A Random Value From -1.0f To 1.0f
83 obj[loop].flap=0.0f; // flap Starts Off At 0.0f;
84 obj[loop].fi=0.05f+(rand()%100)/1000.0f; // fi Is A Random Value From 0.05f To 0.15f
85 obj[loop].yi=0.001f+(rand()%1000)/10000.0f; // yi Is A Random Value From 0.001f To 0.101f
86 }
87
88 void LoadGLTextures() // Creates Textures From Bitmaps In The Resource File
89 {
90 HBITMAP hBMP; // Handle Of The Bitmap
91 BITMAP BMP; // Bitmap Structure
92 int loop;
93
94 // The ID Of The 3 Bitmap Images We Want To Load From The Resource File
95 byte Texture[]={ IDB_BUTTERFLY1, IDB_BUTTERFLY2, IDB_BUTTERFLY3 };
96
97 glGenTextures(sizeof(Texture), &texture[0]); // Generate 3 Textures (sizeof(Texture)=3 ID's)
98 for (loop=0; loop<sizeof(Texture); loop++) // Loop Through All The ID's (Bitmap Images)
99 {
100 hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(Texture[loop]), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
101 if (hBMP) // Does The Bitmap Exist?
102 { // If So...
103 GetObject(hBMP,sizeof(BMP), &BMP); // Get The Object
104 // hBMP: Handle To Graphics Object
105 // sizeof(BMP): Size Of Buffer For Object Information
106 // Buffer For Object Information
107 glPixelStorei(GL_UNPACK_ALIGNMENT,4); // Pixel Storage Mode (Word Alignment / 4 Bytes)
108 glBindTexture(GL_TEXTURE_2D, texture[loop]); // Bind Our Texture
109 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
110 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); // Mipmap Linear Filtering
111
112 // Generate Mipmapped Texture (3 Bytes, Width, Height And Data From The BMP)
113 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, BMP.bmWidth, BMP.bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);
114 }
115 }
116 }
117
118 HGLRC InitOGLWindow(HWND hWnd)
119 {
120 HDC hDC = GetDC(hWnd);
121 HGLRC hRC = 0;
122 PIXELFORMATDESCRIPTOR pfd;
123 int nFormat;
124
125 ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
126
127 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
128 pfd.nVersion = 1;
129 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
130 pfd.cColorBits = 24;
131 pfd.cDepthBits = 24;
132
133 nFormat = ChoosePixelFormat(hDC, &pfd);
134 DescribePixelFormat(hDC, nFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
135 SetPixelFormat(hDC, nFormat, &pfd);
136
137 hRC = wglCreateContext(hDC);
138 wglMakeCurrent(hDC, hRC);
139
140 ReleaseDC(hWnd, hDC);
141
142 return hRC;
143 }
144
145 void InitOpenGL(GLsizei width, GLsizei height)
146 {
147 int loop;
148
149 if (height==0) // Prevent A Divide By Zero By
150 {
151 height=1; // Making Height Equal One
152 }
153
154 glViewport(0,0,width,height); // Reset The Current Viewport
155
156 glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
157 glLoadIdentity(); // Reset The Projection Matrix
158
159 // Calculate The Aspect Ratio Of The Window
160 gluPerspective (45.0f, (GLfloat)(width)/(GLfloat)(height),1.0f, 1000.0f);
161
162 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
163 glLoadIdentity();
164 // Start Of User Initialization
165 LoadGLTextures(); // Load The Textures From Our Resource File
166
167 glClearColor (0.0f, 0.0f, 0.0f, 0.5f); // Black Background
168 glClearDepth (1.0f); // Depth Buffer Setup
169 glDepthFunc (GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
170 glDisable(GL_DEPTH_TEST); // Disable Depth Testing
171 glShadeModel (GL_SMOOTH); // Select Smooth Shading
172 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
173 glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
174 glBlendFunc(GL_ONE,GL_SRC_ALPHA); // Set Blending Mode (Cheap / Quick)
175 glEnable(GL_BLEND);
176
177
178 for (loop=0; loop<50; loop++) // Loop To Initialize 50 Objects
179 {
180 SetObject(loop); // Call SetObject To Assign New Random Values
181 }
182
183 }
184
185 void Display()
186 {
187 int loop;
188 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
189
190 for (loop=0; loop<50; loop++) // Loop Of 50 (Draw 50 Objects)
191 {
192 glLoadIdentity (); // Reset The Modelview Matrix
193 glBindTexture(GL_TEXTURE_2D, texture[obj[loop].tex]); // Bind Our Texture
194 glTranslatef(obj[loop].x,obj[loop].y,obj[loop].z); // Position The Object
195 glRotatef(45.0f,1.0f,0.0f,0.0f); // Rotate On The X-Axis
196 if (dRotate)
197 {
198 glRotatef((obj[loop].spinz),0.0f,0.0f,1.0f); // Spin On The Z-Axis
199 }
200 glBegin(GL_TRIANGLES); // Begin Drawing Triangles
201 // First Triangle _____
202 glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // (2)| / (1)
203 glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f, 1.0f, obj[loop].flap); // | /
204 glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // (3)|/
205
206 // Second Triangle
207 glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // /|(1)
208 glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // / |
209 glTexCoord2f(1.0f,0.0f); glVertex3f( 1.0f,-1.0f, obj[loop].flap); // (2)/____|(3)
210
211 glEnd(); // Done Drawing Triangles
212
213 obj[loop].y-=obj[loop].yi; // Move Object Down The Screen
214 obj[loop].spinz+=obj[loop].spinzi; // Increase Z Rotation By spinzi
215 obj[loop].flap+=obj[loop].fi; // Increase flap Value By fi
216
217 if (obj[loop].y<-18.0f) // Is Object Off The Screen?
218 {
219 SetObject(loop); // If So, Reassign New Values
220 }
221
222 if ((obj[loop].flap>1.0f) || (obj[loop].flap<-1.0f)) // Time To Change Flap Direction?
223 {
224 obj[loop].fi=-obj[loop].fi; // Change Direction By Making fi = -fi
225 }
226 }
227
228 Sleep(15); // Create A Short Delay (15 Milliseconds)
229
230 glFlush ();
231
232 }
233
234 BOOL AboutProc(HWND hdlg, UINT msg, WPARAM wpm, LPARAM lpm){
235 /*
236 switch(msg){
237 case WM_CTLCOLORSTATIC:
238 if(HWND(lpm) == GetDlgItem(hdlg, WEBPAGE1))
239 {
240 SetTextColor(HDC(wpm), RGB(0,0,255));
241 SetBkColor(HDC(wpm), COLORREF(GetSysColor(COLOR_3DFACE)));
242 return(int(GetSysColorBrush(COLOR_3DFACE)));
243 }
244 if(HWND(lpm) == GetDlgItem(hdlg, WEBPAGE2))
245 {
246 SetTextColor(HDC(wpm), RGB(0,0,255));
247 SetBkColor(HDC(wpm), COLORREF(GetSysColor(COLOR_3DFACE)));
248 return(int(GetSysColorBrush(COLOR_3DFACE)));
249 }
250 break;
251 case WM_COMMAND:
252 switch(LOWORD(wpm)){
253 case IDOK:
254 EndDialog(hdlg, LOWORD(wpm));
255 break;
256 case WEBPAGE1:
257 ShellExecute(NULL, "open", "http://nehe.gamedev.net", NULL, NULL, SW_SHOWNORMAL);
258 break;
259 case WEBPAGE2:
260 ShellExecute(NULL, "open", "http://www.thaputer.com", NULL, NULL, SW_SHOWNORMAL);
261 break;
262 }
263 }*/
264 return FALSE;
265 }
266
267 LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message,
268 WPARAM wParam, LPARAM lParam)
269 {
270 static HGLRC hRC;
271 static DWORD timer = 1;
272 HDC hDC;
273 RECT WindowRect;
274 int width;
275 int height;
276
277 switch (message)
278 {
279 case WM_CREATE:
280 ReadRegistry();
281 hRC = InitOGLWindow(hWnd);
282 GetClientRect (hWnd, &WindowRect);
283 width = WindowRect.right - WindowRect.left;
284 height = WindowRect.bottom - WindowRect.top;
285 InitOpenGL(width,height);
286 SetTimer(hWnd, timer, 5, NULL);
287 break;
288 case WM_TIMER:
289 hDC = GetDC(hWnd);
290 Display();
291 SwapBuffers(hDC);
292 ReleaseDC(hWnd, hDC);
293 break;
294 case WM_DESTROY:
295 wglMakeCurrent(NULL, NULL);
296 wglDeleteContext(hRC);
297 break;
298 }
299
300 return DefScreenSaverProc(hWnd, message, wParam, lParam);
301 }
302
303 BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message,
304 WPARAM wParam, LPARAM lParam)
305 {
306 switch (message)
307 {
308 case WM_INITDIALOG:
309 ReadRegistry();
310 CheckDlgButton(hDlg, ROTATE, dRotate);
311 return TRUE;
312 case WM_COMMAND:
313 switch (LOWORD(wParam))
314 {
315 case IDOK:
316 dRotate = (IsDlgButtonChecked(hDlg, ROTATE) == BST_CHECKED);
317 WriteRegistry();
318 EndDialog(hDlg, TRUE);
319 return TRUE;
320 case IDCANCEL:
321 EndDialog(hDlg, TRUE);
322 break;
323 case IDABOUT:
324 //DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLG_ABOUT), hDlg, DLGPROC(AboutProc));
325 break;
326 }
327 }
328
329 return FALSE;
330 }
331
332 BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
333 {
334 return TRUE;
335 }
336