|
- //
- // Lol Engine
- //
- // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the Do What The Fuck You Want To
- // Public License, Version 2, as published by Sam Hocevar. See
- // http://www.wtfpl.net/ for more details.
- //
-
- #if defined HAVE_CONFIG_H
- # include "config.h"
- #endif
-
- #include "core.h"
- #include "lolgl.h"
-
- #if defined _WIN32 && defined USE_D3D9
- # define FAR
- # define NEAR
- # include <d3d9.h>
- #endif
-
- using namespace std;
-
- #if defined USE_D3D9
- extern IDirect3DDevice9 *g_d3ddevice;
- #elif defined _XBOX
- extern D3DDevice *g_d3ddevice;
- #endif
-
- namespace lol
- {
-
- //
- // The FrameBufferData class
- // -------------------------
- //
-
- class FrameBufferData
- {
- friend class FrameBuffer;
-
- ivec2 m_size;
-
- #if defined USE_D3D9
- IDirect3DTexture9 *m_texture;
- IDirect3DSurface9 *m_surface, *m_back_surface;
- #elif defined _XBOX
- D3DTexture *m_texture;
- D3DSurface *m_surface, *m_back_surface;
- #else
- GLuint m_fbo, m_texture, m_depth;
- #endif
- };
-
- //
- // The FrameBuffer class
- // ----------------------
- //
-
- FrameBuffer::FrameBuffer(ivec2 size)
- : m_data(new FrameBufferData)
- {
- m_data->m_size = size;
- #if defined USE_D3D9
- if (FAILED(g_d3ddevice->CreateTexture(size.x, size.y, 1,
- D3DUSAGE_RENDERTARGET,
- D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
- &m_data->m_texture, nullptr)))
- Abort();
- if (FAILED(m_data->m_texture->GetSurfaceLevel(0, &m_data->m_surface)))
- Abort();
- #elif defined _XBOX
- if (FAILED(g_d3ddevice->CreateTexture(size.x, size.y, 1, 0,
- D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
- &m_data->m_texture, nullptr)))
- Abort();
- if (FAILED(g_d3ddevice->CreateRenderTarget(size.x, size.y,
- D3DFMT_A8R8G8B8,
- D3DMULTISAMPLE_NONE, 0, 0,
- &m_data->m_surface, nullptr)))
- Abort();
- #else
- # if GL_VERSION_1_1
- GLenum internal_format = GL_RGBA8;
- GLenum format = GL_BGRA;
- GLenum depth = GL_DEPTH_COMPONENT;
- # elif defined __CELLOS_LV2__
- /* Supported drawable formats on the PS3: GL_ARGB_SCE, GL_RGB16F_ARB,
- * GL_RGBA16F_ARB, GL_RGB32F_ARB, GL_RGBA32F_ARB, GL_LUMINANCE32F_ARB. */
- GLenum internal_format = GL_ARGB_SCE;
- GLenum format = GL_RGBA;
- # else
- GLenum internal_format = GL_RGBA;
- GLenum format = GL_RGBA;
- # endif
- GLenum wrapmode = GL_REPEAT;
- GLenum filtering = GL_NEAREST;
-
- # if GL_VERSION_1_1 || GL_ES_VERSION_2_0
- glGenFramebuffers(1, &m_data->m_fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
- # else
- glGenFramebuffersOES(1, &m_data->m_fbo);
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
- # endif
-
- glGenTextures(1, &m_data->m_texture);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)wrapmode);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)wrapmode);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)filtering);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)filtering);
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size.x, size.y, 0,
- format, GL_UNSIGNED_BYTE, nullptr);
-
- # if GL_VERSION_1_1 || GL_ES_VERSION_2_0
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, m_data->m_texture, 0);
- # else
- glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_data->m_texture, 0);
- # endif
-
- m_data->m_depth = GL_INVALID_ENUM;
- # if GL_VERSION_1_1
- /* FIXME: not implemented on GL ES, see
- * http://stackoverflow.com/q/4041682/111461 */
- if (depth != GL_INVALID_ENUM)
- {
- glGenRenderbuffers(1, &m_data->m_depth);
- glBindRenderbuffer(GL_RENDERBUFFER, m_data->m_depth);
- glRenderbufferStorage(GL_RENDERBUFFER, depth, size.x, size.y);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, m_data->m_depth);
- }
- # endif
-
- # if GL_VERSION_1_1 || GL_ES_VERSION_2_0
- glCheckFramebufferStatus(GL_FRAMEBUFFER);
- # endif
-
- Unbind();
- #endif
- }
-
- FrameBuffer::~FrameBuffer()
- {
- #if defined USE_D3D9 || defined _XBOX
- m_data->m_surface->Release();
- m_data->m_texture->Release();
- #else
- # if GL_VERSION_1_1 || GL_ES_VERSION_2_0
- glDeleteFramebuffers(1, &m_data->m_fbo);
- # else
- glDeleteFramebuffersOES(1, &m_data->m_fbo);
- # endif
- glDeleteTextures(1, &m_data->m_texture);
- # if GL_VERSION_1_1
- if (m_data->m_depth != GL_INVALID_ENUM)
- glDeleteRenderbuffers(1, &m_data->m_depth);
- # endif
- #endif
- delete m_data;
- }
-
- ShaderTexture FrameBuffer::GetTexture() const
- {
- ShaderTexture ret;
- #if defined USE_D3D9 || defined _XBOX
- ret.m_flags = (uint64_t)(uintptr_t)m_data->m_texture;
- #else
- ret.m_flags = m_data->m_texture;
- #endif
- return ret;
- }
-
- void FrameBuffer::Bind()
- {
- #if defined USE_D3D9 || defined _XBOX
- if (FAILED(g_d3ddevice->GetRenderTarget(0, &m_data->m_back_surface)))
- Abort();
- if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_surface)))
- Abort();
- #else
- # if GL_VERSION_1_1 || GL_ES_VERSION_2_0
- glBindFramebuffer(GL_FRAMEBUFFER, m_data->m_fbo);
- # else
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_data->m_fbo);
- # endif
- #endif
- }
-
- void FrameBuffer::Unbind()
- {
- #if defined USE_D3D9
- if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface)))
- Abort();
- m_data->m_back_surface->Release();
- #elif defined _XBOX
- if (FAILED(g_d3ddevice->Resolve(D3DRESOLVE_RENDERTARGET0, nullptr,
- m_data->m_texture, nullptr, 0, 0, nullptr,
- 0, 0, nullptr)))
- Abort();
- if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface)))
- Abort();
- m_data->m_back_surface->Release();
- #else
- # if GL_VERSION_1_1 || GL_ES_VERSION_2_0
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- # else
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
- # endif
- #endif
- }
-
- } /* namespace lol */
|