mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	- removed lots of unused code from gekko
- updated code style/naming conventions
This commit is contained in:
		
							parent
							
								
									7a7917df27
								
							
						
					
					
						commit
						8c60294243
					
				
					 3 changed files with 118 additions and 375 deletions
				
			
		|  | @ -37,15 +37,7 @@ public: | ||||||
|         kFramebuffer_Texture |         kFramebuffer_Texture | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     /// Used for referencing the render modes
 |     RendererBase() : m_current_fps(0), m_current_frame(0) { | ||||||
|     enum kRenderMode { |  | ||||||
|         kRenderMode_None = 0, |  | ||||||
|         kRenderMode_Multipass = 1, |  | ||||||
|         kRenderMode_ZComp = 2, |  | ||||||
|         kRenderMode_UseDstAlpha = 4 |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     RendererBase() : current_fps_(0), current_frame_(0) { |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ~RendererBase() { |     ~RendererBase() { | ||||||
|  | @ -54,56 +46,6 @@ public: | ||||||
|     /// Swap buffers (render frame)
 |     /// Swap buffers (render frame)
 | ||||||
|     virtual void SwapBuffers() = 0; |     virtual void SwapBuffers() = 0; | ||||||
| 
 | 
 | ||||||
|     /** 
 |  | ||||||
|      * Blits the EFB to the external framebuffer (XFB) |  | ||||||
|      * @param src_rect Source rectangle in EFB to copy |  | ||||||
|      * @param dst_rect Destination rectangle in EFB to copy to |  | ||||||
|      * @param dest_height Destination height in pixels |  | ||||||
|      */ |  | ||||||
|     virtual void CopyToXFB(const Rect& src_rect, const Rect& dst_rect) = 0; |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * Clear the screen |  | ||||||
|      * @param rect Screen rectangle to clear |  | ||||||
|      * @param enable_color Enable color clearing |  | ||||||
|      * @param enable_alpha Enable alpha clearing |  | ||||||
|      * @param enable_z Enable depth clearing |  | ||||||
|      * @param color Clear color |  | ||||||
|      * @param z Clear depth |  | ||||||
|      */ |  | ||||||
|     virtual void Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z,  |  | ||||||
|         u32 color, u32 z) = 0; |  | ||||||
| 
 |  | ||||||
|     /// Sets the renderer viewport location, width, and height
 |  | ||||||
|     virtual void SetViewport(int x, int y, int width, int height) = 0; |  | ||||||
| 
 |  | ||||||
|     /// Sets the renderer depthrange, znear and zfar
 |  | ||||||
|     virtual void SetDepthRange(double znear, double zfar) = 0; |  | ||||||
| 
 |  | ||||||
|     /* Sets the scissor box
 |  | ||||||
|      * @param rect Renderer rectangle to set scissor box to |  | ||||||
|      */ |  | ||||||
|     virtual void SetScissorBox(const Rect& rect) = 0; |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * Sets the line and point size |  | ||||||
|      * @param line_width Line width to use |  | ||||||
|      * @param point_size Point size to use |  | ||||||
|      */ |  | ||||||
|     virtual void SetLinePointSize(f32 line_width, f32 point_size) = 0; |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * Set a specific render mode |  | ||||||
|      * @param flag Render flags mode to enable |  | ||||||
|      */ |  | ||||||
|     virtual void SetMode(kRenderMode flags) = 0; |  | ||||||
| 
 |  | ||||||
|     /// Reset the full renderer API to the NULL state
 |  | ||||||
|     virtual void ResetRenderState() = 0; |  | ||||||
| 
 |  | ||||||
|     /// Restore the full renderer API state - As the game set it
 |  | ||||||
|     virtual void RestoreRenderState() = 0; |  | ||||||
| 
 |  | ||||||
|     /** 
 |     /** 
 | ||||||
|      * Set the emulator window to use for renderer |      * Set the emulator window to use for renderer | ||||||
|      * @param window EmuWindow handle to emulator window to use for rendering |      * @param window EmuWindow handle to emulator window to use for rendering | ||||||
|  | @ -119,13 +61,17 @@ public: | ||||||
|     // Getter/setter functions:
 |     // Getter/setter functions:
 | ||||||
|     // ------------------------
 |     // ------------------------
 | ||||||
| 
 | 
 | ||||||
|     f32 current_fps() const { return current_fps_; } |     f32 GetCurrentframe() const { | ||||||
|  |         return m_current_fps; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     int current_frame() const { return current_frame_; } |     int current_frame() const { | ||||||
|  |         return m_current_frame; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|     f32 current_fps_;                       ///< Current framerate, should be set by the renderer
 |     f32 m_current_fps;              ///< Current framerate, should be set by the renderer
 | ||||||
|     int current_frame_;                     ///< Current frame, should be set by the renderer
 |     int m_current_frame;            ///< Current frame, should be set by the renderer
 | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     DISALLOW_COPY_AND_ASSIGN(RendererBase); |     DISALLOW_COPY_AND_ASSIGN(RendererBase); | ||||||
|  |  | ||||||
|  | @ -26,13 +26,53 @@ | ||||||
| #include "video_core.h" | #include "video_core.h" | ||||||
| #include "renderer_opengl/renderer_opengl.h" | #include "renderer_opengl/renderer_opengl.h" | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /// RendererOpenGL constructor
 | ||||||
|  | RendererOpenGL::RendererOpenGL() { | ||||||
|  |     memset(m_fbo, 0, sizeof(m_fbo));   | ||||||
|  |     memset(m_fbo_rbo, 0, sizeof(m_fbo_rbo));   | ||||||
|  |     memset(m_fbo_depth_buffers, 0, sizeof(m_fbo_depth_buffers)); | ||||||
|  | 
 | ||||||
|  |     m_resolution_width = max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); | ||||||
|  |     m_resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; | ||||||
|  | 
 | ||||||
|  |     m_xfb_texture_top = 0; | ||||||
|  |     m_xfb_texture_bottom = 0; | ||||||
|  | 
 | ||||||
|  |     m_xfb_top = 0; | ||||||
|  |     m_xfb_bottom = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// RendererOpenGL destructor
 | ||||||
|  | RendererOpenGL::~RendererOpenGL() { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Swap buffers (render frame)
 | ||||||
|  | void RendererOpenGL::SwapBuffers() { | ||||||
|  |     // EFB->XFB copy
 | ||||||
|  |     // TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some 
 | ||||||
|  |     // register write We're also treating both framebuffers as a single one in OpenGL.
 | ||||||
|  |     Rect framebuffer_size(0, 0, m_resolution_width, m_resolution_height); | ||||||
|  |     RenderXFB(framebuffer_size, framebuffer_size); | ||||||
|  | 
 | ||||||
|  |     // XFB->Window copy
 | ||||||
|  |     RenderFramebuffer(); | ||||||
|  | 
 | ||||||
|  |     // Swap buffers
 | ||||||
|  |     m_render_window->PollEvents(); | ||||||
|  |     m_render_window->SwapBuffers(); | ||||||
|  | 
 | ||||||
|  |     // Switch back to EFB and clear
 | ||||||
|  |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_EFB]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Helper function to flip framebuffer from left-to-right to top-to-bottom |  * Helper function to flip framebuffer from left-to-right to top-to-bottom | ||||||
|  * @param addr Address of framebuffer in RAM |  * @param addr Address of framebuffer in RAM | ||||||
|  * @param out Pointer to output buffer with flipped framebuffer |  * @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 |  * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei | ||||||
|  */ |  */ | ||||||
| inline void _flip_framebuffer(u32 addr, u8* out) { | void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out) { | ||||||
|     u8* in = Memory::GetPointer(addr); |     u8* in = Memory::GetPointer(addr); | ||||||
|     for (int y = 0; y < VideoCore::kScreenTopHeight; y++) { |     for (int y = 0; y < VideoCore::kScreenTopHeight; y++) { | ||||||
|         for (int x = 0; x < VideoCore::kScreenTopWidth; x++) { |         for (int x = 0; x < VideoCore::kScreenTopWidth; x++) { | ||||||
|  | @ -47,79 +87,31 @@ inline void _flip_framebuffer(u32 addr, u8* out) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// RendererOpenGL constructor
 |  | ||||||
| RendererOpenGL::RendererOpenGL() { |  | ||||||
|     memset(fbo_, 0, sizeof(fbo_));   |  | ||||||
|     memset(fbo_rbo_, 0, sizeof(fbo_rbo_));   |  | ||||||
|     memset(fbo_depth_buffers_, 0, sizeof(fbo_depth_buffers_)); |  | ||||||
| 
 |  | ||||||
|     resolution_width_ = max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); |  | ||||||
|     resolution_height_ = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; |  | ||||||
| 
 |  | ||||||
|     xfb_texture_top_ = 0; |  | ||||||
|     xfb_texture_bottom_ = 0; |  | ||||||
| 
 |  | ||||||
|     xfb_top_ = 0; |  | ||||||
|     xfb_bottom_ = 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// RendererOpenGL destructor
 |  | ||||||
| RendererOpenGL::~RendererOpenGL() { |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Swap buffers (render frame)
 |  | ||||||
| void RendererOpenGL::SwapBuffers() { |  | ||||||
| 
 |  | ||||||
|     ResetRenderState(); |  | ||||||
| 
 |  | ||||||
|     // EFB->XFB copy
 |  | ||||||
|     // TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some 
 |  | ||||||
|     // register write We're also treating both framebuffers as a single one in OpenGL.
 |  | ||||||
|     Rect framebuffer_size(0, 0, resolution_width_, resolution_height_); |  | ||||||
|     RenderXFB(framebuffer_size, framebuffer_size); |  | ||||||
| 
 |  | ||||||
|     // XFB->Window copy
 |  | ||||||
|     RenderFramebuffer(); |  | ||||||
| 
 |  | ||||||
|     // Swap buffers
 |  | ||||||
|     render_window_->PollEvents(); |  | ||||||
|     render_window_->SwapBuffers(); |  | ||||||
| 
 |  | ||||||
|     // Switch back to EFB and clear
 |  | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]); |  | ||||||
| 
 |  | ||||||
|     RestoreRenderState(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** 
 | /** 
 | ||||||
|  * Renders external framebuffer (XFB) |  * Renders external framebuffer (XFB) | ||||||
|  * @param src_rect Source rectangle in XFB to copy |  * @param src_rect Source rectangle in XFB to copy | ||||||
|  * @param dst_rect Destination rectangle in output framebuffer to copy to |  * @param dst_rect Destination rectangle in output framebuffer to copy to | ||||||
|  */ |  */ | ||||||
| void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) { | void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {   | ||||||
|     static u8 xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth *3];  |  | ||||||
|     static u8 xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth *3];      |  | ||||||
| 
 | 
 | ||||||
|     _flip_framebuffer(0x20282160, xfb_top_flipped); |     FlipFramebuffer(0x20282160, m_xfb_top_flipped); | ||||||
|     _flip_framebuffer(0x202118E0, xfb_bottom_flipped); |     FlipFramebuffer(0x202118E0, m_xfb_bottom_flipped); | ||||||
| 
 |  | ||||||
|     ResetRenderState(); |  | ||||||
| 
 | 
 | ||||||
|     // Blit the top framebuffer
 |     // Blit the top framebuffer
 | ||||||
|     // ------------------------
 |     // ------------------------
 | ||||||
| 
 | 
 | ||||||
|     // Update textures with contents of XFB in RAM - top
 |     // Update textures with contents of XFB in RAM - top
 | ||||||
|     glBindTexture(GL_TEXTURE_2D, xfb_texture_top_); |     glBindTexture(GL_TEXTURE_2D, m_xfb_texture_top); | ||||||
|     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, |     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, | ||||||
|         GL_RGB, GL_UNSIGNED_BYTE, xfb_top_flipped); |         GL_RGB, GL_UNSIGNED_BYTE, m_xfb_top_flipped); | ||||||
|     glBindTexture(GL_TEXTURE_2D, 0); |     glBindTexture(GL_TEXTURE_2D, 0); | ||||||
| 
 | 
 | ||||||
|     // Render target is destination framebuffer
 |     // Render target is destination framebuffer
 | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]); | ||||||
|     glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight); |     glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight); | ||||||
| 
 | 
 | ||||||
|     // Render source is our EFB
 |     // Render source is our EFB
 | ||||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_top_); |     glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_top); | ||||||
|     glReadBuffer(GL_COLOR_ATTACHMENT0); |     glReadBuffer(GL_COLOR_ATTACHMENT0); | ||||||
| 
 | 
 | ||||||
|     // Blit
 |     // Blit
 | ||||||
|  | @ -133,18 +125,18 @@ void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) { | ||||||
|     // ---------------------------
 |     // ---------------------------
 | ||||||
| 
 | 
 | ||||||
|     // Update textures with contents of XFB in RAM - bottom
 |     // Update textures with contents of XFB in RAM - bottom
 | ||||||
|     glBindTexture(GL_TEXTURE_2D, xfb_texture_bottom_); |     glBindTexture(GL_TEXTURE_2D, m_xfb_texture_bottom); | ||||||
|     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, |     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, | ||||||
|         GL_RGB, GL_UNSIGNED_BYTE, xfb_bottom_flipped); |         GL_RGB, GL_UNSIGNED_BYTE, m_xfb_bottom_flipped); | ||||||
|     glBindTexture(GL_TEXTURE_2D, 0); |     glBindTexture(GL_TEXTURE_2D, 0); | ||||||
| 
 | 
 | ||||||
|     // Render target is destination framebuffer
 |     // Render target is destination framebuffer
 | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]); | ||||||
|     glViewport(0, 0, |     glViewport(0, 0, | ||||||
|         VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight); |         VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight); | ||||||
| 
 | 
 | ||||||
|     // Render source is our EFB
 |     // Render source is our EFB
 | ||||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_bottom_); |     glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_bottom); | ||||||
|     glReadBuffer(GL_COLOR_ATTACHMENT0); |     glReadBuffer(GL_COLOR_ATTACHMENT0); | ||||||
| 
 | 
 | ||||||
|     // Blit
 |     // Blit
 | ||||||
|  | @ -154,190 +146,37 @@ void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) { | ||||||
|                       GL_COLOR_BUFFER_BIT, GL_LINEAR); |                       GL_COLOR_BUFFER_BIT, GL_LINEAR); | ||||||
| 
 | 
 | ||||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); |     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); | ||||||
| 
 |  | ||||||
|     RestoreRenderState(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** 
 |  | ||||||
|  * Blits the EFB to the external framebuffer (XFB) |  | ||||||
|  * @param src_rect Source rectangle in EFB to copy |  | ||||||
|  * @param dst_rect Destination rectangle in EFB to copy to |  | ||||||
|  */ |  | ||||||
| void RendererOpenGL::CopyToXFB(const Rect& src_rect, const Rect& dst_rect) { |  | ||||||
|     ERROR_LOG(RENDER, "CopyToXFB not implemented! No EFB support yet!"); |  | ||||||
|     //ResetRenderState();
 |  | ||||||
| 
 |  | ||||||
|     //// Render target is destination framebuffer
 |  | ||||||
|     //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]);
 |  | ||||||
|     //glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight);
 |  | ||||||
| 
 |  | ||||||
|     //// Render source is our EFB
 |  | ||||||
|     //glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
 |  | ||||||
|     //glReadBuffer(GL_COLOR_ATTACHMENT0);
 |  | ||||||
| 
 |  | ||||||
|     //// Blit
 |  | ||||||
|     //glBlitFramebuffer(src_rect.x0_, src_rect.y0_, src_rect.x1_, src_rect.y1_, 
 |  | ||||||
|     //                  dst_rect.x0_, dst_rect.y1_, dst_rect.x1_, dst_rect.y0_,
 |  | ||||||
|     //                  GL_COLOR_BUFFER_BIT, GL_LINEAR);
 |  | ||||||
| 
 |  | ||||||
|     //glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
 |  | ||||||
| 
 |  | ||||||
|     //RestoreRenderState();
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Clear the screen |  | ||||||
|  * @param rect Screen rectangle to clear |  | ||||||
|  * @param enable_color Enable color clearing |  | ||||||
|  * @param enable_alpha Enable alpha clearing |  | ||||||
|  * @param enable_z Enable depth clearing |  | ||||||
|  * @param color Clear color |  | ||||||
|  * @param z Clear depth |  | ||||||
|  */ |  | ||||||
| void RendererOpenGL::Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z,  |  | ||||||
|     u32 color, u32 z) { |  | ||||||
|     GLboolean const color_mask = enable_color ? GL_TRUE : GL_FALSE; |  | ||||||
|     GLboolean const alpha_mask = enable_alpha ? GL_TRUE : GL_FALSE; |  | ||||||
| 
 |  | ||||||
|     ResetRenderState(); |  | ||||||
| 
 |  | ||||||
|     // Clear color
 |  | ||||||
|     glColorMask(color_mask,  color_mask,  color_mask,  alpha_mask); |  | ||||||
|     glClearColor(float((color >> 16) & 0xFF) / 255.0f, float((color >> 8) & 0xFF) / 255.0f, |  | ||||||
|         float((color >> 0) & 0xFF) / 255.0f, float((color >> 24) & 0xFF) / 255.0f); |  | ||||||
| 
 |  | ||||||
|     // Clear depth
 |  | ||||||
|     glDepthMask(enable_z ? GL_TRUE : GL_FALSE); |  | ||||||
|     glClearDepth(float(z & 0xFFFFFF) / float(0xFFFFFF)); |  | ||||||
| 
 |  | ||||||
|     // Specify the rectangle of the EFB to clear
 |  | ||||||
|     glEnable(GL_SCISSOR_TEST); |  | ||||||
|     glScissor(rect.x0_, rect.y1_, rect.width(), rect.height()); |  | ||||||
| 
 |  | ||||||
|     // Clear it!
 |  | ||||||
|     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |  | ||||||
| 
 |  | ||||||
|     RestoreRenderState(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Sets the renderer viewport location, width, and height
 |  | ||||||
| void RendererOpenGL::SetViewport(int x, int y, int width, int height) { |  | ||||||
|     glViewport(x, y, width, height); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Sets the renderer depthrange, znear and zfar
 |  | ||||||
| void RendererOpenGL::SetDepthRange(double znear, double zfar) { |  | ||||||
|     glDepthRange(znear, zfar); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Sets the scissor box
 |  | ||||||
|  * @param rect Renderer rectangle to set scissor box to |  | ||||||
|  */ |  | ||||||
| void RendererOpenGL::SetScissorBox(const Rect& rect) { |  | ||||||
|     glScissor(rect.x0_, rect.y1_, rect.width(), rect.height()); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Sets the line and point size |  | ||||||
|  * @param line_width Line width to use |  | ||||||
|  * @param point_size Point size to use |  | ||||||
|  */ |  | ||||||
| void RendererOpenGL::SetLinePointSize(f32 line_width, f32 point_size) { |  | ||||||
|     glLineWidth((GLfloat)line_width); |  | ||||||
|     glPointSize((GLfloat)point_size); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Set a specific render mode |  | ||||||
|  * @param flag Render flags mode to enable |  | ||||||
|  */ |  | ||||||
| void RendererOpenGL::SetMode(kRenderMode flags) { |  | ||||||
|     if(flags & kRenderMode_ZComp) { |  | ||||||
|         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |  | ||||||
|     } |  | ||||||
|     if(flags & kRenderMode_Multipass) { |  | ||||||
|         glEnable(GL_DEPTH_TEST); |  | ||||||
|         glDepthMask(GL_FALSE);           |  | ||||||
|         glDepthFunc(GL_EQUAL); |  | ||||||
|     } |  | ||||||
|     if (flags & kRenderMode_UseDstAlpha) { |  | ||||||
|         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); |  | ||||||
|         glDisable(GL_BLEND); |  | ||||||
|     } |  | ||||||
|     last_mode_ |= flags; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Reset the full renderer API to the NULL state
 |  | ||||||
| void RendererOpenGL::ResetRenderState() { |  | ||||||
|     glDisable(GL_SCISSOR_TEST); |  | ||||||
|     glDisable(GL_DEPTH_TEST); |  | ||||||
|     glDisable(GL_CULL_FACE); |  | ||||||
|     glDisable(GL_BLEND); |  | ||||||
|     glDepthMask(GL_FALSE); |  | ||||||
|     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Restore the full renderer API state - As the game set it
 |  | ||||||
| void RendererOpenGL::RestoreRenderState() { |  | ||||||
|      |  | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]); |  | ||||||
|      |  | ||||||
|     //gp::XF_UpdateViewport();
 |  | ||||||
|     SetViewport(0, 0, resolution_width_, resolution_height_); |  | ||||||
|     SetDepthRange(0.0f, 1.0f); |  | ||||||
|      |  | ||||||
|     //SetGenerationMode();
 |  | ||||||
|     glEnable(GL_CULL_FACE); |  | ||||||
|     glFrontFace(GL_CCW); |  | ||||||
|      |  | ||||||
|     //glEnable(GL_SCISSOR_TEST);
 |  | ||||||
|     //gp::BP_SetScissorBox();
 |  | ||||||
|     glDisable(GL_SCISSOR_TEST); |  | ||||||
| 
 |  | ||||||
|     //SetColorMask(gp::g_bp_regs.cmode0);
 |  | ||||||
|     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |  | ||||||
|      |  | ||||||
|     //SetDepthMode();
 |  | ||||||
|     glDisable(GL_DEPTH_TEST); |  | ||||||
|     glDepthMask(GL_FALSE); |  | ||||||
| 
 |  | ||||||
|     //SetBlendMode(gp::g_bp_regs.cmode0, gp::g_bp_regs.cmode1, true);
 |  | ||||||
|     //if (common::g_config->current_renderer_config().enable_wireframe) {
 |  | ||||||
|     //    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 |  | ||||||
|     //} else {
 |  | ||||||
|     //    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 |  | ||||||
|     //}
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Initialize the FBO
 | /// Initialize the FBO
 | ||||||
| void RendererOpenGL::InitFramebuffer() { | void RendererOpenGL::InitFramebuffer() { | ||||||
|     // TODO(en): This should probably be implemented with the top screen and bottom screen as 
 |     // TODO(bunnei): This should probably be implemented with the top screen and bottom screen as 
 | ||||||
|     // separate framebuffers
 |     // separate framebuffers
 | ||||||
| 
 | 
 | ||||||
|     // Init the FBOs
 |     // Init the FBOs
 | ||||||
|     // -------------
 |     // -------------
 | ||||||
| 
 | 
 | ||||||
|     glGenFramebuffers(kMaxFramebuffers, fbo_); // Generate primary framebuffer
 |     glGenFramebuffers(kMaxFramebuffers, m_fbo); // Generate primary framebuffer
 | ||||||
|     glGenRenderbuffers(kMaxFramebuffers, fbo_rbo_); // Generate primary RBOs
 |     glGenRenderbuffers(kMaxFramebuffers, m_fbo_rbo); // Generate primary RBOs
 | ||||||
|     glGenRenderbuffers(kMaxFramebuffers, fbo_depth_buffers_); // Generate primary depth buffer
 |     glGenRenderbuffers(kMaxFramebuffers, m_fbo_depth_buffers); // Generate primary depth buffer
 | ||||||
| 
 | 
 | ||||||
|     for (int i = 0; i < kMaxFramebuffers; i++) { |     for (int i = 0; i < kMaxFramebuffers; i++) { | ||||||
|         // Generate color buffer storage
 |         // Generate color buffer storage
 | ||||||
|         glBindRenderbuffer(GL_RENDERBUFFER, fbo_rbo_[i]); |         glBindRenderbuffer(GL_RENDERBUFFER, m_fbo_rbo[i]); | ||||||
|         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, VideoCore::kScreenTopWidth,  |         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, VideoCore::kScreenTopWidth,  | ||||||
|             VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); |             VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); | ||||||
| 
 | 
 | ||||||
|         // Generate depth buffer storage
 |         // Generate depth buffer storage
 | ||||||
|         glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth_buffers_[i]); |         glBindRenderbuffer(GL_RENDERBUFFER, m_fbo_depth_buffers[i]); | ||||||
|         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, VideoCore::kScreenTopWidth,  |         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, VideoCore::kScreenTopWidth,  | ||||||
|             VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); |             VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); | ||||||
| 
 | 
 | ||||||
|         // Attach the buffers
 |         // Attach the buffers
 | ||||||
|         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[i]); |         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[i]); | ||||||
|         glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, |         glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, | ||||||
|             GL_RENDERBUFFER, fbo_depth_buffers_[i]); |             GL_RENDERBUFFER, m_fbo_depth_buffers[i]); | ||||||
|         glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |         glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | ||||||
|             GL_RENDERBUFFER, fbo_rbo_[i]); |             GL_RENDERBUFFER, m_fbo_rbo[i]); | ||||||
| 
 | 
 | ||||||
|         // Check for completeness
 |         // Check for completeness
 | ||||||
|         if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)) { |         if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)) { | ||||||
|  | @ -353,56 +192,55 @@ void RendererOpenGL::InitFramebuffer() { | ||||||
|     // -------------------------------
 |     // -------------------------------
 | ||||||
| 
 | 
 | ||||||
|     // Create XFB textures
 |     // Create XFB textures
 | ||||||
|     glGenTextures(1, &xfb_texture_top_);   |     glGenTextures(1, &m_xfb_texture_top);   | ||||||
|     glGenTextures(1, &xfb_texture_bottom_);   |     glGenTextures(1, &m_xfb_texture_bottom);   | ||||||
| 
 | 
 | ||||||
|     // Alocate video memorry for XFB textures
 |     // Alocate video memorry for XFB textures
 | ||||||
|     glBindTexture(GL_TEXTURE_2D, xfb_texture_top_); |     glBindTexture(GL_TEXTURE_2D, m_xfb_texture_top); | ||||||
|     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, |     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, | ||||||
|         0, GL_RGB, GL_UNSIGNED_BYTE, NULL); |         0, GL_RGB, GL_UNSIGNED_BYTE, NULL); | ||||||
|     glBindTexture(GL_TEXTURE_2D, 0); |     glBindTexture(GL_TEXTURE_2D, 0); | ||||||
| 
 | 
 | ||||||
|     glBindTexture(GL_TEXTURE_2D, xfb_texture_bottom_); |     glBindTexture(GL_TEXTURE_2D, m_xfb_texture_bottom); | ||||||
|     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, |     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight, | ||||||
|         0, GL_RGB, GL_UNSIGNED_BYTE, NULL); |         0, GL_RGB, GL_UNSIGNED_BYTE, NULL); | ||||||
|     glBindTexture(GL_TEXTURE_2D, 0); |     glBindTexture(GL_TEXTURE_2D, 0); | ||||||
| 
 | 
 | ||||||
|     // Create the FBO and attach color/depth textures
 |     // Create the FBO and attach color/depth textures
 | ||||||
|     glGenFramebuffers(1, &xfb_top_); // Generate framebuffer
 |     glGenFramebuffers(1, &m_xfb_top); // Generate framebuffer
 | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_top_); |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_xfb_top); | ||||||
|     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,  |     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,  | ||||||
|         xfb_texture_top_, 0); |         m_xfb_texture_top, 0); | ||||||
|     glBindFramebuffer(GL_FRAMEBUFFER, 0); |     glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||||
| 
 | 
 | ||||||
|     glGenFramebuffers(1, &xfb_bottom_); // Generate framebuffer
 |     glGenFramebuffers(1, &m_xfb_bottom); // Generate framebuffer
 | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_bottom_); |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_xfb_bottom); | ||||||
|     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,  |     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,  | ||||||
|         xfb_texture_bottom_, 0); |         m_xfb_texture_bottom, 0); | ||||||
|     glBindFramebuffer(GL_FRAMEBUFFER, 0); |     glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Blit the FBO to the OpenGL default framebuffer
 | /// Blit the FBO to the OpenGL default framebuffer
 | ||||||
| void RendererOpenGL::RenderFramebuffer() { | void RendererOpenGL::RenderFramebuffer() { | ||||||
| 
 |  | ||||||
|     // Render target is default framebuffer
 |     // Render target is default framebuffer
 | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | ||||||
|     glViewport(0, 0, resolution_width_, resolution_height_); |     glViewport(0, 0, m_resolution_width, m_resolution_height); | ||||||
| 
 | 
 | ||||||
|     // Render source is our XFB
 |     // Render source is our XFB
 | ||||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); |     glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]); | ||||||
|     glReadBuffer(GL_COLOR_ATTACHMENT0); |     glReadBuffer(GL_COLOR_ATTACHMENT0); | ||||||
| 
 | 
 | ||||||
|     // Blit
 |     // Blit
 | ||||||
|     glBlitFramebuffer(0, 0, resolution_width_, resolution_height_, 0, 0,  |     glBlitFramebuffer(0, 0, m_resolution_width, m_resolution_height, 0, 0, m_resolution_width,  | ||||||
|         resolution_width_, resolution_height_, GL_COLOR_BUFFER_BIT, GL_LINEAR); |         m_resolution_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); | ||||||
| 
 | 
 | ||||||
|     // Update the FPS count
 |     // Update the FPS count
 | ||||||
|     UpdateFramerate(); |     UpdateFramerate(); | ||||||
| 
 | 
 | ||||||
|     // Rebind EFB
 |     // Rebind EFB
 | ||||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]); |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_EFB]); | ||||||
| 
 | 
 | ||||||
|     current_frame_++; |     m_current_frame++; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Updates the framerate
 | /// Updates the framerate
 | ||||||
|  | @ -414,19 +252,19 @@ void RendererOpenGL::UpdateFramerate() { | ||||||
|  * @param window EmuWindow handle to emulator window to use for rendering |  * @param window EmuWindow handle to emulator window to use for rendering | ||||||
|  */ |  */ | ||||||
| void RendererOpenGL::SetWindow(EmuWindow* window) { | void RendererOpenGL::SetWindow(EmuWindow* window) { | ||||||
|     render_window_ = window; |     m_render_window = window; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Initialize the renderer
 | /// Initialize the renderer
 | ||||||
| void RendererOpenGL::Init() { | void RendererOpenGL::Init() { | ||||||
|     render_window_->MakeCurrent(); |     m_render_window->MakeCurrent(); | ||||||
|     glShadeModel(GL_SMOOTH); |     glShadeModel(GL_SMOOTH); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     glStencilFunc(GL_ALWAYS, 0, 0); |     glStencilFunc(GL_ALWAYS, 0, 0); | ||||||
|     glBlendFunc(GL_ONE, GL_ONE); |     glBlendFunc(GL_ONE, GL_ONE); | ||||||
| 
 | 
 | ||||||
|     glViewport(0, 0, resolution_width_, resolution_height_); |     glViewport(0, 0, m_resolution_width, m_resolution_height); | ||||||
| 
 | 
 | ||||||
|     glClearDepth(1.0f); |     glClearDepth(1.0f); | ||||||
|     glEnable(GL_DEPTH_TEST); |     glEnable(GL_DEPTH_TEST); | ||||||
|  | @ -438,12 +276,12 @@ void RendererOpenGL::Init() { | ||||||
|     glDisable(GL_STENCIL_TEST); |     glDisable(GL_STENCIL_TEST); | ||||||
|     glEnable(GL_SCISSOR_TEST); |     glEnable(GL_SCISSOR_TEST); | ||||||
| 
 | 
 | ||||||
|     glScissor(0, 0, resolution_width_, resolution_height_); |     glScissor(0, 0, m_resolution_width, m_resolution_height); | ||||||
|     glClearDepth(1.0f); |     glClearDepth(1.0f); | ||||||
| 
 | 
 | ||||||
|     GLenum err = glewInit(); |     GLenum err = glewInit(); | ||||||
|     if (GLEW_OK != err) { |     if (GLEW_OK != err) { | ||||||
|         ERROR_LOG(RENDER, " Failed to initialize GLEW! Error message: \"%s\". Exiting...",  |         ERROR_LOG(RENDER, "Failed to initialize GLEW! Error message: \"%s\". Exiting...",  | ||||||
|             glewGetErrorString(err)); |             glewGetErrorString(err)); | ||||||
|         exit(-1); |         exit(-1); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -51,55 +51,6 @@ public: | ||||||
|      */ |      */ | ||||||
|     void RenderXFB(const Rect& src_rect, const Rect& dst_rect); |     void RenderXFB(const Rect& src_rect, const Rect& dst_rect); | ||||||
| 
 | 
 | ||||||
|     /** 
 |  | ||||||
|      * Blits the EFB to the external framebuffer (XFB) |  | ||||||
|      * @param src_rect Source rectangle in EFB to copy |  | ||||||
|      * @param dst_rect Destination rectangle in EFB to copy to |  | ||||||
|      */ |  | ||||||
|     void CopyToXFB(const Rect& src_rect, const Rect& dst_rect); |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * Clear the screen |  | ||||||
|      * @param rect Screen rectangle to clear |  | ||||||
|      * @param enable_color Enable color clearing |  | ||||||
|      * @param enable_alpha Enable alpha clearing |  | ||||||
|      * @param enable_z Enable depth clearing |  | ||||||
|      * @param color Clear color |  | ||||||
|      * @param z Clear depth |  | ||||||
|      */ |  | ||||||
|     void Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z,  |  | ||||||
|         u32 color, u32 z); |  | ||||||
| 
 |  | ||||||
|     /// Sets the renderer viewport location, width, and height
 |  | ||||||
|     void SetViewport(int x, int y, int width, int height); |  | ||||||
| 
 |  | ||||||
|     /// Sets the renderer depthrange, znear and zfar
 |  | ||||||
|     void SetDepthRange(double znear, double zfar); |  | ||||||
| 
 |  | ||||||
|     /* Sets the scissor box
 |  | ||||||
|      * @param rect Renderer rectangle to set scissor box to |  | ||||||
|      */ |  | ||||||
|     void SetScissorBox(const Rect& rect); |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * Sets the line and point size |  | ||||||
|      * @param line_width Line width to use |  | ||||||
|      * @param point_size Point size to use |  | ||||||
|      */ |  | ||||||
|     void SetLinePointSize(f32 line_width, f32 point_size); |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * Set a specific render mode |  | ||||||
|      * @param flag Render flags mode to enable |  | ||||||
|      */ |  | ||||||
|     void SetMode(kRenderMode flags); |  | ||||||
| 
 |  | ||||||
|     /// Reset the full renderer API to the NULL state
 |  | ||||||
|     void ResetRenderState(); |  | ||||||
| 
 |  | ||||||
|     /// Restore the full renderer API state - As the game set it
 |  | ||||||
|     void RestoreRenderState(); |  | ||||||
| 
 |  | ||||||
|     /** 
 |     /** 
 | ||||||
|      * Set the emulator window to use for renderer |      * Set the emulator window to use for renderer | ||||||
|      * @param window EmuWindow handle to emulator window to use for rendering |      * @param window EmuWindow handle to emulator window to use for rendering | ||||||
|  | @ -112,11 +63,6 @@ public: | ||||||
|     /// Shutdown the renderer
 |     /// Shutdown the renderer
 | ||||||
|     void ShutDown(); |     void ShutDown(); | ||||||
| 
 | 
 | ||||||
|     // Framebuffer object(s)
 |  | ||||||
|     // ---------------------
 |  | ||||||
| 
 |  | ||||||
|     GLuint fbo_[kMaxFramebuffers];  ///< Framebuffer objects
 |  | ||||||
| 
 |  | ||||||
| private: | private: | ||||||
| 
 | 
 | ||||||
|     /// Initialize the FBO
 |     /// Initialize the FBO
 | ||||||
|  | @ -128,26 +74,39 @@ private: | ||||||
|     /// Updates the framerate
 |     /// Updates the framerate
 | ||||||
|     void UpdateFramerate(); |     void UpdateFramerate(); | ||||||
| 
 | 
 | ||||||
|     EmuWindow*  render_window_; |     /**
 | ||||||
|     u32         last_mode_;                         ///< Last render mode
 |      * Helper function to flip framebuffer from left-to-right to top-to-bottom | ||||||
|  |      * @param addr Address of framebuffer in RAM | ||||||
|  |      * @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 | ||||||
|  |      */ | ||||||
|  |     void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out); | ||||||
| 
 | 
 | ||||||
|     int resolution_width_; |  | ||||||
|     int resolution_height_; |  | ||||||
| 
 | 
 | ||||||
|     // Render buffers
 |     EmuWindow*  m_render_window;                    ///< Handle to render window
 | ||||||
|     // --------------
 |     u32         m_last_mode;                        ///< Last render mode
 | ||||||
| 
 | 
 | ||||||
|     GLuint fbo_rbo_[kMaxFramebuffers];              ///< Render buffer objects
 |     int m_resolution_width;                         ///< Current resolution width
 | ||||||
|     GLuint fbo_depth_buffers_[kMaxFramebuffers];    ///< Depth buffers objects
 |     int m_resolution_height;                        ///< Current resolution height
 | ||||||
| 
 | 
 | ||||||
|     // External framebuffers
 |     // Framebuffers
 | ||||||
|     // ---------------------
 |     // ------------
 | ||||||
| 
 | 
 | ||||||
|     GLuint xfb_texture_top_;                         ///< GL handle to top framebuffer texture
 |     GLuint m_fbo[kMaxFramebuffers];                 ///< Framebuffer objects
 | ||||||
|     GLuint xfb_texture_bottom_;                      ///< GL handle to bottom framebuffer texture
 |     GLuint m_fbo_rbo[kMaxFramebuffers];             ///< Render buffer objects
 | ||||||
|  |     GLuint m_fbo_depth_buffers[kMaxFramebuffers];   ///< Depth buffers objects
 | ||||||
| 
 | 
 | ||||||
|     GLuint xfb_top_; |     GLuint m_xfb_texture_top;                       ///< GL handle to top framebuffer texture
 | ||||||
|     GLuint xfb_bottom_; |     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
 | ||||||
|  | 
 | ||||||
|  |     // "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 m_xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4];  | ||||||
|  |     u8 m_xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4];    | ||||||
| 
 | 
 | ||||||
|     DISALLOW_COPY_AND_ASSIGN(RendererOpenGL); |     DISALLOW_COPY_AND_ASSIGN(RendererOpenGL); | ||||||
| }; | }; | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue