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

Last change on this file since 2506 was 2506, checked in by sam, 7 years ago

base: start removing occurrences of NULL on our long journey to nullptr.

  • Property svn:keywords set to Id
File size: 6.3 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 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://www.wtfpl.net/ 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, nullptr)))
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, nullptr)))
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, nullptr)))
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#   elif defined __CELLOS_LV2__
90    /* Supported drawable formats on the PS3: GL_ARGB_SCE, GL_RGB16F_ARB,
91     * GL_RGBA16F_ARB, GL_RGB32F_ARB, GL_RGBA32F_ARB, GL_LUMINANCE32F_ARB. */
92    GLenum internal_format = GL_ARGB_SCE;
93    GLenum format = GL_RGBA;
94#   else
95    GLenum internal_format = GL_RGBA;
96    GLenum format = GL_RGBA;
97#   endif
98    GLenum wrapmode = GL_REPEAT;
99    GLenum filtering = GL_NEAREST;
100
101#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
102    glGenFramebuffers(1, &m_data->m_fbo);
103    glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
104#   else
105    glGenFramebuffersOES(1, &m_data->m_fbo);
106    glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
107#   endif
108
109    glGenTextures(1, &m_data->m_texture);
110    glActiveTexture(GL_TEXTURE0);
111    glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
112    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)wrapmode);
113    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)wrapmode);
114    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)filtering);
115    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)filtering);
116    glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size.x, size.y, 0,
117                 format, GL_UNSIGNED_BYTE, nullptr);
118
119#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
120    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
121                           GL_TEXTURE_2D, m_data->m_texture, 0);
122#   else
123    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT,
124                              GL_TEXTURE_2D, m_data->m_texture, 0);
125#   endif
126
127    m_data->m_depth = GL_INVALID_ENUM;
128#   if GL_VERSION_1_1
129    /* FIXME: not implemented on GL ES, see
130     * http://stackoverflow.com/q/4041682/111461 */
131    if (depth != GL_INVALID_ENUM)
132    {
133        glGenRenderbuffers(1, &m_data->m_depth);
134        glBindRenderbuffer(GL_RENDERBUFFER, m_data->m_depth);
135        glRenderbufferStorage(GL_RENDERBUFFER, depth, size.x, size.y);
136        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
137                                  GL_RENDERBUFFER, m_data->m_depth);
138    }
139#   endif
140
141#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
142    glCheckFramebufferStatus(GL_FRAMEBUFFER);
143#   endif
144
145    Unbind();
146#endif
147}
148
149FrameBuffer::~FrameBuffer()
150{
151#if defined USE_D3D9 || defined _XBOX
152    m_data->m_surface->Release();
153    m_data->m_texture->Release();
154#else
155#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
156    glDeleteFramebuffers(1, &m_data->m_fbo);
157#   else
158    glDeleteFramebuffersOES(1, &m_data->m_fbo);
159#   endif
160    glDeleteTextures(1, &m_data->m_texture);
161#   if GL_VERSION_1_1
162    if (m_data->m_depth != GL_INVALID_ENUM)
163        glDeleteRenderbuffers(1, &m_data->m_depth);
164#   endif
165#endif
166    delete m_data;
167}
168
169ShaderTexture FrameBuffer::GetTexture() const
170{
171    ShaderTexture ret;
172#if defined USE_D3D9 || defined _XBOX
173    ret.m_flags = (uint64_t)(uintptr_t)m_data->m_texture;
174#else
175    ret.m_flags = m_data->m_texture;
176#endif
177    return ret;
178}
179
180void FrameBuffer::Bind()
181{
182#if defined USE_D3D9 || defined _XBOX
183    if (FAILED(g_d3ddevice->GetRenderTarget(0, &m_data->m_back_surface)))
184        Abort();
185    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_surface)))
186        Abort();
187#else
188#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
189    glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
190#   else
191    glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
192#   endif
193#endif
194}
195
196void FrameBuffer::Unbind()
197{
198#if defined USE_D3D9
199    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface)))
200        Abort();
201    m_data->m_back_surface->Release();
202#elif defined _XBOX
203    if (FAILED(g_d3ddevice->Resolve(D3DRESOLVE_RENDERTARGET0, nullptr,
204                                    m_data->m_texture, nullptr, 0, 0, nullptr,
205                                    0, 0, nullptr)))
206        Abort();
207    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface)))
208        Abort();
209    m_data->m_back_surface->Release();
210#else
211#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
212    glBindFramebuffer(GL_FRAMEBUFFER, 0);
213#   else
214    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
215#   endif
216#endif
217}
218
219} /* namespace lol */
220
Note: See TracBrowser for help on using the repository browser.