Source code of Windows XP (NT5)
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.

266 lines
7.5 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: dlgdraw.c
  3. *
  4. * For gl drawing in dialog boxes
  5. *
  6. * Created: 12-06-95 -by- Marc Fortier [marcfo]
  7. *
  8. * Copyright (c) 1995 Microsoft Corporation
  9. \**************************************************************************/
  10. #include <windows.h>
  11. #include <commdlg.h>
  12. #include <scrnsave.h>
  13. #include <stdarg.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <malloc.h>
  17. #include "ssintrnl.hxx"
  18. #include "dlgdraw.hxx"
  19. // Define this if want each TEX_BUTTON to be a separate window. This is
  20. // necessary if the main dialog window has WS_CLIP_CHILDREN, but so far this
  21. // doesn't seem to be the case.
  22. //#define SS_MULTIWINDOW 1
  23. static void CalcGLViewport( HWND hwndParent, HWND hwndChild, IPOINT2D *pOrigin, ISIZE *pSize );
  24. //materials for varying intensities
  25. enum{
  26. MAT_INTENSITY_LOW = 0,
  27. MAT_INTENSITY_MID,
  28. MAT_INTENSITY_HIGH,
  29. MAT_COUNT
  30. };
  31. MATERIAL gMat[MAT_COUNT] = {
  32. {{0.3f, 0.3f, 0.3f}, {0.6f, 0.6f, 0.6f}, {0.2f, 0.2f, 0.2f}, 0.3f },
  33. {{0.2f, 0.2f, 0.2f}, {0.8f, 0.8f, 0.8f}, {0.2f, 0.2f, 0.2f}, 0.3f },
  34. {{0.2f, 0.2f, 0.2f}, {1.0f, 1.0f, 1.0f}, {0.2f, 0.2f, 0.2f}, 0.3f }
  35. };
  36. float colorBlack[3] = {0.0f, 0.0f, 0.0f};
  37. /**************************************************************************\
  38. * SS_TEX_BUTTON constructor
  39. *
  40. * This allows drawing GL textures on a button
  41. *
  42. * For optimum performance, GL is configured on the main dialog window, and
  43. * 'viewported' to the button.
  44. * Defining SS_MULTIWINDOW results in the texture being drawn in the actual
  45. * button window.
  46. *
  47. * Note: this only works for buttons on the main dialog window for now.
  48. \**************************************************************************/
  49. SS_TEX_BUTTON::SS_TEX_BUTTON( HWND hDlg, HWND hDlgBtn )
  50. {
  51. PSSW psswParent = gpss->sswTable.PsswFromHwnd( hDlg );
  52. SS_ASSERT( psswParent, "SS_TEX_BUTTON constructor: NULL psswParent\n" );
  53. // The parent needs to have an hrc context, since we will be using it
  54. // for drawing.
  55. SS_GL_CONFIG GLc = { 0, 0, NULL };
  56. if( !psswParent->ConfigureForGL( &GLc ) ) {
  57. SS_WARNING( "SS_TEX_BUTTON constructor: ConfigureForGL failed\n" );
  58. return;
  59. }
  60. #ifdef SS_MULTIWINDOW
  61. // Each button is a separate GL window, using its parents hrc
  62. pssw = new SSW( psswParent, hDlgBtn );
  63. SS_ASSERT( pssw, "SS_TEX_BUTTON constructor: pssw alloc failure\n" );
  64. // Configure the pssw for GL
  65. GLc.pfFlags = 0;
  66. GLc.hrc = psswParent->GetHRC();
  67. GLc.pStretch = NULL;
  68. if( ! pssw->ConfigureForGL( &GLc ) ) {
  69. SS_WARNING( "SS_TEX_BUTTON constructor: ConfigureForGL failed\n" );
  70. return;
  71. }
  72. #else
  73. // Make the button a 'subwindow' of the parent
  74. pssw = NULL;
  75. // Calculate the viewport to draw to
  76. CalcGLViewport( hDlg, hDlgBtn, &origin, &size );
  77. #endif
  78. // Init various GL stuff
  79. InitGL();
  80. pCurTex = NULL;
  81. bEnabled = TRUE;
  82. }
  83. /**************************************************************************\
  84. * SS_TEX_BUTTON destructor
  85. *
  86. \**************************************************************************/
  87. SS_TEX_BUTTON::~SS_TEX_BUTTON()
  88. {
  89. if( pssw )
  90. delete pssw;
  91. }
  92. /**************************************************************************\
  93. * InitGL
  94. *
  95. \**************************************************************************/
  96. void
  97. SS_TEX_BUTTON::InitGL()
  98. {
  99. float ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
  100. float diffuse[] = {0.7f, 0.7f, 0.7f, 1.0f};
  101. float position[] = {0.0f, 0.0f, -150.0f, 1.0f};
  102. float lmodel_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
  103. MATERIAL *pMat;
  104. // lighting, for intensity levels
  105. glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  106. glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  107. glLightfv(GL_LIGHT0, GL_POSITION, position);
  108. glEnable(GL_LIGHT0);
  109. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  110. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  111. glCullFace( GL_BACK );
  112. glEnable(GL_CULL_FACE);
  113. glFrontFace( GL_CW );
  114. glShadeModel( GL_FLAT );
  115. glColor3f( 1.0f, 1.0f, 1.0f );
  116. gluOrtho2D( -1.0, 1.0, -1.0, 1.0 );
  117. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  118. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  119. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  120. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  121. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  122. }
  123. /**************************************************************************\
  124. * SetTexture
  125. *
  126. * Set a current texture for the button
  127. *
  128. * Note this is a pointer to a texture, so any texture memory management is
  129. * done by the caller.
  130. \**************************************************************************/
  131. void
  132. SS_TEX_BUTTON::SetTexture( TEXTURE *pTex )
  133. {
  134. pCurTex = pTex;
  135. }
  136. /**************************************************************************\
  137. * Draw
  138. *
  139. \**************************************************************************/
  140. void
  141. SS_TEX_BUTTON::Draw( TEXTURE *pTex )
  142. {
  143. if( pTex != NULL ) {
  144. glEnable(GL_TEXTURE_2D);
  145. ss_SetTexture( pTex ); // doesn't look at iPalRot yet
  146. // Set the texture palette if it exists
  147. if( pTex->pal && pTex->iPalRot )
  148. ss_SetTexturePalette( pTex, pTex->iPalRot );
  149. }
  150. // else white rectangle will be drawn
  151. if( bEnabled )
  152. intensity = DLG_INTENSITY_HIGH;
  153. else
  154. intensity = DLG_INTENSITY_LOW;
  155. switch( intensity ) {
  156. case DLG_INTENSITY_LOW:
  157. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  158. glEnable(GL_LIGHTING);
  159. glColor3f( 0.5f, 0.5f, 0.5f );
  160. break;
  161. case DLG_INTENSITY_MID:
  162. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  163. glEnable(GL_LIGHTING);
  164. glColor3f( 0.7f, 0.7f, 0.7f );
  165. break;
  166. case DLG_INTENSITY_HIGH:
  167. default:
  168. glColor3f( 1.0f, 1.0f, 1.0f );
  169. glDisable(GL_LIGHTING);
  170. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  171. }
  172. // Set the viewport
  173. #ifdef SS_MULTIWINDOW
  174. glViewport( 0, 0, pssw->size.width, pssw->size.height );
  175. #else
  176. glViewport( origin.x, origin.y, size.width, size.height );
  177. #endif
  178. glBegin( GL_QUADS );
  179. glTexCoord2f( 0.0f, 1.0f );
  180. glVertex2f( -1.0f, 1.0f );
  181. glTexCoord2f( 1.0f, 1.0f );
  182. glVertex2f( 1.0f, 1.0f );
  183. glTexCoord2f( 1.0f, 0.0f );
  184. glVertex2f( 1.0f, -1.0f );
  185. glTexCoord2f( 0.0f, 0.0f );
  186. glVertex2f( -1.0f, -1.0f );
  187. glEnd();
  188. glDisable( GL_TEXTURE_2D);
  189. glFlush();
  190. }
  191. void
  192. SS_TEX_BUTTON::Draw()
  193. {
  194. Draw( pCurTex );
  195. }
  196. /**************************************************************************\
  197. * CalcGLViewport
  198. *
  199. * Calculate viewport for the child window
  200. *
  201. \**************************************************************************/
  202. static void
  203. CalcGLViewport( HWND hwndParent, HWND hwndChild, IPOINT2D *pOrigin, ISIZE *pSize )
  204. {
  205. RECT childRect, parentRect;
  206. // Get size of the child window
  207. GetClientRect( hwndChild, &childRect );
  208. pSize->width = childRect.right;
  209. pSize->height = childRect.bottom;
  210. // Calc origin of the child window wrt its parents client area
  211. // Note that the y-coord must be inverted for GL
  212. // Map the child client rect to the parent client coords
  213. MapWindowPoints( hwndChild, hwndParent, (POINT *) &childRect, 2 );
  214. pOrigin->x = childRect.left;
  215. // invert y coord
  216. GetClientRect( hwndParent, &parentRect );
  217. pOrigin->y = parentRect.bottom - childRect.bottom;
  218. }