Merge pull request #3155 from degasus/videosw

VideoSW: Split up OGL window handling
This commit is contained in:
flacs 2015-10-17 04:56:44 +02:00
commit d85344bd58
11 changed files with 210 additions and 425 deletions

View File

@ -16,7 +16,7 @@ void InitInterface()
GLInterface = HostGL_CreateGLInterface(); GLInterface = HostGL_CreateGLInterface();
} }
GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShader) GLuint OpenGL_CompileProgram(const std::string& vertexShader, const std::string& fragmentShader)
{ {
// generate objects // generate objects
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
@ -24,7 +24,8 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade
GLuint programID = glCreateProgram(); GLuint programID = glCreateProgram();
// compile vertex shader // compile vertex shader
glShaderSource(vertexShaderID, 1, &vertexShader, nullptr); const char* shader = vertexShader.c_str();
glShaderSource(vertexShaderID, 1, &shader, nullptr);
glCompileShader(vertexShaderID); glCompileShader(vertexShaderID);
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
GLint Result = GL_FALSE; GLint Result = GL_FALSE;
@ -35,22 +36,23 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade
if (Result && stringBufferUsage) if (Result && stringBufferUsage)
{ {
ERROR_LOG(VIDEO, "GLSL vertex shader warnings:\n%s%s", stringBuffer, vertexShader); ERROR_LOG(VIDEO, "GLSL vertex shader warnings:\n%s%s", stringBuffer, vertexShader.c_str());
} }
else if (!Result) else if (!Result)
{ {
ERROR_LOG(VIDEO, "GLSL vertex shader error:\n%s%s", stringBuffer, vertexShader); ERROR_LOG(VIDEO, "GLSL vertex shader error:\n%s%s", stringBuffer, vertexShader.c_str());
} }
else else
{ {
DEBUG_LOG(VIDEO, "GLSL vertex shader compiled:\n%s", vertexShader); DEBUG_LOG(VIDEO, "GLSL vertex shader compiled:\n%s", vertexShader.c_str());
} }
bool shader_errors = !Result; bool shader_errors = !Result;
#endif #endif
// compile fragment shader // compile fragment shader
glShaderSource(fragmentShaderID, 1, &fragmentShader, nullptr); shader = fragmentShader.c_str();
glShaderSource(fragmentShaderID, 1, &shader, nullptr);
glCompileShader(fragmentShaderID); glCompileShader(fragmentShaderID);
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result);
@ -58,15 +60,15 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade
if (Result && stringBufferUsage) if (Result && stringBufferUsage)
{ {
ERROR_LOG(VIDEO, "GLSL fragment shader warnings:\n%s%s", stringBuffer, fragmentShader); ERROR_LOG(VIDEO, "GLSL fragment shader warnings:\n%s%s", stringBuffer, fragmentShader.c_str());
} }
else if (!Result) else if (!Result)
{ {
ERROR_LOG(VIDEO, "GLSL fragment shader error:\n%s%s", stringBuffer, fragmentShader); ERROR_LOG(VIDEO, "GLSL fragment shader error:\n%s%s", stringBuffer, fragmentShader.c_str());
} }
else else
{ {
DEBUG_LOG(VIDEO, "GLSL fragment shader compiled:\n%s", fragmentShader); DEBUG_LOG(VIDEO, "GLSL fragment shader compiled:\n%s", fragmentShader.c_str());
} }
shader_errors |= !Result; shader_errors |= !Result;
@ -82,11 +84,11 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade
if (Result && stringBufferUsage) if (Result && stringBufferUsage)
{ {
ERROR_LOG(VIDEO, "GLSL linker warnings:\n%s%s%s", stringBuffer, vertexShader, fragmentShader); ERROR_LOG(VIDEO, "GLSL linker warnings:\n%s%s%s", stringBuffer, vertexShader.c_str(), fragmentShader.c_str());
} }
else if (!Result && !shader_errors) else if (!Result && !shader_errors)
{ {
ERROR_LOG(VIDEO, "GLSL linker error:\n%s%s%s", stringBuffer, vertexShader, fragmentShader); ERROR_LOG(VIDEO, "GLSL linker error:\n%s%s%s", stringBuffer, vertexShader.c_str(), fragmentShader.c_str());
} }
#endif #endif

View File

@ -4,6 +4,8 @@
#pragma once #pragma once
#include <string>
#include "Common/GL/GLExtensions/GLExtensions.h" #include "Common/GL/GLExtensions/GLExtensions.h"
#ifndef _WIN32 #ifndef _WIN32
@ -14,7 +16,7 @@
void InitInterface(); void InitInterface();
// Helpers // Helpers
GLuint OpenGL_CompileProgram(const char *vertexShader, const char *fragmentShader); GLuint OpenGL_CompileProgram(const std::string& vertexShader, const std::string& fragmentShader);
// Creates and deletes a VAO and VBO suitable for attributeless rendering. // Creates and deletes a VAO and VBO suitable for attributeless rendering.
// Called by the Renderer. // Called by the Renderer.

View File

@ -1,23 +1,23 @@
set(SRCS BPMemLoader.cpp set(SRCS BPMemLoader.cpp
Clipper.cpp
SWCommandProcessor.cpp
CPMemLoader.cpp CPMemLoader.cpp
Clipper.cpp
DebugUtil.cpp DebugUtil.cpp
EfbCopy.cpp EfbCopy.cpp
EfbInterface.cpp EfbInterface.cpp
SWmain.cpp
OpcodeDecoder.cpp OpcodeDecoder.cpp
RasterFont.cpp
Rasterizer.cpp Rasterizer.cpp
SWCommandProcessor.cpp
SWOGLWindow.cpp
SWRenderer.cpp SWRenderer.cpp
SetupUnit.cpp
SWStatistics.cpp SWStatistics.cpp
SWVertexLoader.cpp
SWVideoConfig.cpp
SWmain.cpp
SetupUnit.cpp
Tev.cpp Tev.cpp
TextureEncoder.cpp TextureEncoder.cpp
TextureSampler.cpp TextureSampler.cpp
TransformUnit.cpp TransformUnit.cpp
SWVertexLoader.cpp
SWVideoConfig.cpp
XFMemLoader.cpp) XFMemLoader.cpp)
set(LIBS videocommon set(LIBS videocommon

View File

@ -1,211 +0,0 @@
// Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <string.h>
#include "Common/GL/GLUtil.h"
#include "VideoBackends/Software/RasterFont.h"
const GLubyte rasters[][13] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18},
{0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70},
{0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e},
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c},
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06},
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60},
{0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e},
{0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},
{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},
{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},
{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c},
{0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18},
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70},
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03},
{0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e},
{0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00},
{0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00},
{0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}
};
RasterFont::RasterFont()
{
// set GL modes
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// create the raster font
fontOffset = glGenLists(128);
for (int i = 32; i < 127; i++)
{
glNewList(i + fontOffset, GL_COMPILE);
glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i - 32]);
glEndList();
}
temp_buffer = new char[TEMP_BUFFER_SIZE];
}
RasterFont::~RasterFont()
{
glDeleteLists(fontOffset, 128);
delete [] temp_buffer;
}
void RasterFont::printString(const char *s, double x, double y, double z)
{
int length = (int)strlen(s);
if (!length)
return;
if (length >= TEMP_BUFFER_SIZE)
length = TEMP_BUFFER_SIZE - 1;
// Sanitize string to avoid GL errors.
char *s2 = temp_buffer;
memcpy(s2, s, length);
s2[length] = 0;
for (int i = 0; i < length; i++)
{
if (s2[i] < 32 || s2[i] > 126)
s2[i] = '!';
}
// go to the right spot
glRasterPos3d(x, y, z);
glPushAttrib (GL_LIST_BIT);
glListBase(fontOffset);
glCallLists((GLsizei)strlen(s2), GL_UNSIGNED_BYTE, (GLubyte *) s2);
glPopAttrib();
}
void RasterFont::printCenteredString(const char *s, double y, int screen_width, double z)
{
int length = (int)strlen(s);
int x = (int)(screen_width/2.0 - (length/2.0) * CHAR_WIDTH);
printString(s, x, y, z);
}
void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight)
{
double x = start_x;
double y = start_y;
char temp[1024];
char *t = temp;
while (*text)
{
if (*text == '\n')
{
*t = 0;
printString(temp, x, y, z);
y -= CHAR_HEIGHT * 2.0f / bbHeight;
x = start_x;
t = temp;
}
else if (*text == '\r')
{
t = temp;
}
else if (*text == '\t')
{
//todo: add tabs every something like 4 * CHAR_WIDTH
*t = 0;
int cpos = (int)strlen(temp);
int newpos = (cpos + 4) & (~3);
printString(temp, x, y, z);
x = start_x + (CHAR_WIDTH * newpos) * 2.0f / bbWidth;
t = temp;
*t++ = ' ';
}
else
{
*t++ = *text;
}
text++;
}
// ????
if (t != text)
{
*t = 0;
printString(temp, x, y, z);
}
}

View File

@ -1,27 +0,0 @@
// Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
class RasterFont
{
public:
RasterFont();
~RasterFont();
static int debug;
// and the happy helper functions
void printString(const char *s, double x, double y, double z=0.0);
void printCenteredString(const char *s, double y, int screen_width, double z=0.0);
void printMultilineText(const char *text, double x, double y, double z, int bbWidth, int bbHeight);
private:
int fontOffset;
char *temp_buffer;
static const int TEMP_BUFFER_SIZE = 64 * 1024;
static const int CHAR_WIDTH = 10;
static const int CHAR_HEIGHT = 15;
};

View File

@ -0,0 +1,130 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "Common/GL/GLInterfaceBase.h"
#include "Common/GL/GLUtil.h"
#include "Common/Logging/Log.h"
#include "VideoBackends/Software/SWOGLWindow.h"
std::unique_ptr<SWOGLWindow> SWOGLWindow::s_instance;
void SWOGLWindow::Init(void *window_handle)
{
InitInterface();
GLInterface->SetMode(GLInterfaceMode::MODE_DETECT);
if (!GLInterface->Create(window_handle))
{
INFO_LOG(VIDEO, "GLInterface::Create failed.");
}
s_instance.reset(new SWOGLWindow());
}
void SWOGLWindow::Shutdown()
{
GLInterface->Shutdown();
delete GLInterface;
GLInterface = nullptr;
SWOGLWindow::s_instance.release();
}
void SWOGLWindow::Prepare()
{
if (m_init) return;
m_init = true;
// Init extension support.
if (!GLExtensions::Init())
{
ERROR_LOG(VIDEO, "GLExtensions::Init failed!Does your video card support OpenGL 2.0?");
return;
}
else if (GLExtensions::Version() < 310)
{
ERROR_LOG(VIDEO, "OpenGL Version %d detected, but at least 3.1 is required.", GLExtensions::Version());
return;
}
std::string frag_shader =
"in vec2 TexCoord;\n"
"out vec4 ColorOut;\n"
"uniform sampler2D Texture;\n"
"void main() {\n"
" ColorOut = texture2D(Texture, TexCoord);\n"
"}\n";
std::string vertex_shader =
"out vec2 TexCoord;\n"
"void main() {\n"
" vec2 rawpos = vec2(gl_VertexID & 1, (gl_VertexID & 2) >> 1);\n"
" gl_Position = vec4(rawpos * 2.0 - 1.0, 0.0, 1.0);\n"
" TexCoord = vec2(rawpos.x, -rawpos.y);\n"
"}\n";
std::string header =
GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL ?
"#version 140\n"
:
"#version 300 es\n"
"precision highp float;\n";
m_image_program = OpenGL_CompileProgram(header + vertex_shader, header + frag_shader);
glUseProgram(m_image_program);
glUniform1i(glGetUniformLocation(m_image_program, "Texture"), 0);
glGenTextures(1, &m_image_texture);
glBindTexture(GL_TEXTURE_2D, m_image_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenVertexArrays(1, &m_image_vao);
}
void SWOGLWindow::PrintText(const std::string& text, int x, int y, u32 color)
{
TextData data{text, x, y, color};
m_text.emplace_back(data);
}
void SWOGLWindow::ShowImage(u8* data, int stride, int width, int height, float aspect)
{
GLInterface->MakeCurrent();
GLInterface->Update();
Prepare();
GLsizei glWidth = (GLsizei)GLInterface->GetBackBufferWidth();
GLsizei glHeight = (GLsizei)GLInterface->GetBackBufferHeight();
glViewport(0, 0, glWidth, glHeight);
glBindTexture(GL_TEXTURE_2D, m_image_texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / 4);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glUseProgram(m_image_program);
glBindVertexArray(m_image_vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// TODO: implement OSD
// for (TextData& text : m_text)
// {
// }
m_text.clear();
GLInterface->Swap();
GLInterface->ClearCurrent();
}
int SWOGLWindow::PeekMessages()
{
return GLInterface->PeekMessages();
}

View File

@ -0,0 +1,45 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "Common/CommonTypes.h"
class SWOGLWindow
{
public:
static void Init(void* window_handle);
static void Shutdown();
// Will be printed on the *next* image
void PrintText(const std::string& text, int x, int y, u32 color);
// Image to show, will be swapped immediately
void ShowImage(u8* data, int stride, int width, int height, float aspect);
int PeekMessages();
static std::unique_ptr<SWOGLWindow> s_instance;
private:
SWOGLWindow() {}
void Prepare();
struct TextData
{
std::string text;
int x, y;
u32 color;
};
std::vector<TextData> m_text;
bool m_init {false};
u32 m_image_program, m_image_texture, m_image_vao;
};

View File

@ -9,25 +9,17 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/GL/GLInterfaceBase.h"
#include "Common/GL/GLUtil.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "VideoBackends/Software/RasterFont.h"
#include "VideoBackends/Software/SWCommandProcessor.h" #include "VideoBackends/Software/SWCommandProcessor.h"
#include "VideoBackends/Software/SWOGLWindow.h"
#include "VideoBackends/Software/SWRenderer.h" #include "VideoBackends/Software/SWRenderer.h"
#include "VideoBackends/Software/SWStatistics.h" #include "VideoBackends/Software/SWStatistics.h"
#include "VideoCommon/ImageWrite.h" #include "VideoCommon/ImageWrite.h"
#include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/OnScreenDisplay.h"
static GLuint s_RenderTarget = 0;
static GLint attr_pos = -1, attr_tex = -1;
static GLint uni_tex = -1;
static GLuint program;
static u8 *s_xfbColorTexture[2]; static u8 *s_xfbColorTexture[2];
static int s_currentColorTexture = 0; static int s_currentColorTexture = 0;
@ -35,11 +27,6 @@ static std::atomic<bool> s_bScreenshot;
static std::mutex s_criticalScreenshot; static std::mutex s_criticalScreenshot;
static std::string s_sScreenshotName; static std::string s_sScreenshotName;
// Rasterfont isn't compatible with GLES
// degasus: I think it does, but I can't test it
static RasterFont* s_pfont = nullptr;
void SWRenderer::Init() void SWRenderer::Init()
{ {
s_bScreenshot.store(false); s_bScreenshot.store(false);
@ -49,45 +36,6 @@ void SWRenderer::Shutdown()
{ {
delete[] s_xfbColorTexture[0]; delete[] s_xfbColorTexture[0];
delete[] s_xfbColorTexture[1]; delete[] s_xfbColorTexture[1];
glDeleteProgram(program);
glDeleteTextures(1, &s_RenderTarget);
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL)
{
delete s_pfont;
s_pfont = nullptr;
}
}
static void CreateShaders()
{
static const char *fragShaderText =
"#ifdef GL_ES\n"
"precision highp float;\n"
"#endif\n"
"varying vec2 TexCoordOut;\n"
"uniform sampler2D Texture;\n"
"void main() {\n"
" gl_FragColor = texture2D(Texture, TexCoordOut);\n"
"}\n";
static const char *vertShaderText =
"#ifdef GL_ES\n"
"precision highp float;\n"
"#endif\n"
"attribute vec4 pos;\n"
"attribute vec2 TexCoordIn;\n "
"varying vec2 TexCoordOut;\n "
"void main() {\n"
" gl_Position = pos;\n"
" TexCoordOut = TexCoordIn;\n"
"}\n";
program = OpenGL_CompileProgram(vertShaderText, fragShaderText);
glUseProgram(program);
uni_tex = glGetUniformLocation(program, "Texture");
attr_pos = glGetAttribLocation(program, "pos");
attr_tex = glGetAttribLocation(program, "TexCoordIn");
} }
void SWRenderer::Prepare() void SWRenderer::Prepare()
@ -96,18 +44,6 @@ void SWRenderer::Prepare()
s_xfbColorTexture[1] = new u8[MAX_XFB_WIDTH * MAX_XFB_HEIGHT * 4]; s_xfbColorTexture[1] = new u8[MAX_XFB_WIDTH * MAX_XFB_HEIGHT * 4];
s_currentColorTexture = 0; s_currentColorTexture = 0;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
glGenTextures(1, &s_RenderTarget);
CreateShaders();
// TODO: Enable for GLES once RasterFont supports GLES
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL)
{
s_pfont = new RasterFont();
glEnable(GL_TEXTURE_2D);
}
} }
void SWRenderer::SetScreenshot(const char *_szFilename) void SWRenderer::SetScreenshot(const char *_szFilename)
@ -119,16 +55,7 @@ void SWRenderer::SetScreenshot(const char *_szFilename)
void SWRenderer::RenderText(const char* pstr, int left, int top, u32 color) void SWRenderer::RenderText(const char* pstr, int left, int top, u32 color)
{ {
if (GLInterface->GetMode() != GLInterfaceMode::MODE_OPENGL) SWOGLWindow::s_instance->PrintText(pstr, left, top, color);
return;
int nBackbufferWidth = (int)GLInterface->GetBackBufferWidth();
int nBackbufferHeight = (int)GLInterface->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 SWRenderer::DrawDebugText() void SWRenderer::DrawDebugText()
@ -213,81 +140,23 @@ void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidt
// Called on the GPU thread // Called on the GPU thread
void SWRenderer::Swap(u32 fbWidth, u32 fbHeight) void SWRenderer::Swap(u32 fbWidth, u32 fbHeight)
{ {
GLInterface->Update(); // just updates the render window position and the backbuffer size
SWRenderer::DrawTexture(GetCurrentColorTexture(), fbWidth, fbHeight);
swstats.frameCount++;
SWRenderer::SwapBuffer();
Core::Callback_VideoCopiedToXFB(true); // FIXME: should this function be called FrameRendered?
}
void SWRenderer::DrawTexture(u8 *texture, int width, int height)
{
// FIXME: This should add black bars when the game has set the VI to render less than the full xfb.
// Save screenshot // Save screenshot
if (s_bScreenshot.load()) if (s_bScreenshot.load())
{ {
std::lock_guard<std::mutex> lk(s_criticalScreenshot); std::lock_guard<std::mutex> lk(s_criticalScreenshot);
TextureToPng(texture, width * 4, s_sScreenshotName, width, height, false); TextureToPng(GetCurrentColorTexture(), fbWidth * 4, s_sScreenshotName, fbWidth, fbHeight, false);
// Reset settings // Reset settings
s_sScreenshotName.clear(); s_sScreenshotName.clear();
s_bScreenshot.store(false); s_bScreenshot.store(false);
} }
GLsizei glWidth = (GLsizei)GLInterface->GetBackBufferWidth();
GLsizei glHeight = (GLsizei)GLInterface->GetBackBufferHeight();
// Update GLViewPort
glViewport(0, 0, glWidth, glHeight);
glScissor(0, 0, glWidth, glHeight);
glBindTexture(GL_TEXTURE_2D, s_RenderTarget);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glUseProgram(program);
static const GLfloat verts[4][2] = {
{ -1, -1}, // Left top
{ -1, 1}, // left bottom
{ 1, 1}, // right bottom
{ 1, -1} // right top
};
static const GLfloat texverts[4][2] = {
{0, 1},
{0, 0},
{1, 0},
{1, 1}
};
glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts);
glEnableVertexAttribArray(attr_pos);
glEnableVertexAttribArray(attr_tex);
glUniform1i(uni_tex, 0);
glActiveTexture(GL_TEXTURE0);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(attr_pos);
glDisableVertexAttribArray(attr_tex);
glBindTexture(GL_TEXTURE_2D, 0);
}
void SWRenderer::SwapBuffer()
{
// Do our OSD callbacks
OSD::DoCallbacks(OSD::OSD_ONFRAME); OSD::DoCallbacks(OSD::OSD_ONFRAME);
DrawDebugText(); DrawDebugText();
glFlush(); SWOGLWindow::s_instance->ShowImage(GetCurrentColorTexture(), fbWidth * 4, fbWidth, fbHeight, 1.0);
GLInterface->Swap();
swstats.frameCount++;
swstats.ResetFrame(); swstats.ResetFrame();
Core::Callback_VideoCopiedToXFB(true); // FIXME: should this function be called FrameRendered?
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }

View File

@ -22,8 +22,6 @@ namespace SWRenderer
u8* GetCurrentColorTexture(); u8* GetCurrentColorTexture();
void SwapColorTexture(); void SwapColorTexture();
void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight); void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight);
void DrawTexture(u8 *texture, int width, int height);
void Swap(u32 fbWidth, u32 fbHeight); void Swap(u32 fbWidth, u32 fbHeight);
void SwapBuffer();
} }

View File

@ -8,9 +8,6 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/FileUtil.h" #include "Common/FileUtil.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/GL/GLInterfaceBase.h"
#include "Common/GL/GLUtil.h"
#include "Common/GL/GLExtensions/GLExtensions.h"
#include "Common/Logging/LogManager.h" #include "Common/Logging/LogManager.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
@ -26,6 +23,7 @@
#include "VideoBackends/Software/OpcodeDecoder.h" #include "VideoBackends/Software/OpcodeDecoder.h"
#include "VideoBackends/Software/Rasterizer.h" #include "VideoBackends/Software/Rasterizer.h"
#include "VideoBackends/Software/SWCommandProcessor.h" #include "VideoBackends/Software/SWCommandProcessor.h"
#include "VideoBackends/Software/SWOGLWindow.h"
#include "VideoBackends/Software/SWRenderer.h" #include "VideoBackends/Software/SWRenderer.h"
#include "VideoBackends/Software/SWStatistics.h" #include "VideoBackends/Software/SWStatistics.h"
#include "VideoBackends/Software/SWVertexLoader.h" #include "VideoBackends/Software/SWVertexLoader.h"
@ -81,13 +79,7 @@ bool VideoSoftware::Initialize(void *window_handle)
{ {
g_SWVideoConfig.Load((File::GetUserPath(D_CONFIG_IDX) + GetConfigName() + ".ini").c_str()); g_SWVideoConfig.Load((File::GetUserPath(D_CONFIG_IDX) + GetConfigName() + ".ini").c_str());
InitInterface(); SWOGLWindow::Init(window_handle);
GLInterface->SetMode(GLInterfaceMode::MODE_DETECT);
if (!GLInterface->Create(window_handle, false))
{
INFO_LOG(VIDEO, "GLInterface::Create failed.");
return false;
}
InitBPMemory(); InitBPMemory();
InitXFMemory(); InitXFMemory();
@ -165,31 +157,16 @@ void VideoSoftware::Shutdown()
// Do our OSD callbacks // Do our OSD callbacks
OSD::DoCallbacks(OSD::OSD_SHUTDOWN); OSD::DoCallbacks(OSD::OSD_SHUTDOWN);
GLInterface->Shutdown(); SWOGLWindow::Shutdown();
delete GLInterface;
GLInterface = nullptr;
} }
void VideoSoftware::Video_Cleanup() void VideoSoftware::Video_Cleanup()
{ {
GLInterface->ClearCurrent();
} }
// This is called after Video_Initialize() from the Core // This is called after Video_Initialize() from the Core
void VideoSoftware::Video_Prepare() void VideoSoftware::Video_Prepare()
{ {
GLInterface->MakeCurrent();
// Init extension support.
if (!GLExtensions::Init())
{
ERROR_LOG(VIDEO, "GLExtensions::Init failed!Does your video card support OpenGL 2.0?");
return;
}
// Handle VSync on/off
GLInterface->SwapInterval(VSYNC_ENABLED);
// Do our OSD callbacks // Do our OSD callbacks
OSD::DoCallbacks(OSD::OSD_INIT); OSD::DoCallbacks(OSD::OSD_INIT);
@ -367,7 +344,7 @@ void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
// Draw messages on top of the screen // Draw messages on top of the screen
unsigned int VideoSoftware::PeekMessages() unsigned int VideoSoftware::PeekMessages()
{ {
return GLInterface->PeekMessages(); return SWOGLWindow::s_instance->PeekMessages();
} }
} }

View File

@ -42,11 +42,11 @@
<ClCompile Include="EfbCopy.cpp" /> <ClCompile Include="EfbCopy.cpp" />
<ClCompile Include="EfbInterface.cpp" /> <ClCompile Include="EfbInterface.cpp" />
<ClCompile Include="OpcodeDecoder.cpp" /> <ClCompile Include="OpcodeDecoder.cpp" />
<ClCompile Include="RasterFont.cpp" />
<ClCompile Include="Rasterizer.cpp" /> <ClCompile Include="Rasterizer.cpp" />
<ClCompile Include="SetupUnit.cpp" /> <ClCompile Include="SetupUnit.cpp" />
<ClCompile Include="SWCommandProcessor.cpp" /> <ClCompile Include="SWCommandProcessor.cpp" />
<ClCompile Include="SWmain.cpp" /> <ClCompile Include="SWmain.cpp" />
<ClCompile Include="SWOGLWindow.cpp" />
<ClCompile Include="SWRenderer.cpp" /> <ClCompile Include="SWRenderer.cpp" />
<ClCompile Include="SWStatistics.cpp" /> <ClCompile Include="SWStatistics.cpp" />
<ClCompile Include="SWVertexLoader.cpp" /> <ClCompile Include="SWVertexLoader.cpp" />
@ -66,10 +66,10 @@
<ClInclude Include="EfbInterface.h" /> <ClInclude Include="EfbInterface.h" />
<ClInclude Include="NativeVertexFormat.h" /> <ClInclude Include="NativeVertexFormat.h" />
<ClInclude Include="OpcodeDecoder.h" /> <ClInclude Include="OpcodeDecoder.h" />
<ClInclude Include="RasterFont.h" />
<ClInclude Include="Rasterizer.h" /> <ClInclude Include="Rasterizer.h" />
<ClInclude Include="SetupUnit.h" /> <ClInclude Include="SetupUnit.h" />
<ClInclude Include="SWCommandProcessor.h" /> <ClInclude Include="SWCommandProcessor.h" />
<ClInclude Include="SWOGLWindow.h" />
<ClInclude Include="SWRenderer.h" /> <ClInclude Include="SWRenderer.h" />
<ClInclude Include="SWStatistics.h" /> <ClInclude Include="SWStatistics.h" />
<ClInclude Include="SWVertexLoader.h" /> <ClInclude Include="SWVertexLoader.h" />