2014-04-09 01:04:25 +02:00
|
|
|
// Copyright 2014 Citra Emulator Project
|
|
|
|
// Licensed under GPLv2
|
|
|
|
// Refer to the license.txt file included.
|
2014-04-06 22:55:39 +02:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <GL/glew.h>
|
|
|
|
|
2014-04-09 02:15:08 +02:00
|
|
|
#include "common/common.h"
|
|
|
|
#include "common/emu_window.h"
|
2014-04-06 22:55:39 +02:00
|
|
|
|
2014-04-09 02:15:08 +02:00
|
|
|
#include "video_core/renderer_base.h"
|
2014-04-06 22:55:39 +02:00
|
|
|
|
|
|
|
|
|
|
|
class RendererOpenGL : virtual public RendererBase {
|
|
|
|
public:
|
|
|
|
|
|
|
|
static const int kMaxFramebuffers = 2; ///< Maximum number of framebuffers
|
|
|
|
|
|
|
|
RendererOpenGL();
|
|
|
|
~RendererOpenGL();
|
|
|
|
|
|
|
|
/// Swap buffers (render frame)
|
|
|
|
void SwapBuffers();
|
|
|
|
|
2014-04-07 06:52:34 +02:00
|
|
|
/**
|
|
|
|
* Renders external framebuffer (XFB)
|
|
|
|
* @param src_rect Source rectangle in XFB to copy
|
|
|
|
* @param dst_rect Destination rectangle in output framebuffer to copy to
|
|
|
|
*/
|
2014-05-20 02:57:35 +02:00
|
|
|
void RenderXFB(const common::Rect& src_rect, const common::Rect& dst_rect);
|
2014-04-07 06:52:34 +02:00
|
|
|
|
2014-04-06 22:55:39 +02:00
|
|
|
/**
|
|
|
|
* Set the emulator window to use for renderer
|
|
|
|
* @param window EmuWindow handle to emulator window to use for rendering
|
|
|
|
*/
|
|
|
|
void SetWindow(EmuWindow* window);
|
|
|
|
|
|
|
|
/// Initialize the renderer
|
|
|
|
void Init();
|
|
|
|
|
|
|
|
/// Shutdown the renderer
|
|
|
|
void ShutDown();
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
/// Initialize the FBO
|
|
|
|
void InitFramebuffer();
|
|
|
|
|
|
|
|
// Blit the FBO to the OpenGL default framebuffer
|
|
|
|
void RenderFramebuffer();
|
|
|
|
|
|
|
|
/// Updates the framerate
|
|
|
|
void UpdateFramerate();
|
|
|
|
|
2014-04-09 00:59:02 +02:00
|
|
|
/**
|
|
|
|
* Helper function to flip framebuffer from left-to-right to top-to-bottom
|
2014-04-27 18:42:01 +02:00
|
|
|
* @param in Pointer to input raw framebuffer in V/RAM
|
2014-04-09 00:59:02 +02:00
|
|
|
* @param out Pointer to output buffer with flipped framebuffer
|
|
|
|
* @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
|
|
|
|
*/
|
2014-04-28 07:23:01 +02:00
|
|
|
void FlipFramebuffer(const u8* in, u8* out);
|
2014-04-09 00:59:02 +02:00
|
|
|
|
|
|
|
|
|
|
|
EmuWindow* m_render_window; ///< Handle to render window
|
|
|
|
u32 m_last_mode; ///< Last render mode
|
2014-04-06 22:55:39 +02:00
|
|
|
|
2014-04-09 00:59:02 +02:00
|
|
|
int m_resolution_width; ///< Current resolution width
|
|
|
|
int m_resolution_height; ///< Current resolution height
|
2014-04-06 22:55:39 +02:00
|
|
|
|
2014-04-09 00:59:02 +02:00
|
|
|
// Framebuffers
|
|
|
|
// ------------
|
2014-04-06 22:55:39 +02:00
|
|
|
|
2014-04-09 00:59:02 +02:00
|
|
|
GLuint m_fbo[kMaxFramebuffers]; ///< Framebuffer objects
|
|
|
|
GLuint m_fbo_rbo[kMaxFramebuffers]; ///< Render buffer objects
|
|
|
|
GLuint m_fbo_depth_buffers[kMaxFramebuffers]; ///< Depth buffers objects
|
2014-04-06 22:55:39 +02:00
|
|
|
|
2014-04-09 00:59:02 +02:00
|
|
|
GLuint m_xfb_texture_top; ///< GL handle to top framebuffer texture
|
|
|
|
GLuint m_xfb_texture_bottom; ///< GL handle to bottom framebuffer texture
|
|
|
|
|
|
|
|
GLuint m_xfb_top; ///< GL handle to top framebuffer
|
|
|
|
GLuint m_xfb_bottom; ///< GL handle to bottom framebuffer
|
2014-04-07 04:57:04 +02:00
|
|
|
|
2014-04-09 00:59:02 +02:00
|
|
|
// "Flipped" framebuffers translate scanlines from native 3DS left-to-right to top-to-bottom
|
|
|
|
// as OpenGL expects them in a texture. There probably is a more efficient way of doing this:
|
2014-04-07 04:57:04 +02:00
|
|
|
|
2014-04-09 00:59:02 +02:00
|
|
|
u8 m_xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4];
|
|
|
|
u8 m_xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4];
|
2014-04-07 04:57:04 +02:00
|
|
|
|
2014-04-06 22:55:39 +02:00
|
|
|
};
|