windows-nt/Source/XPSP1/NT/multimedia/opengl/test/gldd/single/vtex.c
2020-09-26 16:20:57 +08:00

1149 lines
22 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#include <vfw.h>
#include <gldd.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#define PI 3.14159265358979323846
#define NLETTERS 64
#define FIRST_LETTER '@'
#define NOBJS 6
GLenum doubleBuffer;
GLenum videoMemory;
GLenum noSwap;
GLenum noClear;
GLenum fullScreen;
GLenum useMcd;
GLenum modeX;
GLenum stretch;
GLenum paletted;
GLenum timings;
GLenum spin;
GLenum updateMovie = GL_TRUE;
GLenum linearFilter = GL_FALSE;
int fullWidth, fullHeight, fullDepth;
int winWidth, winHeight;
int texWidth, texHeight;
int movX, movY;
int movWidth, movHeight;
GLuint clearBits;
DWORD ticks;
int frames;
GLint letters;
GLYPHMETRICSFLOAT letterMetrics[NLETTERS];
double xrot, yrot;
GLDDWINDOW gwMain = NULL;
PFNGLCOLORTABLEEXTPROC pfnColorTableEXT;
PFNGLCOLORSUBTABLEEXTPROC pfnColorSubTableEXT;
LPDIRECTDRAWSURFACE pddsTex;
DDSURFACEDESC ddsdTex;
char *aviFileName = "d:\\winnt\\clock.avi";
PAVISTREAM aviStream;
long aviLength;
long curFrame;
PGETFRAME aviGetFrame;
BITMAPINFO *pbmiMovie;
typedef struct _Object
{
void (*build_fn)(void);
GLenum canCull;
GLenum needsZ;
GLint dlist;
} Object;
int objIdx = 0;
float c[6][4][3] = {
{
{
1.0f, 1.0f, -1.0f
},
{
-1.0f, 1.0f, -1.0f
},
{
-1.0f, -1.0f, -1.0f
},
{
1.0f, -1.0f, -1.0f
}
},
{
{
1.0f, 1.0f, 1.0f
},
{
1.0f, 1.0f, -1.0f
},
{
1.0f, -1.0f, -1.0f
},
{
1.0f, -1.0f, 1.0f
}
},
{
{
-1.0f, 1.0f, 1.0f
},
{
1.0f, 1.0f, 1.0f
},
{
1.0f, -1.0f, 1.0f
},
{
-1.0f, -1.0f, 1.0f
}
},
{
{
-1.0f, 1.0f, -1.0f
},
{
-1.0f, 1.0f, 1.0f
},
{
-1.0f, -1.0f, 1.0f
},
{
-1.0f, -1.0f, -1.0f
}
},
{
{
-1.0f, 1.0f, 1.0f
},
{
-1.0f, 1.0f, -1.0f
},
{
1.0f, 1.0f, -1.0f
},
{
1.0f, 1.0f, 1.0f
}
},
{
{
-1.0f, -1.0f, -1.0f
},
{
-1.0f, -1.0f, 1.0f
},
{
1.0f, -1.0f, 1.0f
},
{
1.0f, -1.0f, -1.0f
}
}
};
float n[6][3] = {
{
0.0f, 0.0f, -1.0f
},
{
1.0f, 0.0f, 0.0f
},
{
0.0f, 0.0f, 1.0f
},
{
-1.0f, 0.0f, 0.0f
},
{
0.0f, 1.0f, 0.0f
},
{
0.0f, -1.0f, 0.0f
}
};
float t[6][4][2] = {
{
{
1.0f, 1.0f
},
{
-0.0f, 1.0f
},
{
-0.0f, -0.0f
},
{
1.0f, -0.0f
}
},
{
{
1.0f, 1.0f
},
{
-0.0f, 1.0f
},
{
-0.0f, -0.0f
},
{
1.0f, -0.0f
}
},
{
{
-0.0f, 1.0f
},
{
1.0f, 1.0f
},
{
1.0f, -0.0f
},
{
-0.0f, -0.0f
}
},
{
{
1.0f, 1.0f
},
{
-0.0f, 1.0f
},
{
-0.0f, -0.0f
},
{
1.0f, -0.0f
}
},
{
{
1.0f, 1.0f
},
{
-0.0f, 1.0f
},
{
-0.0f, -0.0f
},
{
1.0f, -0.0f
}
},
{
{
1.0f, 1.0f
},
{
-0.0f, 1.0f
},
{
-0.0f, -0.0f
},
{
1.0f, -0.0f
}
},
};
void BuildSphere(void)
{
GLUquadricObj *quadObj;
quadObj = gluNewQuadric ();
gluQuadricDrawStyle (quadObj, GLU_FILL);
gluQuadricNormals (quadObj, GLU_SMOOTH);
gluQuadricTexture (quadObj, GL_TRUE);
gluSphere (quadObj, 1.0, 16, 16);
gluDeleteQuadric(quadObj);
}
void BuildCube(void)
{
GLint i;
for (i = 0; i < 6; i++)
{
glBegin(GL_POLYGON);
glNormal3fv(n[i]); glTexCoord2fv(t[i][0]); glVertex3fv(c[i][0]);
glNormal3fv(n[i]); glTexCoord2fv(t[i][3]); glVertex3fv(c[i][3]);
glNormal3fv(n[i]); glTexCoord2fv(t[i][2]); glVertex3fv(c[i][2]);
glNormal3fv(n[i]); glTexCoord2fv(t[i][1]); glVertex3fv(c[i][1]);
glEnd();
}
}
void BuildCylinder(void)
{
GLUquadricObj *quadObj;
glPushMatrix ();
glRotatef ((GLfloat)90.0, (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0.0);
glTranslatef ((GLfloat)0.0, (GLfloat)0.0, (GLfloat)-1.0);
quadObj = gluNewQuadric ();
gluQuadricDrawStyle (quadObj, GLU_FILL);
gluQuadricTexture (quadObj, GL_TRUE);
gluCylinder (quadObj, 1.0, 1.0, 1.5, 20, 2);
glPopMatrix ();
gluDeleteQuadric(quadObj);
}
void BuildCone(void)
{
GLUquadricObj *quadObj;
quadObj = gluNewQuadric ();
gluQuadricDrawStyle (quadObj, GLU_FILL);
gluQuadricTexture (quadObj, GL_TRUE);
gluCylinder (quadObj, 1.0, 0.0, 1.5, 20, 2);
gluDeleteQuadric(quadObj);
}
void BuildTeapot(void)
{
auxSolidTeapot(1.0);
}
#define STRING "OpenGL"
void BuildString(void)
{
char *str;
int i, l;
float wd, ht;
GLfloat fv4[4];
str = STRING;
l = strlen(str);
wd = 0.0f;
for (i = 0; i < l-1; i++)
{
wd += letterMetrics[str[i]-FIRST_LETTER].gmfCellIncX;
}
wd += letterMetrics[str[i]-FIRST_LETTER].gmfBlackBoxX;
ht = letterMetrics[str[0]-FIRST_LETTER].gmfBlackBoxY;
glPushMatrix();
glScalef(1.0f, 2.0f, 1.0f);
glTranslatef(-wd/2.0f, -ht/2.0f, 0.0f);
fv4[0] = 1.0f/wd;
fv4[1] = 0.0f;
fv4[2] = 0.0f;
fv4[3] = 0.0f;
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGenfv(GL_S, GL_EYE_PLANE, fv4 );
fv4[0] = 0.0f;
fv4[1] = -1.0f/ht;
fv4[2] = 0.0f;
fv4[3] = 0.0f;
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGenfv(GL_T, GL_EYE_PLANE, fv4 );
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glListBase(letters-FIRST_LETTER);
glCallLists(l, GL_UNSIGNED_BYTE, str);
glListBase(0);
glPopMatrix();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
}
Object objects[NOBJS] =
{
BuildCube, GL_TRUE, GL_FALSE, 0,
BuildSphere, GL_TRUE, GL_FALSE, 0,
BuildCylinder, GL_FALSE, GL_TRUE, 0,
BuildCone, GL_FALSE, GL_TRUE, 0,
BuildTeapot, GL_FALSE, GL_TRUE, 0,
BuildString, GL_TRUE, GL_TRUE, 0,
};
void BuildLists(void)
{
int i;
GLint base;
base = glGenLists(NOBJS);
for (i = 0; i < NOBJS; i++)
{
objects[i].dlist = base+i;
glNewList(objects[i].dlist, GL_COMPILE);
objects[i].build_fn();
glEndList();
}
}
void Quit(char *fmt, ...)
{
va_list args;
if (fmt != NULL)
{
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
if (aviGetFrame != NULL)
{
AVIStreamGetFrameClose(aviGetFrame);
}
if (aviStream != NULL)
{
AVIStreamRelease(aviStream);
AVIFileExit();
}
if (gwMain != NULL)
{
glddDestroyWindow(gwMain);
}
exit(1);
}
void Draw(void)
{
DWORD fticks;
fticks = GetTickCount();
glClear(clearBits);
glLoadIdentity();
glRotated(xrot, 1.0, 0.0, 0.0);
glRotated(yrot, 0.0, 1.0, 0.0);
glCallList(objects[objIdx].dlist);
glFlush();
if (doubleBuffer && !noSwap)
{
glddSwapBuffers(gwMain);
}
ticks += GetTickCount()-fticks;
frames++;
if (timings && ticks > 1000)
{
printf("%d frames in %d ticks, %.3lf f/s\n", frames, ticks,
(double)frames*1000.0/ticks);
frames = 0;
ticks = 0;
}
}
void *UpdateBmi(BITMAPINFO *pbmi)
{
if (pbmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
{
Quit("Unknown stream format data\n");
}
memcpy(pbmiMovie->bmiColors, pbmi->bmiColors, 256*sizeof(RGBQUAD));
// Return pointer to data after BITMAPINFO
return pbmi->bmiColors+256;
}
void FrameToTex(long frame)
{
HDC hdc;
HRESULT hr;
LPVOID pvFrame, pvData;
pvFrame = AVIStreamGetFrame(aviGetFrame, frame);
if (pvFrame == NULL)
{
Quit("AVIStreamGetFrame failed\n");
}
// Skip past BITMAPINFO at start of frame.
// If it becomes interesting to support palette changes per frame
// this should call UpdateBmi
#if 0
pvData = (LPVOID)((BYTE *)pvFrame+sizeof(BITMAPINFO)+255*sizeof(RGBQUAD));
#else
pvData = UpdateBmi(pvFrame);
if (paletted)
{
pfnColorSubTableEXT(GL_TEXTURE_2D, 0, 256, GL_BGRA_EXT,
GL_UNSIGNED_BYTE, pbmiMovie->bmiColors);
}
#endif
if (stretch)
{
hr = pddsTex->lpVtbl->GetDC(pddsTex, &hdc);
if (hr != DD_OK)
{
Quit("Stretch GetDC failed, 0x%08lX\n", hr);
}
StretchDIBits(hdc, 0, 0, texWidth, texHeight,
0, 0, movWidth, movHeight, pvData, pbmiMovie,
DIB_RGB_COLORS, SRCCOPY);
pddsTex->lpVtbl->ReleaseDC(pddsTex, hdc);
}
else if (!paletted)
{
hr = pddsTex->lpVtbl->GetDC(pddsTex, &hdc);
if (hr != DD_OK)
{
Quit("Set GetDC failed, 0x%08lX\n", hr);
}
// The only AVI sources currently allowed are 8bpp so if the texture
// isn't paletted a conversion is necessary
SetDIBitsToDevice(hdc, movX, movY, movWidth, movHeight,
0, 0, 0, movHeight, pvData, pbmiMovie,
DIB_RGB_COLORS);
pddsTex->lpVtbl->ReleaseDC(pddsTex, hdc);
}
else
{
UINT cbLine;
int y;
BYTE *pbSrc, *pbDst;
HRESULT hr;
hr = pddsTex->lpVtbl->Lock(pddsTex, NULL, &ddsdTex,
DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,
NULL);
if (hr != S_OK)
{
Quit("Unable to lock texture, 0x%08lX\n", hr);
}
cbLine = (movWidth+3) & ~3;
pbSrc = (BYTE *)pvData;
pbDst = (BYTE *)ddsdTex.lpSurface+ddsdTex.lPitch*movY+movX;
#if 1
for (y = 0; y < movHeight; y++)
{
memcpy(pbDst, pbSrc, movWidth);
pbSrc += cbLine;
pbDst += ddsdTex.lPitch;
}
#else
for (y = 0; y < movHeight; y++)
{
memset(pbDst, y*256/movHeight, movWidth);
pbSrc += cbLine;
pbDst += ddsdTex.lPitch;
}
#endif
pddsTex->lpVtbl->Unlock(pddsTex, ddsdTex.lpSurface);
}
}
void Animate(GLDDWINDOW gw)
{
if (updateMovie)
{
if (++curFrame == aviLength)
{
curFrame = 0;
}
FrameToTex(curFrame);
}
if (spin)
{
xrot += 2;
yrot += 3;
}
Draw();
}
void SetView(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)winWidth/winHeight, 0.1, 10);
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
}
void ToggleGl(GLenum state)
{
if (glIsEnabled(state))
{
glDisable(state);
}
else
{
glEnable(state);
}
}
void SetObject(int idx)
{
objIdx = idx;
clearBits = GL_COLOR_BUFFER_BIT;
if (objects[objIdx].canCull)
{
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
}
else
{
glDisable(GL_CULL_FACE);
}
if (objects[objIdx].needsZ)
{
clearBits |= GL_DEPTH_BUFFER_BIT;
glEnable(GL_DEPTH_TEST);
}
else
{
glDisable(GL_DEPTH_TEST);
}
}
void SetTexFilter(void)
{
GLenum filter;
filter = linearFilter ? GL_LINEAR : GL_NEAREST;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
}
void ClearTex(void)
{
DDBLTFX ddbltfx;
RECT drct;
HRESULT hr;
drct.left = 0;
drct.top = 0;
drct.right = texWidth;
drct.bottom = texHeight;
memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = 0;
hr = pddsTex->lpVtbl->Blt(pddsTex, &drct, NULL, NULL,
DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
if (hr != DD_OK)
{
Quit("Blt failed, 0x%08lX\n", hr);
}
}
void Key(UINT key)
{
switch(key)
{
case VK_ESCAPE:
Quit(NULL);
break;
case VK_SPACE:
spin = !spin;
break;
case 'D':
ToggleGl(GL_DITHER);
break;
case 'F':
linearFilter = !linearFilter;
SetTexFilter();
break;
case 'H':
stretch = !stretch;
break;
case 'M':
updateMovie = !updateMovie;
break;
case 'O':
if (++objIdx == NOBJS)
{
objIdx = 0;
}
SetObject(objIdx);
break;
case 'S':
spin = !spin;
break;
case 'T':
timings = !timings;
frames = 0;
ticks = 0;
break;
case 'X':
ToggleGl(GL_TEXTURE_2D);
break;
default:
break;
}
}
BOOL Message(GLDDWINDOW gw, HWND hwnd, UINT uiMsg, WPARAM wpm, LPARAM lpm,
LRESULT *plr)
{
switch(uiMsg)
{
case WM_KEYDOWN:
Key((UINT)wpm);
break;
case WM_SIZE:
winWidth = LOWORD(lpm);
winHeight = HIWORD(lpm);
SetView();
break;
default:
return FALSE;
}
*plr = 0;
return TRUE;
}
void GetStreamFormat(void)
{
HRESULT hr;
LONG fmtSize;
void *pvFmt;
hr = AVIStreamFormatSize(aviStream, 0, &fmtSize);
if (hr != S_OK)
{
Quit("AVIStreamFormatSize failed, 0x%08lX\n", hr);
}
pvFmt = malloc(fmtSize);
if (pvFmt == NULL)
{
Quit("Unable to allocate format buffer\n");
}
hr = AVIStreamReadFormat(aviStream, 0, pvFmt, &fmtSize);
if (hr != S_OK)
{
Quit("AVIStreamReadFormat failed, 0x%08lX\n", hr);
}
UpdateBmi((BITMAPINFO *)pvFmt);
free(pvFmt);
}
void OpenMovie(void)
{
HRESULT hr;
AVISTREAMINFO sinfo;
BITMAPINFOHEADER *pbmih;
AVIFileInit();
hr = AVIStreamOpenFromFile(&aviStream, aviFileName, streamtypeVIDEO,
0, OF_READ | OF_SHARE_DENY_WRITE, NULL);
if (hr != S_OK)
{
Quit("AVIStreamOpenFromFile failed, 0x%08lX\n", hr);
}
aviLength = AVIStreamLength(aviStream);
hr = AVIStreamInfo(aviStream, &sinfo, sizeof(sinfo));
if (hr != S_OK)
{
Quit("AVIStreamInfo failed, 0x%08lX\n", hr);
}
if (sinfo.dwFlags & AVISTREAMINFO_FORMATCHANGES)
{
printf("WARNING: Stream contains format changes, unhandled\n");
}
GetStreamFormat();
movWidth = sinfo.rcFrame.right-sinfo.rcFrame.left;
movHeight = sinfo.rcFrame.bottom-sinfo.rcFrame.top;
#if 1
printf("Movie '%s' is %d x %d\n", aviFileName, movWidth, movHeight);
#endif
#if 0
if ((movWidth & (movWidth-1)) != 0 ||
(movHeight & (movHeight-1)) != 0)
{
Quit("Movie must have frames that are a power of two in size, "
"movie is %d x %d\n", movWidth, movHeight);
}
#endif
pbmih = &pbmiMovie->bmiHeader;
memset(pbmih, 0, sizeof(BITMAPINFOHEADER));
pbmih->biSize = sizeof(BITMAPINFOHEADER);
pbmih->biWidth = movWidth;
pbmih->biHeight = movHeight;
pbmih->biPlanes = 1;
pbmih->biBitCount = 8;
pbmih->biCompression = BI_RGB;
aviGetFrame = AVIStreamGetFrameOpen(aviStream, pbmih);
if (aviGetFrame == NULL)
{
Quit("AVIStreamGetFrameOpen failed\n");
}
}
BOOL WINAPI texCallback(LPDDSURFACEDESC pddsd, LPVOID pv)
{
if ((paletted && pddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) ||
(!paletted && pddsd->ddpfPixelFormat.dwFlags == DDPF_RGB))
{
ddsdTex = *pddsd;
return FALSE;
}
else
{
return TRUE;
}
}
void CreateTex(int minWidth, int minHeight)
{
LPDIRECTDRAW pdd;
HRESULT hr;
texWidth = 1;
texHeight = 1;
while (texWidth < minWidth && texWidth < winWidth)
{
texWidth *= 2;
}
if (texWidth > winWidth)
{
texWidth /= 2;
}
while (texHeight < minHeight && texHeight < winHeight)
{
texHeight *= 2;
}
if (texHeight > winHeight)
{
texHeight /= 2;
}
if (!wglEnumTextureFormats(texCallback, NULL))
{
Quit("wglEnumTextureFormats failed, %d\n", GetLastError());
}
hr = DirectDrawCreate(NULL, &pdd, NULL);
if (hr != DD_OK)
{
Quit("DirectDrawCreate failed, 0x%08lX\n", hr);
}
hr = pdd->lpVtbl->SetCooperativeLevel(pdd, NULL, DDSCL_NORMAL);
if (hr != DD_OK)
{
Quit("SetCooperativeLevel failed, 0x%08lX\n", hr);
}
ddsdTex.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
ddsdTex.dwWidth = texWidth;
ddsdTex.dwHeight = texHeight;
ddsdTex.ddsCaps.dwCaps &= ~DDSCAPS_MIPMAP;
hr = pdd->lpVtbl->CreateSurface(pdd, &ddsdTex, &pddsTex, NULL);
if (hr != DD_OK)
{
Quit("Texture CreateSurface failed, 0x%08lX\n", hr);
}
ClearTex();
}
void Init(void)
{
HDC hdc, screen;
HFONT fnt;
pfnColorTableEXT = (PFNGLCOLORTABLEEXTPROC)
wglGetProcAddress("glColorTableEXT");
if (pfnColorTableEXT == NULL)
{
Quit("glColorTableEXT not supported\n");
}
pfnColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)
wglGetProcAddress("glColorSubTableEXT");
if (pfnColorSubTableEXT == NULL)
{
Quit("glColorSubTableEXT not supported\n");
}
pbmiMovie = (BITMAPINFO *)malloc(sizeof(BITMAPINFO)+255*sizeof(RGBQUAD));
if (pbmiMovie == NULL)
{
Quit("Unable to allocate pbmiMovie\n");
}
OpenMovie();
// Must come after movie is open so width and height are set
CreateTex(movWidth, movHeight);
movX = (texWidth-movWidth)/2;
movY = (texHeight-movHeight)/2;
wglBindDirectDrawTexture(pddsTex);
// Create texture palette if necessary
if (paletted)
{
pfnColorTableEXT(GL_TEXTURE_2D, GL_RGB, 256, GL_BGRA_EXT,
GL_UNSIGNED_BYTE, pbmiMovie->bmiColors);
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
linearFilter = GL_FALSE;
SetTexFilter();
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// Fill in initial movie frame
curFrame = 0;
FrameToTex(curFrame);
// Provide letters for objects to compose themselves from
screen = GetDC(NULL);
hdc = CreateCompatibleDC(screen);
if (hdc == NULL)
{
Quit("CreateCompatibleDC failed, %d\n", GetLastError());
}
fnt = CreateFont(72, 0, 0, 0, FW_HEAVY, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_TT_ONLY_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH |
TMPF_TRUETYPE | FF_DONTCARE, "Arial");
if (fnt == NULL)
{
Quit("CreateFont failed, %d\n", GetLastError());
}
SelectObject(hdc, fnt);
letters = glGenLists(NLETTERS);
if (!wglUseFontOutlines(hdc, FIRST_LETTER, NLETTERS, letters, 0.0f, 0.1f,
WGL_FONT_POLYGONS, letterMetrics))
{
Quit("wglUseFontOutlines failed, %d\n", GetLastError());
}
DeleteDC(hdc);
DeleteObject(fnt);
ReleaseDC(NULL, screen);
BuildLists();
SetObject(0);
xrot = 0.0;
yrot = 0.0;
SetView();
}
GLenum Args(int argc, char **argv)
{
GLint i;
winWidth = 320;
winHeight = 320;
doubleBuffer = GL_TRUE;
videoMemory = GL_FALSE;
noSwap = GL_FALSE;
noClear = GL_FALSE;
fullScreen = GL_FALSE;
fullWidth = 640;
fullHeight = 480;
fullDepth = 16;
useMcd = GL_FALSE;
modeX = GL_FALSE;
stretch = GL_TRUE;
paletted = GL_TRUE;
timings = GL_FALSE;
spin = GL_TRUE;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-sb") == 0) {
doubleBuffer = GL_FALSE;
} else if (strcmp(argv[i], "-db") == 0) {
doubleBuffer = GL_TRUE;
} else if (strcmp(argv[i], "-rgb") == 0) {
paletted = GL_FALSE;
} else if (strcmp(argv[i], "-stretch") == 0) {
stretch = GL_TRUE;
} else if (strcmp(argv[i], "-nostretch") == 0) {
stretch = GL_FALSE;
} else if (strcmp(argv[i], "-nospin") == 0) {
spin = GL_FALSE;
} else if (strcmp(argv[i], "-vm") == 0) {
videoMemory = GL_TRUE;
} else if (strcmp(argv[i], "-noswap") == 0) {
noSwap = GL_TRUE;
} else if (strcmp(argv[i], "-noclear") == 0) {
noClear = GL_TRUE;
} else if (strcmp(argv[i], "-full") == 0) {
fullScreen = GL_TRUE;
} else if (strcmp(argv[i], "-modex") == 0) {
modeX = GL_TRUE;
fullWidth = 320;
fullHeight = 240;
fullDepth = 8;
} else if (strcmp(argv[i], "-mcd") == 0) {
useMcd = GL_TRUE;
} else if (strcmp(argv[i], "-surf") == 0) {
if (i+2 >= argc ||
argv[i+1][0] == '-' ||
argv[i+2][0] == '-')
{
printf("-surf (No numbers).\n");
return GL_FALSE;
}
else
{
winWidth = atoi(argv[++i]);
winHeight = atoi(argv[++i]);
}
} else if (strcmp(argv[i], "-fdim") == 0) {
if (i+3 >= argc ||
argv[i+1][0] == '-' ||
argv[i+2][0] == '-' ||
argv[i+3][0] == '-')
{
printf("-fdim (No numbers).\n");
return GL_FALSE;
}
else
{
fullWidth = atoi(argv[++i]);
fullHeight = atoi(argv[++i]);
fullDepth = atoi(argv[++i]);
}
} else if (strcmp(argv[i], "-mov") == 0) {
if (i+1 >= argc ||
argv[i+1][0] == '-')
{
printf("-mov (No filename).\n");
return GL_FALSE;
}
else
{
aviFileName = argv[++i];
}
} else {
printf("%s (Bad option).\n", argv[i]);
return GL_FALSE;
}
}
return GL_TRUE;
}
void __cdecl main(int argc, char **argv)
{
DWORD dwFlags;
GLDDWINDOW gw;
if (Args(argc, argv) == GL_FALSE) {
exit(1);
}
dwFlags = GLDD_Z_BUFFER_16;
dwFlags |= doubleBuffer ? GLDD_BACK_BUFFER : 0;
dwFlags |= videoMemory ? GLDD_VIDEO_MEMORY : 0;
dwFlags |= useMcd ? GLDD_GENERIC_ACCELERATED : 0;
if (fullScreen)
{
dwFlags |= GLDD_FULL_SCREEN;
dwFlags |= modeX ? GLDD_USE_MODE_X : 0;
winWidth = fullWidth;
winHeight = fullHeight;
}
gw = glddCreateWindow("Video Texture", 10, 30, winWidth, winHeight,
fullDepth, dwFlags);
if (gw == NULL)
{
printf("glddCreateWindow failed with 0x%08lX\n", glddGetLastError());
exit(1);
}
gwMain = gw;
glddMakeCurrent(gw);
Init();
glddIdleCallback(gw, Animate);
glddMessageCallback(gw, Message);
glddRun(gw);
Quit(NULL);
}