Developer Documentation
PostProcessorPhilipsStereo.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision: 12293 $ *
45 * $LastChangedBy: moebius $ *
46 * $Date: 2011-09-08 11:00:06 +0200 (Do, 08 Sep 2011) $ *
47 * *
48 \*===========================================================================*/
49 
50 
51 #include <ACG/GL/acg_glew.hh>
52 
53 #include "PostProcessorPhilipsStereo.hh"
54 
55 #include <ACG/GL/ScreenQuad.hh>
56 
59 
60 #include "CRC/crc32.hh"
61 
62 PostProcessorPhilipsStereoPlugin::PostProcessorPhilipsStereoPlugin():
63  pProgram_(0),
64  settingsWidget_(0)
65 {
66 
67 }
68 
70  return QString("Philips Stereo Display Output");
71 }
72 
73 QAction* PostProcessorPhilipsStereoPlugin::optionsAction() {
74  QAction* action = new QAction("Philips Stereo Options",0);
75  connect(action,SIGNAL(triggered()),this,SLOT(slotShowOptionsMenu()));
76  return action;
77 }
78 
79 
80 
81 QString PostProcessorPhilipsStereoPlugin::checkOpenGL() {
82  if ( ! ACG::openGLVersion(3, 0) )
83  return QString("Insufficient OpenGL Version! OpenGL 3.0 or higher required");
84 
85  // Check extensions
86  QString missing("");
87  if ( !ACG::checkExtensionSupported("GL_ARB_texture_rectangle") )
88  missing += "GL_ARB_texture_rectangle extension missing\n";
89 
90  return missing;
91 }
92 
93 //-----------------------------------------------------------------------------
94 
95 void PostProcessorPhilipsStereoPlugin::postProcess(ACG::GLState* _glstate, const std::vector<const PostProcessorInput*>& _input, const PostProcessorOutput& _output) {
96 
97  // load shader if needed
98  if (!pProgram_)
99  pProgram_ = GLSL::loadProgram("Philips/screenquad.glsl", "Philips/Fragment42.glsl");
100 
101  if (!pProgram_)
102  return;
103 
104  int vp_l, vp_b, vp_w, vp_h;
105  _glstate->get_viewport(vp_l, vp_b, vp_w, vp_h);
106 
107 
108  // Turn on shader program
109  pProgram_->use();
110 
111  // ======================================================================================================
112  // Bind textures to different texture units and tell shader where to find them
113  // ======================================================================================================
114  _input[0]->bindDepthTex(1);
115  _input[0]->bindColorTex(0);
116 
117  pProgram_->setUniform("ColorTexture", 0);
118  pProgram_->setUniform("DepthStencil", 1);
119 
120  // ======================================================================================================
121  // Setup render states
122  // ======================================================================================================
123 
124  glDisable(GL_LIGHTING);
125  glDisable(GL_COLOR_MATERIAL);
126  glDisable(GL_DEPTH_TEST);
127  glDisable(GL_BLEND);
128 
129  glDepthMask(1);
130  glColorMask(1,1,1,1);
131 
132  // ======================================================================================================
133  // Setup orthogonal projection
134  // ======================================================================================================
135  _glstate->push_projection_matrix();
136  _glstate->push_modelview_matrix();
137 
138  _glstate->reset_projection();
139  _glstate->reset_modelview();
140 
141  _glstate->ortho(0, vp_w, 0, vp_h, 0, 1);
142 
143  // ======================================================================================================
144  // Bind textures to different texture units and tell shader where to find them
145  // ======================================================================================================
146  glColor3f(1.0, 1.0, 1.0);
147 
148 
149  // ======================================================================================================
150  // Bind output FBO
151  // ======================================================================================================
152 
153  _output.bind();
154 
155  // ======================================================================================================
156  // Execute
157  // ======================================================================================================
158  ACG::ScreenQuad::draw(pProgram_);
159 
160 
161  pProgram_->disable();
162 
163  glBindTexture(GL_TEXTURE_2D, 0);
164 
165  // ======================================================================================================
166  // Compute the header required for the display
167  // ======================================================================================================
168  uchar *header = new uchar[6];
169 
170  // Header ID
171  // Basic identifier used by the display to verify the header
172  header[0] = 241; // Header_ID1 = 11110001
173 
174  // Header content type
175  // This entry controls the displays internal rendering based on the input data specified here.
176  // There is no info about how this changes the rendering
177  // Possible values:
178  // 0 No Depth
179  // 1 Signage
180  // 2 Movie
181  // 3 Game
182  // 4 CGI
183  // 5 Still
184  header[1] = OpenFlipperSettings().value("Core/Stereo/Philips/Content",3).toInt(); // Hdr_Content_type (Game) = 00000011 (Gaming Mode)
185 
186  // Header Factor
187  // Each 3D Display has a 'Display recommended depth value', which corresponds to an
188  // acceptable maximum depth factor value for that specific type of display. This value strongly
189  // depends on the lens design. The factor field in the header contains the percentage to be
190  // used from the display recommended depth value. The value of 64 corresponds with the 100%
191  // of the display recommended depth value. It is allowed to use values higher than 64. The factor
192  // works on a linear scale and is multiplied with the factor controlled by the user in the Display
193  // Control Tool.
194  // Value range: 0-255 (default 64)
195  header[2] = OpenFlipperSettings().value("Core/Stereo/Philips/Factor",64).toInt(); // Hdr_Factor
196 
197  // Header Offset CC
198  // Values in the Depth map equal to the header-offset value will be located on the plane of the
199  // display. All values in the disparity map with a higher value will de displayed in front of the
200  // display.
201  // Offset_CC is the offset controlled by the Content Creator. In the system there is also an
202  // Offset_user present, which is controlled by the user using the Display Control Tool.
203  // Value Range: 0-255 (default 128)
204  header[3] = OpenFlipperSettings().value("Core/Stereo/Philips/Offset",128).toInt(); // Hdr_Offset_CC
205 
206  // Header select
207  // When all select signals are low the rendering settings are set to optimal settings for the content
208  // type denoted by Hdr_content_type. By making select signals high the settings for Factor and
209  // Offset_cc can be controlled individually by the header.
210  // Possible Values:
211  // 0 Use Displays defaults and automatic optimizations
212  // 1 Use Header provided factor
213  // 2 Use Header provided offset
214  // 3 Use both factor and offset
215  header[4] = OpenFlipperSettings().value("Core/Stereo/Philips/Select",0).toInt(); // Hdr_Factor_select(1) + Hdr_Offset_select(1) + reserved(6)
216 
217  // Unused Header entry (leave at 0 !)
218  header[5] = 0; // Reserved
219 
220  // Header checksum.
221  // The 4-byte EDC field H(6) − H(9) contains an Error Detection Code computed over the first 6
222  // header bytes. This EDC uses the standard CRC-32 polynomial as defined in IEEE 802.3 and ITU-T
223  // V.42. The initial value and final XOR value are both 0.
224  // unsigned long has 32bit = 4Byte
225  unsigned long checksum = CalcCRC32(&header[0], 6);
226 
227  // Store the complete header in a bit vector
228  std::vector<uchar> bitVector;
229 
230  // For all bytes of the header
231  for (int i = 0; i < 6; i++) {
232 
233  // For each bit of a headers byte
234  for (int j = 7; j >= 0; --j) {
235 
236  // Red and Green component have to be 0
237  bitVector.push_back(0);
238  bitVector.push_back(0);
239 
240  // If bit is set, the full component will be set to one otherwise zero
241  // And the order of the bits has to be reversed!
242  if (header[i] & (1 << j)) {
243  bitVector.push_back(255);
244  } else {
245  bitVector.push_back(0);
246  }
247 
248  // Only every second pixel is used for the header
249  // Skip every odd one by filling in 0 for RGB
250  bitVector.push_back(0);
251  bitVector.push_back(0);
252  bitVector.push_back(0);
253  }
254  }
255 
256  // Append checksum to header.
257  // Reversed bit order!
258  for (int i = 31; i >= 0; i--) {
259 
260  // Red and Green component have to be 0
261  bitVector.push_back(0);
262  bitVector.push_back(0);
263 
264  if (checksum & (1 << i))
265  bitVector.push_back(255);
266  else
267  bitVector.push_back(0);
268 
269  // Only every second pixel is used for the header
270  // Skip every odd one by filling in 0 for RGB
271  bitVector.push_back(0);
272  bitVector.push_back(0);
273  bitVector.push_back(0);
274  }
275 
276  // Select the top left of the renderbuffer and
277  // write complete header into these bits
278 // glRasterPos2i(0, _glstate->context_height() - 1);
279  glRasterPos2i(_output.viewport_[0], _output.viewport_[1] + _output.height - 1);
280  glDrawPixels(bitVector.size() / 3, 1, GL_RGB, GL_UNSIGNED_BYTE, &bitVector[0]);
281 
282  // ======================================================================================================
283  // Reset projection and modelview
284  // ======================================================================================================
285  _glstate->pop_projection_matrix();
286  _glstate->pop_modelview_matrix();
287 
288 
289 }
290 
291 #if QT_VERSION < 0x050000
292  Q_EXPORT_PLUGIN2( postprocessorphilipsstereoplugin , PostProcessorPhilipsStereoPlugin );
293 #endif
294 
void push_projection_matrix()
push projection matrix
Definition: GLState.cc:967
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
Definition: ScreenQuad.cc:147
void pop_projection_matrix()
pop projection matrix
Definition: GLState.cc:985
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1006
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
Definition: GLSLShader.cc:1082
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition: GLState.cc:400
QString postProcessorName()
announce name for the postProcessor function
bool openGLVersion(const int _major, const int _minor)
Definition: gl.cc:95
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1022
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:332
bool checkExtensionSupported(const std::string &_extension)
Definition: gl.cc:73
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:819
void reset_modelview()
reset modelview matrix (load identity)
Definition: GLState.cc:368