blob: ee54ad150e407740c0a78c79de15f2cd801f42d3 [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
162GLenum Framebuffer::completeness()
163{
164 gl::Context *context = gl::getContext();
165
166 int width = 0;
167 int height = 0;
168
169 if (mColorbufferType != GL_NONE)
170 {
171 Colorbuffer *colorbuffer = getColorbuffer();
172
173 if (!colorbuffer)
174 {
175 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
176 }
177
178 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
179 {
180 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
181 }
182
183 width = colorbuffer->getWidth();
184 height = colorbuffer->getHeight();
185 }
186
187 if (mDepthbufferType != GL_NONE)
188 {
189 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
190
191 if (!depthbuffer)
192 {
193 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
194 }
195
196 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
197 {
198 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
199 }
200
201 if (width == 0)
202 {
203 width = depthbuffer->getWidth();
204 height = depthbuffer->getHeight();
205 }
206 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
207 {
208 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
209 }
210 }
211
212 if (mStencilbufferType != GL_NONE)
213 {
214 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
215
216 if (!stencilbuffer)
217 {
218 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
219 }
220
221 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
222 {
223 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
224 }
225
226 if (width == 0)
227 {
228 width = stencilbuffer->getWidth();
229 height = stencilbuffer->getHeight();
230 }
231 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
232 {
233 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
234 }
235 }
236
237 return GL_FRAMEBUFFER_COMPLETE;
238}
239}