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 | |
20 | IMPLEMENT_STANDARD_HANDLE (OpenGl_FrameBuffer, OpenGl_Resource) |
21 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_Resource) |
7fd59977 |
22 | |
fd4a6963 |
23 | // ======================================================================= |
24 | // function : OpenGl_FrameBuffer |
25 | // purpose : |
26 | // ======================================================================= |
7fd59977 |
27 | OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat) |
18f4e8e2 |
28 | : myVPSizeX (0), |
7fd59977 |
29 | myVPSizeY (0), |
30 | myTextFormat (theTextureFormat), |
7fd59977 |
31 | myGlFBufferId (NO_FRAMEBUFFER), |
18f4e8e2 |
32 | myColorTexture (new OpenGl_Texture()), |
33 | myDepthStencilTexture (new OpenGl_Texture()) |
7fd59977 |
34 | { |
35 | // |
36 | } |
37 | |
fd4a6963 |
38 | // ======================================================================= |
39 | // function : ~OpenGl_FrameBuffer |
40 | // purpose : |
41 | // ======================================================================= |
42 | OpenGl_FrameBuffer::~OpenGl_FrameBuffer() |
43 | { |
44 | Release (NULL); |
45 | } |
46 | |
47 | // ======================================================================= |
48 | // function : Init |
49 | // purpose : |
50 | // ======================================================================= |
2166f0fa |
51 | Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext, |
fd4a6963 |
52 | const GLsizei theViewportSizeX, |
18f4e8e2 |
53 | const GLsizei theViewportSizeY) |
7fd59977 |
54 | { |
01ca42b2 |
55 | if (theGlContext->arbFBO == NULL) |
7fd59977 |
56 | { |
7fd59977 |
57 | return Standard_False; |
58 | } |
59 | |
60 | // clean up previous state |
fd4a6963 |
61 | Release (theGlContext.operator->()); |
7fd59977 |
62 | |
7fd59977 |
63 | // setup viewport sizes as is |
64 | myVPSizeX = theViewportSizeX; |
65 | myVPSizeY = theViewportSizeY; |
66 | |
18f4e8e2 |
67 | // Create the textures (will be used as color buffer and depth-stencil buffer) |
68 | if (!initTrashTextures (theGlContext)) |
7fd59977 |
69 | { |
fd4a6963 |
70 | Release (theGlContext.operator->()); |
7fd59977 |
71 | return Standard_False; |
72 | } |
73 | |
7fd59977 |
74 | // Build FBO and setup it as texture |
01ca42b2 |
75 | theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId); |
76 | theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId); |
18f4e8e2 |
77 | theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
78 | GL_TEXTURE_2D, myColorTexture->TextureId(), 0); |
ca3c13d1 |
79 | #ifdef GL_DEPTH_STENCIL_ATTACHMENT |
18f4e8e2 |
80 | theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
81 | GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0); |
ca3c13d1 |
82 | #else |
83 | theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, |
84 | GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0); |
85 | theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, |
86 | GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0); |
87 | #endif |
01ca42b2 |
88 | if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
7fd59977 |
89 | { |
fd4a6963 |
90 | Release (theGlContext.operator->()); |
7fd59977 |
91 | return Standard_False; |
92 | } |
93 | |
18f4e8e2 |
94 | UnbindBuffer (theGlContext); |
7fd59977 |
95 | return Standard_True; |
96 | } |
97 | |
fd4a6963 |
98 | // ======================================================================= |
99 | // function : Release |
100 | // purpose : |
101 | // ======================================================================= |
10b9c7df |
102 | void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx) |
7fd59977 |
103 | { |
18f4e8e2 |
104 | if (isValidFrameBuffer()) |
7fd59977 |
105 | { |
fd4a6963 |
106 | // application can not handle this case by exception - this is bug in code |
107 | Standard_ASSERT_RETURN (theGlCtx != NULL, |
108 | "OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",); |
fd4a6963 |
109 | if (theGlCtx->IsValid()) |
2166f0fa |
110 | { |
01ca42b2 |
111 | theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId); |
2166f0fa |
112 | } |
fd4a6963 |
113 | myGlFBufferId = NO_FRAMEBUFFER; |
7fd59977 |
114 | } |
7fd59977 |
115 | |
18f4e8e2 |
116 | myColorTexture->Release (theGlCtx); |
117 | myDepthStencilTexture->Release (theGlCtx); |
7fd59977 |
118 | } |
119 | |
fd4a6963 |
120 | // ======================================================================= |
121 | // function : initTrashTexture |
122 | // purpose : |
123 | // ======================================================================= |
18f4e8e2 |
124 | Standard_Boolean OpenGl_FrameBuffer::initTrashTextures (const Handle(OpenGl_Context)& theGlContext) |
7fd59977 |
125 | { |
18f4e8e2 |
126 | return myColorTexture->Init (theGlContext, myTextFormat, |
127 | GL_RGBA, GL_UNSIGNED_BYTE, |
128 | myVPSizeX, myVPSizeY, Graphic3d_TOT_2D) |
129 | && myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8, |
130 | GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, |
131 | myVPSizeX, myVPSizeY, Graphic3d_TOT_2D); |
7fd59977 |
132 | } |
fd4a6963 |
133 | |
134 | // ======================================================================= |
135 | // function : SetupViewport |
136 | // purpose : |
137 | // ======================================================================= |
138 | void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& /*theGlCtx*/) |
139 | { |
140 | glViewport (0, 0, myVPSizeX, myVPSizeY); |
141 | } |
142 | |
143 | // ======================================================================= |
144 | // function : ChangeViewport |
145 | // purpose : |
146 | // ======================================================================= |
147 | void OpenGl_FrameBuffer::ChangeViewport (const GLsizei theVPSizeX, |
148 | const GLsizei theVPSizeY) |
149 | { |
150 | myVPSizeX = theVPSizeX; |
151 | myVPSizeY = theVPSizeY; |
152 | } |
153 | |
154 | // ======================================================================= |
155 | // function : BindBuffer |
156 | // purpose : |
157 | // ======================================================================= |
158 | void OpenGl_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theGlCtx) |
159 | { |
01ca42b2 |
160 | theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId); |
fd4a6963 |
161 | } |
162 | |
b86bb3df |
163 | // ======================================================================= |
164 | // function : BindDrawBuffer |
165 | // purpose : |
166 | // ======================================================================= |
167 | void OpenGl_FrameBuffer::BindDrawBuffer (const Handle(OpenGl_Context)& theGlCtx) |
168 | { |
169 | theGlCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myGlFBufferId); |
170 | } |
171 | |
172 | // ======================================================================= |
173 | // function : BindReadBuffer |
174 | // purpose : |
175 | // ======================================================================= |
176 | void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx) |
177 | { |
178 | theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId); |
179 | } |
180 | |
fd4a6963 |
181 | // ======================================================================= |
182 | // function : UnbindBuffer |
183 | // purpose : |
184 | // ======================================================================= |
185 | void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx) |
186 | { |
01ca42b2 |
187 | theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER); |
fd4a6963 |
188 | } |