- removed lots of unused code from gekko
- updated code style/naming conventions
This commit is contained in:
		| @@ -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,7 +276,7 @@ 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(); | ||||||
|   | |||||||
| @@ -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); | ||||||
| }; | }; | ||||||
		Reference in New Issue
	
	Block a user