summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/src/renderer_base.h72
-rw-r--r--src/video_core/src/renderer_opengl/renderer_opengl.cpp310
-rw-r--r--src/video_core/src/renderer_opengl/renderer_opengl.h95
3 files changed, 110 insertions, 367 deletions
diff --git a/src/video_core/src/renderer_base.h b/src/video_core/src/renderer_base.h
index 50f1475b2..61c568694 100644
--- a/src/video_core/src/renderer_base.h
+++ b/src/video_core/src/renderer_base.h
@@ -37,15 +37,7 @@ public:
37 kFramebuffer_Texture 37 kFramebuffer_Texture
38 }; 38 };
39 39
40 /// Used for referencing the render modes 40 RendererBase() : m_current_fps(0), m_current_frame(0) {
41 enum kRenderMode {
42 kRenderMode_None = 0,
43 kRenderMode_Multipass = 1,
44 kRenderMode_ZComp = 2,
45 kRenderMode_UseDstAlpha = 4
46 };
47
48 RendererBase() : current_fps_(0), current_frame_(0) {
49 } 41 }
50 42
51 ~RendererBase() { 43 ~RendererBase() {
@@ -55,56 +47,6 @@ public:
55 virtual void SwapBuffers() = 0; 47 virtual void SwapBuffers() = 0;
56 48
57 /** 49 /**
58 * Blits the EFB to the external framebuffer (XFB)
59 * @param src_rect Source rectangle in EFB to copy
60 * @param dst_rect Destination rectangle in EFB to copy to
61 * @param dest_height Destination height in pixels
62 */
63 virtual void CopyToXFB(const Rect& src_rect, const Rect& dst_rect) = 0;
64
65 /**
66 * Clear the screen
67 * @param rect Screen rectangle to clear
68 * @param enable_color Enable color clearing
69 * @param enable_alpha Enable alpha clearing
70 * @param enable_z Enable depth clearing
71 * @param color Clear color
72 * @param z Clear depth
73 */
74 virtual void Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z,
75 u32 color, u32 z) = 0;
76
77 /// Sets the renderer viewport location, width, and height
78 virtual void SetViewport(int x, int y, int width, int height) = 0;
79
80 /// Sets the renderer depthrange, znear and zfar
81 virtual void SetDepthRange(double znear, double zfar) = 0;
82
83 /* Sets the scissor box
84 * @param rect Renderer rectangle to set scissor box to
85 */
86 virtual void SetScissorBox(const Rect& rect) = 0;
87
88 /**
89 * Sets the line and point size
90 * @param line_width Line width to use
91 * @param point_size Point size to use
92 */
93 virtual void SetLinePointSize(f32 line_width, f32 point_size) = 0;
94
95 /**
96 * Set a specific render mode
97 * @param flag Render flags mode to enable
98 */
99 virtual void SetMode(kRenderMode flags) = 0;
100
101 /// Reset the full renderer API to the NULL state
102 virtual void ResetRenderState() = 0;
103
104 /// Restore the full renderer API state - As the game set it
105 virtual void RestoreRenderState() = 0;
106
107 /**
108 * Set the emulator window to use for renderer 50 * Set the emulator window to use for renderer
109 * @param window EmuWindow handle to emulator window to use for rendering 51 * @param window EmuWindow handle to emulator window to use for rendering
110 */ 52 */
@@ -119,13 +61,17 @@ public:
119 // Getter/setter functions: 61 // Getter/setter functions:
120 // ------------------------ 62 // ------------------------
121 63
122 f32 current_fps() const { return current_fps_; } 64 f32 GetCurrentframe() const {
65 return m_current_fps;
66 }
123 67
124 int current_frame() const { return current_frame_; } 68 int current_frame() const {
69 return m_current_frame;
70 }
125 71
126protected: 72protected:
127 f32 current_fps_; ///< Current framerate, should be set by the renderer 73 f32 m_current_fps; ///< Current framerate, should be set by the renderer
128 int current_frame_; ///< Current frame, should be set by the renderer 74 int m_current_frame; ///< Current frame, should be set by the renderer
129 75
130private: 76private:
131 DISALLOW_COPY_AND_ASSIGN(RendererBase); 77 DISALLOW_COPY_AND_ASSIGN(RendererBase);
diff --git a/src/video_core/src/renderer_opengl/renderer_opengl.cpp b/src/video_core/src/renderer_opengl/renderer_opengl.cpp
index 27917a5a2..8a4d1ab72 100644
--- a/src/video_core/src/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/src/renderer_opengl/renderer_opengl.cpp
@@ -26,41 +26,21 @@
26#include "video_core.h" 26#include "video_core.h"
27#include "renderer_opengl/renderer_opengl.h" 27#include "renderer_opengl/renderer_opengl.h"
28 28
29/**
30 * Helper function to flip framebuffer from left-to-right to top-to-bottom
31 * @param addr Address of framebuffer in RAM
32 * @param out Pointer to output buffer with flipped framebuffer
33 * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
34 */
35inline void _flip_framebuffer(u32 addr, u8* out) {
36 u8* in = Memory::GetPointer(addr);
37 for (int y = 0; y < VideoCore::kScreenTopHeight; y++) {
38 for (int x = 0; x < VideoCore::kScreenTopWidth; x++) {
39 int in_coord = (VideoCore::kScreenTopHeight * 3 * x) + (VideoCore::kScreenTopHeight * 3)
40 - (3 * y + 3);
41 int out_coord = (VideoCore::kScreenTopWidth * y * 3) + (x * 3);
42
43 out[out_coord + 0] = in[in_coord + 0];
44 out[out_coord + 1] = in[in_coord + 1];
45 out[out_coord + 2] = in[in_coord + 2];
46 }
47 }
48}
49 29
50/// RendererOpenGL constructor 30/// RendererOpenGL constructor
51RendererOpenGL::RendererOpenGL() { 31RendererOpenGL::RendererOpenGL() {
52 memset(fbo_, 0, sizeof(fbo_)); 32 memset(m_fbo, 0, sizeof(m_fbo));
53 memset(fbo_rbo_, 0, sizeof(fbo_rbo_)); 33 memset(m_fbo_rbo, 0, sizeof(m_fbo_rbo));
54 memset(fbo_depth_buffers_, 0, sizeof(fbo_depth_buffers_)); 34 memset(m_fbo_depth_buffers, 0, sizeof(m_fbo_depth_buffers));
55 35
56 resolution_width_ = max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); 36 m_resolution_width = max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth);
57 resolution_height_ = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; 37 m_resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight;
58 38
59 xfb_texture_top_ = 0; 39 m_xfb_texture_top = 0;
60 xfb_texture_bottom_ = 0; 40 m_xfb_texture_bottom = 0;
61 41
62 xfb_top_ = 0; 42 m_xfb_top = 0;
63 xfb_bottom_ = 0; 43 m_xfb_bottom = 0;
64} 44}
65 45
66/// RendererOpenGL destructor 46/// RendererOpenGL destructor
@@ -69,26 +49,42 @@ RendererOpenGL::~RendererOpenGL() {
69 49
70/// Swap buffers (render frame) 50/// Swap buffers (render frame)
71void RendererOpenGL::SwapBuffers() { 51void RendererOpenGL::SwapBuffers() {
72
73 ResetRenderState();
74
75 // EFB->XFB copy 52 // EFB->XFB copy
76 // TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some 53 // TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some
77 // register write We're also treating both framebuffers as a single one in OpenGL. 54 // register write We're also treating both framebuffers as a single one in OpenGL.
78 Rect framebuffer_size(0, 0, resolution_width_, resolution_height_); 55 Rect framebuffer_size(0, 0, m_resolution_width, m_resolution_height);
79 RenderXFB(framebuffer_size, framebuffer_size); 56 RenderXFB(framebuffer_size, framebuffer_size);
80 57
81 // XFB->Window copy 58 // XFB->Window copy
82 RenderFramebuffer(); 59 RenderFramebuffer();
83 60
84 // Swap buffers 61 // Swap buffers
85 render_window_->PollEvents(); 62 m_render_window->PollEvents();
86 render_window_->SwapBuffers(); 63 m_render_window->SwapBuffers();
87 64
88 // Switch back to EFB and clear 65 // Switch back to EFB and clear
89 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]); 66 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_EFB]);
67}
90 68
91 RestoreRenderState(); 69/**
70 * Helper function to flip framebuffer from left-to-right to top-to-bottom
71 * @param addr Address of framebuffer in RAM
72 * @param out Pointer to output buffer with flipped framebuffer
73 * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
74 */
75void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out) {
76 u8* in = Memory::GetPointer(addr);
77 for (int y = 0; y < VideoCore::kScreenTopHeight; y++) {
78 for (int x = 0; x < VideoCore::kScreenTopWidth; x++) {
79 int in_coord = (VideoCore::kScreenTopHeight * 3 * x) + (VideoCore::kScreenTopHeight * 3)
80 - (3 * y + 3);
81 int out_coord = (VideoCore::kScreenTopWidth * y * 3) + (x * 3);
82
83 out[out_coord + 0] = in[in_coord + 0];
84 out[out_coord + 1] = in[in_coord + 1];
85 out[out_coord + 2] = in[in_coord + 2];
86 }
87 }
92} 88}
93 89
94/** 90/**
@@ -96,30 +92,26 @@ void RendererOpenGL::SwapBuffers() {
96 * @param src_rect Source rectangle in XFB to copy 92 * @param src_rect Source rectangle in XFB to copy
97 * @param dst_rect Destination rectangle in output framebuffer to copy to 93 * @param dst_rect Destination rectangle in output framebuffer to copy to
98 */ 94 */
99void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) { 95void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {
100 static u8 xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth *3];
101 static u8 xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth *3];
102
103 _flip_framebuffer(0x20282160, xfb_top_flipped);
104 _flip_framebuffer(0x202118E0, xfb_bottom_flipped);
105 96
106 ResetRenderState(); 97 FlipFramebuffer(0x20282160, m_xfb_top_flipped);
98 FlipFramebuffer(0x202118E0, m_xfb_bottom_flipped);
107 99
108 // Blit the top framebuffer 100 // Blit the top framebuffer
109 // ------------------------ 101 // ------------------------
110 102
111 // Update textures with contents of XFB in RAM - top 103 // Update textures with contents of XFB in RAM - top
112 glBindTexture(GL_TEXTURE_2D, xfb_texture_top_); 104 glBindTexture(GL_TEXTURE_2D, m_xfb_texture_top);
113 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, 105 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
114 GL_RGB, GL_UNSIGNED_BYTE, xfb_top_flipped); 106 GL_RGB, GL_UNSIGNED_BYTE, m_xfb_top_flipped);
115 glBindTexture(GL_TEXTURE_2D, 0); 107 glBindTexture(GL_TEXTURE_2D, 0);
116 108
117 // Render target is destination framebuffer 109 // Render target is destination framebuffer
118 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); 110 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]);
119 glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight); 111 glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight);
120 112
121 // Render source is our EFB 113 // Render source is our EFB
122 glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_top_); 114 glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_top);
123 glReadBuffer(GL_COLOR_ATTACHMENT0); 115 glReadBuffer(GL_COLOR_ATTACHMENT0);
124 116
125 // Blit 117 // Blit
@@ -133,18 +125,18 @@ void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {
133 // --------------------------- 125 // ---------------------------
134 126
135 // Update textures with contents of XFB in RAM - bottom 127 // Update textures with contents of XFB in RAM - bottom
136 glBindTexture(GL_TEXTURE_2D, xfb_texture_bottom_); 128 glBindTexture(GL_TEXTURE_2D, m_xfb_texture_bottom);
137 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, 129 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
138 GL_RGB, GL_UNSIGNED_BYTE, xfb_bottom_flipped); 130 GL_RGB, GL_UNSIGNED_BYTE, m_xfb_bottom_flipped);
139 glBindTexture(GL_TEXTURE_2D, 0); 131 glBindTexture(GL_TEXTURE_2D, 0);
140 132
141 // Render target is destination framebuffer 133 // Render target is destination framebuffer
142 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); 134 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]);
143 glViewport(0, 0, 135 glViewport(0, 0,
144 VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight); 136 VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight);
145 137
146 // Render source is our EFB 138 // Render source is our EFB
147 glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_bottom_); 139 glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_bottom);
148 glReadBuffer(GL_COLOR_ATTACHMENT0); 140 glReadBuffer(GL_COLOR_ATTACHMENT0);
149 141
150 // Blit 142 // Blit
@@ -154,190 +146,37 @@ void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {
154 GL_COLOR_BUFFER_BIT, GL_LINEAR); 146 GL_COLOR_BUFFER_BIT, GL_LINEAR);
155 147
156 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); 148 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
157
158 RestoreRenderState();
159}
160
161/**
162 * Blits the EFB to the external framebuffer (XFB)
163 * @param src_rect Source rectangle in EFB to copy
164 * @param dst_rect Destination rectangle in EFB to copy to
165 */
166void RendererOpenGL::CopyToXFB(const Rect& src_rect, const Rect& dst_rect) {
167 ERROR_LOG(RENDER, "CopyToXFB not implemented! No EFB support yet!");
168 //ResetRenderState();
169
170 //// Render target is destination framebuffer
171 //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]);
172 //glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight);
173
174 //// Render source is our EFB
175 //glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
176 //glReadBuffer(GL_COLOR_ATTACHMENT0);
177
178 //// Blit
179 //glBlitFramebuffer(src_rect.x0_, src_rect.y0_, src_rect.x1_, src_rect.y1_,
180 // dst_rect.x0_, dst_rect.y1_, dst_rect.x1_, dst_rect.y0_,
181 // GL_COLOR_BUFFER_BIT, GL_LINEAR);
182
183 //glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
184
185 //RestoreRenderState();
186}
187
188/**
189 * Clear the screen
190 * @param rect Screen rectangle to clear
191 * @param enable_color Enable color clearing
192 * @param enable_alpha Enable alpha clearing
193 * @param enable_z Enable depth clearing
194 * @param color Clear color
195 * @param z Clear depth
196 */
197void RendererOpenGL::Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z,
198 u32 color, u32 z) {
199 GLboolean const color_mask = enable_color ? GL_TRUE : GL_FALSE;
200 GLboolean const alpha_mask = enable_alpha ? GL_TRUE : GL_FALSE;
201
202 ResetRenderState();
203
204 // Clear color
205 glColorMask(color_mask, color_mask, color_mask, alpha_mask);
206 glClearColor(float((color >> 16) & 0xFF) / 255.0f, float((color >> 8) & 0xFF) / 255.0f,
207 float((color >> 0) & 0xFF) / 255.0f, float((color >> 24) & 0xFF) / 255.0f);
208
209 // Clear depth
210 glDepthMask(enable_z ? GL_TRUE : GL_FALSE);
211 glClearDepth(float(z & 0xFFFFFF) / float(0xFFFFFF));
212
213 // Specify the rectangle of the EFB to clear
214 glEnable(GL_SCISSOR_TEST);
215 glScissor(rect.x0_, rect.y1_, rect.width(), rect.height());
216
217 // Clear it!
218 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
219
220 RestoreRenderState();
221}
222
223/// Sets the renderer viewport location, width, and height
224void RendererOpenGL::SetViewport(int x, int y, int width, int height) {
225 glViewport(x, y, width, height);
226}
227
228/// Sets the renderer depthrange, znear and zfar
229void RendererOpenGL::SetDepthRange(double znear, double zfar) {
230 glDepthRange(znear, zfar);
231}
232
233/* Sets the scissor box
234 * @param rect Renderer rectangle to set scissor box to
235 */
236void RendererOpenGL::SetScissorBox(const Rect& rect) {
237 glScissor(rect.x0_, rect.y1_, rect.width(), rect.height());
238}
239
240/**
241 * Sets the line and point size
242 * @param line_width Line width to use
243 * @param point_size Point size to use
244 */
245void RendererOpenGL::SetLinePointSize(f32 line_width, f32 point_size) {
246 glLineWidth((GLfloat)line_width);
247 glPointSize((GLfloat)point_size);
248}
249
250/**
251 * Set a specific render mode
252 * @param flag Render flags mode to enable
253 */
254void RendererOpenGL::SetMode(kRenderMode flags) {
255 if(flags & kRenderMode_ZComp) {
256 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
257 }
258 if(flags & kRenderMode_Multipass) {
259 glEnable(GL_DEPTH_TEST);
260 glDepthMask(GL_FALSE);
261 glDepthFunc(GL_EQUAL);
262 }
263 if (flags & kRenderMode_UseDstAlpha) {
264 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
265 glDisable(GL_BLEND);
266 }
267 last_mode_ |= flags;
268}
269
270/// Reset the full renderer API to the NULL state
271void RendererOpenGL::ResetRenderState() {
272 glDisable(GL_SCISSOR_TEST);
273 glDisable(GL_DEPTH_TEST);
274 glDisable(GL_CULL_FACE);
275 glDisable(GL_BLEND);
276 glDepthMask(GL_FALSE);
277 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
278}
279
280/// Restore the full renderer API state - As the game set it
281void RendererOpenGL::RestoreRenderState() {
282
283 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
284
285 //gp::XF_UpdateViewport();
286 SetViewport(0, 0, resolution_width_, resolution_height_);
287 SetDepthRange(0.0f, 1.0f);
288
289 //SetGenerationMode();
290 glEnable(GL_CULL_FACE);
291 glFrontFace(GL_CCW);
292
293 //glEnable(GL_SCISSOR_TEST);
294 //gp::BP_SetScissorBox();
295 glDisable(GL_SCISSOR_TEST);
296
297 //SetColorMask(gp::g_bp_regs.cmode0);
298 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
299
300 //SetDepthMode();
301 glDisable(GL_DEPTH_TEST);
302 glDepthMask(GL_FALSE);
303
304 //SetBlendMode(gp::g_bp_regs.cmode0, gp::g_bp_regs.cmode1, true);
305 //if (common::g_config->current_renderer_config().enable_wireframe) {
306 // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
307 //} else {
308 // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
309 //}
310} 149}
311 150
312/// Initialize the FBO 151/// Initialize the FBO
313void RendererOpenGL::InitFramebuffer() { 152void RendererOpenGL::InitFramebuffer() {
314 // TODO(en): This should probably be implemented with the top screen and bottom screen as 153 // TODO(bunnei): This should probably be implemented with the top screen and bottom screen as
315 // separate framebuffers 154 // separate framebuffers
316 155
317 // Init the FBOs 156 // Init the FBOs
318 // ------------- 157 // -------------
319 158
320 glGenFramebuffers(kMaxFramebuffers, fbo_); // Generate primary framebuffer 159 glGenFramebuffers(kMaxFramebuffers, m_fbo); // Generate primary framebuffer
321 glGenRenderbuffers(kMaxFramebuffers, fbo_rbo_); // Generate primary RBOs 160 glGenRenderbuffers(kMaxFramebuffers, m_fbo_rbo); // Generate primary RBOs
322 glGenRenderbuffers(kMaxFramebuffers, fbo_depth_buffers_); // Generate primary depth buffer 161 glGenRenderbuffers(kMaxFramebuffers, m_fbo_depth_buffers); // Generate primary depth buffer
323 162
324 for (int i = 0; i < kMaxFramebuffers; i++) { 163 for (int i = 0; i < kMaxFramebuffers; i++) {
325 // Generate color buffer storage 164 // Generate color buffer storage
326 glBindRenderbuffer(GL_RENDERBUFFER, fbo_rbo_[i]); 165 glBindRenderbuffer(GL_RENDERBUFFER, m_fbo_rbo[i]);
327 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, VideoCore::kScreenTopWidth, 166 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, VideoCore::kScreenTopWidth,
328 VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); 167 VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
329 168
330 // Generate depth buffer storage 169 // Generate depth buffer storage
331 glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth_buffers_[i]); 170 glBindRenderbuffer(GL_RENDERBUFFER, m_fbo_depth_buffers[i]);
332 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, VideoCore::kScreenTopWidth, 171 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, VideoCore::kScreenTopWidth,
333 VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); 172 VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
334 173
335 // Attach the buffers 174 // Attach the buffers
336 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[i]); 175 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[i]);
337 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 176 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
338 GL_RENDERBUFFER, fbo_depth_buffers_[i]); 177 GL_RENDERBUFFER, m_fbo_depth_buffers[i]);
339 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 178 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
340 GL_RENDERBUFFER, fbo_rbo_[i]); 179 GL_RENDERBUFFER, m_fbo_rbo[i]);
341 180
342 // Check for completeness 181 // Check for completeness
343 if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)) { 182 if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)) {
@@ -353,56 +192,55 @@ void RendererOpenGL::InitFramebuffer() {
353 // ------------------------------- 192 // -------------------------------
354 193
355 // Create XFB textures 194 // Create XFB textures
356 glGenTextures(1, &xfb_texture_top_); 195 glGenTextures(1, &m_xfb_texture_top);
357 glGenTextures(1, &xfb_texture_bottom_); 196 glGenTextures(1, &m_xfb_texture_bottom);
358 197
359 // Alocate video memorry for XFB textures 198 // Alocate video memorry for XFB textures
360 glBindTexture(GL_TEXTURE_2D, xfb_texture_top_); 199 glBindTexture(GL_TEXTURE_2D, m_xfb_texture_top);
361 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, 200 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
362 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); 201 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
363 glBindTexture(GL_TEXTURE_2D, 0); 202 glBindTexture(GL_TEXTURE_2D, 0);
364 203
365 glBindTexture(GL_TEXTURE_2D, xfb_texture_bottom_); 204 glBindTexture(GL_TEXTURE_2D, m_xfb_texture_bottom);
366 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, 205 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
367 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); 206 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
368 glBindTexture(GL_TEXTURE_2D, 0); 207 glBindTexture(GL_TEXTURE_2D, 0);
369 208
370 // Create the FBO and attach color/depth textures 209 // Create the FBO and attach color/depth textures
371 glGenFramebuffers(1, &xfb_top_); // Generate framebuffer 210 glGenFramebuffers(1, &m_xfb_top); // Generate framebuffer
372 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_top_); 211 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_xfb_top);
373 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 212 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
374 xfb_texture_top_, 0); 213 m_xfb_texture_top, 0);
375 glBindFramebuffer(GL_FRAMEBUFFER, 0); 214 glBindFramebuffer(GL_FRAMEBUFFER, 0);
376 215
377 glGenFramebuffers(1, &xfb_bottom_); // Generate framebuffer 216 glGenFramebuffers(1, &m_xfb_bottom); // Generate framebuffer
378 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_bottom_); 217 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_xfb_bottom);
379 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 218 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
380 xfb_texture_bottom_, 0); 219 m_xfb_texture_bottom, 0);
381 glBindFramebuffer(GL_FRAMEBUFFER, 0); 220 glBindFramebuffer(GL_FRAMEBUFFER, 0);
382} 221}
383 222
384/// Blit the FBO to the OpenGL default framebuffer 223/// Blit the FBO to the OpenGL default framebuffer
385void RendererOpenGL::RenderFramebuffer() { 224void RendererOpenGL::RenderFramebuffer() {
386
387 // Render target is default framebuffer 225 // Render target is default framebuffer
388 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 226 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
389 glViewport(0, 0, resolution_width_, resolution_height_); 227 glViewport(0, 0, m_resolution_width, m_resolution_height);
390 228
391 // Render source is our XFB 229 // Render source is our XFB
392 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); 230 glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]);
393 glReadBuffer(GL_COLOR_ATTACHMENT0); 231 glReadBuffer(GL_COLOR_ATTACHMENT0);
394 232
395 // Blit 233 // Blit
396 glBlitFramebuffer(0, 0, resolution_width_, resolution_height_, 0, 0, 234 glBlitFramebuffer(0, 0, m_resolution_width, m_resolution_height, 0, 0, m_resolution_width,
397 resolution_width_, resolution_height_, GL_COLOR_BUFFER_BIT, GL_LINEAR); 235 m_resolution_height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
398 236
399 // Update the FPS count 237 // Update the FPS count
400 UpdateFramerate(); 238 UpdateFramerate();
401 239
402 // Rebind EFB 240 // Rebind EFB
403 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]); 241 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_EFB]);
404 242
405 current_frame_++; 243 m_current_frame++;
406} 244}
407 245
408/// Updates the framerate 246/// Updates the framerate
@@ -414,19 +252,19 @@ void RendererOpenGL::UpdateFramerate() {
414 * @param window EmuWindow handle to emulator window to use for rendering 252 * @param window EmuWindow handle to emulator window to use for rendering
415 */ 253 */
416void RendererOpenGL::SetWindow(EmuWindow* window) { 254void RendererOpenGL::SetWindow(EmuWindow* window) {
417 render_window_ = window; 255 m_render_window = window;
418} 256}
419 257
420/// Initialize the renderer 258/// Initialize the renderer
421void RendererOpenGL::Init() { 259void RendererOpenGL::Init() {
422 render_window_->MakeCurrent(); 260 m_render_window->MakeCurrent();
423 glShadeModel(GL_SMOOTH); 261 glShadeModel(GL_SMOOTH);
424 262
425 263
426 glStencilFunc(GL_ALWAYS, 0, 0); 264 glStencilFunc(GL_ALWAYS, 0, 0);
427 glBlendFunc(GL_ONE, GL_ONE); 265 glBlendFunc(GL_ONE, GL_ONE);
428 266
429 glViewport(0, 0, resolution_width_, resolution_height_); 267 glViewport(0, 0, m_resolution_width, m_resolution_height);
430 268
431 glClearDepth(1.0f); 269 glClearDepth(1.0f);
432 glEnable(GL_DEPTH_TEST); 270 glEnable(GL_DEPTH_TEST);
@@ -438,12 +276,12 @@ void RendererOpenGL::Init() {
438 glDisable(GL_STENCIL_TEST); 276 glDisable(GL_STENCIL_TEST);
439 glEnable(GL_SCISSOR_TEST); 277 glEnable(GL_SCISSOR_TEST);
440 278
441 glScissor(0, 0, resolution_width_, resolution_height_); 279 glScissor(0, 0, m_resolution_width, m_resolution_height);
442 glClearDepth(1.0f); 280 glClearDepth(1.0f);
443 281
444 GLenum err = glewInit(); 282 GLenum err = glewInit();
445 if (GLEW_OK != err) { 283 if (GLEW_OK != err) {
446 ERROR_LOG(RENDER, " Failed to initialize GLEW! Error message: \"%s\". Exiting...", 284 ERROR_LOG(RENDER, "Failed to initialize GLEW! Error message: \"%s\". Exiting...",
447 glewGetErrorString(err)); 285 glewGetErrorString(err));
448 exit(-1); 286 exit(-1);
449 } 287 }
diff --git a/src/video_core/src/renderer_opengl/renderer_opengl.h b/src/video_core/src/renderer_opengl/renderer_opengl.h
index b84afc5d2..b91fcacaa 100644
--- a/src/video_core/src/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/src/renderer_opengl/renderer_opengl.h
@@ -52,55 +52,6 @@ public:
52 void RenderXFB(const Rect& src_rect, const Rect& dst_rect); 52 void RenderXFB(const Rect& src_rect, const Rect& dst_rect);
53 53
54 /** 54 /**
55 * Blits the EFB to the external framebuffer (XFB)
56 * @param src_rect Source rectangle in EFB to copy
57 * @param dst_rect Destination rectangle in EFB to copy to
58 */
59 void CopyToXFB(const Rect& src_rect, const Rect& dst_rect);
60
61 /**
62 * Clear the screen
63 * @param rect Screen rectangle to clear
64 * @param enable_color Enable color clearing
65 * @param enable_alpha Enable alpha clearing
66 * @param enable_z Enable depth clearing
67 * @param color Clear color
68 * @param z Clear depth
69 */
70 void Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z,
71 u32 color, u32 z);
72
73 /// Sets the renderer viewport location, width, and height
74 void SetViewport(int x, int y, int width, int height);
75
76 /// Sets the renderer depthrange, znear and zfar
77 void SetDepthRange(double znear, double zfar);
78
79 /* Sets the scissor box
80 * @param rect Renderer rectangle to set scissor box to
81 */
82 void SetScissorBox(const Rect& rect);
83
84 /**
85 * Sets the line and point size
86 * @param line_width Line width to use
87 * @param point_size Point size to use
88 */
89 void SetLinePointSize(f32 line_width, f32 point_size);
90
91 /**
92 * Set a specific render mode
93 * @param flag Render flags mode to enable
94 */
95 void SetMode(kRenderMode flags);
96
97 /// Reset the full renderer API to the NULL state
98 void ResetRenderState();
99
100 /// Restore the full renderer API state - As the game set it
101 void RestoreRenderState();
102
103 /**
104 * Set the emulator window to use for renderer 55 * Set the emulator window to use for renderer
105 * @param window EmuWindow handle to emulator window to use for rendering 56 * @param window EmuWindow handle to emulator window to use for rendering
106 */ 57 */
@@ -112,11 +63,6 @@ public:
112 /// Shutdown the renderer 63 /// Shutdown the renderer
113 void ShutDown(); 64 void ShutDown();
114 65
115 // Framebuffer object(s)
116 // ---------------------
117
118 GLuint fbo_[kMaxFramebuffers]; ///< Framebuffer objects
119
120private: 66private:
121 67
122 /// Initialize the FBO 68 /// Initialize the FBO
@@ -128,26 +74,39 @@ private:
128 /// Updates the framerate 74 /// Updates the framerate
129 void UpdateFramerate(); 75 void UpdateFramerate();
130 76
131 EmuWindow* render_window_; 77 /**
132 u32 last_mode_; ///< Last render mode 78 * Helper function to flip framebuffer from left-to-right to top-to-bottom
79 * @param addr Address of framebuffer in RAM
80 * @param out Pointer to output buffer with flipped framebuffer
81 * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
82 */
83 void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out);
84
85
86 EmuWindow* m_render_window; ///< Handle to render window
87 u32 m_last_mode; ///< Last render mode
133 88
134 int resolution_width_; 89 int m_resolution_width; ///< Current resolution width
135 int resolution_height_; 90 int m_resolution_height; ///< Current resolution height
136 91
137 // Render buffers 92 // Framebuffers
138 // -------------- 93 // ------------
139 94
140 GLuint fbo_rbo_[kMaxFramebuffers]; ///< Render buffer objects 95 GLuint m_fbo[kMaxFramebuffers]; ///< Framebuffer objects
141 GLuint fbo_depth_buffers_[kMaxFramebuffers]; ///< Depth buffers objects 96 GLuint m_fbo_rbo[kMaxFramebuffers]; ///< Render buffer objects
97 GLuint m_fbo_depth_buffers[kMaxFramebuffers]; ///< Depth buffers objects
142 98
143 // External framebuffers 99 GLuint m_xfb_texture_top; ///< GL handle to top framebuffer texture
144 // --------------------- 100 GLuint m_xfb_texture_bottom; ///< GL handle to bottom framebuffer texture
101
102 GLuint m_xfb_top; ///< GL handle to top framebuffer
103 GLuint m_xfb_bottom; ///< GL handle to bottom framebuffer
145 104
146 GLuint xfb_texture_top_; ///< GL handle to top framebuffer texture 105 // "Flipped" framebuffers translate scanlines from native 3DS left-to-right to top-to-bottom
147 GLuint xfb_texture_bottom_; ///< GL handle to bottom framebuffer texture 106 // as OpenGL expects them in a texture. There probably is a more efficient way of doing this:
148 107
149 GLuint xfb_top_; 108 u8 m_xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4];
150 GLuint xfb_bottom_; 109 u8 m_xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4];
151 110
152 DISALLOW_COPY_AND_ASSIGN(RendererOpenGL); 111 DISALLOW_COPY_AND_ASSIGN(RendererOpenGL);
153}; \ No newline at end of file 112}; \ No newline at end of file