forked from dolphin-emu/dolphin
		
	Added it to scons to fix the unresolved symbol on scons build git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4415 8ced0084-cf51-0410-be5f-012b33b47a6e
		
			
				
	
	
		
			202 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (C) 2003-2009 Dolphin Project.
 | 
						|
 | 
						|
// 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, version 2.0.
 | 
						|
 | 
						|
// 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 2.0 for more details.
 | 
						|
 | 
						|
// A copy of the GPL 2.0 should have been included with the program.
 | 
						|
// If not, see http://www.gnu.org/licenses/
 | 
						|
 | 
						|
// Official SVN repository and contact information can be found at
 | 
						|
// http://code.google.com/p/dolphin-emu/
 | 
						|
 | 
						|
#include "Common.h"
 | 
						|
 | 
						|
#include "GLUtil.h"
 | 
						|
#include "Renderer.h"
 | 
						|
#include "main.h"
 | 
						|
#include "Statistics.h"
 | 
						|
#include "RasterFont.h"
 | 
						|
 | 
						|
#define VSYNC_ENABLED 0
 | 
						|
 | 
						|
static GLuint s_RenderTarget = 0;
 | 
						|
 | 
						|
RasterFont* s_pfont = NULL;
 | 
						|
 | 
						|
void Renderer::Init(SVideoInitialize *_pVideoInitialize)
 | 
						|
{
 | 
						|
    if (!OpenGL_Create(g_VideoInitialize, 640, 480)) // 640x480 will be the default if all else fails
 | 
						|
	{
 | 
						|
        g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
	_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
 | 
						|
    _pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
 | 
						|
    _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;    
 | 
						|
}
 | 
						|
 | 
						|
void Renderer::Shutdown()
 | 
						|
{
 | 
						|
    glDeleteTextures(1, &s_RenderTarget);	
 | 
						|
 | 
						|
    delete s_pfont;
 | 
						|
    s_pfont = 0;
 | 
						|
}
 | 
						|
 | 
						|
void Renderer::Prepare()
 | 
						|
{
 | 
						|
    OpenGL_MakeCurrent();
 | 
						|
 | 
						|
    // Init extension support.
 | 
						|
	if (glewInit() != GLEW_OK) {
 | 
						|
        ERROR_LOG(VIDEO, "glewInit() failed!Does your video card support OpenGL 2.x?");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    	// Handle VSync on/off
 | 
						|
#ifdef _WIN32
 | 
						|
	if (WGLEW_EXT_swap_control)
 | 
						|
		wglSwapIntervalEXT(VSYNC_ENABLED);
 | 
						|
	else
 | 
						|
		ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)Does your video card support OpenGL 2.x?");
 | 
						|
#elif defined(HAVE_X11) && HAVE_X11
 | 
						|
	if (glXSwapIntervalSGI)
 | 
						|
		glXSwapIntervalSGI(VSYNC_ENABLED);
 | 
						|
	else
 | 
						|
		ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)");
 | 
						|
#endif
 | 
						|
 | 
						|
    glStencilFunc(GL_ALWAYS, 0, 0);
 | 
						|
    // used by hw rasterizer if it enables blending and depth test
 | 
						|
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
						|
    glDepthFunc(GL_LEQUAL);
 | 
						|
 | 
						|
    glShadeModel(GL_SMOOTH);
 | 
						|
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 | 
						|
    glClearDepth(1.0f);
 | 
						|
    glEnable(GL_SCISSOR_TEST);
 | 
						|
    
 | 
						|
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);  // 4-byte pixel alignment
 | 
						|
    
 | 
						|
    glDisable(GL_LIGHTING);
 | 
						|
    glDisable(GL_BLEND);
 | 
						|
    glDisable(GL_STENCIL_TEST);
 | 
						|
    //glDisable(GL_SCISSOR_TEST);
 | 
						|
 | 
						|
    glMatrixMode(GL_PROJECTION);
 | 
						|
    glLoadIdentity();
 | 
						|
    glMatrixMode(GL_MODELVIEW);
 | 
						|
    glLoadIdentity();
 | 
						|
 | 
						|
    s_pfont = new RasterFont();    
 | 
						|
 | 
						|
    // legacy multitexturing: select texture channel only.
 | 
						|
    glActiveTexture(GL_TEXTURE0);
 | 
						|
    glClientActiveTexture(GL_TEXTURE0);
 | 
						|
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 | 
						|
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 | 
						|
 | 
						|
    glGenTextures(1, &s_RenderTarget);
 | 
						|
	glEnable(GL_TEXTURE_RECTANGLE_ARB);
 | 
						|
}
 | 
						|
 | 
						|
void Renderer::RenderText(const char* pstr, int left, int top, u32 color)
 | 
						|
{
 | 
						|
	int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
 | 
						|
	int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
 | 
						|
	glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f,
 | 
						|
	          ((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f);
 | 
						|
	s_pfont->printMultilineText(pstr,
 | 
						|
		left * 2.0f / (float)nBackbufferWidth - 1,
 | 
						|
		1 - top * 2.0f / (float)nBackbufferHeight,
 | 
						|
		0, nBackbufferWidth, nBackbufferHeight);
 | 
						|
}
 | 
						|
 | 
						|
void Renderer::DrawDebugText()
 | 
						|
{
 | 
						|
    char debugtext_buffer[8192];
 | 
						|
	char *p = debugtext_buffer;
 | 
						|
	p[0] = 0;
 | 
						|
 | 
						|
	if (g_Config.bShowStats) 
 | 
						|
	{
 | 
						|
        p+=sprintf(p,"Objects: %i\n",stats.thisFrame.numDrawnObjects);
 | 
						|
        p+=sprintf(p,"Primatives: %i\n",stats.thisFrame.numPrimatives);
 | 
						|
        p+=sprintf(p,"Vertices Loaded: %i\n",stats.thisFrame.numVerticesLoaded);
 | 
						|
 | 
						|
        p+=sprintf(p,"Triangles Input:   %i\n",stats.thisFrame.numTrianglesIn);
 | 
						|
        p+=sprintf(p,"Triangles Rejected:   %i\n",stats.thisFrame.numTrianglesRejected);
 | 
						|
        p+=sprintf(p,"Triangles Culled:   %i\n",stats.thisFrame.numTrianglesCulled);
 | 
						|
        p+=sprintf(p,"Triangles Clipped:  %i\n",stats.thisFrame.numTrianglesClipped);
 | 
						|
        p+=sprintf(p,"Triangles Drawn:   %i\n",stats.thisFrame.numTrianglesDrawn);
 | 
						|
 | 
						|
        p+=sprintf(p,"Rasterized Pix:   %i\n",stats.thisFrame.rasterizedPixels);
 | 
						|
        p+=sprintf(p,"TEV Pix In:   %i\n",stats.thisFrame.tevPixelsIn);
 | 
						|
        p+=sprintf(p,"TEV Pix Out:   %i\n",stats.thisFrame.tevPixelsOut);        
 | 
						|
    }
 | 
						|
 | 
						|
	// Render a shadow, and then the text.
 | 
						|
	Renderer::RenderText(debugtext_buffer, 21, 21, 0xDD000000);
 | 
						|
	Renderer::RenderText(debugtext_buffer, 20, 20, 0xFFFFFF00);
 | 
						|
}
 | 
						|
 | 
						|
void Renderer::DrawTexture(u8 *texture, int width, int height)
 | 
						|
{
 | 
						|
    OpenGL_Update(); // just updates the render window position and the backbuffer size	
 | 
						|
 | 
						|
	GLsizei glWidth = (GLsizei)OpenGL_GetBackbufferWidth();
 | 
						|
	GLsizei glHeight = (GLsizei)OpenGL_GetBackbufferHeight();
 | 
						|
 | 
						|
	// Update GLViewPort
 | 
						|
	glViewport(0, 0, glWidth, glHeight);
 | 
						|
    glScissor(0, 0, glWidth, glHeight);
 | 
						|
 | 
						|
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
 | 
						|
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
 | 
						|
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
						|
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
						|
 | 
						|
	GL_REPORT_ERRORD();
 | 
						|
 | 
						|
    GLfloat u_max = (GLfloat)width;
 | 
						|
    GLfloat v_max = (GLfloat)glHeight;
 | 
						|
    
 | 
						|
    glBegin(GL_QUADS);
 | 
						|
		glTexCoord2f(0, v_max); glVertex2f(-1, -1);
 | 
						|
		glTexCoord2f(0, 0); glVertex2f(-1,  1);
 | 
						|
		glTexCoord2f(u_max, 0); glVertex2f( 1,  1);
 | 
						|
		glTexCoord2f(u_max, v_max); glVertex2f( 1, -1);
 | 
						|
	glEnd();
 | 
						|
 | 
						|
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);    
 | 
						|
}
 | 
						|
 | 
						|
void Renderer::SwapBuffer()
 | 
						|
{
 | 
						|
    DrawDebugText();
 | 
						|
 | 
						|
    glFlush();
 | 
						|
 | 
						|
	OpenGL_SwapBuffers();
 | 
						|
    
 | 
						|
	GL_REPORT_ERRORD();
 | 
						|
 | 
						|
    stats.ResetFrame();
 | 
						|
	
 | 
						|
	// Clear framebuffer
 | 
						|
	glClearColor(0, 0, 0, 0);
 | 
						|
    glClearDepth(1.0);
 | 
						|
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 | 
						|
 | 
						|
	GL_REPORT_ERRORD();
 | 
						|
}
 | 
						|
 | 
						|
 |