2025-04-27 07:49:33 -04:00

480 lines
14 KiB
C

#define DBLBUFFER 1
#define USE_COLOR_INDEX 1
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <ptypes32.h>
#include <pwin32.h>
long WndProc ( HWND hwnd, UINT message, DWORD wParam, LONG lParam );
void DoGlStuff( HWND hWnd, HDC hDc );
HGLRC hrcInitGL(HWND hwnd, HDC hdc);
void vCleanupGL(HGLRC hrc);
#include <GL\gl.h>
#define TERMINATE DbgPrint("%s (%d)\n", __FILE__, __LINE__), ExitProcess(0)
#define WINDSIZEX(Rect) (Rect.right - Rect.left)
#define WINDSIZEY(Rect) (Rect.bottom - Rect.top)
// Default Logical Palette indexes
#define BLACK_INDEX 0
#define WHITE_INDEX 19
#define RED_INDEX 13
#define GREEN_INDEX 14
#define BLUE_INDEX 16
#define YELLOW_INDEX 15
#define MAGENTA_INDEX 17
#define CYAN_INDEX 18
// Global variables defining current position and orientation.
GLfloat AngleX = 0.0;
GLfloat AngleY = 0.0;
GLfloat AngleZ = 0.0;
GLfloat OffsetX = 0.0;
GLfloat OffsetY = 0.0;
GLfloat OffsetZ = -3.0;
HGLRC ghrc = (HGLRC) 0;
#ifdef DBLBUFFER
HDC ghdcMem;
HBITMAP ghbmBackBuffer, ghbmOld;
#endif
int WINAPI
WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
static char szAppName[] = "GL Cube";
HWND hwnd;
MSG msg;
RECT Rect;
WNDCLASS wndclass;
if ( !hPrevInstance )
{
//wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
RegisterClass(&wndclass);
}
/*
* Make the windows a reasonable size and pick a
* position for it.
*/
Rect.left = 100;
Rect.top = 100;
Rect.right = 200;
Rect.bottom = 200;
AdjustWindowRect( &Rect, WS_OVERLAPPEDWINDOW, FALSE );
hwnd = CreateWindow ( szAppName, // window class name
"GL Cube", // window caption
WS_OVERLAPPEDWINDOW, // window style
Rect.left, // initial x position
Rect.top, // initial y position
WINDSIZEX(Rect), // initial x size
WINDSIZEY(Rect), // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL // creation parameter
);
ShowWindow( hwnd, nCmdShow );
UpdateWindow( hwnd );
while ( GetMessage( &msg, NULL, 0, 0 ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return( msg.wParam );
}
long
WndProc ( HWND hWnd,
UINT message,
DWORD wParam,
LONG lParam
)
{
HDC hDc;
PAINTSTRUCT ps;
BOOL bValidKey = TRUE;
switch ( message )
{
case WM_PAINT:
hDc = BeginPaint( hWnd, &ps );
if (ghrc == (HGLRC) 0)
ghrc = hrcInitGL(hWnd, hDc);
DoGlStuff( hWnd, hDc );
EndPaint( hWnd, &ps );
return(0);
case WM_CHAR:
switch(wParam)
{
case 'u':
case 'U':
AngleX += 10.0;
AngleX = (AngleX > 360.0) ? 0.0 : AngleX;
break;
case 'j':
case 'J':
AngleX -= 10.0;
AngleX = (AngleX < 0.0) ? 360.0 : AngleX;
break;
case 'i':
case 'I':
AngleY += 10.0;
AngleY = (AngleY > 360.0) ? 0.0 : AngleY;
break;
case 'k':
case 'K':
AngleY -= 10.0;
AngleY = (AngleY < 0.0) ? 360.0 : AngleY;
break;
case 'o':
case 'O':
AngleZ += 10.0;
AngleZ = (AngleZ > 360.0) ? 0.0 : AngleZ;
break;
case 'l':
case 'L':
AngleZ -= 10.0;
AngleZ = (AngleZ < 0.0) ? 360.0 : AngleZ;
break;
case 'd':
case 'D':
OffsetX += 0.2;
break;
case 'a':
case 'A':
OffsetX -= 0.2;
break;
// !!! Note: currently the coordinate system is upside down, so
// !!! so up and down are reversed.
case 's':
case 'S':
OffsetY += 0.2;
break;
case 'w':
case 'W':
OffsetY -= 0.2;
break;
case 'q':
case 'Q':
OffsetZ += 0.2;
break;
case 'e':
case 'E':
OffsetZ -= 0.2;
break;
default:
bValidKey = FALSE;
}
if (bValidKey)
{
hDc = GetDC(hWnd);
if (ghrc == (HGLRC) 0)
ghrc = hrcInitGL(hWnd, hDc);
DoGlStuff( hWnd, hDc );
ReleaseDC(hWnd, hDc);
}
return 0;
case WM_DESTROY:
vCleanupGL(ghrc);
PostQuitMessage( 0 );
return( 0 );
}
return( DefWindowProc( hWnd, message, wParam, lParam ) );
}
HGLRC hrcInitGL(HWND hwnd, HDC hdc)
{
RECT Rect;
HGLRC hrc;
int iWidth, iHeight;
#if !USE_COLOR_INDEX
static GLfloat ClearColor[] = {
(GLfloat)0.0, // Red
(GLfloat)0.0, // Green
(GLfloat)0.0, // Blue
(GLfloat)1.0 // Alpha
};
#endif
/* Get the size of the client area */
GetClientRect( hwnd, &Rect );
iWidth = Rect.right-Rect.left;
iHeight = Rect.bottom-Rect.top;
/* Create a Rendering Context */
#if DBLBUFFER
ghdcMem = CreateCompatibleDC(hdc);
SelectObject(ghdcMem, GetStockObject(DEFAULT_PALETTE));
ghbmBackBuffer = CreateCompatibleBitmap(hdc, iWidth, iHeight);
ghbmOld = SelectObject(ghdcMem, ghbmBackBuffer);
//!!! [GilmanW] OpenGL hack !!!
//!!!
//!!! For some reason we need to prepare the memory DC. GL
//!!! drawing seems limited to the area drawn to by GDI calls.
//!!! By BitBlt'ing the entire memory DC, the whole thing is
//!!! is available to GL.
//!!!
//!!! There must be something we need to update on the server
//!!! side so that this is not necessary.
BitBlt(ghdcMem, 0, 0, iWidth, iHeight, NULL, 0, 0, BLACKNESS);
hrc = wglCreateContext( ghdcMem );
#else
hrc = wglCreateContext( hdc );
#endif
/* Make it Current */
#if DBLBUFFER
wglMakeCurrent( ghdcMem, hrc );
#else
wglMakeCurrent( hdc, hrc );
#endif
// !!! Note: currently the coordinate system is upside down, so we
// !!! need to reverse the default "front face" definition.
glFrontFace(GL_CW);
/* Set the clear color */
#if USE_COLOR_INDEX
glClearIndex(BLACK_INDEX);
#else
glClearColor( ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3] );
#endif
/* Turn off dithering */
glDisable(GL_DITHER);
/* Turn on z-buffer */
glEnable(GL_DEPTH_TEST);
return hrc;
}
void
vCleanupGL(hrc)
{
/* Destroy our context */
wglDeleteContext( hrc );
#if DBLBUFFER
DeleteObject(SelectObject(ghdcMem, ghbmOld));
DeleteDC(ghdcMem);
#endif
}
void
DoGlStuff( HWND hWnd, HDC hDc )
{
RECT Rect;
HGLRC hRc;
#if !USE_COLOR_INDEX
static GLfloat Cyan[] = {
(GLfloat)0.0, // Read
(GLfloat)0.666, // Green
(GLfloat)0.666, // Blue
(GLfloat)1.0 // Alpha
};
static GLfloat Yellow[] = {
(GLfloat)0.666, // Red
(GLfloat)0.666, // Green
(GLfloat)0.0, // Blue
(GLfloat)1.0 // Alpha
};
static GLfloat Magenta[] = {
(GLfloat)0.666, // Red
(GLfloat)0.0, // Green
(GLfloat)0.666, // Blue
(GLfloat)1.0 // Alpha
};
static GLfloat Red[] = {
(GLfloat)1.0, // Red
(GLfloat)0.0, // Green
(GLfloat)0.0, // Blue
(GLfloat)1.0 // Alpha
};
static GLfloat Green[] = {
(GLfloat)0.0, // Red
(GLfloat)1.0, // Green
(GLfloat)0.0, // Blue
(GLfloat)1.0 // Alpha
};
static GLfloat Blue[] = {
(GLfloat)0.0, // Red
(GLfloat)0.0, // Green
(GLfloat)1.0, // Blue
(GLfloat)1.0 // Alpha
};
#endif
/* Get the size of the client area */
GetClientRect( hWnd, &Rect );
/* Set up the projection matrix */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(OffsetX, OffsetY, OffsetZ);
glRotatef(AngleX, 1.0, 0.0, 0.0);
glRotatef(AngleY, 0.0, 1.0, 0.0);
glRotatef(AngleZ, 0.0, 0.0, 1.0);
glViewport(0, 0, WINDSIZEX(Rect), WINDSIZEY(Rect));
/* Clear the color buffer */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
/* Draw the cube */
glBegin(GL_QUADS);
#if USE_COLOR_INDEX
glIndexi(BLUE_INDEX);
#else
glColor4fv( Blue );
#endif
glVertex3f( (GLfloat) 0.7, (GLfloat) 0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) -0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) -0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) 0.7, (GLfloat) -0.7);
#if USE_COLOR_INDEX
glIndexi(GREEN_INDEX);
#else
glColor4fv( Green );
#endif
glVertex3f( (GLfloat) 0.7, (GLfloat) 0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) -0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) -0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) 0.7, (GLfloat) -0.7);
#if USE_COLOR_INDEX
glIndexi(RED_INDEX);
#else
glColor4fv( Red );
#endif
glVertex3f( (GLfloat) -0.7, (GLfloat) 0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) -0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) -0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) 0.7, (GLfloat) 0.7);
#if USE_COLOR_INDEX
glIndexi(CYAN_INDEX);
#else
glColor4fv( Cyan );
#endif
glVertex3f( (GLfloat) -0.7, (GLfloat) 0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) -0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) -0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) 0.7, (GLfloat) 0.7);
#if USE_COLOR_INDEX
glIndexi(YELLOW_INDEX);
#else
glColor4fv( Yellow );
#endif
glVertex3f( (GLfloat) 0.7, (GLfloat) 0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) 0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) 0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) 0.7, (GLfloat) 0.7);
#if USE_COLOR_INDEX
glIndexi(MAGENTA_INDEX);
#else
glColor4fv( Magenta );
#endif
glVertex3f( (GLfloat) 0.7, (GLfloat) -0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) -0.7, (GLfloat) 0.7);
glVertex3f( (GLfloat) -0.7, (GLfloat) -0.7, (GLfloat) -0.7);
glVertex3f( (GLfloat) 0.7, (GLfloat) -0.7, (GLfloat) -0.7);
glEnd();
glFlush();
#if DBLBUFFER
BitBlt(hDc, 0, 0, Rect.right-Rect.left, Rect.bottom-Rect.top, ghdcMem, 0, 0, SRCCOPY);
GdiFlush();
#endif
}