/******************************Module*Header*******************************\ * Module Name: dlgdraw.c * * For gl drawing in dialog boxes * * Created: 12-06-95 -by- Marc Fortier [marcfo] * * Copyright (c) 1995 Microsoft Corporation \**************************************************************************/ #include #include #include #include #include #include #include #include "ssintrnl.hxx" #include "dlgdraw.hxx" // Define this if want each TEX_BUTTON to be a separate window. This is // necessary if the main dialog window has WS_CLIP_CHILDREN, but so far this // doesn't seem to be the case. //#define SS_MULTIWINDOW 1 static void CalcGLViewport( HWND hwndParent, HWND hwndChild, IPOINT2D *pOrigin, ISIZE *pSize ); //materials for varying intensities enum{ MAT_INTENSITY_LOW = 0, MAT_INTENSITY_MID, MAT_INTENSITY_HIGH, MAT_COUNT }; MATERIAL gMat[MAT_COUNT] = { {{0.3f, 0.3f, 0.3f}, {0.6f, 0.6f, 0.6f}, {0.2f, 0.2f, 0.2f}, 0.3f }, {{0.2f, 0.2f, 0.2f}, {0.8f, 0.8f, 0.8f}, {0.2f, 0.2f, 0.2f}, 0.3f }, {{0.2f, 0.2f, 0.2f}, {1.0f, 1.0f, 1.0f}, {0.2f, 0.2f, 0.2f}, 0.3f } }; float colorBlack[3] = {0.0f, 0.0f, 0.0f}; /**************************************************************************\ * SS_TEX_BUTTON constructor * * This allows drawing GL textures on a button * * For optimum performance, GL is configured on the main dialog window, and * 'viewported' to the button. * Defining SS_MULTIWINDOW results in the texture being drawn in the actual * button window. * * Note: this only works for buttons on the main dialog window for now. \**************************************************************************/ SS_TEX_BUTTON::SS_TEX_BUTTON( HWND hDlg, HWND hDlgBtn ) { PSSW psswParent = gpss->sswTable.PsswFromHwnd( hDlg ); SS_ASSERT( psswParent, "SS_TEX_BUTTON constructor: NULL psswParent\n" ); // The parent needs to have an hrc context, since we will be using it // for drawing. SS_GL_CONFIG GLc = { 0, 0, NULL }; if( !psswParent->ConfigureForGL( &GLc ) ) { SS_WARNING( "SS_TEX_BUTTON constructor: ConfigureForGL failed\n" ); return; } #ifdef SS_MULTIWINDOW // Each button is a separate GL window, using its parents hrc pssw = new SSW( psswParent, hDlgBtn ); SS_ASSERT( pssw, "SS_TEX_BUTTON constructor: pssw alloc failure\n" ); // Configure the pssw for GL GLc.pfFlags = 0; GLc.hrc = psswParent->GetHRC(); GLc.pStretch = NULL; if( ! pssw->ConfigureForGL( &GLc ) ) { SS_WARNING( "SS_TEX_BUTTON constructor: ConfigureForGL failed\n" ); return; } #else // Make the button a 'subwindow' of the parent pssw = NULL; // Calculate the viewport to draw to CalcGLViewport( hDlg, hDlgBtn, &origin, &size ); #endif // Init various GL stuff InitGL(); pCurTex = NULL; bEnabled = TRUE; } /**************************************************************************\ * SS_TEX_BUTTON destructor * \**************************************************************************/ SS_TEX_BUTTON::~SS_TEX_BUTTON() { if( pssw ) delete pssw; } /**************************************************************************\ * InitGL * \**************************************************************************/ void SS_TEX_BUTTON::InitGL() { float ambient[] = {0.2f, 0.2f, 0.2f, 1.0f}; float diffuse[] = {0.7f, 0.7f, 0.7f, 1.0f}; float position[] = {0.0f, 0.0f, -150.0f, 1.0f}; float lmodel_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f}; MATERIAL *pMat; // lighting, for intensity levels glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHT0); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); glCullFace( GL_BACK ); glEnable(GL_CULL_FACE); glFrontFace( GL_CW ); glShadeModel( GL_FLAT ); glColor3f( 1.0f, 1.0f, 1.0f ); gluOrtho2D( -1.0, 1.0, -1.0, 1.0 ); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } /**************************************************************************\ * SetTexture * * Set a current texture for the button * * Note this is a pointer to a texture, so any texture memory management is * done by the caller. \**************************************************************************/ void SS_TEX_BUTTON::SetTexture( TEXTURE *pTex ) { pCurTex = pTex; } /**************************************************************************\ * Draw * \**************************************************************************/ void SS_TEX_BUTTON::Draw( TEXTURE *pTex ) { if( pTex != NULL ) { glEnable(GL_TEXTURE_2D); ss_SetTexture( pTex ); // doesn't look at iPalRot yet // Set the texture palette if it exists if( pTex->pal && pTex->iPalRot ) ss_SetTexturePalette( pTex, pTex->iPalRot ); } // else white rectangle will be drawn if( bEnabled ) intensity = DLG_INTENSITY_HIGH; else intensity = DLG_INTENSITY_LOW; switch( intensity ) { case DLG_INTENSITY_LOW: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_LIGHTING); glColor3f( 0.5f, 0.5f, 0.5f ); break; case DLG_INTENSITY_MID: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_LIGHTING); glColor3f( 0.7f, 0.7f, 0.7f ); break; case DLG_INTENSITY_HIGH: default: glColor3f( 1.0f, 1.0f, 1.0f ); glDisable(GL_LIGHTING); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); } // Set the viewport #ifdef SS_MULTIWINDOW glViewport( 0, 0, pssw->size.width, pssw->size.height ); #else glViewport( origin.x, origin.y, size.width, size.height ); #endif glBegin( GL_QUADS ); glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -1.0f, 1.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 1.0f, 1.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 1.0f, -1.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -1.0f, -1.0f ); glEnd(); glDisable( GL_TEXTURE_2D); glFlush(); } void SS_TEX_BUTTON::Draw() { Draw( pCurTex ); } /**************************************************************************\ * CalcGLViewport * * Calculate viewport for the child window * \**************************************************************************/ static void CalcGLViewport( HWND hwndParent, HWND hwndChild, IPOINT2D *pOrigin, ISIZE *pSize ) { RECT childRect, parentRect; // Get size of the child window GetClientRect( hwndChild, &childRect ); pSize->width = childRect.right; pSize->height = childRect.bottom; // Calc origin of the child window wrt its parents client area // Note that the y-coord must be inverted for GL // Map the child client rect to the parent client coords MapWindowPoints( hwndChild, hwndParent, (POINT *) &childRect, 2 ); pOrigin->x = childRect.left; // invert y coord GetClientRect( hwndParent, &parentRect ); pOrigin->y = parentRect.bottom - childRect.bottom; }