citra/src/video_core/renderer_opengl/renderer_opengl.h

103 lines
3 KiB
C
Raw Normal View History

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 "generated/gl_3_2_core.h"
2014-04-06 22:55:39 +02:00
#include "common/common.h"
#include "common/emu_window.h"
2014-04-06 22:55:39 +02:00
#include "video_core/renderer_base.h"
2014-04-06 22:55:39 +02:00
#include <array>
2014-04-06 22:55:39 +02:00
class RendererOpenGL : public RendererBase {
2014-04-06 22:55:39 +02:00
public:
RendererOpenGL();
~RendererOpenGL() override;
2014-04-06 22:55:39 +02:00
/// Swap buffers (render frame)
void SwapBuffers();
/**
* Renders external framebuffer (XFB)
* @param src_rect Source rectangle in XFB to copy
* @param dst_rect Destination rectangle in output framebuffer to copy to
*/
void RenderXFB(const Common::Rect& src_rect, const Common::Rect& dst_rect);
/**
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();
/// Structure used for storing information for rendering each 3DS screen
struct ScreenInfo {
// Properties
int width;
int height;
int stride; ///< Number of bytes between the coordinates (0,0) and (1,0)
// OpenGL object IDs
GLuint texture_id;
GLuint vertex_buffer_id;
// Temporary
u8* flipped_xfb_data;
};
/**
* Helper function to flip framebuffer from left-to-right to top-to-bottom
* @param raw_data Pointer to input raw framebuffer in V/RAM
* @param screen_info ScreenInfo structure with screen size and output buffer pointer
* @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
*/
void FlipFramebuffer(const u8* raw_data, ScreenInfo& screen_info);
2014-04-06 22:55:39 +02:00
EmuWindow* render_window; ///< Handle to render window
u32 last_mode; ///< Last render mode
2014-04-06 22:55:39 +02:00
int resolution_width; ///< Current resolution width
int resolution_height; ///< Current resolution height
2014-04-06 22:55:39 +02:00
// OpenGL global object IDs
GLuint vertex_array_id;
GLuint program_id;
GLuint sampler_id;
// Shader attribute input indices
GLuint attrib_position;
GLuint attrib_texcoord;
2014-04-06 22:55:39 +02:00
struct : std::array<ScreenInfo, 2> {
ScreenInfo& Top() { return (*this)[0]; }
ScreenInfo& Bottom() { return (*this)[1]; }
} screen_info;
2014-04-07 04:57:04 +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:
u8 xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopHeight * 4];
u8 xfb_bottom_flipped[VideoCore::kScreenBottomWidth * VideoCore::kScreenBottomHeight * 4];
2014-04-07 04:57:04 +02:00
};