0025703: Visualization - Decrease number of samplers used in ray-tracing mode
[occt.git] / src / OpenGl / OpenGl_FrameBuffer.cxx
CommitLineData
b311480e 1// Created by: Kirill GAVRILOV
973c2be1 2// Copyright (c) 2011-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15#include <OpenGl_FrameBuffer.hxx>
01ca42b2 16#include <OpenGl_ArbFBO.hxx>
7fd59977 17
fd4a6963 18#include <Standard_Assert.hxx>
19
20IMPLEMENT_STANDARD_HANDLE (OpenGl_FrameBuffer, OpenGl_Resource)
21IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_Resource)
7fd59977 22
7fd59977 23static inline bool isOddNumber (const GLsizei theNumber)
24{
25 return theNumber & 0x01;
26}
27
28static inline GLsizei getEvenNumber (const GLsizei theNumber)
29{
30 return isOddNumber (theNumber) ? (theNumber + 1) : theNumber;
31}
32
33//! Notice - 0 is not power of two here
34static inline bool isPowerOfTwo (const GLsizei theNumber)
35{
18f4e8e2 36 return !(theNumber & (theNumber - 1));
7fd59977 37}
38
fd4a6963 39// =======================================================================
40// function : OpenGl_FrameBuffer
41// purpose :
42// =======================================================================
7fd59977 43OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
18f4e8e2 44: myVPSizeX (0),
7fd59977 45 myVPSizeY (0),
46 myTextFormat (theTextureFormat),
7fd59977 47 myGlFBufferId (NO_FRAMEBUFFER),
18f4e8e2 48 myColorTexture (new OpenGl_Texture()),
49 myDepthStencilTexture (new OpenGl_Texture())
7fd59977 50{
51 //
52}
53
fd4a6963 54// =======================================================================
55// function : ~OpenGl_FrameBuffer
56// purpose :
57// =======================================================================
58OpenGl_FrameBuffer::~OpenGl_FrameBuffer()
59{
60 Release (NULL);
61}
62
63// =======================================================================
64// function : Init
65// purpose :
66// =======================================================================
2166f0fa 67Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
fd4a6963 68 const GLsizei theViewportSizeX,
18f4e8e2 69 const GLsizei theViewportSizeY)
7fd59977 70{
01ca42b2 71 if (theGlContext->arbFBO == NULL)
7fd59977 72 {
7fd59977 73 return Standard_False;
74 }
75
76 // clean up previous state
fd4a6963 77 Release (theGlContext.operator->());
7fd59977 78
7fd59977 79 // setup viewport sizes as is
80 myVPSizeX = theViewportSizeX;
81 myVPSizeY = theViewportSizeY;
82
18f4e8e2 83 // Create the textures (will be used as color buffer and depth-stencil buffer)
84 if (!initTrashTextures (theGlContext))
7fd59977 85 {
fd4a6963 86 Release (theGlContext.operator->());
7fd59977 87 return Standard_False;
88 }
89
7fd59977 90 // Build FBO and setup it as texture
01ca42b2 91 theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
92 theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
18f4e8e2 93 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
94 GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
ca3c13d1 95#ifdef GL_DEPTH_STENCIL_ATTACHMENT
18f4e8e2 96 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
97 GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
ca3c13d1 98#else
99 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
100 GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
101 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
102 GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
103#endif
01ca42b2 104 if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
7fd59977 105 {
fd4a6963 106 Release (theGlContext.operator->());
7fd59977 107 return Standard_False;
108 }
109
18f4e8e2 110 UnbindBuffer (theGlContext);
7fd59977 111 return Standard_True;
112}
113
fd4a6963 114// =======================================================================
115// function : Release
116// purpose :
117// =======================================================================
10b9c7df 118void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
7fd59977 119{
18f4e8e2 120 if (isValidFrameBuffer())
7fd59977 121 {
fd4a6963 122 // application can not handle this case by exception - this is bug in code
123 Standard_ASSERT_RETURN (theGlCtx != NULL,
124 "OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",);
fd4a6963 125 if (theGlCtx->IsValid())
2166f0fa 126 {
01ca42b2 127 theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId);
2166f0fa 128 }
fd4a6963 129 myGlFBufferId = NO_FRAMEBUFFER;
7fd59977 130 }
7fd59977 131
18f4e8e2 132 myColorTexture->Release (theGlCtx);
133 myDepthStencilTexture->Release (theGlCtx);
7fd59977 134}
135
fd4a6963 136// =======================================================================
137// function : initTrashTexture
138// purpose :
139// =======================================================================
18f4e8e2 140Standard_Boolean OpenGl_FrameBuffer::initTrashTextures (const Handle(OpenGl_Context)& theGlContext)
7fd59977 141{
18f4e8e2 142 return myColorTexture->Init (theGlContext, myTextFormat,
143 GL_RGBA, GL_UNSIGNED_BYTE,
144 myVPSizeX, myVPSizeY, Graphic3d_TOT_2D)
145 && myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
146 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
147 myVPSizeX, myVPSizeY, Graphic3d_TOT_2D);
7fd59977 148}
fd4a6963 149
150// =======================================================================
151// function : SetupViewport
152// purpose :
153// =======================================================================
154void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& /*theGlCtx*/)
155{
156 glViewport (0, 0, myVPSizeX, myVPSizeY);
157}
158
159// =======================================================================
160// function : ChangeViewport
161// purpose :
162// =======================================================================
163void OpenGl_FrameBuffer::ChangeViewport (const GLsizei theVPSizeX,
164 const GLsizei theVPSizeY)
165{
166 myVPSizeX = theVPSizeX;
167 myVPSizeY = theVPSizeY;
168}
169
170// =======================================================================
171// function : BindBuffer
172// purpose :
173// =======================================================================
174void OpenGl_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theGlCtx)
175{
01ca42b2 176 theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
fd4a6963 177}
178
179// =======================================================================
180// function : UnbindBuffer
181// purpose :
182// =======================================================================
183void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx)
184{
01ca42b2 185 theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);
fd4a6963 186}