123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- //---------------------------------------------------------------------------
- /*: Simple TGLShader based multipass demo.
- This demo uses a custom TGLShader subclass to implement the classic
- multipass hidden lines rendering technique on a torus: first pass renders
- model with filled triangles, second pass does the wireframe.
- You'll also note the glPolygonOffset call, it displaces fragments depths
- value a little "farther away" so that surface fill depth values do not
- interact with the rendering of the lines (comment out the call and you'll
- see).<br>
- The axis and sphere allow you to see the limit of that simple technique:
- it actually "paints" between the lines, so you cannot use it to make
- transparent wireframed objects with hidden lines - if that thought ever
- blossomed in your mind ;)
- Additionnal objects around the show a glow/toon edges effect achieved in two
- passes too: the 1st pass activate lines and gives them a width, the second
- is used to fill the surface (and clear the lines that aren't on edges).
- (TOutLineShader thanks to Delauney Jerome, [email protected])
- */
- #include <vcl.h>
- #pragma hdrstop
- #include "Unit1.h"
- #include <assert.h>
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- #pragma link "GLGeomObjects"
- #pragma link "GLObjects"
- #pragma link "GLScene"
- #pragma link "GLTexture"
- #pragma link "GLWin32Viewer"
- #pragma link "GLBaseClasses"
- #pragma link "GLCoordinates"
- #pragma link "GLCrossPlatform"
- #pragma link "GLMaterial"
- #include "OpenGLTokens.hpp"
- #include "OpenGL1x.hpp"
- #pragma resource "*.dfm"
- TForm1 *Form1;
- //---------------------------------------------------------------------------
- __fastcall TForm1::TForm1(TComponent* Owner)
- : TForm(Owner)
- {
- }
- //---------------------------------------------------------------------------
- __fastcall THiddenLineShader::THiddenLineShader(TComponent* AOwner)
- : TGLShader(AOwner)
- {
- }
- //---------------------------------------------------------------------------
- __fastcall THiddenLineShader::~THiddenLineShader(void)
- {
- }
- //---------------------------------------------------------------------------
- void __fastcall THiddenLineShader::DoApply(TGLRenderContextInfo &rci, System::TObject* Sender)
- {
- // new object getting rendered, 1st pass
- PassCount = 1;
- // backup state
- glPushAttrib(GL_ENABLE_BIT);
- // disable lighting, this is a solid fill
- glDisable(GL_LIGHTING);
- rci.GLStates->PolygonMode = GL_FRONT_AND_BACK, GL_FILL;
- // use background color
- glColor3fv(&BackgroundColor.X);
- // enable and adjust polygon offset
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1, 2);
- }
- //---------------------------------------------------------------------------
- bool __fastcall THiddenLineShader::DoUnApply(TGLRenderContextInfo &rci)
- {
- bool result;
- switch (PassCount)
- {
- case 1 : {
- // 1st pass completed, we setup for the second
- PassCount = 2;
- // switch to wireframe and its color
- rci.GLStates->PolygonMode = GL_FRONT_AND_BACK, GL_LINE;
- glColor3fv(&LineColor.X);
- // disable polygon offset
- glDisable(GL_POLYGON_OFFSET_LINE);
- result = true;
- break;
- }
- case 2 : {
- // restore state
- glPopAttrib();
- // we're done
- result = false;
- break;
- }
- default : {
- // doesn't hurt to be cautious
- assert(false);
- result = false;
- }
- }
- return result;
- }
- //---------------------------------------------------------------------------
- __fastcall TOutLineShader::TOutLineShader(TComponent* AOwner)
- : TGLShader(AOwner)
- {
- }
- //---------------------------------------------------------------------------
- __fastcall TOutLineShader::~TOutLineShader(void)
- {
- }
- //---------------------------------------------------------------------------
- void __fastcall TOutLineShader::DoApply(TGLRenderContextInfo &rci, System::TObject* Sender)
- {
- PassCount = 1;
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_LIGHTING);
- if (OutlineSmooth)
- {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
- glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
- glEnable(GL_LINE_SMOOTH);
- }
- else glDisable(GL_LINE_SMOOTH);
- glGetFloatv(GL_LINE_WIDTH,&OldlineWidth);
- glLineWidth(OutlineWidth);
- glPolygonMode(GL_BACK, GL_LINE);
- glCullFace(GL_FRONT);
- glDepthFunc(GL_LEQUAL);
- glColor3fv(&LineColor.X);
- }
- //---------------------------------------------------------------------------
- bool __fastcall TOutLineShader::DoUnApply(TGLRenderContextInfo &rci)
- {
- bool result;
- switch (PassCount)
- {
- case 1 : {
- PassCount=2;
- if (Lighting)
- glEnable(GL_LIGHTING);
- else glColor3fv(&BackgroundColor.X);
- glDepthFunc(GL_LESS);
- glCullFace(GL_BACK);
- glPolygonMode(GL_BACK, GL_FILL);
- result=true;
- break;
- }
- case 2 : {
- glPopAttrib();
- glLineWidth(OldlineWidth);
- result=false;
- break;
- }
- default : {
- assert(false);
- result=false;
- }
- }
- return result;
- }
- //---------------------------------------------------------------------------
- void __fastcall TForm1::BUBindClick(TObject *Sender)
- {
- THiddenLineShader *shader1;
- TOutLineShader *shader2 ,*shader3;
- BUBind->Enabled=False;
- // instantiate our shaders
- shader1 = new THiddenLineShader(this);
- shader1->BackgroundColor=ConvertWinColor(GLSceneViewer1->Buffer->BackgroundColor,0);
- shader1->LineColor=clrBlue;
- shader2 = new TOutLineShader(this);
- shader2->BackgroundColor=ConvertWinColor(GLSceneViewer1->Buffer->BackgroundColor,0);
- shader2->OutlineSmooth=true;
- shader2->OutlineWidth=2;
- shader2->Lighting=false;
- shader2->LineColor=clrBlack;
- shader3 = new TOutLineShader(this);
- shader3->BackgroundColor=ConvertWinColor(GLSceneViewer1->Buffer->BackgroundColor,0);
- shader3->OutlineSmooth=false;
- shader3->OutlineWidth=4;
- shader3->Lighting=true;
- shader3->LineColor=clrRed;
- // binds the shaders to the materials
- GLMaterialLibrary1->Materials->Items[0]->Shader=shader1;
- GLMaterialLibrary1->Materials->Items[1]->Shader=shader2;
- GLMaterialLibrary1->Materials->Items[2]->Shader=shader3;
- }
- //---------------------------------------------------------------------------
- void __fastcall TForm1::GLSceneViewer1MouseDown(TObject *Sender,
- TMouseButton Button, TShiftState Shift, int X, int Y)
- {
- mx=X; my=Y;
- }
- //---------------------------------------------------------------------------
- void __fastcall TForm1::GLSceneViewer1MouseMove(TObject *Sender,
- TShiftState Shift, int X, int Y)
- {
- if (Shift.Contains(ssLeft))
- GLCamera1->MoveAroundTarget(my-Y, mx-X);
- else if (Shift.Contains(ssRight))
- GLCamera1->RotateTarget(my-Y, mx-X, 0);
- mx=X; my=Y;
- }
- //---------------------------------------------------------------------------
|