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 #include <ACG/GL/acg_glew.hh>
44
45 #include "PostProcessorPhilipsStereo.hh"
46
47 #include <ACG/GL/ScreenQuad.hh>
48
49 #include <OpenFlipper/BasePlugin/PluginFunctions.hh>
50 #include <OpenFlipper/common/GlobalOptions.hh>
51
52 #include "CRC/crc32.hh"
53
54 PostProcessorPhilipsStereoPlugin::PostProcessorPhilipsStereoPlugin():
55 pProgram_(0),
56 settingsWidget_(0)
57 {
58
59 }
60
61 QString PostProcessorPhilipsStereoPlugin::postProcessorName() {
62 return QString("Philips Stereo Display Output");
63 }
64
65 QAction* PostProcessorPhilipsStereoPlugin::optionsAction() {
66 QAction* action = new QAction("Philips Stereo Options",0);
67 connect(action,SIGNAL(triggered()),this,SLOT(slotShowOptionsMenu()));
68 return action;
69 }
70
71
72
73 QString PostProcessorPhilipsStereoPlugin::checkOpenGL() {
74 if ( ! ACG::openGLVersion(3, 0) )
75 return QString("Insufficient OpenGL Version! OpenGL 3.0 or higher required");
76
77 // Check extensions
78 QString missing("");
79 if ( !ACG::checkExtensionSupported("GL_ARB_texture_rectangle") )
80 missing += "GL_ARB_texture_rectangle extension missing\n";
81
82 return missing;
83 }
84
85 //-----------------------------------------------------------------------------
86
87 void PostProcessorPhilipsStereoPlugin::postProcess(ACG::GLState* _glstate, const std::vector<const PostProcessorInput*>& _input, const PostProcessorOutput& _output) {
88
89 // load shader if needed
90 if (!pProgram_)
91 pProgram_ = GLSL::loadProgram("Philips/screenquad.glsl", "Philips/Fragment42.glsl");
92
93 if (!pProgram_)
94 return;
95
96 int vp_l, vp_b, vp_w, vp_h;
97 _glstate->get_viewport(vp_l, vp_b, vp_w, vp_h);
98
99
100 // Turn on shader program
101 pProgram_->use();
102
103 // ======================================================================================================
104 // Bind textures to different texture units and tell shader where to find them
105 // ======================================================================================================
106 _input[0]->bindDepthTex(1);
107 _input[0]->bindColorTex(0);
108
109 pProgram_->setUniform("ColorTexture", 0);
110 pProgram_->setUniform("DepthStencil", 1);
111
112 // ======================================================================================================
113 // Setup render states
114 // ======================================================================================================
115
116 glDisable(GL_LIGHTING);
117 glDisable(GL_COLOR_MATERIAL);
118 glDisable(GL_DEPTH_TEST);
119 glDisable(GL_BLEND);
120
121 glDepthMask(1);
122 glColorMask(1,1,1,1);
123
124 // ======================================================================================================
125 // Setup orthogonal projection
126 // ======================================================================================================
127 _glstate->push_projection_matrix();
128 _glstate->push_modelview_matrix();
129
130 _glstate->reset_projection();
131 _glstate->reset_modelview();
132
133 _glstate->ortho(0, vp_w, 0, vp_h, 0, 1);
134
135 // ======================================================================================================
136 // Bind textures to different texture units and tell shader where to find them
137 // ======================================================================================================
138 glColor3f(1.0, 1.0, 1.0);
139
140
141 // ======================================================================================================
142 // Bind output FBO
143 // ======================================================================================================
144
145 _output.bind();
146
147 // ======================================================================================================
148 // Execute
149 // ======================================================================================================
150 ACG::ScreenQuad::draw(pProgram_);
151
152
153 pProgram_->disable();
154
155 glBindTexture(GL_TEXTURE_2D, 0);
156
157 // ======================================================================================================
158 // Compute the header required for the display
159 // ======================================================================================================
160 uchar *header = new uchar[6];
161
162 // Header ID
163 // Basic identifier used by the display to verify the header
164 header[0] = 241; // Header_ID1 = 11110001
165
166 // Header content type
167 // This entry controls the displays internal rendering based on the input data specified here.
168 // There is no info about how this changes the rendering
169 // Possible values:
170 // 0 No Depth
171 // 1 Signage
172 // 2 Movie
173 // 3 Game
174 // 4 CGI
175 // 5 Still
176 header[1] = OpenFlipperSettings().value("Core/Stereo/Philips/Content",3).toInt(); // Hdr_Content_type (Game) = 00000011 (Gaming Mode)
177
178 // Header Factor
179 // Each 3D Display has a 'Display recommended depth value', which corresponds to an
180 // acceptable maximum depth factor value for that specific type of display. This value strongly
181 // depends on the lens design. The factor field in the header contains the percentage to be
182 // used from the display recommended depth value. The value of 64 corresponds with the 100%
183 // of the display recommended depth value. It is allowed to use values higher than 64. The factor
184 // works on a linear scale and is multiplied with the factor controlled by the user in the Display
185 // Control Tool.
186 // Value range: 0-255 (default 64)
187 header[2] = OpenFlipperSettings().value("Core/Stereo/Philips/Factor",64).toInt(); // Hdr_Factor
188
189 // Header Offset CC
190 // Values in the Depth map equal to the header-offset value will be located on the plane of the
191 // display. All values in the disparity map with a higher value will de displayed in front of the
192 // display.
193 // Offset_CC is the offset controlled by the Content Creator. In the system there is also an
194 // Offset_user present, which is controlled by the user using the Display Control Tool.
195 // Value Range: 0-255 (default 128)
196 header[3] = OpenFlipperSettings().value("Core/Stereo/Philips/Offset",128).toInt(); // Hdr_Offset_CC
197
198 // Header select
199 // When all select signals are low the rendering settings are set to optimal settings for the content
200 // type denoted by Hdr_content_type. By making select signals high the settings for Factor and
201 // Offset_cc can be controlled individually by the header.
202 // Possible Values:
203 // 0 Use Displays defaults and automatic optimizations
204 // 1 Use Header provided factor
205 // 2 Use Header provided offset
206 // 3 Use both factor and offset
207 header[4] = OpenFlipperSettings().value("Core/Stereo/Philips/Select",0).toInt(); // Hdr_Factor_select(1) + Hdr_Offset_select(1) + reserved(6)
208
209 // Unused Header entry (leave at 0 !)
210 header[5] = 0; // Reserved
211
212 // Header checksum.
213 // The 4-byte EDC field H(6) − H(9) contains an Error Detection Code computed over the first 6
214 // header bytes. This EDC uses the standard CRC-32 polynomial as defined in IEEE 802.3 and ITU-T
215 // V.42. The initial value and final XOR value are both 0.
216 // unsigned long has 32bit = 4Byte
217 unsigned long checksum = CalcCRC32(&header[0], 6);
218
219 // Store the complete header in a bit vector
220 std::vector<uchar> bitVector;
221
222 // For all bytes of the header
223 for (int i = 0; i < 6; i++) {
224
225 // For each bit of a headers byte
226 for (int j = 7; j >= 0; --j) {
227
228 // Red and Green component have to be 0
229 bitVector.push_back(0);
230 bitVector.push_back(0);
231
232 // If bit is set, the full component will be set to one otherwise zero
233 // And the order of the bits has to be reversed!
234 if (header[i] & (1 << j)) {
235 bitVector.push_back(255);
236 } else {
237 bitVector.push_back(0);
238 }
239
240 // Only every second pixel is used for the header
241 // Skip every odd one by filling in 0 for RGB
242 bitVector.push_back(0);
243 bitVector.push_back(0);
244 bitVector.push_back(0);
245 }
246 }
247
248 // Append checksum to header.
249 // Reversed bit order!
250 for (int i = 31; i >= 0; i--) {
251
252 // Red and Green component have to be 0
253 bitVector.push_back(0);
254 bitVector.push_back(0);
255
256 if (checksum & (1 << i))
257 bitVector.push_back(255);
258 else
259 bitVector.push_back(0);
260
261 // Only every second pixel is used for the header
262 // Skip every odd one by filling in 0 for RGB
263 bitVector.push_back(0);
264 bitVector.push_back(0);
265 bitVector.push_back(0);
266 }
267
268 // Select the top left of the renderbuffer and
269 // write complete header into these bits
270 // glRasterPos2i(0, _glstate->context_height() - 1);
271 glRasterPos2i(_output.viewport_[0], _output.viewport_[1] + _output.height - 1);
272 glDrawPixels(bitVector.size() / 3, 1, GL_RGB, GL_UNSIGNED_BYTE, &bitVector[0]);
273
274 // ======================================================================================================
275 // Reset projection and modelview
276 // ======================================================================================================
277 _glstate->pop_projection_matrix();
278 _glstate->pop_modelview_matrix();
279
280
281 }
282
283
OpenFlipperSettings
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.cc:1038
ACG::GLState::push_modelview_matrix
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1010
PluginFunctions.hh
ACG::GLState::reset_modelview
void reset_modelview()
reset modelview matrix (load identity)
Definition: GLState.cc:370
ACG::GLState::push_projection_matrix
void push_projection_matrix()
push projection matrix
Definition: GLState.cc:971
GlobalOptions.hh
ACG::GLState::ortho
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition: GLState.cc:402
ACG::GLState
Definition: GLState.hh:213
PostProcessorOutput
Definition: PostProcessorInterface.hh:89
ACG::GLState::get_viewport
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:816
PostProcessorPhilipsStereoPlugin::postProcessorName
QString postProcessorName()
announce name for the postProcessor function
Definition: PostProcessorPhilipsStereo.cc:61
ACG::GLState::reset_projection
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:334
ACG::ScreenQuad::draw
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
Definition: ScreenQuad.cc:138
OpenFlipperQSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: OpenFlipperQSettings.cc:46
ACG::GLState::pop_modelview_matrix
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1026
GLSL::loadProgram
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:1076
ACG::GLState::pop_projection_matrix
void pop_projection_matrix()
pop projection matrix
Definition: GLState.cc:989
ACG::checkExtensionSupported
bool checkExtensionSupported(const std::string &_extension)
Definition: gl.cc:107
ACG::openGLVersion
bool openGLVersion(const int _major, const int _minor, bool _verbose)
Definition: gl.cc:129