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

Last change on this file since 1773 was 1773, checked in by sam, 9 years ago

gpu: create the ShaderTexture class, replace Shader::SetTexture with a
Shader::SetUniform override, and implement most of the FBO code for
the Direct3D backend.

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