1 #include <GLviewer/DistortionRendering.hh>
2 #include <GLviewer/GLProjectionParametersInterface.hh>
4 #include <Base/Image/Image.hh>
5 #include <Base/Image/ImageIO.hh>
6 #include <Utils/GlewInitWrapper.hh>
9 #ifdef BIAS_HAVE_CLASS_DISTORTIONRENDERING
15 template<
class imgType>
16 void Dump(
glfTexture2D& textureA,
const std::string& fileNameA)
21 BIASERR(
"could not dump to "<<fileNameA);
28 NotDistortedImageWidth_(0),
29 NotDistortedImageHeight_(0)
31 loadDistortionShaders_ =
true;
32 ClearColor_.
Set(0., 0., 0., 0.);
33 UseStencilBuffer_ =
true;
34 DistortionShadersInitialized_=
false;
46 void DistortionRendering::
47 SetQuadDataTexture_(
float* data)
83 void DistortionRendering::
84 SetupPrimitiveRendering_()
92 SetQuadDataTexture_(vertexData);
95 vertices_.
Create(4, vertexFormat, vertexData,
false );
109 GLuint quadIndices[4] = {0,1,2,3};
123 if (!GLEW_EXT_framebuffer_object) {
124 BIASWARN(
"Required rendering state not supported. Distortion rendering disabled!");
128 BIASDOUT(GLP_ACTIVITY_MEDIUM,
"[DistortionRendering ]: INIT ");
131 unsigned int distortedImageWidth=0, distortedImageHeight=0;
133 distortedImageHeight);
135 BIASDOUT(GLP_ACTIVITY_MEDIUM,
"Image Dim:"<<distortedImageWidth<<
","<<distortedImageHeight);
137 BIASASSERT(distortedImageWidth>0);
138 BIASASSERT(distortedImageHeight>0);
142 NotDistortedImageHeight_);
143 BIASDOUT(GLP_ACTIVITY_MEDIUM,
"Undistorted Image Dim:"
144 <<NotDistortedImageWidth_<<
","<<NotDistortedImageHeight_);
146 BIASASSERT(NotDistortedImageWidth_>0);
147 BIASASSERT(NotDistortedImageHeight_>0);
149 GLenum depthformat = GL_DEPTH_COMPONENT;
150 if(UseStencilBuffer_) depthformat = GL_DEPTH24_STENCIL8_EXT;
152 NotDistortedDepthTexture_.
Create();
155 NotDistortedDepthTexture_.
SetWrapT(GL_CLAMP);
156 NotDistortedDepthTexture_.
SetWrapS(GL_CLAMP);
157 NotDistortedDepthTexture_.
Allocate(NotDistortedImageWidth_,
158 NotDistortedImageHeight_,
166 glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
167 GLenum format = (alphaBits>0) ? GL_RGBA8 : GL_RGB8;
168 NotDistortedColorTexture_.
Create();
170 NotDistortedColorTexture_.
SetMinFilter(GL_LINEAR_MIPMAP_LINEAR);
172 NotDistortedColorTexture_.
SetWrapT(GL_CLAMP);
173 NotDistortedColorTexture_.
SetWrapS(GL_CLAMP);
174 NotDistortedColorTexture_.
Allocate(NotDistortedImageWidth_,
175 NotDistortedImageHeight_,
180 DistortionRenderingFBO_.
Create();
181 DistortionRenderingFBO_.
AttachTexture(NotDistortedColorTexture_,
182 GL_COLOR_ATTACHMENT0_EXT);
183 DistortionRenderingFBO_.
AttachTexture(NotDistortedDepthTexture_,
184 GL_DEPTH_ATTACHMENT_EXT);
185 if(UseStencilBuffer_)
188 DistortionRenderingFBO_.
AttachTexture(NotDistortedDepthTexture_,
189 GL_STENCIL_ATTACHMENT_EXT);
193 ClearColor_[2], ClearColor_[3]);
202 BIASDOUT(GLP_STATE_HIGH,
"[DistortionRendering ]: DISTORTION FBO OK");
205 K = projParams->
GetK();
209 Image<float> lookupTexture(distortedImageWidth, distortedImageHeight, 3);
215 BIASDOUT(GLP_STATE_HIGH,
"[DistortionRendering ]: ideal size "<<
216 NotDistortedImageWidth_<<
"x"<<NotDistortedImageHeight_);
218 for (
unsigned int y=0; y<distortedImageHeight; y++) {
219 for (
unsigned int x=0; x<distortedImageWidth; x++) {
225 source = idealK * Kinv * source;
228 source[0] /= NotDistortedImageWidth_;
229 source[1] /= NotDistortedImageHeight_;
231 tex[c++] = source[0];
232 tex[c++] = 1.0-source[1];
233 tex[c++] = source[2];
242 distortionMap_.
UploadImage(lookupTexture, GL_RGB32F_ARB);
245 if(loadDistortionShaders_) {
246 BIASDOUT(GLP_ACTIVITY_MEDIUM,
"[DistortionRendering ]: loading shaders");
248 std::string fragmentProgramCode_ =
249 "uniform sampler2D lookup;"
250 "uniform sampler2D color;"
251 "uniform sampler2D depth;"
255 " vec2 indirect = texture2D(lookup, gl_TexCoord[0].st).st;"
256 " gl_FragColor = texture2D(color, indirect);"
258 " gl_FragDepth = texture2D(depth, indirect).r;"
263 PerspectiveDistortionFragmentShader_.
Create(GL_FRAGMENT_SHADER,
264 fragmentProgramCode_);
269 distortionProgram_.
Create();
270 distortionProgram_.
AttachShader(PerspectiveDistortionFragmentShader_);
272 distortionProgram_.
Link();
283 loadDistortionShaders_ =
false;
287 targetViewport_.
SetOrigin(lastUsedGLViewport_[0],
288 lastUsedGLViewport_[1]);
289 targetViewport_.
SetSize(lastUsedGLViewport_[2],
290 lastUsedGLViewport_[3]);
292 distortionBatch_.
SetTexture(&distortionMap_, 0);
293 distortionBatch_.
SetTexture(&NotDistortedColorTexture_, 1);
294 distortionBatch_.
SetTexture(&NotDistortedDepthTexture_, 2);
302 SetupPrimitiveRendering_();
306 undistortedViewport_.
SetSize(NotDistortedImageWidth_,
307 NotDistortedImageHeight_);
309 DistortionShadersInitialized_ =
true;
310 BIASDOUT(GLP_ACTIVITY_BASIC,
"Distortion-shaders should be initialized now");
312 GLF_THROW_ON_OPENGL_ERROR;
319 DistortionShadersInitialized_ =
false;
326 glGetIntegerv(GL_VIEWPORT, lastUsedGLViewport_.
GetData());
328 if((useStencil)&&(!GLEW_EXT_packed_depth_stencil))
330 BIASWARNONCE(
"Required stencil buffer capabilites not supported." "Distortion rendering disabled!");
334 if ((!GLEW_EXT_framebuffer_object)) {
335 BIASWARNONCE(
"DistortionRendering is unsupported by your hardware");
339 BIASDOUT(GLP_ACTIVITY_HIGH,
"[DistortionRendering]:**** DrawScenes ****");
340 UseStencilBuffer_ = useStencil;
343 if(!DistortionShadersInitialized_) {
345 BIASDOUT(GLP_STATE_HIGH,
"[DistortionRendering]: Distortion not Initialized");
347 if(
Init(projParams)!=0) {
348 BIASERR(
"error during perspective distortion intialization");
351 BIASDOUT(GLP_STATE_HIGH,
352 "[DistortionRendering]: Distortion already Initialized");
355 BIASERR(
"ERROR in INIT of Distortion rendering: \n"
376 GLF_THROW_ON_OPENGL_ERROR;
380 DistortionRenderingFBO_.
Bind();
386 undistortedViewport_.
Bind();
390 ClearColor_[2], ClearColor_[3]);
403 if(UseStencilBuffer_)
420 DistortionRenderingFBO_.
Bind();
426 undistortedViewport_.
Bind();
430 ClearColor_[2], ClearColor_[3]);
443 if(UseStencilBuffer_)
457 undistortedViewport_.
Bind();
458 DistortionRenderingFBO_.
Bind();
464 if (!GLEW_EXT_framebuffer_object) {
465 BIASERR(
"Distortion rendering was not possible!");
472 renderTarget->
Bind();
474 targetViewport_.
SetOrigin(lastUsedGLViewport_[0],
475 lastUsedGLViewport_[1]);
476 targetViewport_.
SetSize(lastUsedGLViewport_[2],
477 lastUsedGLViewport_[3]);
480 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
482 glPushAttrib(GL_ALL_ATTRIB_BITS);
484 glMatrixMode(GL_MODELVIEW);
486 glMatrixMode(GL_PROJECTION);
490 distortionBatch_.
Draw();
492 for (
int i=2; i>=0; i--) {
493 glActiveTexture(GL_TEXTURE0+i);
494 glDisable(GL_TEXTURE_2D);
498 glMatrixMode(GL_PROJECTION);
500 glMatrixMode(GL_MODELVIEW);
506 glEnable(GL_DEPTH_TEST);
515 GLF_THROW_ON_OPENGL_ERROR;
522 bool& FirstRenderingPassFinished,
523 bool& informScenesOfChange,
534 for (
unsigned int i=0; i<scenes.size(); i++) {
535 if(informScenesOfChange)
536 scenes[i]->UpdateCameraRelatedState();
539 FirstRenderingPassFinished =
false;
540 informScenesOfChange =
false;
546 glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_TEXTURE_BIT |GL_STENCIL_BUFFER_BIT);
547 glEnable(GL_STENCIL_TEST);
548 glEnable(GL_DEPTH_TEST);
549 glDepthMask(GL_TRUE);
550 glStencilFunc(GL_EQUAL, 1, (GLuint)(~0));
551 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
552 glMatrixMode(GL_MODELVIEW);
555 glMatrixMode(GL_PROJECTION);
558 glDepthFunc(GL_ALWAYS);
559 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
560 glColorMask(0,0,0,1);
562 glDisable(GL_TEXTURE_2D);
565 glVertex3f(-s, s, -s);
566 glVertex3f(-s, -s, -s);
567 glVertex3f(s, -s, -s);
568 glVertex3f(s, s, -s);
570 glColorMask(1,1,1,1);
571 glDepthFunc(GL_LESS);
572 glMatrixMode(GL_PROJECTION);
574 glMatrixMode(GL_MODELVIEW);
578 glDisable(GL_STENCIL_TEST);
590 #endif // BIAS_HAVE_CLASS_DISTORTIONRENDERING
void SetVertexBuffer(const glfVertexBuffer *vertexBuffer)
Sets the vertex buffer.
void Allocate(int width, int height, GLenum internalFormat, int mipmap=0)
Creates a texture with undefined content.
void AttachTexture(const glfTexture &texture, GLenum attachmentPoint, int attachedMipMapLevel=0, int zSlice=0, GLenum cubeMapSide=0)
Attaches a texture to an attachment point which can be.
void Create()
Creates the shader program.
void SetUniform(const std::string &varName, float value)
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
void SetPrimitiveType(GLenum primitiveType)
Sets the primitive type to rendering.
void SetDepthFunc(GLenum depthFunc)
Sets the depth buffer comparison function.
virtual void Bind() const
Binds the viewport.
void Link()
Links the attached shaders.
void AttachShader(const glfShader &shader)
Attaches a shader to the program.
void Create()
Creates the texture but does not upload any data yet.
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
void SetDepthBufferMode(const glfDepthBufferMode *depthBufferMode)
Sets the depth buffer mode.
void Create(GLenum type)
Creates the shader without the GLSL source code, use other Create() methods to upload source afterwar...
void Draw()
Draws the batch.
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
int Init(BIAS::ProjectionParametersPerspective *projParams)
void SetWrapS(GLenum wrapS)
Sets the wrapping mode for the 1st texture coordinate.
void Set(const T &scalar)
set all elements to a scalat value
int DrawScenes(std::vector< SceneBase * > &scenes, bool &FirstRenderingPassFinished, bool &informScenesOfChange, BIAS::ProjectionParametersPerspective *projParams, BIAS::glfRenderTarget *renderTarget, bool useStencil=false)
void UploadImage(const BIAS::ImageBase &image, GLenum internalFormat=0, int mipmap=0)
Uploads a BIAS::Image to a mipmap of the texture.
void CopyToImage(ImageBase &image, int mipmap=0)
Copies the pixels of a mipmap of the texture to a BIAS::ImageBase.
Exception class used for run-time errors in the OpenGLFramework.
int BeginRendering(BIAS::ProjectionParametersPerspective *projParams, bool useStencil=false)
void Create(int numVertices, const glfVertexFormat &format, const void *data=NULL, bool useBufferIfPossible=true)
Creates the vertex buffer for the given number of vertices and vertex format.
const std::string & GetMessageString() const
Returns the description of the error including the file name and line number where the error occured...
void SetMinFilter(GLenum minFilter)
Sets the minifying function.
void SetViewport(const glfViewport *viewport)
Sets the viewport.
int EndRendering(BIAS::glfRenderTarget *renderTarget)
void CheckComplete() const
Checks whether the framebuffer object is supported in its current state.
virtual void Bind() const =0
Makes this render target the currently used render target.
void SetTexture(const glfTexture *texture, int textureUnit)
Sets the texture of a texture unit.
void SetWrapT(GLenum wrapT)
Sets the wrapping mode for the 2nd texture coordinate.
The image template class for specific storage types.
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
void SetRenderTarget(const glfRenderTarget *renderTarget)
Sets the render target.
void GetIdealK(KMatrix &K) const
void ClearDepthBuffer(float depth=1.0f)
Clears the depth buffer of the render target with the given value.
virtual int GetImageSize(unsigned int &Width, unsigned int &Height) const
Obtain image dimensions.
void Create(int numIndices, GLenum type, GLenum mode, const void *indices)
Creates the element buffer for the given number of indices.
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
virtual bool Undistort(BIAS::HomgPoint2D &point2d) const
Using the Matlab camera calibration toolbox parameters for an undistortion of distorted coordinates...
virtual BIAS::KMatrix GetK() const
void SetShaderProgram(const glfShaderProgram *shaderProgram)
Sets the shader program.
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn't change the...
void SetDepthTest(bool enable)
Sets whether to use depth buffer tests.
void SetSize(int width, int height)
Sets the size of the viewport in pixel coordinates.
void GenerateMipMap()
Explicitly generates the mipmaps of the texture in hardware.
virtual void Bind() const
Makes this render target the currently used render target.
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
void SetOrigin(int x, int y)
Sets the position of the upper-left corner of the viewport in pixel coordinates.
void SetElementBuffer(const glfElementBuffer *elementBuffer)
Sets the element buffer.
void ClearStencilBuffer(int s=0)
Clears the stencil buffer of the render target with the given value.
void ClearColorBuffer(float red=0.0f, float green=0.0f, float blue=0.0f, float alpha=0.0f)
Clears the color buffer of the render target with the given color.
void GetIdealImageSize(unsigned int &width, unsigned int &height) const
KMatrix Invert() const
returns analyticaly inverted matrix
Interface for render targets.
void SetRange(int first, int count)
Sets the range of vertices to be rendered if no element buffer is set, or the range of vertex indices...
void Create()
Creates the framebuffer object.
void SetMagFilter(GLenum magFilter)
Sets the magnification function.