2 * Copyright 2003 J Brown
3 * Copyright 2006 Andrey Korotaev <unC0Rr@inbox.ru>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
25 #define APPNAME _T("Cylfrac")
29 #define timerdelay 1000/FPS
42 GLUquadricObj
* cylinder
;
46 float rval
, gval
, bval
;
48 BOOL fullscreen
= FALSE
;
50 float _RGB(float H
, float M1
, float M2
)
52 if(H
< 0.0) H
+= 360.0;
53 else if(H
> 360.0) H
-= 360.0;
54 if(H
< 60) return M1
+ (M2
- M1
) * H
/ 60.0;
55 if((H
>= 60 )&&(H
< 180)) return M2
;
56 if((H
>= 180)&&(H
< 240)) return M1
+ (M2
- M1
)*(240 - H
) / 60.0;
60 void HLStoRGB(float H
, float L
, float S
,
61 float* R
, float* G
, float* B
)
64 if(S
<= 0.5) M2
= S
* (1 + L
);
65 else M2
= S
* (1 - L
) + L
;
73 *R
= _RGB(H
+ 120.0, M1
, M2
);
74 *G
= _RGB(H
, M1
, M2
);
75 *B
= _RGB(H
- 120.0, M1
, M2
);
79 void DrawCylinder(int n
, float rota
, float width
)
82 glColor3f(rval
/n
, gval
/n
, bval
/n
);
83 glRotatef(rota
, 0.0, 1.0, 0.0);
84 gluCylinder(cylinder
, width
, width
* wfactor
, n
* 0.5, cylquality
, 1);
85 glTranslatef(0.0, 0.0, -n
* 0.5);
86 gluCylinder(cylinder
, width
* wfactor
, width
, n
* 0.5, cylquality
, 1);
89 float r
= rota
* rotfactor
;
90 glRotatef(90.0, 1.0, 0.0, 0.0);
91 DrawCylinder(n
- 1, r
, width
* wfactor
);
92 glTranslatef(0.0, n
, 0.0);
93 DrawCylinder(n
- 1, -r
, width
* wfactor
);
98 void DrawScene(HWND hwnd
, HDC dc
, int ticks
)
101 dc
= BeginPaint(hwnd
, &ps
);
102 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
103 glRotatef(ticks
* 0.01, 0.0, 1.0, -0.5);
104 angle
+= ticks
* 0.01;
105 colorh
+= ticks
* 0.003;
106 if (colorh
> 360.0) colorh
-= 360.0;
107 HLStoRGB(colorh
, 1.0, 0.7, &rval
, &gval
, &bval
);
108 DrawCylinder(lvls
, angle
, 0.2);
113 void CALLBACK
TimeProc(UINT uID
, UINT uMsg
, DWORD dwUser
, DWORD dw1
, DWORD dw2
)
115 InvalidateRect((HWND
)dwUser
, NULL
, 0);
118 void MyPixelFormat(HDC dc
)
121 PIXELFORMATDESCRIPTOR pfd
;
123 ZeroMemory(&pfd
, sizeof(pfd
));
124 pfd
.nSize
= sizeof(pfd
);
126 pfd
.dwFlags
= PFD_DOUBLEBUFFER
| PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_WINDOW
;
128 npf
= ChoosePixelFormat(dc
, &pfd
);
130 SetPixelFormat(dc
, npf
, &pfd
);
133 void InitGL(HWND hwnd
)
135 GLfloat lightpos
[4] = {2.0, 2.0, -2.0, 0.7};
139 hrc
= wglCreateContext(dc
);
140 wglMakeCurrent(dc
, hrc
);
141 cylinder
= gluNewQuadric();
142 glEnable(GL_DEPTH_TEST
);
144 glLightfv(GL_LIGHT0
, GL_POSITION
, (GLfloat
*)&lightpos
);
145 glLightfv(GL_LIGHT0
, GL_LINEAR_ATTENUATION
, &ca
);
146 glEnable(GL_LIGHTING
);
147 glEnable(GL_COLOR_MATERIAL
);
150 LRESULT WINAPI
WndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
154 GetCursorPos(&initpoint
);
156 oldticks
= GetTickCount();
157 TimerID
= timeSetEvent (timerdelay
, 0, TimeProc
, (DWORD
)hwnd
, TIME_PERIODIC
);
161 DWORD ticks
= oldticks
;
163 oldticks
= GetTickCount();
164 DrawScene(hwnd
, dc
, oldticks
- ticks
);
167 GetCursorPos(&currpoint
);
168 if(abs(currpoint
.x
- initpoint
.x
) + (abs(currpoint
.y
- initpoint
.y
)) > 10)
169 PostMessage(hwnd
, WM_CLOSE
, 0, 0);
174 timeKillEvent(TimerID
);
175 gluDeleteQuadric(cylinder
);
176 wglMakeCurrent(0, 0);
177 wglDeleteContext(hrc
);
184 PostMessage(hwnd
, WM_CLOSE
, 0, 0);
188 int width
= LOWORD(lParam
);
189 int height
= HIWORD(lParam
);
191 glViewport(0, 0, width
, height
);
192 glMatrixMode(GL_MODELVIEW
);
194 fscale
= 0.8/(float)lvls
;
195 glScalef(fscale
, fscale
, fscale
);
200 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
203 void InitSaver(HWND hwndParent
)
206 ZeroMemory(&wc
, sizeof(wc
));
207 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
208 wc
.lpfnWndProc
= WndProc
;
209 wc
.lpszClassName
= APPNAME
;
215 GetClientRect(hwndParent
, &rect
);
216 CreateWindow(APPNAME
, APPNAME
,
217 WS_VISIBLE
| WS_CHILD
,
226 hwnd
= CreateWindow(APPNAME
, APPNAME
,
227 WS_VISIBLE
| WS_POPUP
| WS_EX_TOPMOST
,
229 GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
),
232 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
238 void ParseCommandLine(PSTR szCmdLine
, int *chOption
, HWND
*hwndParent
)
242 if (!strlen(szCmdLine
))
247 if(ch
== '-' || ch
== '/')
250 if(ch
>= 'A' && ch
<= 'Z')
255 if (ch
== 's' || ch
== 'c')
263 while(ch
== ' ' || ch
== '\t')
268 unsigned int i
= atoi(szCmdLine
- 1);
269 *hwndParent
= (HWND
)i
;
275 int WINAPI
WinMain (HINSTANCE hInst
,
286 ParseCommandLine(lpCmdLine
, &chOption
, &hwndParent
);
295 InitSaver(hwndParent
);
301 _T("Cylinders fractal by unC0Rr.\nSpecial for ReactOS.\n"),
303 MB_OK
| MB_ICONINFORMATION
);
307 while (GetMessage(&Message
, 0, 0, 0))
308 DispatchMessage(&Message
);
310 return Message
.wParam
;