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