2009-07-28 21:32:10 +00:00
|
|
|
// Copyright (C) 2003 Dolphin Project.
|
2008-12-08 05:25:12 +00:00
|
|
|
|
|
|
|
// 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 "Globals.h"
|
2009-09-13 09:23:30 +00:00
|
|
|
#include "VideoConfig.h"
|
2008-12-08 05:25:12 +00:00
|
|
|
#include "IniFile.h"
|
2011-01-31 01:28:32 +00:00
|
|
|
#include "Core.h"
|
|
|
|
#include "Host.h"
|
|
|
|
#include "VideoBackend.h"
|
|
|
|
#include "ConfigManager.h"
|
2008-12-08 05:25:12 +00:00
|
|
|
|
|
|
|
#include "Render.h"
|
2010-12-21 23:58:25 +00:00
|
|
|
#include "VertexShaderManager.h"
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2010-07-16 21:56:40 +00:00
|
|
|
#include "GLUtil.h"
|
|
|
|
|
|
|
|
GLWindow GLWin;
|
2012-12-17 14:54:20 -06:00
|
|
|
cInterfaceBase *GLInterface;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2011-01-31 01:28:32 +00:00
|
|
|
namespace OGL
|
|
|
|
{
|
|
|
|
|
2009-02-19 06:52:01 +00:00
|
|
|
// Draw messages on top of the screen
|
2011-01-31 01:28:32 +00:00
|
|
|
unsigned int VideoBackend::PeekMessages()
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2012-12-17 14:54:20 -06:00
|
|
|
return GLInterface->PeekMessages();
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-02-28 16:33:59 +00:00
|
|
|
|
2009-02-19 06:52:01 +00:00
|
|
|
// Show the current FPS
|
2011-01-31 01:28:32 +00:00
|
|
|
void VideoBackend::UpdateFPSDisplay(const char *text)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2011-01-10 23:48:59 +00:00
|
|
|
char temp[100];
|
2011-08-21 16:30:19 -05:00
|
|
|
snprintf(temp, sizeof temp, "%s | OpenGL | %s", scm_rev_str, text);
|
2012-12-17 14:54:20 -06:00
|
|
|
return GLInterface->UpdateFPSDisplay(temp);
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
|
2011-01-31 01:28:32 +00:00
|
|
|
}
|
2012-12-17 14:54:20 -06:00
|
|
|
void InitInterface()
|
2010-02-16 04:59:45 +00:00
|
|
|
{
|
2012-12-17 14:54:20 -06:00
|
|
|
#if defined(USE_EGL) && USE_EGL
|
|
|
|
GLInterface = new cInterfaceEGL;
|
|
|
|
#elif defined(USE_WX) && USE_WX
|
|
|
|
GLInterface = new cInterfaceWX;
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
GLInterface = new cInterfaceAGL;
|
|
|
|
#elif defined(_WIN32)
|
|
|
|
GLInterface = new cInterfaceWGL;
|
|
|
|
#elif defined(HAVE_X11) && HAVE_X11
|
|
|
|
GLInterface = new cInterfaceGLX;
|
|
|
|
#endif
|
2010-03-15 23:25:11 +00:00
|
|
|
}
|
|
|
|
|
2012-12-17 14:54:20 -06:00
|
|
|
GLuint OpenGL_CompileProgram ( const char* vertexShader, const char* fragmentShader )
|
2010-03-15 23:25:11 +00:00
|
|
|
{
|
2012-12-17 14:54:20 -06:00
|
|
|
// generate objects
|
|
|
|
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
GLuint programID = glCreateProgram();
|
|
|
|
GLint Result = GL_FALSE;
|
|
|
|
char stringBuffer[1024];
|
|
|
|
GLsizei stringBufferUsage = 0;
|
|
|
|
|
|
|
|
// compile vertex shader
|
|
|
|
glShaderSource(vertexShaderID, 1, &vertexShader, NULL);
|
|
|
|
glCompileShader(vertexShaderID);
|
|
|
|
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
|
|
|
|
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &Result);
|
|
|
|
glGetShaderInfoLog(vertexShaderID, 1024, &stringBufferUsage, stringBuffer);
|
|
|
|
if(Result && stringBufferUsage) {
|
|
|
|
ERROR_LOG(VIDEO, "GLSL vertex shader warnings:\n%s%s", stringBuffer, vertexShader);
|
|
|
|
} else if(!Result) {
|
|
|
|
ERROR_LOG(VIDEO, "GLSL vertex shader error:\n%s%s", stringBuffer, vertexShader);
|
2011-02-06 01:56:45 +00:00
|
|
|
} else {
|
2012-12-17 14:54:20 -06:00
|
|
|
DEBUG_LOG(VIDEO, "GLSL vertex shader compiled:\n%s", vertexShader);
|
2010-02-20 04:18:19 +00:00
|
|
|
}
|
2012-12-17 14:54:20 -06:00
|
|
|
bool shader_errors = !Result;
|
2010-08-08 00:13:05 +00:00
|
|
|
#endif
|
2012-12-17 14:54:20 -06:00
|
|
|
|
|
|
|
// compile fragment shader
|
|
|
|
glShaderSource(fragmentShaderID, 1, &fragmentShader, NULL);
|
|
|
|
glCompileShader(fragmentShaderID);
|
|
|
|
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
|
|
|
|
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result);
|
|
|
|
glGetShaderInfoLog(fragmentShaderID, 1024, &stringBufferUsage, stringBuffer);
|
|
|
|
if(Result && stringBufferUsage) {
|
|
|
|
ERROR_LOG(VIDEO, "GLSL fragment shader warnings:\n%s%s", stringBuffer, fragmentShader);
|
|
|
|
} else if(!Result) {
|
|
|
|
ERROR_LOG(VIDEO, "GLSL fragment shader error:\n%s%s", stringBuffer, fragmentShader);
|
|
|
|
} else {
|
|
|
|
DEBUG_LOG(VIDEO, "GLSL fragment shader compiled:\n%s", fragmentShader);
|
fixed fps limiting when using using virtual xfb, now fps = vps, in fact now real xfb is as fast as no using xfb, i'm thinking now that the correct thing is leave it enabled as default, and even remove the option.
the problem is one strange behavior i found, in opengl when xfb is enable, frame limit causes the frame rate to be limited exact half the correct speed, so if you choose auto and the game uses 30 fps you get 15 fps
so in opengl, you have to limit to the exact double of the game speed, 100 to pal games and 120 to ntsc.
in d3d this not happened every time, it just happen when you change some time consuming setting like changing the ssaa or resizing the window, in that case you have to disable and re enable frame limit to get the correct fps
to all the devs please if you can help me debug this, will give you a lot of thanks as i'm short in time to debug this error and is driving me crazy not to find the source of the problem.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5249 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-03-28 23:51:32 +00:00
|
|
|
}
|
2012-12-17 14:54:20 -06:00
|
|
|
shader_errors |= !Result;
|
2008-12-08 05:25:12 +00:00
|
|
|
#endif
|
2011-03-31 05:36:54 +00:00
|
|
|
|
2012-12-17 14:54:20 -06:00
|
|
|
// link them
|
|
|
|
glAttachShader(programID, vertexShaderID);
|
|
|
|
glAttachShader(programID, fragmentShaderID);
|
|
|
|
glLinkProgram(programID);
|
|
|
|
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
|
|
|
|
glGetProgramiv(programID, GL_LINK_STATUS, &Result);
|
|
|
|
glGetProgramInfoLog(programID, 1024, &stringBufferUsage, stringBuffer);
|
|
|
|
if(Result && stringBufferUsage) {
|
|
|
|
ERROR_LOG(VIDEO, "GLSL linker warnings:\n%s%s%s", stringBuffer, vertexShader, fragmentShader);
|
|
|
|
} else if(!Result && !shader_errors) {
|
|
|
|
ERROR_LOG(VIDEO, "GLSL linker error:\n%s%s%s", stringBuffer, vertexShader, fragmentShader);
|
2009-03-22 11:21:44 +00:00
|
|
|
}
|
2008-12-08 09:58:02 +00:00
|
|
|
#endif
|
2012-12-17 14:54:20 -06:00
|
|
|
|
|
|
|
// cleanup
|
|
|
|
glDeleteShader(vertexShaderID);
|
|
|
|
glDeleteShader(fragmentShaderID);
|
|
|
|
|
|
|
|
return programID;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-02-21 13:11:49 +00:00
|
|
|
|
2009-03-22 11:21:44 +00:00
|
|
|
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line)
|
|
|
|
{
|
|
|
|
GLint err = glGetError();
|
|
|
|
if (err != GL_NO_ERROR)
|
|
|
|
{
|
2012-12-17 14:54:20 -06:00
|
|
|
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL error 0x%x\n",
|
|
|
|
file, line, function, err);
|
2009-03-22 11:21:44 +00:00
|
|
|
}
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGL_ReportARBProgramError()
|
2009-02-21 13:11:49 +00:00
|
|
|
{
|
2012-12-17 14:54:20 -06:00
|
|
|
#ifndef USE_GLES
|
2009-02-21 13:11:49 +00:00
|
|
|
const GLubyte* pstr = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
|
|
|
|
if (pstr != NULL && pstr[0] != 0)
|
|
|
|
{
|
|
|
|
GLint loc = 0;
|
|
|
|
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &loc);
|
2009-02-28 01:26:56 +00:00
|
|
|
ERROR_LOG(VIDEO, "program error at %d: ", loc);
|
2010-12-05 09:04:34 +00:00
|
|
|
ERROR_LOG(VIDEO, "%s", (char*)pstr);
|
|
|
|
ERROR_LOG(VIDEO, "\n");
|
2009-02-21 13:11:49 +00:00
|
|
|
}
|
2012-12-17 14:54:20 -06:00
|
|
|
#endif
|
2009-03-22 11:21:44 +00:00
|
|
|
}
|
2009-02-21 13:11:49 +00:00
|
|
|
|
2009-03-22 11:21:44 +00:00
|
|
|
bool OpenGL_ReportFBOError(const char *function, const char *file, int line)
|
|
|
|
{
|
2012-12-17 14:54:20 -06:00
|
|
|
#ifndef USE_GLES
|
2009-03-22 11:21:44 +00:00
|
|
|
unsigned int fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
|
|
|
if (fbo_status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
2009-02-21 13:11:49 +00:00
|
|
|
{
|
2009-03-22 11:21:44 +00:00
|
|
|
const char *error = "-";
|
|
|
|
switch (fbo_status)
|
|
|
|
{
|
2011-03-02 05:16:49 +00:00
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
|
|
|
error = "INCOMPLETE_ATTACHMENT_EXT";
|
|
|
|
break;
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
|
|
|
error = "INCOMPLETE_MISSING_ATTACHMENT_EXT";
|
|
|
|
break;
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
|
|
|
error = "INCOMPLETE_DIMENSIONS_EXT";
|
|
|
|
break;
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
|
|
|
error = "INCOMPLETE_FORMATS_EXT";
|
|
|
|
break;
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
|
|
|
error = "INCOMPLETE_DRAW_BUFFER_EXT";
|
|
|
|
break;
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
|
|
|
error = "INCOMPLETE_READ_BUFFER_EXT";
|
|
|
|
break;
|
|
|
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
|
|
|
error = "UNSUPPORTED_EXT";
|
|
|
|
break;
|
2009-03-22 11:21:44 +00:00
|
|
|
}
|
2011-03-02 05:16:49 +00:00
|
|
|
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n",
|
|
|
|
file, line, function, error);
|
2009-03-22 11:21:44 +00:00
|
|
|
return false;
|
2009-02-21 13:11:49 +00:00
|
|
|
}
|
2012-12-17 14:54:20 -06:00
|
|
|
#endif
|
2009-03-22 11:21:44 +00:00
|
|
|
return true;
|
2009-02-21 13:11:49 +00:00
|
|
|
}
|
2009-09-09 19:52:45 +00:00
|
|
|
|