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

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

gpu: port FBO code to the Xbox360.

  • Property svn:keywords set to Id
File size: 5.2 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 || defined _XBOX
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#else
75#   if GL_VERSION_1_1
76    GLenum internal_format = GL_RGBA8;
77    GLenum format = GL_BGRA;
78    GLenum depth = GL_DEPTH_COMPONENT;
79#   else
80    GLenum internal_format = GL_RGBA;
81    GLenum format = GL_RGBA;
82#   endif
83    GLenum wrapmode = GL_REPEAT;
84    GLenum filtering = GL_NEAREST;
85
86#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
87    glGenFramebuffers(1, &m_data->m_fbo);
88    glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
89#   else
90    glGenFramebuffersOES(1, &m_data->m_fbo);
91    glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
92#   endif
93
94    glGenTextures(1, &m_data->m_texture);
95    glActiveTexture(GL_TEXTURE0);
96    glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
97    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)wrapmode);
98    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)wrapmode);
99    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)filtering);
100    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)filtering);
101    glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size.x, size.y, 0,
102                 format, GL_UNSIGNED_BYTE, NULL);
103
104#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
105    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
106                           GL_TEXTURE_2D, m_data->m_texture, 0);
107#   else
108    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT,
109                              GL_TEXTURE_2D, m_data->m_texture, 0);
110#   endif
111
112    m_data->m_depth = GL_INVALID_ENUM;
113#   if GL_VERSION_1_1
114    /* FIXME: not implemented on GL ES, see
115     * http://stackoverflow.com/q/4041682/111461 */
116    if (depth != GL_INVALID_ENUM)
117    {
118        glGenRenderbuffers(1, &m_data->m_depth);
119        glBindRenderbuffer(GL_RENDERBUFFER, m_data->m_depth);
120        glRenderbufferStorage(GL_RENDERBUFFER, depth, size.x, size.y);
121        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
122                                  GL_RENDERBUFFER, m_data->m_depth);
123    }
124#   endif
125
126#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
127    glCheckFramebufferStatus(GL_FRAMEBUFFER);
128#   endif
129
130    Unbind();
131#endif
132}
133
134FrameBuffer::~FrameBuffer()
135{
136#if defined USE_D3D9 || defined _XBOX
137    m_data->m_surface->Release();
138    m_data->m_texture->Release();
139#else
140#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
141    glDeleteFramebuffers(1, &m_data->m_fbo);
142#   else
143    glDeleteFramebuffersOES(1, &m_data->m_fbo);
144#   endif
145    glDeleteTextures(1, &m_data->m_texture);
146#   if GL_VERSION_1_1
147    if (m_data->m_depth != GL_INVALID_ENUM)
148        glDeleteRenderbuffers(1, &m_data->m_depth);
149#   endif
150#endif
151    delete m_data;
152}
153
154ShaderTexture FrameBuffer::GetTexture() const
155{
156    ShaderTexture ret;
157#if defined USE_D3D9 || defined _XBOX
158    ret.m_flags = (uint64_t)(uintptr_t)m_data->m_texture;
159#else
160    ret.m_flags = m_data->m_texture;
161#endif
162    return ret;
163}
164
165void FrameBuffer::Bind()
166{
167#if defined USE_D3D9 || defined _XBOX
168    if (FAILED(g_d3ddevice->GetRenderTarget(0, &m_data->m_back_surface)))
169        Abort();
170    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_surface)))
171        Abort();
172#else
173#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
174    glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
175#   else
176    glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
177#   endif
178#endif
179}
180
181void FrameBuffer::Unbind()
182{
183#if defined USE_D3D9 || defined _XBOX
184    if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface)))
185        Abort();
186#else
187#   if GL_VERSION_1_1 || GL_ES_VERSION_2_0
188    glBindFramebuffer(GL_FRAMEBUFFER, NULL);
189#   else
190    glBindFramebufferOES(GL_FRAMEBUFFER_OES, NULL);
191#   endif
192#endif
193}
194
195} /* namespace lol */
196
Note: See TracBrowser for help on using the repository browser.