fMultipassC.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //---------------------------------------------------------------------------
  2. /*: Simple TGLShader based multipass demo.
  3. This demo uses a custom TGLShader subclass to implement the classic
  4. multipass hidden lines rendering technique on a torus: first pass renders
  5. model with filled triangles, second pass does the wireframe.
  6. You'll also note the glPolygonOffset call, it displaces fragments depths
  7. value a little "farther away" so that surface fill depth values do not
  8. interact with the rendering of the lines (comment out the call and you'll
  9. see).<br>
  10. The axis and sphere allow you to see the limit of that simple technique:
  11. it actually "paints" between the lines, so you cannot use it to make
  12. transparent wireframed objects with hidden lines - if that thought ever
  13. blossomed in your mind ;)
  14. Additionnal objects around the show a glow/toon edges effect achieved in two
  15. passes too: the 1st pass activate lines and gives them a width, the second
  16. is used to fill the surface (and clear the lines that aren't on edges).
  17. (TOutLineShader thanks to Delauney Jerome, [email protected])
  18. */
  19. #include <vcl.h>
  20. #pragma hdrstop
  21. #include "fMultipassC.h"
  22. #include <assert.h>
  23. //---------------------------------------------------------------------------
  24. #pragma package(smart_init)
  25. #pragma link "GLS.GeomObjects"
  26. #pragma link "GLS.Objects"
  27. #pragma link "GLS.Scene"
  28. #pragma link "GLS.Texture"
  29. #pragma link "GLS.SceneViewer"
  30. #pragma link "GLS.BaseClasses"
  31. #pragma link "GLS.Coordinates"
  32. #pragma link "GLS.Material"
  33. #include "GLS.OpenGLTokens.hpp"
  34. #pragma resource "*.dfm"
  35. TForm1 *Form1;
  36. //---------------------------------------------------------------------------
  37. __fastcall TForm1::TForm1(TComponent* Owner)
  38. : TForm(Owner)
  39. {
  40. }
  41. //---------------------------------------------------------------------------
  42. __fastcall THiddenLineShader::THiddenLineShader(TComponent* AOwner)
  43. : TGLShader(AOwner)
  44. {
  45. }
  46. //---------------------------------------------------------------------------
  47. __fastcall THiddenLineShader::~THiddenLineShader(void)
  48. {
  49. }
  50. //---------------------------------------------------------------------------
  51. void __fastcall THiddenLineShader::DoApply(TGLRenderContextInfo &rci, System::TObject* Sender)
  52. {
  53. // new object getting rendered, 1st pass
  54. PassCount = 1;
  55. // backup state
  56. glPushAttrib(GL_ENABLE_BIT);
  57. // disable lighting, this is a solid fill
  58. glDisable(GL_LIGHTING);
  59. rci.GLStates->PolygonMode = GL_FRONT_AND_BACK, GL_FILL;
  60. // use background color
  61. glColor3fv(&BackgroundColor.X);
  62. // enable and adjust polygon offset
  63. glEnable(GL_POLYGON_OFFSET_FILL);
  64. glPolygonOffset(1, 2);
  65. }
  66. //---------------------------------------------------------------------------
  67. bool __fastcall THiddenLineShader::DoUnApply(TGLRenderContextInfo &rci)
  68. {
  69. bool result;
  70. switch (PassCount)
  71. {
  72. case 1 : {
  73. // 1st pass completed, we setup for the second
  74. PassCount = 2;
  75. // switch to wireframe and its color
  76. rci.GLStates->PolygonMode = GL_FRONT_AND_BACK, GL_LINE;
  77. glColor3fv(&LineColor.X);
  78. // disable polygon offset
  79. glDisable(GL_POLYGON_OFFSET_LINE);
  80. result = true;
  81. break;
  82. }
  83. case 2 : {
  84. // restore state
  85. glPopAttrib();
  86. // we're done
  87. result = false;
  88. break;
  89. }
  90. default : {
  91. // doesn't hurt to be cautious
  92. assert(false);
  93. result = false;
  94. }
  95. }
  96. return result;
  97. }
  98. //---------------------------------------------------------------------------
  99. __fastcall TOutLineShader::TOutLineShader(TComponent* AOwner)
  100. : TGLShader(AOwner)
  101. {
  102. }
  103. //---------------------------------------------------------------------------
  104. __fastcall TOutLineShader::~TOutLineShader(void)
  105. {
  106. }
  107. //---------------------------------------------------------------------------
  108. void __fastcall TOutLineShader::DoApply(TGLRenderContextInfo &rci, System::TObject* Sender)
  109. {
  110. PassCount = 1;
  111. glPushAttrib(GL_ENABLE_BIT);
  112. glDisable(GL_LIGHTING);
  113. if (OutlineSmooth)
  114. {
  115. glEnable(GL_BLEND);
  116. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  117. glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  118. glEnable(GL_LINE_SMOOTH);
  119. }
  120. else glDisable(GL_LINE_SMOOTH);
  121. glGetFloatv(GL_LINE_WIDTH,&OldlineWidth);
  122. glLineWidth(OutlineWidth);
  123. glPolygonMode(GL_BACK, GL_LINE);
  124. glCullFace(GL_FRONT);
  125. glDepthFunc(GL_LEQUAL);
  126. glColor3fv(&LineColor.X);
  127. }
  128. //---------------------------------------------------------------------------
  129. bool __fastcall TOutLineShader::DoUnApply(TGLRenderContextInfo &rci)
  130. {
  131. bool result;
  132. switch (PassCount)
  133. {
  134. case 1 : {
  135. PassCount=2;
  136. if (Lighting)
  137. glEnable(GL_LIGHTING);
  138. else glColor3fv(&BackgroundColor.X);
  139. glDepthFunc(GL_LESS);
  140. glCullFace(GL_BACK);
  141. glPolygonMode(GL_BACK, GL_FILL);
  142. result=true;
  143. break;
  144. }
  145. case 2 : {
  146. glPopAttrib();
  147. glLineWidth(OldlineWidth);
  148. result=false;
  149. break;
  150. }
  151. default : {
  152. assert(false);
  153. result=false;
  154. }
  155. }
  156. return result;
  157. }
  158. //---------------------------------------------------------------------------
  159. void __fastcall TForm1::BUBindClick(TObject *Sender)
  160. {
  161. THiddenLineShader *shader1;
  162. TOutLineShader *shader2 ,*shader3;
  163. BUBind->Enabled=False;
  164. // instantiate our shaders
  165. shader1 = new THiddenLineShader(this);
  166. shader1->BackgroundColor=ConvertWinColor(GLSceneViewer1->Buffer->BackgroundColor,0);
  167. shader1->LineColor=clrBlue;
  168. shader2 = new TOutLineShader(this);
  169. shader2->BackgroundColor=ConvertWinColor(GLSceneViewer1->Buffer->BackgroundColor,0);
  170. shader2->OutlineSmooth=true;
  171. shader2->OutlineWidth=2;
  172. shader2->Lighting=false;
  173. shader2->LineColor=clrBlack;
  174. shader3 = new TOutLineShader(this);
  175. shader3->BackgroundColor=ConvertWinColor(GLSceneViewer1->Buffer->BackgroundColor,0);
  176. shader3->OutlineSmooth=false;
  177. shader3->OutlineWidth=4;
  178. shader3->Lighting=true;
  179. shader3->LineColor=clrRed;
  180. // binds the shaders to the materials
  181. GLMaterialLibrary1->Materials->Items[0]->Shader=shader1;
  182. GLMaterialLibrary1->Materials->Items[1]->Shader=shader2;
  183. GLMaterialLibrary1->Materials->Items[2]->Shader=shader3;
  184. }
  185. //---------------------------------------------------------------------------
  186. void __fastcall TForm1::GLSceneViewer1MouseDown(TObject *Sender,
  187. TMouseButton Button, TShiftState Shift, int X, int Y)
  188. {
  189. mx=X; my=Y;
  190. }
  191. //---------------------------------------------------------------------------
  192. void __fastcall TForm1::GLSceneViewer1MouseMove(TObject *Sender,
  193. TShiftState Shift, int X, int Y)
  194. {
  195. if (Shift.Contains(ssLeft))
  196. GLCamera1->MoveAroundTarget(my-Y, mx-X);
  197. else if (Shift.Contains(ssRight))
  198. GLCamera1->RotateTarget(my-Y, mx-X, 0);
  199. mx=X; my=Y;
  200. }
  201. //---------------------------------------------------------------------------