1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    TestGenericVertexAttributesGLSLDepthPeelingPass.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 // .NAME Test of vtkGLSLShaderDeviceAdapter2 with XML shader style 2 with
17 // depth peeling pass.
18 // .SECTION Description
19 // this program tests the shader support in vtkRendering.
20 
21 
22 #include "vtkActor.h"
23 #include "vtkBrownianPoints.h"
24 #include "vtkCamera.h"
25 #include "vtkProperty.h"
26 #include "vtkPolyDataMapper.h"
27 #include "vtkOpenGLRenderer.h"
28 #include "vtkRenderWindow.h"
29 #include "vtkRenderWindowInteractor.h"
30 #include "vtkSphereSource.h"
31 
32 #include "vtkCameraPass.h"
33 #include "vtkLightsPass.h"
34 #include "vtkSequencePass.h"
35 #include "vtkOpaquePass.h"
36 #include "vtkDepthPeelingPass.h"
37 #include "vtkTranslucentPass.h"
38 #include "vtkVolumetricPass.h"
39 #include "vtkOverlayPass.h"
40 #include "vtkRenderPassCollection.h"
41 
42 #include "vtkTestUtilities.h"
43 #include "vtkRegressionTestImage.h"
44 
45 #include "vtkgl.h"
46 
47 // Make sure to have a valid OpenGL context current on the calling thread
48 // before calling it. Defined in TestGenericVertexAttributesGLSLAlphaBlending.
49 bool MesaHasVTKBug8135(vtkRenderWindow *);
50 
TestGenericVertexAttributesGLSLDepthPeelingPass(int argc,char * argv[])51 int TestGenericVertexAttributesGLSLDepthPeelingPass(int argc, char *argv[])
52 {
53   char shaders1[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
54   <Material name=\"GenericAttributes1\"> \
55     <Shader scope=\"Vertex\" name=\"VertexShader\" location=\"Inline\"\
56       language=\"GLSL\" entry=\"main\" style=\"2\"> attribute vec3 genAttrVector; \
57       varying vec4 color; \
58       void propFuncVS(void) \
59       { \
60         gl_Position = gl_ModelViewProjectionMatrix *gl_Vertex; \
61         color = vec4(normalize(genAttrVector), 0.3); \
62       } \
63     </Shader> \
64     <Shader scope=\"Fragment\" name=\"FragmentShader\" location=\"Inline\" \
65       language=\"GLSL\" entry=\"main\" style=\"2\"> \
66       varying vec4 color; \
67       void propFuncFS() \
68       { \
69         gl_FragColor = color; \
70       } \
71     </Shader> \
72   </Material>";
73 
74   vtkSphereSource * sphere = vtkSphereSource::New();
75   sphere->SetRadius(5);
76   sphere->SetPhiResolution(20);
77   sphere->SetThetaResolution(20);
78 
79   vtkBrownianPoints * randomVector = vtkBrownianPoints::New();
80   randomVector->SetMinimumSpeed(0);
81   randomVector->SetMaximumSpeed(1);
82   randomVector->SetInputConnection(sphere->GetOutputPort());
83 
84   vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
85   mapper->SetInputConnection(randomVector->GetOutputPort());
86 
87   vtkActor *actor = vtkActor::New();
88   actor->SetMapper(mapper);
89   actor->GetProperty()->LoadMaterialFromString(shaders1);
90   actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
91   actor->GetProperty()->GetShading();
92   actor->GetProperty()->ShadingOn();
93   actor->GetProperty()->SetOpacity(0.99); // to force depth peeling.
94 
95   mapper->MapDataArrayToVertexAttribute("genAttrVector", "BrownianVectors", 0, -1);
96 
97   vtkRenderer *renderer = vtkRenderer::New();
98   renderer->SetBackground(0.5, 0.5, 0.5);
99 
100   vtkOpenGLRenderer *glrenderer = vtkOpenGLRenderer::SafeDownCast(renderer);
101 
102   vtkRenderWindow *renWin = vtkRenderWindow::New();
103   renWin->SetMultiSamples(0);
104   renWin->SetAlphaBitPlanes(1);
105   renWin->AddRenderer(renderer);
106 
107   // All the passes.
108   vtkCameraPass *cameraP=vtkCameraPass::New();
109 
110   vtkSequencePass *seq=vtkSequencePass::New();
111   vtkOpaquePass *opaque=vtkOpaquePass::New();
112   vtkDepthPeelingPass *peeling=vtkDepthPeelingPass::New();
113   peeling->SetMaximumNumberOfPeels(200);
114   peeling->SetOcclusionRatio(0.1);
115 
116   vtkTranslucentPass *translucent=vtkTranslucentPass::New();
117   peeling->SetTranslucentPass(translucent);
118 
119   vtkVolumetricPass *volume=vtkVolumetricPass::New();
120   vtkOverlayPass *overlay=vtkOverlayPass::New();
121 
122   vtkLightsPass *lights=vtkLightsPass::New();
123 
124   vtkRenderPassCollection *passes=vtkRenderPassCollection::New();
125   passes->AddItem(lights);
126   passes->AddItem(opaque);
127   passes->AddItem(peeling);
128   passes->AddItem(volume);
129   passes->AddItem(overlay);
130   seq->SetPasses(passes);
131   cameraP->SetDelegatePass(seq);
132   glrenderer->SetPass(cameraP);
133 
134   opaque->Delete();
135   peeling->Delete();
136   translucent->Delete();
137   volume->Delete();
138   overlay->Delete();
139   seq->Delete();
140   passes->Delete();
141   cameraP->Delete();
142   lights->Delete();
143 
144 
145   vtkRenderWindowInteractor *interactor = vtkRenderWindowInteractor::New();
146   interactor->SetRenderWindow(renWin);
147 
148   renWin->SetSize(400,400);
149   renWin->Render();
150 
151   int retVal;
152   if(MesaHasVTKBug8135(renWin))
153     {
154     // Mesa will crash if version<7.3
155     cout<<"This version of Mesa would crash. Skip the test."<<endl;
156     retVal=vtkRegressionTester::PASSED;
157     }
158   else
159     {
160     renderer->AddActor(actor);
161     renderer->ResetCamera();
162     renWin->Render();
163 
164     if(peeling->GetLastRenderingUsedDepthPeeling())
165       {
166       cout<<"depth peeling was used"<<endl;
167       }
168     else
169       {
170       cout<<"depth peeling was not used (alpha blending instead)"<<endl;
171       }
172     interactor->Initialize();
173     renWin->Render();
174 
175     retVal = vtkRegressionTestImageThreshold(renWin,18);
176     if( retVal == vtkRegressionTester::DO_INTERACTOR)
177       {
178       interactor->Start();
179       }
180     }
181 
182   sphere->Delete();
183   randomVector->Delete();
184   mapper->Delete();
185   actor->Delete();
186   renderer->Delete();
187   renWin->Delete();
188   interactor->Delete();
189 
190   return !retVal;
191 }
192