windows-nt/Source/XPSP1/NT/multimedia/opengl/pmesh/demo/viewer.cxx
2020-09-26 16:20:57 +08:00

534 lines
15 KiB
C++

/************************************************************************/
/******************** Includes ******************************************/
/************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "viewer.h"
//IID_IPMesh {0C154611-3C2C-11d0-A459-00AA00BDD621}
__declspec(dllexport) DEFINE_GUID(IID_IPMesh,
0xc154611, 0x3c2c, 0x11d0, 0xa4, 0x59, 0x0, 0xaa, 0x0, 0xbd, 0xd6, 0x21);
//IID_IPMeshGL {0C154612-3C2C-11d0-A459-00AA00BDD621}
__declspec(dllexport) DEFINE_GUID(IID_IPMeshGL,
0xc154612, 0x3c2c, 0x11d0, 0xa4, 0x59, 0x0, 0xaa, 0x0, 0xbd, 0xd6, 0x21);
/************************************************************************/
/******************** Globals *******************************************/
/************************************************************************/
LPPMESH pPMesh;
LPPMESHGL pPMeshGL;
DWORD minV=0, maxV=0;
BOOL pm_ready = FALSE;
float pm_lod_level;
float old_lod;
float curquat[4], lastquat[4];
WININFO g_wi;
SCENE g_s;
int OldScrollPos;
/** OpenGL state **/
BOOL renderDoubleBuffer = TRUE;
int colormode = TRUE;
enum NormalMode normal_mode = PER_VERTEX;
BOOL linesmooth_enable = FALSE;
BOOL polysmooth_enable = FALSE;
GLenum cull_face = GL_FRONT;
GLenum front_face = GL_CCW;
BOOL cull_enable = FALSE;
BOOL depth_mode = TRUE;
BOOL fog_enable = FALSE;
BOOL clip_enable = FALSE;
GLenum shade_model = GL_FLAT;
BOOL polystipple_enable = FALSE;
BOOL linestipple_enable = FALSE;
int matrixmode;
enum TransformType tx_type = ORTHO_PROJECTION;
BOOL dither_enable = TRUE;
BOOL blend_enable = FALSE;
GLenum sblendfunc = GL_SRC_ALPHA;
GLenum dblendfunc = GL_ONE_MINUS_SRC_ALPHA;
BOOL filled_mode = TRUE;
BOOL edge_mode = FALSE;
BOOL displaylist_mode = FALSE;
GLfloat linewidth = 1.0;
GLenum polymodefront = GL_FILL;
GLenum polymodeback = GL_FILL;
BOOL mblur_enable = FALSE;
GLfloat blur_amount = 0.0;
BOOL fsantimode = FALSE;
BOOL fsaredraw = 0;
GLfloat fsajitter = 0.0F;
int cmface = GL_FRONT;
int cmmode = GL_AMBIENT_AND_DIFFUSE;
int cmenable = FALSE;
BOOL tex_enable = FALSE; //************
BOOL texgen_enable = FALSE;
GLenum texenvmode = GL_DECAL;
long tex_pack = 0;
int tex_row = 0;
int tex_col = 0;
int tex_index = 0;
int tex_xpix = 0;
int tex_ypix = 0;
int tex_numpix = 0;
int tex_numcomp = 0;
GLfloat tex_minfilter = GL_NEAREST;
GLfloat tex_magfilter = GL_NEAREST;
unsigned char *Image = NULL;
unsigned char *TextureImage = NULL;
BOOL light_enable = TRUE;
int numInfLights = 0;
int numLocalLights = 0;
BOOL lighttwoside = FALSE;
GLfloat localviewmode = 0.0F;
/************************************************************************/
/******************* Function Prototypes ********************************/
/************************************************************************/
void CustomizeWnd (HINSTANCE, LPWININFO);
LONG APIENTRY MyWndProc(HWND, UINT, UINT, LONG);
void SubclassWindow (HWND, WNDPROC);
void UpdateWinTitle (HWND);
void myHScrollFunc (int);
BOOL read_pm(char *);
void InitScene (LPSCENE);
/************************************************************************/
/******************* Code ***********************************************/
/************************************************************************/
void myHScrollFunc (int i)
{
OldScrollPos = g_s.scroll_pos;
g_s.scroll_pos = i;
if (g_s.scroll_pos != OldScrollPos)
{
if (pm_ready)
{
HRESULT hr;
old_lod = pm_lod_level;
pm_lod_level = (float) (g_s.scroll_pos/1000.0);
DWORD nv = minV + DWORD((maxV - minV + 1) * pm_lod_level *
0.999999f);
hr = pPMesh->SetNumVertices(nv);
if (hr != S_OK)
MessageBox (NULL, "SetNumVertices failed", "Error", MB_OK);
DoGlStuff ();
}
UpdateWinTitle (g_wi.hWnd);
}
}
void InitScene (LPSCENE lps)
{
lps->hither = DEFHITHER;
lps->yon = DEFYONDER;
lps->scale = 1.0;
lps->angle = 0.0;
lps->scroll_pos = 0; //auxGetScrollPos (AUX_HSCROLL);
lps->from[0] /*X*/ = 0.0;
lps->from[1] /*Y*/ = 0.0;
lps->from[2] /*Z*/ = 5.0;
lps->to[0] /*X*/ = 0.0;
lps->to[1] /*Y*/ = 0.0;
lps->to[2] /*Z*/ = 0.0;
lps->up[0] /*X*/ = 0.0;
lps->up[1] /*Y*/ = 1.0;
lps->up[2] /*Z*/ = 0.0;
lps->trans[0] /*X*/ = 0.0;
lps->trans[1] /*Y*/ = 0.0;
lps->trans[2] /*Z*/ = 0.0;
lps->fov = 45.0;
lps->aspect_ratio = 1.0;
lps->zoom = 1.0;
}
void InitPM (void)
{
HRESULT hr;
hr = CreatePMeshGL(IID_IPMesh, (void**)&pPMesh, NULL, 0);
if (hr == S_OK)
{
hr = pPMesh->QueryInterface(IID_IPMeshGL, (LPVOID*)&pPMeshGL);
if (hr != S_OK)
MessageBox (NULL, "QI for IID_IPMeshGL failed", "Error",
MB_OK);
}
else
{
MessageBox (NULL, "CreatePMeshGL failed", "Error", MB_OK);
}
}
//*------------------------------------------------------------------------
//| WinMain:
//| Parameters:
//| hInstance - Handle to current Data Segment
//| hPrevInstance - Always NULL in Win32
//| lpszCmdLine - Pointer to command line info
//| nCmdShow - Integer value specifying how to start app.,
//| (Iconic [7] or Normal [1,5])
//*------------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
int nReturn = 0;
g_wi.wSize.cx = WIN_WIDTH;
g_wi.wSize.cy = WIN_HEIGHT;
auxInitDisplayMode (AUX_DEPTH | AUX_DOUBLE | AUX_RGB | AUX_HSCROLL);
auxInitPosition (0, 0, WIN_WIDTH, WIN_HEIGHT);
auxInitWindow ("Test");
CustomizeWnd(hInstance, &g_wi);
InitScene (&g_s);
InitPM ();
InitGL();
auxReshapeFunc(SetViewWrap);
auxIdleFunc(spin);
auxHScrollFunc(myHScrollFunc);
auxSetScrollPos (AUX_HSCROLL, auxGetScrollMin(AUX_HSCROLL));
auxKeyFunc( AUX_UP, Key_up );
auxKeyFunc( AUX_DOWN, Key_down );
auxKeyFunc( AUX_i, Key_i ); //Initial Position
auxKeyFunc( AUX_x, Key_x );
auxKeyFunc( AUX_X, Key_X );
auxKeyFunc( AUX_y, Key_y );
auxKeyFunc( AUX_Y, Key_Y );
auxKeyFunc( AUX_z, Key_z );
auxKeyFunc( AUX_Z, Key_Z );
//auxMouseFunc( AUX_LEFTBUTTON, AUX_MOUSEDOWN, trackball_MouseDown );
//auxMouseFunc( AUX_LEFTBUTTON, AUX_MOUSEUP, trackball_MouseUp );
//trackball_Init( g_wi.wSize.cx, g_wi.wSize.cy );
auxMainLoop(DoGlStuff);
return(0);
}
void CustomizeWnd(HINSTANCE hInstance, LPWININFO lpWI)
{
HWND hWnd;
if ((hWnd = auxGetHWND()) == NULL)
{
OutputDebugString("auxGetHWND() failed\n");
return;
}
lpWI->hWnd = hWnd;
SubclassWindow (hWnd, (WNDPROC) MyWndProc);
SendMessage(hWnd, WM_USER, 0L, 0L);
lpWI->hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(APPMENU));
SetMenu(hWnd, lpWI->hMenu);
DrawMenuBar(hWnd);
UpdateWinTitle (hWnd);
lpWI->rmouse_down = FALSE;
lpWI->rmouseX = 0;
lpWI->rmouseY = 0;
lpWI->lmouse_down = FALSE;
lpWI->lmouseX = 0;
lpWI->lmouseY = 0;
lpWI->wPosition.x = (int) 0;
lpWI->wPosition.y = (int) 0;
return;
}
/**************************************************************************\
* function: SubclassWindow
*
* input parameters:
* hwnd - window handle to be subclassed,
* SubclassWndProc - the new window procedure.
*
\**************************************************************************/
VOID SubclassWindow (HWND hwnd, WNDPROC SubclassWndProc)
{
LONG pfnOldProc;
pfnOldProc = GetWindowLong (hwnd, GWL_WNDPROC);
SetWindowLong (hwnd, GWL_USERDATA, (LONG) pfnOldProc);
SetWindowLong (hwnd, GWL_WNDPROC, (LONG) SubclassWndProc);
UpdateWinTitle (hwnd);
}
/**************************************************************************\
*
* function: MyWndProc
*
* input parameters: normal window procedure parameters.
*
\**************************************************************************/
LONG APIENTRY MyWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
WNDPROC pfnOldProc;
static UINT uiTmID = 0;
pfnOldProc = (WNDPROC) GetWindowLong (hwnd, GWL_USERDATA);
switch (message) {
case WM_INITMENUPOPUP:
EnableMenuItem (g_wi.hMenu, MENU_POINT, MF_GRAYED);
CheckMenuItem (g_wi.hMenu, MENU_WIREFRAME,
((edge_mode) ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_SOLID,
((filled_mode) ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_FLAT,
((shade_model == GL_FLAT)? MF_CHECKED:MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_GOURAUD,
((shade_model == GL_SMOOTH)? MF_CHECKED:MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_LIGHTING,
((light_enable)? MF_CHECKED:MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_DEPTH,
((depth_mode)? MF_CHECKED:MF_UNCHECKED));
if (!cull_enable)
{
EnableMenuItem (g_wi.hMenu, MENU_FRONTFACE, MF_GRAYED);
EnableMenuItem (g_wi.hMenu, MENU_BACKFACE, MF_GRAYED);
CheckMenuItem (g_wi.hMenu, MENU_CULL, MF_UNCHECKED);
}
else
{
EnableMenuItem (g_wi.hMenu, MENU_FRONTFACE, MF_ENABLED);
EnableMenuItem (g_wi.hMenu, MENU_BACKFACE, MF_ENABLED);
CheckMenuItem (g_wi.hMenu, MENU_CULL, MF_CHECKED);
}
CheckMenuItem (g_wi.hMenu, MENU_BACKFACE,
((cull_face==GL_BACK)? MF_CHECKED:MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_FRONTFACE,
((cull_face==GL_FRONT)? MF_CHECKED:MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_CCW,
((front_face==GL_CCW)? MF_CHECKED:MF_UNCHECKED));
CheckMenuItem (g_wi.hMenu, MENU_CW,
((front_face==GL_CW)? MF_CHECKED:MF_UNCHECKED));
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case MENU_STATS:
if (pm_ready)
{
DWORD nv, nf, mv, mf;
char str[100];
HRESULT hr;
hr = pPMesh->GetNumFaces (&nf);
if (hr != S_OK)
MessageBox (NULL, "GetNumFaces failed", "Error", MB_OK);
hr = pPMesh->GetNumVertices (&nv);
if (hr != S_OK)
MessageBox (NULL, "GetNumVertices failed", "Error", MB_OK);
hr = pPMesh->GetMaxFaces (&mf);
if (hr != S_OK)
MessageBox (NULL, "GetMaxFaces failed", "Error", MB_OK);
hr = pPMesh->GetMaxVertices (&mv);
if (hr != S_OK)
MessageBox (NULL, "GetMaxVertices failed", "Error", MB_OK);
sprintf (str, "NumVerts = %d, NumFaces = %d\nMaxVerts = %d, MaxFaces = %d", nv, nf, mv, mf);
MessageBox (NULL, str, "Stats", MB_OK);
}
break; // Not Implemented
case MENU_FILE_OPEN_PMESH:
{
HRESULT hr;
char* file = OpenPMFile(hwnd, "Open a PMesh file", 1);
if (!file) break;
hr = pPMesh->Load(file, NULL, &minV, &maxV, NULL);
if (hr != S_OK)
{
pm_ready = FALSE;
MessageBox (NULL, "Load failed", "Error", MB_OK);
}
else
{
char str[100];
pm_ready = TRUE;
sprintf (str, "Max = %d; Min = %d", maxV, minV);
MessageBox (NULL, str, "Info", MB_OK);
}
break;
}
break; // Not Implemented
case MENU_EXIT:
PostMessage (hwnd, WM_CLOSE, 0, 0);
break;
case MENU_POINT:
break;
case MENU_CULL:
cull_enable = !cull_enable;
if (cull_enable)
glEnable (GL_CULL_FACE);
else
glDisable (GL_CULL_FACE);
break;
case MENU_BACKFACE:
cull_face = GL_BACK;
if (cull_enable) glCullFace (cull_face);
break;
case MENU_FRONTFACE:
cull_face = GL_FRONT;
if (cull_enable) glCullFace (cull_face);
break;
case MENU_CCW:
front_face = GL_CCW;
glFrontFace (front_face);
break;
case MENU_CW:
front_face = GL_CW;
glFrontFace (front_face);
break;
case MENU_WIREFRAME:
edge_mode = !edge_mode;
break;
case MENU_DEPTH:
depth_mode = !depth_mode;
if (depth_mode)
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
}
else
{
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
}
break;
case MENU_SOLID:
filled_mode = !filled_mode;
break;
case MENU_FLAT:
shade_model = GL_FLAT;
glShadeModel (GL_FLAT);
break;
case MENU_GOURAUD:
shade_model = GL_SMOOTH;
glShadeModel (GL_SMOOTH);
break;
case MENU_LIGHTING:
light_enable = !light_enable;
if (light_enable)
EnableLighting ();
else
DisableLighting ();
break;
default:
MessageBox (NULL, "Not yet implemented\r\n", "Warning", MB_OK);
return 0;
}
break;
case WM_RBUTTONDOWN:
SetCapture(hwnd);
g_wi.rmouseX = LOWORD (lParam);
g_wi.rmouseY = HIWORD (lParam);
g_wi.rmouse_down = TRUE;
DoGlStuff ();
break;
case WM_RBUTTONUP:
ReleaseCapture();
g_wi.rmouse_down = FALSE;
DoGlStuff ();
break;
case WM_LBUTTONDOWN:
SetCapture(hwnd);
g_wi.lmouseX = LOWORD (lParam);
g_wi.lmouseY = HIWORD (lParam);
g_wi.lmouse_down = TRUE;
DoGlStuff ();
break;
case WM_LBUTTONUP:
ReleaseCapture();
g_wi.lmouse_down = FALSE;
DoGlStuff ();
break;
case WM_MOVE:
g_wi.wPosition.x = (int) LOWORD(lParam);
g_wi.wPosition.y = (int) HIWORD(lParam);
break;
case WM_USER:
case WM_DESTROY:
default:
return (pfnOldProc)(hwnd, message, wParam, lParam);
} /* end switch */
//DoGlStuff ();
return 0;
}
void UpdateWinTitle (HWND hwnd)
{
char str[100];
sprintf (str, "LOD=%f", pm_lod_level);
SetWindowText (hwnd, str);
}