blob: fcddd91c57a86811d324b3fa0f9790e7237e4ddc [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
8// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
9
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000010#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000012#include "libGLESv2/main.h"
13#include "libGLESv2/Renderbuffer.h"
14#include "libGLESv2/Texture.h"
daniel@transgaming.com93a81472010-04-20 18:52:58 +000015#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
17namespace gl
18{
19Framebuffer::Framebuffer()
20{
21 mColorbufferType = GL_NONE;
22 mColorbufferHandle = 0;
23
24 mDepthbufferType = GL_NONE;
25 mDepthbufferHandle = 0;
26
27 mStencilbufferType = GL_NONE;
28 mStencilbufferHandle = 0;
29}
30
31Framebuffer::~Framebuffer()
32{
33}
34
35void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
36{
37 mColorbufferType = type;
38 mColorbufferHandle = colorbuffer;
39}
40
41void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
42{
43 mDepthbufferType = type;
44 mDepthbufferHandle = depthbuffer;
45}
46
47void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
48{
49 mStencilbufferType = type;
50 mStencilbufferHandle = stencilbuffer;
51}
52
53void Framebuffer::detachTexture(GLuint texture)
54{
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000055 if (mColorbufferHandle == texture && es2dx::IsTextureTarget(mColorbufferType))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056 {
57 mColorbufferType = GL_NONE;
58 mColorbufferHandle = 0;
59 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000060
61 if (mDepthbufferHandle == texture && es2dx::IsTextureTarget(mDepthbufferType))
62 {
63 mDepthbufferType = GL_NONE;
64 mDepthbufferHandle = 0;
65 }
66
67 if (mStencilbufferHandle == texture && es2dx::IsTextureTarget(mStencilbufferType))
68 {
69 mStencilbufferType = GL_NONE;
70 mStencilbufferHandle = 0;
71 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072}
73
74void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
75{
76 if (mColorbufferHandle == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
77 {
78 mColorbufferType = GL_NONE;
79 mColorbufferHandle = 0;
80 }
81
82 if (mDepthbufferHandle == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
83 {
84 mDepthbufferType = GL_NONE;
85 mDepthbufferHandle = 0;
86 }
87
88 if (mStencilbufferHandle == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
89 {
90 mStencilbufferType = GL_NONE;
91 mStencilbufferHandle = 0;
92 }
93}
94
95IDirect3DSurface9 *Framebuffer::getRenderTarget()
96{
97 Renderbuffer *colorbuffer = getColorbuffer();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000098
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000099 if (colorbuffer)
100 {
101 return colorbuffer->getRenderTarget();
102 }
103
104 return NULL;
105}
106
107IDirect3DSurface9 *Framebuffer::getDepthStencil()
108{
109 gl::Context *context = gl::getContext();
110 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000111
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000112 if (depthbuffer)
113 {
114 return depthbuffer->getDepthStencil();
115 }
116
117 return NULL;
118}
119
120Colorbuffer *Framebuffer::getColorbuffer()
121{
122 gl::Context *context = gl::getContext();
123 Colorbuffer *colorbuffer = NULL;
124
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000125 if (mColorbufferType == GL_NONE)
126 {
127 UNREACHABLE();
128 colorbuffer = NULL;
129 }
130 else if (mColorbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131 {
132 colorbuffer = context->getColorbuffer(mColorbufferHandle);
133 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000134 else
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000136 colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138
139 if (colorbuffer && colorbuffer->isColorbuffer())
140 {
141 return colorbuffer;
142 }
143
144 return NULL;
145}
146
147Depthbuffer *Framebuffer::getDepthbuffer()
148{
149 gl::Context *context = gl::getContext();
150 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000151
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152 if (depthbuffer && depthbuffer->isDepthbuffer())
153 {
154 return depthbuffer;
155 }
156
157 return NULL;
158}
159
160Stencilbuffer *Framebuffer::getStencilbuffer()
161{
162 gl::Context *context = gl::getContext();
163 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000164
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000165 if (stencilbuffer && stencilbuffer->isStencilbuffer())
166 {
167 return stencilbuffer;
168 }
169
170 return NULL;
171}
172
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000173GLenum Framebuffer::getColorbufferType()
174{
175 return mColorbufferType;
176}
177
178GLenum Framebuffer::getDepthbufferType()
179{
180 return mDepthbufferType;
181}
182
183GLenum Framebuffer::getStencilbufferType()
184{
185 return mStencilbufferType;
186}
187
188GLuint Framebuffer::getColorbufferHandle()
189{
190 return mColorbufferHandle;
191}
192
193GLuint Framebuffer::getDepthbufferHandle()
194{
195 return mDepthbufferHandle;
196}
197
198GLuint Framebuffer::getStencilbufferHandle()
199{
200 return mStencilbufferHandle;
201}
202
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203GLenum Framebuffer::completeness()
204{
205 gl::Context *context = gl::getContext();
206
207 int width = 0;
208 int height = 0;
209
210 if (mColorbufferType != GL_NONE)
211 {
212 Colorbuffer *colorbuffer = getColorbuffer();
213
214 if (!colorbuffer)
215 {
216 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
217 }
218
219 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
220 {
221 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
222 }
223
224 width = colorbuffer->getWidth();
225 height = colorbuffer->getHeight();
226 }
227
228 if (mDepthbufferType != GL_NONE)
229 {
230 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
231
232 if (!depthbuffer)
233 {
234 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
235 }
236
237 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
238 {
239 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
240 }
241
242 if (width == 0)
243 {
244 width = depthbuffer->getWidth();
245 height = depthbuffer->getHeight();
246 }
247 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
248 {
249 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
250 }
251 }
252
253 if (mStencilbufferType != GL_NONE)
254 {
255 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
256
257 if (!stencilbuffer)
258 {
259 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
260 }
261
262 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
263 {
264 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
265 }
266
267 if (width == 0)
268 {
269 width = stencilbuffer->getWidth();
270 height = stencilbuffer->getHeight();
271 }
272 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
273 {
274 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
275 }
276 }
277
278 return GL_FRAMEBUFFER_COMPLETE;
279}
280}