blob: 9ca0a8dc29ae3907ecf25d174103ae3224e56d8f [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.com93a81472010-04-20 18:52:58 +000055 if (mColorbufferHandle == texture
56 && (mColorbufferType == GL_TEXTURE_2D || es2dx::IsCubemapTextureTarget(mColorbufferType)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000057 {
58 mColorbufferType = GL_NONE;
59 mColorbufferHandle = 0;
60 }
61}
62
63void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
64{
65 if (mColorbufferHandle == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
66 {
67 mColorbufferType = GL_NONE;
68 mColorbufferHandle = 0;
69 }
70
71 if (mDepthbufferHandle == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
72 {
73 mDepthbufferType = GL_NONE;
74 mDepthbufferHandle = 0;
75 }
76
77 if (mStencilbufferHandle == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
78 {
79 mStencilbufferType = GL_NONE;
80 mStencilbufferHandle = 0;
81 }
82}
83
84IDirect3DSurface9 *Framebuffer::getRenderTarget()
85{
86 Renderbuffer *colorbuffer = getColorbuffer();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000087
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000088 if (colorbuffer)
89 {
90 return colorbuffer->getRenderTarget();
91 }
92
93 return NULL;
94}
95
96IDirect3DSurface9 *Framebuffer::getDepthStencil()
97{
98 gl::Context *context = gl::getContext();
99 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000100
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101 if (depthbuffer)
102 {
103 return depthbuffer->getDepthStencil();
104 }
105
106 return NULL;
107}
108
109Colorbuffer *Framebuffer::getColorbuffer()
110{
111 gl::Context *context = gl::getContext();
112 Colorbuffer *colorbuffer = NULL;
113
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000114 if (mColorbufferType == GL_NONE)
115 {
116 UNREACHABLE();
117 colorbuffer = NULL;
118 }
119 else if (mColorbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000120 {
121 colorbuffer = context->getColorbuffer(mColorbufferHandle);
122 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000123 else
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000125 colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000126 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000127
128 if (colorbuffer && colorbuffer->isColorbuffer())
129 {
130 return colorbuffer;
131 }
132
133 return NULL;
134}
135
136Depthbuffer *Framebuffer::getDepthbuffer()
137{
138 gl::Context *context = gl::getContext();
139 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000140
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000141 if (depthbuffer && depthbuffer->isDepthbuffer())
142 {
143 return depthbuffer;
144 }
145
146 return NULL;
147}
148
149Stencilbuffer *Framebuffer::getStencilbuffer()
150{
151 gl::Context *context = gl::getContext();
152 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000153
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000154 if (stencilbuffer && stencilbuffer->isStencilbuffer())
155 {
156 return stencilbuffer;
157 }
158
159 return NULL;
160}
161
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000162GLenum Framebuffer::getColorbufferType()
163{
164 return mColorbufferType;
165}
166
167GLenum Framebuffer::getDepthbufferType()
168{
169 return mDepthbufferType;
170}
171
172GLenum Framebuffer::getStencilbufferType()
173{
174 return mStencilbufferType;
175}
176
177GLuint Framebuffer::getColorbufferHandle()
178{
179 return mColorbufferHandle;
180}
181
182GLuint Framebuffer::getDepthbufferHandle()
183{
184 return mDepthbufferHandle;
185}
186
187GLuint Framebuffer::getStencilbufferHandle()
188{
189 return mStencilbufferHandle;
190}
191
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000192GLenum Framebuffer::completeness()
193{
194 gl::Context *context = gl::getContext();
195
196 int width = 0;
197 int height = 0;
198
199 if (mColorbufferType != GL_NONE)
200 {
201 Colorbuffer *colorbuffer = getColorbuffer();
202
203 if (!colorbuffer)
204 {
205 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
206 }
207
208 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
209 {
210 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
211 }
212
213 width = colorbuffer->getWidth();
214 height = colorbuffer->getHeight();
215 }
216
217 if (mDepthbufferType != GL_NONE)
218 {
219 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
220
221 if (!depthbuffer)
222 {
223 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
224 }
225
226 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
227 {
228 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
229 }
230
231 if (width == 0)
232 {
233 width = depthbuffer->getWidth();
234 height = depthbuffer->getHeight();
235 }
236 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
237 {
238 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
239 }
240 }
241
242 if (mStencilbufferType != GL_NONE)
243 {
244 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
245
246 if (!stencilbuffer)
247 {
248 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
249 }
250
251 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
252 {
253 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
254 }
255
256 if (width == 0)
257 {
258 width = stencilbuffer->getWidth();
259 height = stencilbuffer->getHeight();
260 }
261 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
262 {
263 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
264 }
265 }
266
267 return GL_FRAMEBUFFER_COMPLETE;
268}
269}