source: trunk/src/gpu/framebuffer.cpp @ 1781

Last change on this file since 1781 was 1781, checked in by sam, 8 years ago

gpu: explicitly create render targets on the Xbox 360.

  • Property svn:keywords set to Id
File size: 6.0 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include "core.h"
16#include "lolgl.h"
17
18#if defined _WIN32 && defined USE_D3D9
19#   define FAR
20#   define NEAR
21#   include <d3d9.h>
22#endif
23
24using namespace std;
25
26#if defined USE_D3D9
27extern IDirect3DDevice9 *g_d3ddevice;
28#elif defined _XBOX
29extern D3DDevice *g_d3ddevice;
30#endif
31
32namespace lol
33{
34
35//
36// The FrameBufferData class
37// -------------------------
38//
39
40class FrameBufferData
41{
42    friend class FrameBuffer;
43
44    ivec2 m_size;
45
46#if defined USE_D3D9
47    IDirect3DTexture9 *m_texture;
48    IDirect3DSurface9 *m_surface, *m_back_surface;
49#elif defined _XBOX
50    D3DTexture *m_texture;
51    D3DSurface *m_surface, *m_back_surface;
52#else
53    GLuint m_fbo, m_texture, m_depth;
54#endif
55};
56
57//
58// The FrameBuffer class
59// ----------------------
60//
61
62FrameBuffer::FrameBuffer(ivec2 size)
63  : m_data(new FrameBufferData)
64{
65    m_data->m_size = size;
66#if defined USE_D3D9
67    if (FAILED(g_d3ddevice->CreateTexture(size.x, size.y, 1,
68                                          D3DUSAGE_RENDERTARGET,
69                                          D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
70                                          &m_data->m_texture, NULL)))
71        Abort();
72    if (FAILED(m_data->m_texture->GetSurfaceLevel(0, &m_data->m_surface)))
73        Abort();
74#elif defined _XBOX
75    if (FAILED(g_d3ddevice->CreateTexture(size.x, size.y, 1, 0,
76                                          D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
77                                          &m_data->m_texture, NULL)))
78        Abort();
79    if (FAILED(g_d3ddevice->CreateRenderTarget(size.x, size.y,
80                                               D3DFMT_A8R8G8B8,
81                                               D3DMULTISAMPLE_NONE, 0, 0,
82                                               &m_data->m_surface, NULL)))
83        Abort();
84#else
85#   if GL_VERSION_1_1
86    GLenum internal_format = GL_RGBA8;
87    GLenum format = GL_BGRA;
88    GLenum depth = GL_DEPTH_COMPONENT;
89#   else
90    GLenum internal_format = GL_RGBA;
91    GLenum format = GL_RGBA;
92#   endif
93    GLenum wrapmode = GL_REPEAT;
94    GLenum filtering = GL_NEAREST;
95
96#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
97    glGenFramebuffers(1, &m_data->m_fbo);
98    glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
99#   else
100    glGenFramebuffersOES(1, &m_data->m_fbo);
101    glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
102#   endif
103
104    glGenTextures(1, &m_data->m_texture);
105    glActiveTexture(GL_TEXTURE0);
106    glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
107    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)wrapmode);
108    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)wrapmode);
109    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)filtering);
110    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)filtering);
111    glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size.x, size.y, 0,
112                 format, GL_UNSIGNED_BYTE, NULL);
113
114#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
115    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
116                           GL_TEXTURE_2D, m_data->m_texture, 0);
117#   else
118    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT,
119                              GL_TEXTURE_2D, m_data->m_texture, 0);
120#   endif
121
122    m_data->m_depth = GL_INVALID_ENUM;
123#   if GL_VERSION_1_1
124    /* FIXME: not implemented on GL ES, see
125     * http://stackoverflow.com/q/4041682/111461 */
126    if (depth != GL_INVALID_ENUM)
127    {
128        glGenRenderbuffers(1, &m_data->m_depth);
129        glBindRenderbuffer(GL_RENDERBUFFER, m_data->m_depth);
130        glRenderbufferStorage(GL_RENDERBUFFER, depth, size.x, size.y);
131        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
132                                  GL_RENDERBUFFER, m_data->m_depth);
133    }
134#   endif
135
136#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
137    glCheckFramebufferStatus(GL_FRAMEBUFFER);
138#   endif
139
140    Unbind();
141#endif
142}
143
144FrameBuffer::~FrameBuffer()
145{
146#if defined USE_D3D9 || defined _XBOX
147    m_data->m_surface->Release();
148    m_data->m_texture->Release();
149#else
150#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
151    glDeleteFramebuffers(1, &m_data->m_fbo);
152#   else
153    glDeleteFramebuffersOES(1, &m_data->m_fbo);
154#   endif
155    glDeleteTextures(1, &m_data->m_texture);
156#   if GL_VERSION_1_1
157    if (m_data->m_depth != GL_INVALID_ENUM)
158        glDeleteRenderbuffers(1, &m_data->m_depth);
159#   endif
160#endif
161    delete m_data;
162}
163
164ShaderTexture FrameBuffer::GetTexture() const
165{
166    ShaderTexture ret;
167#if defined USE_D3D9 || defined _XBOX
168    ret.m_flags = (uint64_t)(uintptr_t)m_data->m_texture;
169#else
170    ret.m_flags = m_data->m_texture;
171#endif
172    return ret;
173}
174
175void FrameBuffer::Bind()
176{
177#if defined USE_D3D9 || defined _XBOX
178    if (FAILED(g_d3ddevice->GetRenderTarget(0, &m_data->m_back_surface)))
179        Abort();
180    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_surface)))
181        Abort();
182#else
183#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
184    glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
185#   else
186    glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
187#   endif
188#endif
189}
190
191void FrameBuffer::Unbind()
192{
193#if defined USE_D3D9
194    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface)))
195        Abort();
196    m_data->m_back_surface->Release();
197#elif defined _XBOX
198    if (FAILED(g_d3ddevice->Resolve(D3DRESOLVE_RENDERTARGET0, NULL,
199                                    m_data->m_texture, NULL, 0, 0, NULL,
200                                    0, 0, NULL)))
201        Abort();
202    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface)))
203        Abort();
204    m_data->m_back_surface->Release();
205#else
206#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
207    glBindFramebuffer(GL_FRAMEBUFFER, NULL);
208#   else
209    glBindFramebufferOES(GL_FRAMEBUFFER_OES, NULL);
210#   endif
211#endif
212}
213
214} /* namespace lol */
215
Note: See TracBrowser for help on using the repository browser.