Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

621 lines
15 KiB

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <commdlg.h>
#include <ptypes32.h>
#include <pwin32.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <sys\types.h>
#include <sys\timeb.h>
#include <GL/glaux.h>
#include "tk.h"
#include "sscommon.h"
#include "trackbal.h"
static void Draw(void);
static void DrawAuto(void);
static void Init(void);
static void InitLighting(void);
static void Reshape(int, int);
static void SetModelView( void );
static GLenum Key(int key, GLenum mask);
static int GetStringExtent( char *string, POINTFLOAT *extent );
static void CalcStringMetrics( char *string );
static void Init(void);
static void InitLighting(void);
static void Reshape(int, int);
static GLenum Key(int key, GLenum mask);
VOID Arg( LPSTR );
// Global variables
GLuint dlFont, dpFont;
GLint firstGlyph;
GLint Width = 300, Height = 300;
POINTFLOAT strSize;
int strLen;
GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
GLdouble zTrans = -200.0;
GLfloat extrusion;
GLenum doubleBuffer = GL_TRUE;
GLenum bLighting = GL_TRUE;
GLenum fontStyle = WGL_FONT_POLYGONS;
LPGLYPHMETRICSFLOAT lpgmf;
// output from tesselator always ccw
GLenum orientation = GL_CCW;
char *texFileName = 0;
GLint matIndex = 1;
BOOL bAutoRotate = TRUE;
BOOL bCullBack = TRUE;
BOOL bTwoSidedLighting = FALSE;
BOOL bInitTexture = TRUE;
BOOL bTexture = FALSE;
BOOL bAntialias = FALSE;
char singleChar[] = "A";
char string[] = "OpenGL!";
char *drawString = singleChar;
#if defined( TIME )
#undef TIME
#endif
typedef struct _timeb TIME;
enum {
TIMER_START = 0,
TIMER_STOP,
TIMER_TIMING,
TIMER_RESET
};
static int gTimerStatus = TIMER_RESET;
int WINAPI
WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
GLenum type;
Arg( lpCmdLine );
tkInitPosition( 0, 0, Width, Height );
type = TK_DEPTH16;
type |= TK_RGB;
type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
tkInitDisplayMode(type);
if (tkInitWindow("Fontal assault") == GL_FALSE) {
tkQuit();
}
Init();
tkExposeFunc( Reshape );
tkReshapeFunc( Reshape );
tkKeyDownFunc( Key );
tkMouseDownFunc( trackball_MouseDown );
tkMouseUpFunc( trackball_MouseUp );
trackball_Init( Width, Height );
if( bAutoRotate ) {
tkIdleFunc( DrawAuto );
tkDisplayFunc(0);
} else {
tkDisplayFunc(Draw);
}
tkExec();
return 1;
}
static GLenum Key(int key, GLenum mask)
{
switch (key) {
case TK_ESCAPE:
tkQuit();
case TK_LEFT:
yRot -= 5;
break;
case TK_RIGHT:
yRot += 5;
break;
case TK_UP:
xRot -= 5;
break;
case TK_DOWN:
xRot += 5;
break;
case TK_X:
zRot += 5;
break;
case TK_x:
zRot -= 5;
break;
case TK_Z:
zTrans -= strSize.y/10.0;
SetModelView();
break;
case TK_z:
zTrans += strSize.y/10.0;
SetModelView();
break;
case TK_l:
if( bLighting = !bLighting ) {
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
else
{
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
}
break;
case TK_m:
if( !bTexture ) {
if( ++matIndex > NUM_TEA_MATERIALS )
matIndex =0;
ss_SetMaterialIndex( matIndex );
}
break;
case TK_n:
singleChar[0] += 1;
break;
case TK_N:
singleChar[0] -= 1;
break;
#if 1
case TK_o:
orientation = (orientation == GL_CCW) ? GL_CW : GL_CCW;
glFrontFace( orientation );
break;
#else
case TK_o:
if( bAntialias = !bAntialias ) {
if( fontStyle == WGL_FONT_LINES ) {
glEnable( GL_LINE_SMOOTH );
glEnable( GL_BLEND );
} else {
glDisable( GL_DEPTH_TEST );
glEnable( GL_POLYGON_SMOOTH );
glEnable( GL_BLEND );
}
} else {
glDisable( GL_POLYGON_SMOOTH );
glDisable( GL_LINE_SMOOTH );
glDisable( GL_BLEND );
glEnable( GL_DEPTH_TEST );
}
break;
#endif
case TK_t:
bTexture = !bTexture;
if( bTexture ) {
ss_SetMaterialIndex( WHITE );
glEnable( GL_TEXTURE_2D );
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
} else {
ss_SetMaterialIndex( matIndex );
glDisable( GL_TEXTURE_2D );
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
}
break;
case TK_s:
// switch between wireframe and solid polygons
fontStyle = (fontStyle == WGL_FONT_LINES) ? WGL_FONT_POLYGONS :
WGL_FONT_LINES;
break;
case TK_c:
drawString = (drawString == singleChar) ? string : singleChar;
CalcStringMetrics( drawString );
// change viewing matrix based on string extent
Reshape( Width, Height );
//SetModelView();
break;
case TK_u:
// cUllface stuff
bCullBack = !bCullBack;
if( bCullBack ) {
glCullFace( GL_BACK );
glEnable( GL_CULL_FACE );
} else {
glDisable( GL_CULL_FACE );
}
break;
case TK_2:
bTwoSidedLighting = !bTwoSidedLighting;
if( bTwoSidedLighting ) {
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 1 );
} else {
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 0 );
}
break;
case TK_a:
// animate or not
bAutoRotate= !bAutoRotate;
if( bAutoRotate ) {
tkIdleFunc(DrawAuto);
tkDisplayFunc(0);
} else {
tkIdleFunc(0);
tkDisplayFunc(Draw);
}
break;
case TK_f :
switch( gTimerStatus ) {
case TIMER_START:
break;
case TIMER_STOP:
case TIMER_RESET:
gTimerStatus = TIMER_START;
break;
case TIMER_TIMING:
gTimerStatus = TIMER_STOP;
break;
default:
break;
}
break;
default:
return GL_FALSE;
}
return GL_TRUE;
}
static void InitLighting(void)
{
static float ambient[] = {0.1f, 0.1f, 0.1f, 1.0f};
static float diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
static float position[] = {0.0f, 0.0f, 150.0f, 0.0f};
static float back_mat_shininess[] = {50.0f};
static float back_mat_specular[] = {0.5f, 0.5f, 0.2f, 1.0f};
static float back_mat_diffuse[] = {1.0f, 0.0f, 0.0f, 1.0f};
static float lmodel_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
static float decal[] = {(GLfloat) GL_DECAL};
static float modulate[] = {(GLfloat) GL_MODULATE};
static float repeat[] = {(GLfloat) GL_REPEAT};
static float nearest[] = {(GLfloat) GL_NEAREST};
TK_RGBImageRec *image;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glFrontFace( orientation );
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
if( bLighting ) {
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
// override back material
glMaterialfv( GL_BACK, GL_AMBIENT, ambient );
glMaterialfv( GL_BACK, GL_DIFFUSE, back_mat_diffuse );
glMaterialfv( GL_BACK, GL_SPECULAR, back_mat_specular );
glMaterialfv( GL_BACK, GL_SHININESS, back_mat_shininess );
if( bTwoSidedLighting ) {
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 1 );
} else {
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 0 );
}
// set back face culling mode
if( bCullBack ) {
glCullFace( GL_BACK );
glEnable( GL_CULL_FACE );
} else {
glDisable( GL_CULL_FACE );
}
// Initialize materials from screen saver common lib
ss_InitMaterials();
matIndex = JADE;
ss_SetMaterialIndex( matIndex );
// do texturing preparations
if( bInitTexture ) {
//glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, modulate);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
if (texFileName) {
image = tkRGBImageLoad(texFileName);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, image->data);
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
if( bTexture ) {
glEnable( GL_TEXTURE_2D );
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
ss_SetMaterialIndex( WHITE );
}
}
}
void Init(void)
{
CHOOSEFONT cf;
LOGFONT lf;
HFONT hfont, hfontOld;
GLfloat chordal_deviation;
int numGlyphs=224;
HWND hwnd;
HDC hdc;
TIME baseTime;
TIME thisTime;
double elapsed;
char buf[100];
hdc = tkGetHDC();
hwnd = tkGetHWND();
// Create and select a font.
cf.lStructSize = sizeof(CHOOSEFONT);
cf.hwndOwner = hwnd;
cf.hDC = hdc;
cf.lpLogFont = &lf;
cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_TTONLY;
memset(&lf, 0, sizeof(LOGFONT));
lstrcpy(lf.lfFaceName, "Arial");
lf.lfHeight = 50;
ChooseFont(&cf);
// lf reflects user's final choices
hfont = CreateFontIndirect(&lf);
hfontOld = SelectObject(hdc, hfont);
// Generate a display list for font
dlFont = glGenLists(numGlyphs);
dpFont = glGenLists(numGlyphs);
chordal_deviation = 0.005f;
extrusion = 0.25f;
firstGlyph = 32;
lpgmf = (LPGLYPHMETRICSFLOAT) LocalAlloc( LMEM_FIXED, numGlyphs *
sizeof(GLYPHMETRICSFLOAT) );
wglUseFontOutlinesA(hdc, firstGlyph, numGlyphs, dlFont, chordal_deviation,
extrusion, WGL_FONT_LINES, lpgmf );
_ftime( &baseTime );
wglUseFontOutlinesA(hdc, firstGlyph, numGlyphs, dpFont, chordal_deviation,
extrusion, WGL_FONT_POLYGONS, NULL );
glFinish();
_ftime( &thisTime );
elapsed = thisTime.time + thisTime.millitm/1000.0 -
(baseTime.time + baseTime.millitm/1000.0);
sprintf( buf, "Setup time = %5.2f seconds", elapsed );
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)buf);
CalcStringMetrics( drawString );
/* Set the clear color */
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
// Initialize lighting
InitLighting();
// Blend func for AA
glBlendFunc( GL_SRC_ALPHA, GL_ONE );
}
static void Reshape( int width, int height )
{
static GLdouble zNear = 0.1, zFar = 1000.0, fovy = 90.0;
float aspect;
trackball_Resize( width, height );
/* Set up the projection matrix */
Width = width;
Height = height;
aspect = Height == 0 ? 1.0f : Width/(float)Height;
glViewport(0, 0, Width, Height );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
zFar = 10.0f * strSize.x;
gluPerspective(fovy, aspect, zNear, zFar );
glMatrixMode(GL_MODELVIEW);
SetModelView();
}
static void SetModelView( void )
{
glLoadIdentity();
#if 1
glTranslated( 0, 0, zTrans );
#else
/* this has side effect of flipping around viewpoint when pass through
origin
*/
gluLookAt( 0, 0, -zTrans,
0, 0, 0,
0, 1, 0 );
#endif
}
void CalcFrameRate( char *buf, struct _timeb baseTime, int frameCount ) {
static struct _timeb thisTime;
double elapsed, frameRate;
_ftime( &thisTime );
elapsed = thisTime.time + thisTime.millitm/1000.0 -
(baseTime.time + baseTime.millitm/1000.0);
if( elapsed == 0.0 )
sprintf( buf, "Frame rate = unknown" );
else {
frameRate = frameCount / elapsed;
sprintf( buf, "Frame rate = %4.1f fps", frameRate );
}
}
static void DrawAuto(void)
{
POINT pt;
float matRot[4][4];
static int frameCount = 0;
static struct _timeb baseTime;
char buf[1024];
HWND hwnd;
BOOL bTiming = TRUE;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if( fontStyle == WGL_FONT_LINES )
glListBase(dlFont-32);
else
glListBase(dpFont-32);
glPushMatrix();
trackball_CalcRotMatrix( matRot );
glMultMatrixf(&(matRot[0][0]));
// now draw text, centered in window
glTranslated( -strSize.x/2.0, -strSize.y/2.0, extrusion/2.0 );
glCallLists(strLen, GL_UNSIGNED_BYTE, (GLubyte *) drawString);
glPopMatrix();
glFlush();
if( doubleBuffer )
tkSwapBuffers();
hwnd = tkGetHWND();
switch( gTimerStatus ) {
case TIMER_START:
gTimerStatus = TIMER_TIMING;
frameCount = 0;
sprintf( buf, "Timing..." );
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)buf);
_ftime( &baseTime );
break;
case TIMER_STOP:
gTimerStatus = TIMER_RESET;
frameCount++;
CalcFrameRate( buf, baseTime, frameCount );
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)buf);
break;
case TIMER_TIMING:
frameCount++;
break;
case TIMER_RESET:
default:
break;
}
}
static void Draw(void)
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if( fontStyle == WGL_FONT_LINES )
glListBase(dlFont-32);
else
glListBase(dpFont-32);
glPushMatrix();
glRotatef( xRot, 1.0f, 0.0f, 0.0f );
glRotatef( yRot, 0.0f, 1.0f, 0.0f );
glRotatef( zRot, 0.0f, 0.0f, 1.0f );
// center the string in window
glTranslated( -strSize.x/2.0, -strSize.y/2.0, extrusion/2.0 );
glCallLists(strLen, GL_UNSIGNED_BYTE, (GLubyte *) drawString);
glPopMatrix();
glFlush();
if( doubleBuffer )
tkSwapBuffers();
}
static int GetStringExtent( char *string, POINTFLOAT *extent )
{
int len, strLen;
unsigned char *c;
GLYPHMETRICSFLOAT *pgmf;
extent->x = extent->y = 0.0f;
len = strLen = lstrlenA( string );
c = string;
for( ; strLen; strLen--, c++ ) {
if( *c < firstGlyph )
continue;
pgmf = &lpgmf[ *c - firstGlyph ];
extent->x += pgmf->gmfCellIncX;
if( pgmf->gmfBlackBoxY > extent->y )
extent->y = pgmf->gmfBlackBoxY;
}
return len;
}
static void CalcStringMetrics( char *string )
{
// get string size for window reshape
strLen = GetStringExtent( string, &strSize );
// set zTrans based on glyph extent
zTrans = - 3.0 * (strSize.y / 2.0f);
}
VOID Arg(LPSTR lpstr)
{
while (*lpstr && *lpstr != '-') lpstr++;
// only one arg for now (e.g.: -f 3.rgb)
lpstr++;
if( *lpstr++ == 'f' ) {
texFileName = ++lpstr;
}
}