2011-10-01 21:28:47 +00:00
|
|
|
/*
|
|
|
|
* Star field screensaver
|
|
|
|
*
|
|
|
|
* Copyright 2011 Carlo Bramini
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#include <windows.h>
|
|
|
|
#include <tchar.h>
|
|
|
|
#include <scrnsave.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
2011-12-19 10:22:06 +00:00
|
|
|
#include <GL/gl.h>
|
|
|
|
#include <GL/glu.h>
|
2011-10-01 21:28:47 +00:00
|
|
|
|
|
|
|
#include "resource.h"
|
|
|
|
#include "settings.h"
|
|
|
|
|
|
|
|
#define FAR_PLANE -80.0f
|
|
|
|
#define NEAR_PLANE 3.0f
|
|
|
|
#define GAP 0.0f
|
|
|
|
#define FIELD_WIDTH 50.f
|
|
|
|
#define FIELD_HEIGHT 45.f
|
|
|
|
#define FIELD_DEPTH (NEAR_PLANE - FAR_PLANE + GAP)
|
|
|
|
|
|
|
|
#define STAR_RED 0.f
|
|
|
|
#define STAR_GREEN 0.f
|
|
|
|
#define STAR_BLUE 0.10f
|
|
|
|
#define STAR_TAIL 0.9f
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
float x1;
|
|
|
|
float y1;
|
|
|
|
float x2;
|
|
|
|
float y2;
|
|
|
|
float z;
|
|
|
|
} VERTEX;
|
|
|
|
|
|
|
|
static VERTEX Vertex[MAX_STARS];
|
|
|
|
static HGLRC hRC; // Permanent Rendering Context
|
|
|
|
static HDC hDC; // Private GDI Device Context
|
|
|
|
static float fAngle;
|
|
|
|
static GLuint glStarTex;
|
|
|
|
|
|
|
|
// Light position
|
|
|
|
static GLfloat g_light_position[4] = {
|
|
|
|
0.0f, 0.0f, 3.0f, 1.0f
|
|
|
|
};
|
|
|
|
|
|
|
|
static PIXELFORMATDESCRIPTOR pfd= // Pixel Format Descriptor
|
|
|
|
{
|
|
|
|
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
|
|
|
1, // Version Number (?)
|
|
|
|
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
|
|
|
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
|
|
|
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
|
|
|
PFD_TYPE_RGBA, // Request An RGBA Format
|
|
|
|
16, // Select A 16Bit Color Depth
|
|
|
|
0, 0, 0, 0, 0, 0, // Color Bits Ignored (?)
|
|
|
|
0, // No Alpha Buffer
|
|
|
|
0, // Shift Bit Ignored (?)
|
|
|
|
0, // No Accumulation Buffer
|
|
|
|
0, 0, 0, 0, // Accumulation Bits Ignored (?)
|
|
|
|
16, // 16Bit Z-Buffer (Depth Buffer)
|
|
|
|
0, // No Stencil Buffer
|
|
|
|
0, // No Auxiliary Buffer (?)
|
|
|
|
PFD_MAIN_PLANE, // Main Drawing Layer
|
|
|
|
0, // Reserved (?)
|
|
|
|
0, 0, 0 // Layer Masks Ignored (?)
|
|
|
|
};
|
|
|
|
|
|
|
|
static HBITMAP CreateStarBitmap(HWND hWnd, HDC hDC)
|
|
|
|
{
|
|
|
|
BITMAPINFO bi;
|
|
|
|
LPBYTE lpBits;
|
|
|
|
LPBYTE *lppBits;
|
|
|
|
HBITMAP hTextBmp, hFileBmp;
|
|
|
|
HDC hTextDC, hFileDC;
|
|
|
|
HGDIOBJ hOldText, hOldFile;
|
|
|
|
UINT i;
|
|
|
|
DWORD *Ptr32;
|
|
|
|
BITMAP bm;
|
|
|
|
HINSTANCE hInstance;
|
|
|
|
|
|
|
|
// Get instance for loading the texture
|
|
|
|
hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
|
|
|
|
|
|
|
|
// Load the texture
|
|
|
|
hFileBmp = (HBITMAP)
|
|
|
|
LoadImage(
|
|
|
|
hInstance,
|
|
|
|
MAKEINTRESOURCE(IDB_STAR),
|
|
|
|
IMAGE_BITMAP,
|
|
|
|
0, 0,
|
|
|
|
LR_CREATEDIBSECTION | LR_DEFAULTSIZE
|
|
|
|
);
|
|
|
|
|
|
|
|
// Get texture specs
|
|
|
|
GetObject(hFileBmp, sizeof(BITMAP), &bm);
|
|
|
|
|
|
|
|
// Allocate new 32 bit texture
|
|
|
|
ZeroMemory(&bi, sizeof(bi));
|
|
|
|
|
|
|
|
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
bi.bmiHeader.biWidth = bm.bmWidth;
|
|
|
|
bi.bmiHeader.biHeight = -bm.bmHeight;
|
|
|
|
bi.bmiHeader.biPlanes = 1;
|
|
|
|
bi.bmiHeader.biBitCount = 32;
|
|
|
|
bi.bmiHeader.biCompression = BI_RGB;
|
|
|
|
|
|
|
|
// Makes GCC happy ;-|
|
|
|
|
lppBits = &lpBits;
|
|
|
|
|
|
|
|
hTextBmp = CreateDIBSection(hDC,
|
|
|
|
(BITMAPINFO*)&bi,
|
|
|
|
DIB_RGB_COLORS,
|
|
|
|
(void**)lppBits,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
|
|
|
// Save new texture specs
|
|
|
|
// GetObject(hTextBmp, sizeof(BITMAP), &bmStarTex);
|
|
|
|
// bmStarTex.bmBits = lpBits;
|
|
|
|
|
|
|
|
// Copy 24 bit texture in 32 texture
|
|
|
|
hTextDC = CreateCompatibleDC(hDC);
|
|
|
|
hFileDC = CreateCompatibleDC(hDC);
|
|
|
|
|
|
|
|
hOldText = SelectObject(hTextDC, hTextBmp);
|
|
|
|
hOldFile = SelectObject(hFileDC, hFileBmp);
|
|
|
|
|
|
|
|
BitBlt(hTextDC, 0, 0, bm.bmWidth, bm.bmHeight, hFileDC, 0, 0, SRCCOPY);
|
|
|
|
|
|
|
|
SelectObject(hTextDC, hOldText);
|
|
|
|
SelectObject(hFileDC, hOldFile);
|
|
|
|
|
|
|
|
DeleteDC(hTextDC);
|
|
|
|
DeleteDC(hFileDC);
|
|
|
|
|
|
|
|
// Delete 24 bit texture
|
|
|
|
DeleteObject(hFileBmp);
|
|
|
|
|
|
|
|
GetObject(hTextBmp, sizeof(BITMAP), &bm);
|
|
|
|
|
|
|
|
// Apply ALPHA channel to new texture
|
|
|
|
for (Ptr32=(DWORD *)lpBits, i=0; i < (UINT)(bm.bmWidth * bm.bmHeight); i++)
|
|
|
|
{
|
|
|
|
DWORD Color = Ptr32[i] & 0x00FFFFFF;
|
|
|
|
DWORD Alpha = Color & 0xFF;
|
|
|
|
|
|
|
|
Color |= Alpha << 24;
|
|
|
|
|
|
|
|
Ptr32[i] = Color;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hTextBmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void InitGL(HBITMAP hStarTex)
|
|
|
|
{
|
|
|
|
BITMAP bm;
|
|
|
|
unsigned int i;
|
|
|
|
float xp, yp, zp;
|
|
|
|
|
|
|
|
// set the GL clear color - use when the color buffer is cleared
|
|
|
|
glClearColor(STAR_RED, STAR_GREEN, STAR_BLUE, STAR_TAIL);
|
|
|
|
|
|
|
|
if (Settings.bSmoothShading)
|
|
|
|
// set the shading model to 'smooth'
|
|
|
|
glShadeModel( GL_SMOOTH );
|
|
|
|
else
|
|
|
|
// set the shading model to 'flat'
|
|
|
|
glShadeModel( GL_FLAT );
|
|
|
|
|
|
|
|
// set GL to render front of polygons
|
|
|
|
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
|
|
|
// enable depth test
|
|
|
|
glDisable( GL_DEPTH_TEST );
|
|
|
|
|
|
|
|
// enable lighting
|
|
|
|
glEnable( GL_LIGHTING );
|
|
|
|
// enable lighting for front
|
|
|
|
glLightModeli( GL_FRONT, GL_TRUE );
|
|
|
|
// material have diffuse and ambient lighting
|
|
|
|
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
|
|
|
|
// enable color
|
|
|
|
glEnable( GL_COLOR_MATERIAL );
|
|
|
|
// enable light 0
|
|
|
|
glEnable( GL_LIGHT0 );
|
|
|
|
|
|
|
|
// set light attenuation
|
|
|
|
glLightf( GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.01f); //0.01f );
|
|
|
|
glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.01f); //0.2f );
|
|
|
|
glLightf( GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.005f); //0.001f );
|
|
|
|
|
|
|
|
// clear the color buffer once
|
|
|
|
glClear( GL_COLOR_BUFFER_BIT );
|
|
|
|
|
|
|
|
// randomly generate
|
|
|
|
srand( time( NULL ) );
|
|
|
|
|
|
|
|
// Initialize *ALL* stars vertexes (not just programmed ones).
|
|
|
|
for (i = 0; i < MAX_STARS; i++)
|
|
|
|
{
|
|
|
|
xp = ( (float) rand() / RAND_MAX - .5f ) * FIELD_WIDTH;
|
|
|
|
yp = ( (float) rand() / RAND_MAX - .5f ) * FIELD_HEIGHT;
|
|
|
|
zp = ( (float) rand() / RAND_MAX ) * FIELD_DEPTH + FAR_PLANE;
|
|
|
|
|
|
|
|
Vertex[i].x1 = -1.f + xp;
|
|
|
|
Vertex[i].y1 = -1.f + yp;
|
|
|
|
Vertex[i].x2 = 1.f + xp;
|
|
|
|
Vertex[i].y2 = 1.f + yp;
|
|
|
|
Vertex[i].z = zp;
|
|
|
|
}
|
|
|
|
|
|
|
|
glGenTextures(1, &glStarTex); // Create One Texture
|
|
|
|
|
|
|
|
// Create Linear Filtered Texture
|
|
|
|
glBindTexture(GL_TEXTURE_2D, glStarTex);
|
|
|
|
|
|
|
|
if (Settings.bEnableFiltering)
|
|
|
|
{
|
|
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
|
|
|
} else {
|
|
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get Texture properties
|
|
|
|
GetObject(hStarTex, sizeof(BITMAP), &bm);
|
|
|
|
|
|
|
|
// Create texture as a mipmap
|
|
|
|
#if 0
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, 4, bm.bmWidth, bm.bmHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, bm.bmBits);
|
|
|
|
#else
|
|
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, bm.bmWidth, bm.bmHeight, GL_RGBA, GL_UNSIGNED_BYTE, bm.bmBits);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Disable Texture Mapping (background smoothing)
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
|
|
|
|
if (Settings.bFinePerspective)
|
|
|
|
// Really Fast Perspective Calculations
|
|
|
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
|
|
|
else
|
|
|
|
// Really Nice Perspective Calculations
|
|
|
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
|
|
|
|
|
|
|
// enable blending
|
|
|
|
glEnable( GL_BLEND );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
render(void)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
float fSpin;
|
|
|
|
float fSpeed;
|
|
|
|
float xp, yp;
|
|
|
|
|
|
|
|
// Initialize current speed
|
|
|
|
fSpeed = (float)Settings.uiSpeed / 100.f;
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
|
|
|
|
|
|
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set The Blending Function For Translucency
|
|
|
|
|
|
|
|
switch (Settings.uiRotation) {
|
|
|
|
case ROTATION_LINEAR:
|
|
|
|
fAngle += fSpeed;
|
|
|
|
glRotatef( fAngle, 0.0f, 0.0f, 1.0f );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ROTATION_PERIODIC:
|
|
|
|
fAngle += fSpeed / 75.f;
|
|
|
|
fSpin = (float)(50. * cos(fAngle));
|
|
|
|
glRotatef( fSpin, 0.0f, 0.0f, 1.0f );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
glColor3ub(255, 255, 255);
|
|
|
|
|
|
|
|
glBegin(GL_QUADS); // Begin Drawing The Textured Quad
|
|
|
|
|
|
|
|
// Draw the stars
|
|
|
|
for (i = 0; i < Settings.uiNumStars; i++)
|
|
|
|
{
|
|
|
|
glTexCoord2f(0.0f, 0.0f); glVertex3f(Vertex[i].x1, Vertex[i].y1, Vertex[i].z);
|
|
|
|
glTexCoord2f(1.0f, 0.0f); glVertex3f(Vertex[i].x2, Vertex[i].y1, Vertex[i].z);
|
|
|
|
glTexCoord2f(1.0f, 1.0f); glVertex3f(Vertex[i].x2, Vertex[i].y2, Vertex[i].z);
|
|
|
|
glTexCoord2f(0.0f, 1.0f); glVertex3f(Vertex[i].x1, Vertex[i].y2, Vertex[i].z);
|
|
|
|
|
|
|
|
// increment z
|
|
|
|
Vertex[i].z += fSpeed;
|
|
|
|
|
|
|
|
// check to see if passed view
|
|
|
|
if( Vertex[i].z > NEAR_PLANE + GAP ||
|
|
|
|
Vertex[i].z < FAR_PLANE )
|
|
|
|
{
|
|
|
|
xp = ( (float) rand() / RAND_MAX - .5f ) * FIELD_WIDTH;
|
|
|
|
yp = ( (float) rand() / RAND_MAX - .5f ) * FIELD_HEIGHT;
|
|
|
|
|
|
|
|
Vertex[i].x1 = -1.f + xp;
|
|
|
|
Vertex[i].y1 = -1.f + yp;
|
|
|
|
Vertex[i].x2 = 1.f + xp;
|
|
|
|
Vertex[i].y2 = 1.f + yp;
|
|
|
|
Vertex[i].z = FAR_PLANE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glEnd(); // Done Drawing The Textured Quad
|
|
|
|
|
|
|
|
glDisable(GL_TEXTURE_2D); // Enable Texture Mapping
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT CALLBACK
|
|
|
|
OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
GLuint PixelFormat;
|
|
|
|
HBITMAP hStarTex;
|
|
|
|
|
|
|
|
LoadSettings();
|
|
|
|
|
|
|
|
// Gets A Device Context For The Window
|
|
|
|
hDC = GetDC(hWnd);
|
|
|
|
|
|
|
|
// Finds The Closest Match To The Pixel Format We Set Above
|
|
|
|
PixelFormat = ChoosePixelFormat(hDC, &pfd);
|
|
|
|
|
|
|
|
// No Matching Pixel Format?
|
|
|
|
if (!PixelFormat)
|
|
|
|
{
|
|
|
|
MessageBox(0, _T("Can't Find A Suitable PixelFormat."), _T("Error"),MB_OK | MB_ICONERROR);
|
|
|
|
|
|
|
|
// This Sends A 'Message' Telling The Program To Quit
|
|
|
|
PostQuitMessage(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can We Set The Pixel Mode?
|
|
|
|
if (!SetPixelFormat(hDC, PixelFormat, &pfd))
|
|
|
|
{
|
|
|
|
MessageBox(0, _TEXT("Can't Set The PixelFormat."), _T("Error"), MB_OK | MB_ICONERROR);
|
|
|
|
|
|
|
|
// This Sends A 'Message' Telling The Program To Quit
|
|
|
|
PostQuitMessage(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Grab A Rendering Context
|
|
|
|
hRC = wglCreateContext(hDC);
|
|
|
|
|
|
|
|
// Did We Get One?
|
|
|
|
if (!hRC)
|
|
|
|
{
|
|
|
|
MessageBox(0, _T("Can't Create A GL Rendering Context."), _T("Error"), MB_OK | MB_ICONERROR);
|
|
|
|
|
|
|
|
// This Sends A 'Message' Telling The Program To Quit
|
|
|
|
PostQuitMessage(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can We Make The RC Active?
|
|
|
|
if (!wglMakeCurrent(hDC, hRC))
|
|
|
|
{
|
|
|
|
MessageBox(0, _T("Can't Activate GLRC."), _TEXT("Error"), MB_OK | MB_ICONERROR);
|
|
|
|
|
|
|
|
// This Sends A 'Message' Telling The Program To Quit
|
|
|
|
PostQuitMessage(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load star texture
|
|
|
|
hStarTex = CreateStarBitmap(hWnd, hDC);
|
|
|
|
|
|
|
|
// Initialize The GL Screen Using Screen Info
|
|
|
|
InitGL(hStarTex);
|
|
|
|
|
|
|
|
// Delete GDI object for texture
|
|
|
|
DeleteObject(hStarTex);
|
|
|
|
|
|
|
|
// Update screen every 10ms
|
|
|
|
SetTimer(hWnd, 1, 10, NULL);
|
|
|
|
|
|
|
|
// Initialize spinning angle
|
|
|
|
fAngle = 0.f;
|
|
|
|
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT CALLBACK
|
|
|
|
OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
// Delete update timer
|
|
|
|
KillTimer(hWnd, 1);
|
|
|
|
|
|
|
|
// Disable Fullscreen Mode
|
|
|
|
ChangeDisplaySettings(NULL, 0);
|
|
|
|
|
|
|
|
// Make The DC Current
|
|
|
|
wglMakeCurrent(hDC, NULL);
|
|
|
|
|
|
|
|
// Kill The RC
|
|
|
|
wglDeleteContext(hRC);
|
|
|
|
|
|
|
|
// Free The DC
|
|
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
|
|
|
|
#ifdef _DEBUG_SSTARS
|
|
|
|
PostQuitMessage(0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT CALLBACK
|
|
|
|
OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
if (Settings.bDoBlending)
|
|
|
|
{
|
|
|
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
|
|
|
|
|
|
|
// disable lighting
|
|
|
|
glDisable( GL_LIGHTING );
|
|
|
|
|
|
|
|
// blend in a polygon
|
|
|
|
glColor4f(STAR_RED, STAR_GREEN, STAR_BLUE, STAR_TAIL);
|
|
|
|
|
|
|
|
// Restore both model view and projection to identity
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// Blur the background
|
|
|
|
glBegin( GL_QUADS );
|
|
|
|
glVertex3f( -1.0f, -1.0f, -1.0f );
|
|
|
|
glVertex3f( -1.0f, 1.0f, -1.0f );
|
|
|
|
glVertex3f( 1.0f, 1.0f, -1.0f );
|
|
|
|
glVertex3f( 1.0f, -1.0f, -1.0f );
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
// Recover previous matrix
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
|
|
|
|
// enable lighting
|
|
|
|
glEnable( GL_LIGHTING );
|
|
|
|
} else {
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
// save the current matrix state, so transformation will
|
|
|
|
// not persist across displayFunc calls, since we
|
|
|
|
// will do a glPopMatrix() at the end of this function
|
|
|
|
glPushMatrix();
|
|
|
|
|
|
|
|
// render the scene
|
|
|
|
render();
|
|
|
|
|
|
|
|
// restore the matrix state
|
|
|
|
glPopMatrix();
|
|
|
|
|
|
|
|
// flush the buffer
|
|
|
|
glFlush();
|
|
|
|
|
|
|
|
// swap the double buffer
|
|
|
|
SwapBuffers(hDC);
|
|
|
|
|
|
|
|
// Clear redraw event
|
|
|
|
ValidateRect(hWnd, NULL);
|
|
|
|
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT CALLBACK
|
|
|
|
OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
GLsizei w = LOWORD(lParam);
|
|
|
|
GLsizei h = HIWORD(lParam);
|
|
|
|
|
|
|
|
// map the view port to the entire client area
|
|
|
|
glViewport(0, 0, w, h);
|
|
|
|
|
|
|
|
// set the matrix mode to projection matrix
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
|
|
|
|
// load the identity matrix
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// set the perspective matrix
|
|
|
|
gluPerspective( 64.0, (GLdouble) w / (GLdouble)h, .1, 300.0 );
|
|
|
|
|
|
|
|
// set the matrix mode to the modelview matrix
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
|
|
|
// load the identity matrix into the modelview matrix
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// set the 'camera'
|
|
|
|
gluLookAt( 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 2.0, 3.0 );
|
|
|
|
|
|
|
|
// set the position of the light
|
|
|
|
glLightfv( GL_LIGHT0, GL_POSITION, g_light_position );
|
|
|
|
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK
|
|
|
|
ScreenSaverProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (uMsg) {
|
|
|
|
case WM_CREATE:
|
|
|
|
return OnCreate(hWnd, wParam, lParam);
|
|
|
|
|
|
|
|
case WM_TIMER:
|
|
|
|
InvalidateRect(hWnd, NULL, FALSE);
|
|
|
|
return 0L;
|
|
|
|
|
|
|
|
case WM_DESTROY:
|
|
|
|
return OnDestroy(hWnd, wParam, lParam);
|
|
|
|
|
|
|
|
case WM_PAINT:
|
|
|
|
return OnPaint(hWnd, wParam, lParam);
|
|
|
|
|
|
|
|
case WM_SIZE: // Resizing The Screen
|
|
|
|
return OnSize(hWnd, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _DEBUG_SSTARS
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
#else
|
|
|
|
return DefScreenSaverProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _DEBUG_SSTARS
|
|
|
|
|
|
|
|
ATOM InitApp(HINSTANCE hInstance, LPCTSTR szClassName)
|
|
|
|
{
|
|
|
|
WNDCLASS wc;
|
|
|
|
|
|
|
|
ZeroMemory(&wc, sizeof(wc));
|
|
|
|
|
|
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
wc.lpfnWndProc = ScreenSaverProc;
|
|
|
|
wc.cbClsExtra = 0;
|
|
|
|
wc.cbWndExtra = 0;
|
|
|
|
wc.hInstance = hInstance;
|
|
|
|
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
|
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
|
|
|
wc.lpszMenuName = NULL;
|
|
|
|
wc.lpszClassName = szClassName;
|
|
|
|
|
|
|
|
return RegisterClass(&wc);
|
|
|
|
}
|
|
|
|
|
|
|
|
HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|
|
|
{
|
|
|
|
HWND hWnd;
|
|
|
|
TCHAR szClass[] = _T("CLASS");
|
|
|
|
TCHAR szTitle[] = _T("TITLE");
|
|
|
|
|
|
|
|
InitApp(hInstance, szClass);
|
|
|
|
|
|
|
|
hWnd = CreateWindow(
|
|
|
|
szClass,
|
|
|
|
szTitle,
|
|
|
|
WS_OVERLAPPEDWINDOW,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
192*3, //CW_USEDEFAULT,
|
|
|
|
108*3, //CW_USEDEFAULT,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
hInstance,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (hWnd)
|
|
|
|
{
|
|
|
|
ShowWindow(hWnd, nCmdShow);
|
|
|
|
UpdateWindow(hWnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return hWnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
|
|
|
{
|
|
|
|
MSG msg;
|
|
|
|
HWND hWnd;
|
|
|
|
HWND hDlg;
|
|
|
|
|
|
|
|
RegisterDialogClasses(hInstance);
|
|
|
|
|
|
|
|
hWnd = InitInstance(hInstance, nShowCmd);
|
|
|
|
|
|
|
|
hDlg = CreateDialog(hInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE), NULL, ScreenSaverConfigureDialog);
|
|
|
|
ShowWindow(hDlg, SW_SHOW);
|
|
|
|
UpdateWindow(hDlg);
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if (GetMessage(&msg, NULL, 0, 0) <= 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|