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 | ||||
|     }; | ||||
| 
 | ||||
|     /// Used for referencing the render modes
 | ||||
|     enum kRenderMode { | ||||
|         kRenderMode_None = 0, | ||||
|         kRenderMode_Multipass = 1, | ||||
|         kRenderMode_ZComp = 2, | ||||
|         kRenderMode_UseDstAlpha = 4 | ||||
|     }; | ||||
| 
 | ||||
|     RendererBase() : current_fps_(0), current_frame_(0) { | ||||
|     RendererBase() : m_current_fps(0), m_current_frame(0) { | ||||
|     } | ||||
| 
 | ||||
|     ~RendererBase() { | ||||
|  | @ -54,56 +46,6 @@ public: | |||
|     /// Swap buffers (render frame)
 | ||||
|     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 | ||||
|      * @param window EmuWindow handle to emulator window to use for rendering | ||||
|  | @ -119,13 +61,17 @@ public: | |||
|     // 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: | ||||
|     f32 current_fps_;                       ///< Current framerate, should be set by the renderer
 | ||||
|     int current_frame_;                     ///< Current frame, should be set by the renderer
 | ||||
|     f32 m_current_fps;              ///< Current framerate, should be set by the renderer
 | ||||
|     int m_current_frame;            ///< Current frame, should be set by the renderer
 | ||||
| 
 | ||||
| private: | ||||
|     DISALLOW_COPY_AND_ASSIGN(RendererBase); | ||||
|  |  | |||
|  | @ -26,13 +26,53 @@ | |||
| #include "video_core.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 | ||||
|  * @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 | ||||
|  */ | ||||
| inline void _flip_framebuffer(u32 addr, u8* out) { | ||||
| void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out) { | ||||
|     u8* in = Memory::GetPointer(addr); | ||||
|     for (int y = 0; y < VideoCore::kScreenTopHeight; y++) { | ||||
|         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) | ||||
|  * @param src_rect Source rectangle in XFB to copy | ||||
|  * @param dst_rect Destination rectangle in output framebuffer to copy to | ||||
|  */ | ||||
| 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); | ||||
|     _flip_framebuffer(0x202118E0, xfb_bottom_flipped); | ||||
| 
 | ||||
|     ResetRenderState(); | ||||
|     FlipFramebuffer(0x20282160, m_xfb_top_flipped); | ||||
|     FlipFramebuffer(0x202118E0, m_xfb_bottom_flipped); | ||||
| 
 | ||||
|     // Blit the top framebuffer
 | ||||
|     // ------------------------
 | ||||
| 
 | ||||
|     // 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, | ||||
|         GL_RGB, GL_UNSIGNED_BYTE, xfb_top_flipped); | ||||
|         GL_RGB, GL_UNSIGNED_BYTE, m_xfb_top_flipped); | ||||
|     glBindTexture(GL_TEXTURE_2D, 0); | ||||
| 
 | ||||
|     // 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); | ||||
| 
 | ||||
|     // Render source is our EFB
 | ||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_top_); | ||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_top); | ||||
|     glReadBuffer(GL_COLOR_ATTACHMENT0); | ||||
| 
 | ||||
|     // 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
 | ||||
|     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, | ||||
|         GL_RGB, GL_UNSIGNED_BYTE, xfb_bottom_flipped); | ||||
|         GL_RGB, GL_UNSIGNED_BYTE, m_xfb_bottom_flipped); | ||||
|     glBindTexture(GL_TEXTURE_2D, 0); | ||||
| 
 | ||||
|     // Render target is destination framebuffer
 | ||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); | ||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]); | ||||
|     glViewport(0, 0, | ||||
|         VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight); | ||||
| 
 | ||||
|     // Render source is our EFB
 | ||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_bottom_); | ||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_bottom); | ||||
|     glReadBuffer(GL_COLOR_ATTACHMENT0); | ||||
| 
 | ||||
|     // Blit
 | ||||
|  | @ -154,190 +146,37 @@ void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) { | |||
|                       GL_COLOR_BUFFER_BIT, GL_LINEAR); | ||||
| 
 | ||||
|     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
 | ||||
| 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
 | ||||
| 
 | ||||
|     // Init the FBOs
 | ||||
|     // -------------
 | ||||
| 
 | ||||
|     glGenFramebuffers(kMaxFramebuffers, fbo_); // Generate primary framebuffer
 | ||||
|     glGenRenderbuffers(kMaxFramebuffers, fbo_rbo_); // Generate primary RBOs
 | ||||
|     glGenRenderbuffers(kMaxFramebuffers, fbo_depth_buffers_); // Generate primary depth buffer
 | ||||
|     glGenFramebuffers(kMaxFramebuffers, m_fbo); // Generate primary framebuffer
 | ||||
|     glGenRenderbuffers(kMaxFramebuffers, m_fbo_rbo); // Generate primary RBOs
 | ||||
|     glGenRenderbuffers(kMaxFramebuffers, m_fbo_depth_buffers); // Generate primary depth buffer
 | ||||
| 
 | ||||
|     for (int i = 0; i < kMaxFramebuffers; i++) { | ||||
|         // Generate color buffer storage
 | ||||
|         glBindRenderbuffer(GL_RENDERBUFFER, fbo_rbo_[i]); | ||||
|         glBindRenderbuffer(GL_RENDERBUFFER, m_fbo_rbo[i]); | ||||
|         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, VideoCore::kScreenTopWidth,  | ||||
|             VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); | ||||
| 
 | ||||
|         // 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,  | ||||
|             VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); | ||||
| 
 | ||||
|         // Attach the buffers
 | ||||
|         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[i]); | ||||
|         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[i]); | ||||
|         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, | ||||
|             GL_RENDERBUFFER, fbo_rbo_[i]); | ||||
|             GL_RENDERBUFFER, m_fbo_rbo[i]); | ||||
| 
 | ||||
|         // Check for completeness
 | ||||
|         if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)) { | ||||
|  | @ -353,56 +192,55 @@ void RendererOpenGL::InitFramebuffer() { | |||
|     // -------------------------------
 | ||||
| 
 | ||||
|     // Create XFB textures
 | ||||
|     glGenTextures(1, &xfb_texture_top_);   | ||||
|     glGenTextures(1, &xfb_texture_bottom_);   | ||||
|     glGenTextures(1, &m_xfb_texture_top);   | ||||
|     glGenTextures(1, &m_xfb_texture_bottom);   | ||||
| 
 | ||||
|     // 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, | ||||
|         0, GL_RGB, GL_UNSIGNED_BYTE, NULL); | ||||
|     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, | ||||
|         0, GL_RGB, GL_UNSIGNED_BYTE, NULL); | ||||
|     glBindTexture(GL_TEXTURE_2D, 0); | ||||
| 
 | ||||
|     // Create the FBO and attach color/depth textures
 | ||||
|     glGenFramebuffers(1, &xfb_top_); // Generate framebuffer
 | ||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_top_); | ||||
|     glGenFramebuffers(1, &m_xfb_top); // Generate framebuffer
 | ||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_xfb_top); | ||||
|     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,  | ||||
|         xfb_texture_top_, 0); | ||||
|         m_xfb_texture_top, 0); | ||||
|     glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||
| 
 | ||||
|     glGenFramebuffers(1, &xfb_bottom_); // Generate framebuffer
 | ||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_bottom_); | ||||
|     glGenFramebuffers(1, &m_xfb_bottom); // Generate framebuffer
 | ||||
|     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_xfb_bottom); | ||||
|     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,  | ||||
|         xfb_texture_bottom_, 0); | ||||
|         m_xfb_texture_bottom, 0); | ||||
|     glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||
| } | ||||
| 
 | ||||
| /// Blit the FBO to the OpenGL default framebuffer
 | ||||
| void RendererOpenGL::RenderFramebuffer() { | ||||
| 
 | ||||
|     // Render target is default framebuffer
 | ||||
|     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
 | ||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]); | ||||
|     glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]); | ||||
|     glReadBuffer(GL_COLOR_ATTACHMENT0); | ||||
| 
 | ||||
|     // Blit
 | ||||
|     glBlitFramebuffer(0, 0, resolution_width_, resolution_height_, 0, 0,  | ||||
|         resolution_width_, resolution_height_, GL_COLOR_BUFFER_BIT, GL_LINEAR); | ||||
|     glBlitFramebuffer(0, 0, m_resolution_width, m_resolution_height, 0, 0, m_resolution_width,  | ||||
|         m_resolution_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); | ||||
| 
 | ||||
|     // Update the FPS count
 | ||||
|     UpdateFramerate(); | ||||
| 
 | ||||
|     // 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
 | ||||
|  | @ -414,19 +252,19 @@ void RendererOpenGL::UpdateFramerate() { | |||
|  * @param window EmuWindow handle to emulator window to use for rendering | ||||
|  */ | ||||
| void RendererOpenGL::SetWindow(EmuWindow* window) { | ||||
|     render_window_ = window; | ||||
|     m_render_window = window; | ||||
| } | ||||
| 
 | ||||
| /// Initialize the renderer
 | ||||
| void RendererOpenGL::Init() { | ||||
|     render_window_->MakeCurrent(); | ||||
|     m_render_window->MakeCurrent(); | ||||
|     glShadeModel(GL_SMOOTH); | ||||
| 
 | ||||
| 
 | ||||
|     glStencilFunc(GL_ALWAYS, 0, 0); | ||||
|     glBlendFunc(GL_ONE, GL_ONE); | ||||
| 
 | ||||
|     glViewport(0, 0, resolution_width_, resolution_height_); | ||||
|     glViewport(0, 0, m_resolution_width, m_resolution_height); | ||||
| 
 | ||||
|     glClearDepth(1.0f); | ||||
|     glEnable(GL_DEPTH_TEST); | ||||
|  | @ -438,7 +276,7 @@ void RendererOpenGL::Init() { | |||
|     glDisable(GL_STENCIL_TEST); | ||||
|     glEnable(GL_SCISSOR_TEST); | ||||
| 
 | ||||
|     glScissor(0, 0, resolution_width_, resolution_height_); | ||||
|     glScissor(0, 0, m_resolution_width, m_resolution_height); | ||||
|     glClearDepth(1.0f); | ||||
| 
 | ||||
|     GLenum err = glewInit(); | ||||
|  |  | |||
|  | @ -51,55 +51,6 @@ public: | |||
|      */ | ||||
|     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 | ||||
|      * @param window EmuWindow handle to emulator window to use for rendering | ||||
|  | @ -112,11 +63,6 @@ public: | |||
|     /// Shutdown the renderer
 | ||||
|     void ShutDown(); | ||||
| 
 | ||||
|     // Framebuffer object(s)
 | ||||
|     // ---------------------
 | ||||
| 
 | ||||
|     GLuint fbo_[kMaxFramebuffers];  ///< Framebuffer objects
 | ||||
| 
 | ||||
| private: | ||||
| 
 | ||||
|     /// Initialize the FBO
 | ||||
|  | @ -128,26 +74,39 @@ private: | |||
|     /// Updates the framerate
 | ||||
|     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
 | ||||
|     GLuint fbo_depth_buffers_[kMaxFramebuffers];    ///< Depth buffers objects
 | ||||
|     int m_resolution_width;                         ///< Current resolution width
 | ||||
|     int m_resolution_height;                        ///< Current resolution height
 | ||||
| 
 | ||||
|     // External framebuffers
 | ||||
|     // ---------------------
 | ||||
|     // Framebuffers
 | ||||
|     // ------------
 | ||||
| 
 | ||||
|     GLuint xfb_texture_top_;                         ///< GL handle to top framebuffer texture
 | ||||
|     GLuint xfb_texture_bottom_;                      ///< GL handle to bottom framebuffer texture
 | ||||
|     GLuint m_fbo[kMaxFramebuffers];                 ///< Framebuffer objects
 | ||||
|     GLuint m_fbo_rbo[kMaxFramebuffers];             ///< Render buffer objects
 | ||||
|     GLuint m_fbo_depth_buffers[kMaxFramebuffers];   ///< Depth buffers objects
 | ||||
| 
 | ||||
|     GLuint xfb_top_; | ||||
|     GLuint xfb_bottom_; | ||||
|     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
 | ||||
| 
 | ||||
|     // "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); | ||||
| }; | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue