X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-video-arachnoid%2Fsrc%2FGraphicsPlugin.cpp;fp=source%2Fmupen64plus-video-arachnoid%2Fsrc%2FGraphicsPlugin.cpp;h=38da3d5b463611310465f25ec5a031277662de85;hb=22726e4d55be26faa48b57b22689cbedde27ae44;hp=0000000000000000000000000000000000000000;hpb=fc5d46b49a19d41f9f2da5a9336daec452900475;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp new file mode 100755 index 0000000..38da3d5 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp @@ -0,0 +1,495 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "GraphicsPlugin.h" +#include "VI.h" //Video interface +#include "Memory.h" //Access to memory (RDRAM, Texture Memory) +#include "OpenGLRenderer.h" //Renderer +#include "FrameBuffer.h" //Framebuffer +#include "DisplayListParser.h" //Displaylist parser +#include "FogManager.h" //Fog +#include "RSP.h" //Reality Signal Processor +#include "RDP.h" //Reality Drawing Processor +#include "GBI.h" //Graphics Binary Interface +#include "ConfigMap.h" //Configuration +#include "Logger.h" //Debug logger +#include "RomDetector.h" +#include +#ifdef HAVE_GLES +#include "eglport.h" +#include +#include +#endif + +//FrameBuffer framebuffer01; +//FrameBuffer framebuffer02; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +GraphicsPlugin::GraphicsPlugin() +: m_openGLMgr( OpenGLManager::getSingleton() ) +{ + m_vi = 0; + m_initialized = false; + m_updateConfig = false; + m_fogManager = 0; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +GraphicsPlugin::~GraphicsPlugin() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +// Initialize +//----------------------------------------------------------------------------- +bool GraphicsPlugin::initialize(GFX_INFO* graphicsInfo) +{ + //Initialize video output + if (CoreVideo_Init() != M64ERR_SUCCESS) + { + Logger::getSingleton().printMsg("Could not initialize video.", M64MSG_ERROR); + return false; + } + + //Save pointer to graphics info + m_graphicsInfo = graphicsInfo; + + m_numDListProcessed = 0; + + //Detect what rom it is + m_romDetector = &ROMDetector::getSingleton(); + m_romDetector->initialize( m_graphicsInfo->HEADER ); +#ifdef HAVE_GLES + SDL_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, SDL_FULLSCREEN); + SDL_ShowCursor(SDL_DISABLE); + EGL_Open(m_config->fullscreenWidth, m_config->fullscreenHeight); +#else + if (m_config->multiSampling > 0) + { + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1); + if (m_config->multiSampling <= 2) + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2); + else if (m_config->multiSampling <= 4) + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4); + else if (m_config->multiSampling <= 8) + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8); + else + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16); + } + + if (CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1) != M64ERR_SUCCESS || + CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 32) != M64ERR_SUCCESS || + CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 24) != M64ERR_SUCCESS) + { + Logger::getSingleton().printMsg("Could not set video attributes.", M64MSG_ERROR); + return false; + } + + if (CoreVideo_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, + m_config->startFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, (m64p_video_flags) 0) != M64ERR_SUCCESS) + { + Logger::getSingleton().printMsg("Could not set video mode.", M64MSG_ERROR); + return false; + } + + CoreVideo_SetCaption("Arachnoid"); +#endif + //Initialize Video Interface + m_vi = new VI(); + m_vi->calcSize(m_graphicsInfo); + + //Initialize Memory + m_memory = new Memory(); + if ( !m_memory->initialize(m_graphicsInfo->RDRAM, m_graphicsInfo->DMEM) ) + { + return false; + } + + m_displayListParser = new DisplayListParser(); + m_displayListParser->initialize(&m_rsp, &m_rdp, &m_gbi, m_memory); + + //Init OpenGL + if ( !m_openGLMgr.initialize(m_config->startFullscreen, m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate, true, false) ) + { + Logger::getSingleton().printMsg("Unable to initialize OpenGL", M64MSG_ERROR); + return false; + } + + + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); + + //Initialize Fog Manager + m_fogManager = new FogManager(); + m_fogManager->initialize(); + + + + //Initialize Texture Cache + //! @todo Not "hardcode" TextureBitDepth. + m_textureCache.initialize(&m_rsp, &m_rdp, m_memory, 16); + m_textureCache.setMipmap( m_config->mipmapping ); + + //Initialize OpenGL Renderer + if ( !OpenGLRenderer::getSingleton().initialize(&m_rsp, &m_rdp, &m_textureCache, m_vi, m_fogManager) ) + { + Logger::getSingleton().printMsg("Unable to initialize OpenGL Renderer", M64MSG_ERROR); + return false; + } + + //Initialize Processors + m_rdp.initialize(m_graphicsInfo, &m_rsp, m_memory, &m_gbi, &m_textureCache, m_vi, m_displayListParser, m_fogManager); + m_rsp.initialize(m_graphicsInfo, &m_rdp, m_memory, m_vi, m_displayListParser, m_fogManager); + m_gbi.initialize(&m_rsp, &m_rdp, m_memory, m_displayListParser); + + + //Set Background color + m_openGLMgr.setClearColor(0.0f, 0.0f, 0.0f); + m_openGLMgr.setLighting(false); + glDisable(GL_LIGHTING); + m_openGLMgr.setCullMode(false, true); + m_openGLMgr.setWireFrame(m_config->wireframe); + + //Initialize framebuffer + //framebuffer01.initialize(width, height); + // framebuffer02.initialize(width, height); + + m_initialized = true; + return true; +} + +//----------------------------------------------------------------------------- +// Dispose +//----------------------------------------------------------------------------- +void GraphicsPlugin::dispose() +{ + //Dispose of Textures + m_textureCache.dispose(); + + //Dispose of member objects + if ( m_vi ) { delete m_vi; m_vi = 0; } + if ( m_memory ) { delete m_memory; m_memory = 0; } + if ( m_displayListParser ) { delete m_displayListParser; m_displayListParser = 0; } + if ( m_fogManager ) { delete m_fogManager; m_fogManager = 0; } + + m_gbi.dispose(); + m_rdp.dispose(); + m_rsp.dispose(); + + //Dispose of OpenGL + //framebuffer01.dispose(); + // framebuffer02.dispose(); + m_openGLMgr.dispose(); + + if (m_initialized) +#ifdef HAVE_GLES + { + EGL_Close(); + SDL_Quit(); // *SEB* *TODO* Close Subsystem only? + } +#else + CoreVideo_Quit(); +#endif + + m_initialized = false; +} + +void renderMotionBlur() +{ + ///glPushMatrix(); + + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glEnable(GL_BLEND); + glColor4f(1, 1, 1, 0.9f); //Alpha blending + +// framebuffer01.render2(); + + glColor4f(1, 1, 1, 1.0f); //Alpha blending + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + //glPopMatrix(); +} + +bool animate(int frameRate) +{ + static clock_t lastTime; + clock_t currentTime = clock() * 1000 / CLOCKS_PER_SEC; + clock_t elapsedTime = currentTime - lastTime; + if (elapsedTime > ((clock_t)1000 / frameRate)) + { + lastTime = currentTime; + return true; + } + return false; + +#if 0 + //Todo: test against new version + static float lastTime = 0.0f; + float elapsedTime = 0.0; + float currentTime = GetTickCount() * 0.001f; + elapsedTime = currentTime - lastTime; + + if( elapsedTime > (1.0f / frameRate) ) + { + lastTime = currentTime; + return true; + } + + return false; +#endif + +} + +void renderQuad() +{ + static float dt = 0; + dt += 0.2f; + + //glDisable(GL_CULL_FACE); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + // glRotatef(dt, 0, 1, 0); + { +#ifdef HAVE_GLES +//*SEB* *TODO* +#else + glBegin(GL_QUADS); + { + glColor3f(1,0,0); glVertex3f(-1,-1,0); + glColor3f(1,1,0); glVertex3f( 1,-1,0); + glColor3f(0,1,1); glVertex3f( 1, 1,0); + glColor3f(0,0,1); glVertex3f(-1, 1,0); + } + glEnd(); +#endif + } + glPopMatrix(); +} + +void renderRedBox(float x, float y, float z, float width, float height, float length) +{ + static float dt = 0; + dt += 10.6f; + glRotatef(dt, 1,1,1); + x = x - width / 2; + y = y - height / 2; + z = z - length / 2; +#ifdef HAVE_GLES +//*SEB* *TODO* +#else + glBegin(GL_QUADS); + glColor3f(1,0,0); + glVertex3f(x, y, z); + glVertex3f(x, y + height, z); + glVertex3f(x + width, y + height, z); + glVertex3f(x + width, y, z); + glVertex3f(x, y, z + length); + glVertex3f(x, y + height, z + length); + glVertex3f(x + width, y + height, z + length); + glVertex3f(x + width, y, z + length); + glVertex3f(x, y, z); + glVertex3f(x, y, z + length); + glVertex3f(x + width, y, z + length); + glVertex3f(x + width, y, z); + glVertex3f(x, y + height, z); + glVertex3f(x, y + height, z + length); + glVertex3f(x + width, y + height, z + length); + glVertex3f(x + width, y + height, z); + glVertex3f(x, y, z); + glVertex3f(x, y, z + length); + glVertex3f(x, y + height, z + length); + glVertex3f(x, y + height, z); + glVertex3f(x + width, y, z); + glVertex3f(x + width, y, z + length); + glVertex3f(x + width, y + height, z + length); + glVertex3f(x + width, y + height, z); + glColor3f(1,1,1); + glEnd(); +#endif +} + +//----------------------------------------------------------------------------- +// ProcessDisplayList +//----------------------------------------------------------------------------- +void GraphicsPlugin::processDisplayList() +{ + if ( (m_numDListProcessed == 1 && m_romDetector->getClearType() == CT_AFTER_ONE_DISPLAY_LIST) || + (m_numDListProcessed == 2 && m_romDetector->getClearType() == CT_AFTER_TWO_DISPLAY_LIST) || + (m_numDListProcessed == 3 && m_romDetector->getClearType() == CT_AFTER_THREE_DISPLAY_LIST) ) + { + bool scissors = OpenGLManager::getSingleton().getScissorEnabled(); + OpenGLManager::getSingleton().setScissorEnabled(false); + glClear(GL_COLOR_BUFFER_BIT); + m_numDListProcessed = 0; + OpenGLManager::getSingleton().setScissorEnabled(scissors); + } + + //Update Config? + if ( m_updateConfig ) + { + m_vi->calcSize(m_graphicsInfo); + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); + OpenGLManager::getSingleton().setViewport(0, 0, m_config->windowWidth, m_config->windowHeight); + m_openGLMgr.setWireFrame( m_config->wireframe ); + _setTextureCacheSize( m_config->textureCacheSize ); + m_updateConfig = false; + + //if ( OpenGLManager::getSingleton().getFullscreen() ) + //{ + // //Initialize framebuffer + // FrameBuffer::getSingleton().dispose(); + // FrameBuffer::getSingleton().initialize(m_config->fullscreenWidth, m_config->fullscreenHeight); + //} + //else + //{ + // //Initialize framebuffer + // FrameBuffer::getSingleton().dispose(); + // FrameBuffer::getSingleton().initialize(m_config->windowWidth, m_config->windowHeight); + //} + + + } + + //Get Video Interface Size + m_vi->calcSize(m_graphicsInfo); + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); + OpenGLManager::getSingleton().setForceDisableCulling( ROMDetector::getSingleton().getDisableFaceCulling() ); + + //Render Scene + OpenGLManager::getSingleton().beginRendering(); + OpenGLManager::getSingleton().setTextureing2D(true); + glEnable(GL_DEPTH_TEST); + { + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_rsp.reset(); + m_rdp.reset(); + m_openGLMgr.setCullMode(false, true); + m_displayListParser->processDisplayList(); + } + + //Clear Screen? + m_numDListProcessed++; + + //glFlush(); +// OpenGLManager::getSingleton().endRendering(); + OpenGLManager::getSingleton().setDrawFlag(); + //Take screenshot? +} + +//----------------------------------------------------------------------------- +// Update Screen +//----------------------------------------------------------------------------- +void GraphicsPlugin::drawScreen() +{ + OpenGLManager::getSingleton().endRendering(); +} + +void GraphicsPlugin::setDrawScreenSignal() +{ + m_rdp.signalUpdate(); +} + +//----------------------------------------------------------------------------- +// Video Interface Status Changed +//----------------------------------------------------------------------------- +void GraphicsPlugin::viStatusChanged() +{ + //Get new VI Size + m_vi->calcSize( m_graphicsInfo ); + + //Re Calculate Scale + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); +} + +//----------------------------------------------------------------------------- +// Toggle Fullscreen +//----------------------------------------------------------------------------- +void GraphicsPlugin::toggleFullscreen() +{ + if ( m_initialized ) + { + CoreVideo_ToggleFullScreen(); + } +} + +//----------------------------------------------------------------------------- +// Take Screenshot +//----------------------------------------------------------------------------- +void GraphicsPlugin::takeScreenshot(void *dest, int *width, int *height, int front) +{ + *width = m_config->windowWidth; + *height = m_config->windowHeight; + if (dest) + { +#ifndef HAVE_GLES + if (front) + glReadBuffer(GL_FRONT); + else + glReadBuffer(GL_BACK); +#endif + glReadPixels(0, 0, *width, *height, GL_RGB, GL_UNSIGNED_BYTE, dest); + } +} + +//----------------------------------------------------------------------------- +// Update Configuration +//----------------------------------------------------------------------------- +void GraphicsPlugin::updateConfig() +{ + m_updateConfig = true; + + //For project 64, Give config dialog time to close before continueing +#ifdef WIN32 + Sleep(300); +#endif + //Resize Window + _setWindowMode(m_config->windowWidth, m_config->windowHeight); + + //Reinitialize OpenGL + OpenGLManager::getSingleton().resize(m_config->windowWidth, m_config->windowHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate); +} + +//----------------------------------------------------------------------------- +// Set Window Mode +//----------------------------------------------------------------------------- +void GraphicsPlugin::_setWindowMode(int width, int height) +{ + if ( m_initialized ) + { + //TODO: is this function needed? + //m_windowMgr->resizeWindow(width, height); + } +} + +//----------------------------------------------------------------------------- +// Set Texture Cache Size +//----------------------------------------------------------------------------- +void GraphicsPlugin::_setTextureCacheSize(int sizeInBytes) +{ + +}