2 * Copyright 2000 Jeff Molofee http://nehe.gamedev.net/ (Original code)
3 * Copyright 2006 Eric Kohl
4 * Copyright 2007 Marc Piulachs (marc.piulachs@codexchange.net) - minor modifications , converted to screensaver
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
30 static HGLRC hRC
; // Permanent Rendering Context
31 static HDC hDC
; // Private GDI Device Context
33 GLuint base
; // Base Display List For The Font Set
34 GLfloat rot
; // Used To Rotate The Text
35 GLfloat extentX
= 0.0f
;
36 GLfloat extentY
= 0.0f
;
38 #define APPNAME _T("3DText")
41 BOOL fullscreen
= FALSE
;
43 // Build Our Bitmap Font
44 GLvoid
BuildFont(GLvoid
)
46 // Address Buffer For Font Storage
47 GLYPHMETRICSFLOAT gmf
[256];
48 // Windows Font Handle
52 GLfloat cellOriginX
= 0.0f
;
53 GLfloat stringOriginX
;
54 GLfloat stringExtentX
= 0.0f
;
55 GLfloat stringExtentY
= 0.0f
;
57 // Storage For 256 Characters
58 base
= glGenLists(256);
60 font
= CreateFont(-12,
62 0, // Angle Of Escapement
63 0, // Orientation Angle
64 FW_BOLD
, // Font Weight
68 DEFAULT_CHARSET
, // Character Set Identifier
69 OUT_TT_PRECIS
, // Output Precision
70 CLIP_DEFAULT_PRECIS
, // Clipping Precision
71 ANTIALIASED_QUALITY
, // Output Quality
72 FF_DONTCARE
|DEFAULT_PITCH
, // Family And Pitch
73 _T("Tahoma")); // Font Name
75 // Selects The Font We Created
76 SelectObject(hDC
, font
);
78 wglUseFontOutlines(hDC
, // Select The Current DC
79 0, // Starting Character
80 255, // Number Of Display Lists To Build
81 base
, // Starting Display Lists
82 0.0f
, // Deviation From The True Outlines
83 0.2f
, // Font Thickness In The Z Direction
84 WGL_FONT_POLYGONS
, // Use Polygons, Not Lines
85 gmf
); // Address Of Buffer To Recieve Data
87 // Calculate the string extent
88 for (i
= 0; i
< _tcslen(m_Text
); i
++)
92 stringOriginX
= cellOriginX
+ gmf
[c
].gmfptGlyphOrigin
.x
;
94 stringExtentX
= stringOriginX
+ gmf
[c
].gmfBlackBoxX
;
95 if (gmf
[c
].gmfBlackBoxY
> stringExtentY
)
96 stringExtentY
= gmf
[c
].gmfBlackBoxY
;
98 cellOriginX
= cellOriginX
+ gmf
[c
].gmfCellIncX
;
101 extentX
= stringExtentX
;
102 extentY
= stringExtentY
;
106 GLvoid
KillFont(GLvoid
)
108 // Delete all 256 characters
109 glDeleteLists(base
, 256);
112 // Custom GL "Print" Routine
113 GLvoid
glPrint(LPTSTR text
)
115 // If there's no text, do nothing
119 // Pushes The Display List Bits
120 glPushAttrib(GL_LIST_BIT
);
122 // Sets The Base Character to 32
125 // Draws The Display List Text
126 glCallLists(_tcslen(text
),
134 // Pops The Display List Bits
138 // Will Be Called Right After The GL Window Is Created
139 GLvoid
InitGL(GLsizei Width
, GLsizei Height
)
141 // Clear The Background Color To Black
142 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.0f
);
144 // Enables Clearing Of The Depth Buffer
147 // The Type Of Depth Test To Do
148 glDepthFunc(GL_LESS
);
150 // Enables Depth Testing
151 glEnable(GL_DEPTH_TEST
);
153 // Enables Smooth Color Shading
154 glShadeModel(GL_SMOOTH
);
156 // Select The Projection Matrix
157 glMatrixMode(GL_PROJECTION
);
159 // Reset The Projection Matrix
162 // Calculate The Aspect Ratio Of The Window
163 gluPerspective(45.0f
, (GLfloat
)Width
/ (GLfloat
)Height
, 0.1f
, 100.0f
);
165 // Select The Modelview Matrix
166 glMatrixMode(GL_MODELVIEW
);
171 // Enable Default Light (Quick And Dirty)
175 glEnable(GL_LIGHTING
);
177 // Enable Coloring Of Material
178 glEnable(GL_COLOR_MATERIAL
);
181 // Handles Window Resizing
182 GLvoid
ReSizeGLScene(GLsizei Width
, GLsizei Height
)
184 // Is Window Too Small (Divide By Zero Error)
187 // If So Make It One Pixel Tall
191 // Reset The Current Viewport And Perspective Transformation
192 glViewport(0, 0, Width
, Height
);
194 // Select The Projection Matrix
195 glMatrixMode(GL_PROJECTION
);
197 // Reset The Projection Matrix
200 // Calculate The Aspect Ratio Of The Window
201 gluPerspective(45.0f
, (GLfloat
)Width
/ (GLfloat
)Height
, 0.1f
, 100.0f
);
203 // Select The Modelview Matrix
204 glMatrixMode(GL_MODELVIEW
);
208 GLvoid
DrawGLScene(GLvoid
)
210 // Clear The Screen And The Depth Buffer
211 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
216 // Move One Unit Into The Screen
217 glTranslatef(0.0f
, 0.0f
, -10.0f
);
219 // Rotate On The X Axis
220 glRotatef(rot
, 1.0f
, 0.0f
, 0.0f
);
222 // Rotate On The Y Axis
223 glRotatef(rot
* 1.2f
, 0.0f
, 1.0f
, 0.0f
);
225 // Rotate On The Z Axis
226 glRotatef(rot
* 1.4f
, 0.0f
, 0.0f
, 1.0f
);
228 // Move to the Left and Down before drawing
229 glTranslatef(-(extentX
/ 2.0f
),
233 // Pulsing Colors Based On The Rotation
234 glColor3f((1.0f
* (cos(rot
/ 20.0f
))),
235 (1.0f
* (sin(rot
/ 25.0f
))),
236 (1.0f
- 0.5f
* (cos(rot
/ 17.0f
))));
238 // Print GL Text To The Screen
241 // Make The Text Blue
242 glColor3f(0.0f
, 0.0f
, 1.0f
);
244 // Increase The Rotation Variable
255 static POINT ptCursor
;
256 static BOOL fFirstTime
= TRUE
;
257 RECT Screen
; // Used Later On To Get The Size Of The Window
258 GLuint PixelFormat
; // Pixel Format Storage
259 static PIXELFORMATDESCRIPTOR pfd
= // Pixel Format Descriptor
261 sizeof(PIXELFORMATDESCRIPTOR
), // Size Of This Pixel Format Descriptor
262 1, // Version Number (?)
263 PFD_DRAW_TO_WINDOW
| // Format Must Support Window
264 PFD_SUPPORT_OPENGL
| // Format Must Support OpenGL
265 PFD_DOUBLEBUFFER
, // Must Support Double Buffering
266 PFD_TYPE_RGBA
, // Request An RGBA Format
267 16, // Select A 16Bit Color Depth
268 0, 0, 0, 0, 0, 0, // Color Bits Ignored (?)
269 0, // No Alpha Buffer
270 0, // Shift Bit Ignored (?)
271 0, // No Accumulation Buffer
272 0, 0, 0, 0, // Accumulation Bits Ignored (?)
273 16, // 16Bit Z-Buffer (Depth Buffer)
274 0, // No Stencil Buffer
275 0, // No Auxiliary Buffer (?)
276 PFD_MAIN_PLANE
, // Main Drawing Layer
278 0, 0, 0 // Layer Masks Ignored (?)
284 // Gets A Device Context For The Window
287 // Finds The Closest Match To The Pixel Format We Set Above
288 PixelFormat
= ChoosePixelFormat(hDC
, &pfd
);
290 // No Matching Pixel Format?
293 MessageBox(0, _TEXT("Can't Find A Suitable PixelFormat."), _TEXT("Error"),MB_OK
| MB_ICONERROR
);
295 // This Sends A 'Message' Telling The Program To Quit
300 // Can We Set The Pixel Mode?
301 if (!SetPixelFormat(hDC
, PixelFormat
, &pfd
))
303 MessageBox(0, _TEXT("Can't Set The PixelFormat."), _TEXT("Error"), MB_OK
| MB_ICONERROR
);
305 // This Sends A 'Message' Telling The Program To Quit
310 // Grab A Rendering Context
311 hRC
= wglCreateContext(hDC
);
316 MessageBox(0, _TEXT("Can't Create A GL Rendering Context."), _TEXT("Error"), MB_OK
| MB_ICONERROR
);
318 // This Sends A 'Message' Telling The Program To Quit
323 // Can We Make The RC Active?
324 if (!wglMakeCurrent(hDC
, hRC
))
326 MessageBox(0, _TEXT("Can't Activate GLRC."), _TEXT("Error"), MB_OK
| MB_ICONERROR
);
328 // This Sends A 'Message' Telling The Program To Quit
333 // Grab Screen Info For The Current Window
334 GetClientRect(hWnd
, &Screen
);
336 // Initialize The GL Screen Using Screen Info
337 InitGL(Screen
.right
, Screen
.bottom
);
342 // Disable Fullscreen Mode
343 ChangeDisplaySettings(NULL
, 0);
345 // Deletes The Font Display List
348 // Make The DC Current
349 wglMakeCurrent(hDC
, NULL
);
352 wglDeleteContext(hRC
);
355 ReleaseDC(hWnd
, hDC
);
368 PostMessage(hWnd
, WM_CLOSE
, 0, 0);
378 // If we've got a parent then we must be a preview
379 if (GetParent(hWnd
) != 0)
384 GetCursorPos(&ptLast
);
388 GetCursorPos(&ptCursor
);
390 // if the mouse has moved more than 3 pixels then exit
391 if (abs(ptCursor
.x
- ptLast
.x
) >= 3 || abs(ptCursor
.y
- ptLast
.y
) >= 3)
392 PostMessage(hWnd
, WM_CLOSE
, 0, 0);
397 case WM_SIZE
: // Resizing The Screen
398 // Resize To The New Window Size
399 ReSizeGLScene(LOWORD(lParam
), HIWORD(lParam
));
403 // Pass Windows Messages
404 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
410 VOID
InitSaver(HWND hwndParent
)
414 ZeroMemory(&wc
, sizeof(wc
));
415 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
416 wc
.lpfnWndProc
= WndProc
;
417 wc
.lpszClassName
= APPNAME
;
424 GetClientRect(hwndParent
, &rect
);
425 CreateWindow(APPNAME
, APPNAME
,
426 WS_VISIBLE
| WS_CHILD
,
437 hwnd
= CreateWindow(APPNAME
, APPNAME
,
438 WS_VISIBLE
| WS_POPUP
| WS_EX_TOPMOST
,
440 GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
),
443 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
450 // Look for any options Windows has passed to us:
452 // -a <hwnd> (set password)
454 // -p <hwnd> (preview)
455 // -c <hwnd> (configure)
457 VOID
ParseCommandLine(LPTSTR szCmdLine
, UCHAR
*chOption
, HWND
*hwndParent
)
459 TCHAR ch
= *szCmdLine
++;
461 if (ch
== _T('-') || ch
== _T('/'))
464 //convert to lower case
465 if (ch
>= _T('A') && ch
<= _T('Z'))
466 ch
+= _T('a') - _T('A');
474 while (ch
== _T(' ') || ch
== _T('\t'))
479 unsigned int i
= _ttoi(szCmdLine
- 1);
480 *hwndParent
= (HWND
)i
;
490 // Dialogbox procedure for Configuration window
492 BOOL CALLBACK
ConfigDlgProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
497 SetDlgItemText(hwnd
, IDC_MESSAGE_TEXT
, m_Text
);
501 switch (LOWORD(wParam
))
504 GetDlgItemText(hwnd
, IDC_MESSAGE_TEXT
, m_Text
, MAX_PATH
);
506 EndDialog(hwnd
, IDOK
);
510 EndDialog(hwnd
, IDCANCEL
);
528 DialogBox(hInstance
, MAKEINTRESOURCE(IDD_CONFIG
), NULL
, (DLGPROC
)ConfigDlgProc
);
532 _tWinMain(HINSTANCE hInst
,
543 ParseCommandLine(lpCmdLine
, &chOption
, &hwndParent
);
554 InitSaver(hwndParent
);
563 while (GetMessage(&Message
, 0, 0, 0))
564 DispatchMessage(&Message
);
566 return Message
.wParam
;