Merge branch 'immediate-removal'
Conflicts: Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
This commit is contained in:
commit
bff0faea2d
|
@ -35,3 +35,4 @@ Source/Core/Common/Src/scmrev.h
|
||||||
*.ipch
|
*.ipch
|
||||||
.sconsign.dblite
|
.sconsign.dblite
|
||||||
Externals/scons-local/*
|
Externals/scons-local/*
|
||||||
|
*~
|
||||||
|
|
|
@ -117,6 +117,8 @@ struct Rectangle
|
||||||
Rectangle(T theLeft, T theTop, T theRight, T theBottom)
|
Rectangle(T theLeft, T theTop, T theRight, T theBottom)
|
||||||
: left(theLeft), top(theTop), right(theRight), bottom(theBottom)
|
: left(theLeft), top(theTop), right(theRight), bottom(theBottom)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; }
|
||||||
|
|
||||||
T GetWidth() const { return abs(right - left); }
|
T GetWidth() const { return abs(right - left); }
|
||||||
T GetHeight() const { return abs(bottom - top); }
|
T GetHeight() const { return abs(bottom - top); }
|
||||||
|
|
|
@ -236,7 +236,7 @@ bool GetConfig(const int &type)
|
||||||
case CONFIG_DISABLEFOG:
|
case CONFIG_DISABLEFOG:
|
||||||
return g_ActiveConfig.bDisableFog;
|
return g_ActiveConfig.bDisableFog;
|
||||||
case CONFIG_SHOWEFBREGIONS:
|
case CONFIG_SHOWEFBREGIONS:
|
||||||
return false;
|
return g_ActiveConfig.bShowEFBCopyRegions;
|
||||||
default:
|
default:
|
||||||
PanicAlert("GetConfig Error: Unknown Config Type!");
|
PanicAlert("GetConfig Error: Unknown Config Type!");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
#include "TextureConverter.h"
|
#include "TextureConverter.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
@ -27,6 +28,11 @@ namespace OGL
|
||||||
|
|
||||||
extern bool s_bHaveFramebufferBlit; // comes from Render.cpp. ugly.
|
extern bool s_bHaveFramebufferBlit; // comes from Render.cpp. ugly.
|
||||||
|
|
||||||
|
static GLuint s_VBO = 0;
|
||||||
|
static GLuint s_VAO = 0;
|
||||||
|
static MathUtil::Rectangle<float> s_cached_sourcerc;
|
||||||
|
static MathUtil::Rectangle<float> s_cached_drawrc;
|
||||||
|
|
||||||
int FramebufferManager::m_targetWidth;
|
int FramebufferManager::m_targetWidth;
|
||||||
int FramebufferManager::m_targetHeight;
|
int FramebufferManager::m_targetHeight;
|
||||||
int FramebufferManager::m_msaaSamples;
|
int FramebufferManager::m_msaaSamples;
|
||||||
|
@ -53,6 +59,15 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
||||||
m_resolvedDepthTexture = 0;
|
m_resolvedDepthTexture = 0;
|
||||||
m_xfbFramebuffer = 0;
|
m_xfbFramebuffer = 0;
|
||||||
|
|
||||||
|
s_cached_sourcerc.bottom = -1;
|
||||||
|
s_cached_sourcerc.left = -1;
|
||||||
|
s_cached_sourcerc.right = -1;
|
||||||
|
s_cached_sourcerc.top = -1;
|
||||||
|
s_cached_drawrc.bottom = -1;
|
||||||
|
s_cached_drawrc.left = -1;
|
||||||
|
s_cached_drawrc.right = -1;
|
||||||
|
s_cached_drawrc.top = -1;
|
||||||
|
|
||||||
m_targetWidth = targetWidth;
|
m_targetWidth = targetWidth;
|
||||||
m_targetHeight = targetHeight;
|
m_targetHeight = targetHeight;
|
||||||
|
|
||||||
|
@ -169,7 +184,28 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
||||||
// Create XFB framebuffer; targets will be created elsewhere.
|
// Create XFB framebuffer; targets will be created elsewhere.
|
||||||
|
|
||||||
glGenFramebuffersEXT(1, &m_xfbFramebuffer);
|
glGenFramebuffersEXT(1, &m_xfbFramebuffer);
|
||||||
|
|
||||||
|
// Generate VBO & VAO - and initialize the VAO for "Draw"
|
||||||
|
glGenBuffers(1, &s_VBO);
|
||||||
|
glGenVertexArrays(1, &s_VAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_VBO);
|
||||||
|
glBindVertexArray(s_VAO);
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 6*sizeof(GLfloat), NULL);
|
||||||
|
|
||||||
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 6*sizeof(GLfloat), (GLfloat*)NULL+2);
|
||||||
|
|
||||||
|
glClientActiveTexture(GL_TEXTURE1);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 6*sizeof(GLfloat), (GLfloat*)NULL+4);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f
|
// EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f
|
||||||
glViewport(0, 0, m_targetWidth, m_targetHeight);
|
glViewport(0, 0, m_targetWidth, m_targetHeight);
|
||||||
glScissor(0, 0, m_targetWidth, m_targetHeight);
|
glScissor(0, 0, m_targetWidth, m_targetHeight);
|
||||||
|
@ -181,6 +217,8 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
||||||
FramebufferManager::~FramebufferManager()
|
FramebufferManager::~FramebufferManager()
|
||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
glDeleteBuffers(1, &s_VBO);
|
||||||
|
glDeleteVertexArrays(1, &s_VAO);
|
||||||
|
|
||||||
GLuint glObj[3];
|
GLuint glObj[3];
|
||||||
|
|
||||||
|
@ -305,24 +343,37 @@ void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc,
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
if(!(s_cached_sourcerc == sourcerc) || !(s_cached_drawrc == drawrc)) {
|
||||||
glTexCoord2f(sourcerc.left, sourcerc.bottom);
|
GLfloat vertices[] = {
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0);
|
drawrc.left, drawrc.bottom,
|
||||||
glVertex2f(drawrc.left, drawrc.bottom);
|
sourcerc.left, sourcerc.bottom,
|
||||||
|
0.0f, 0.0f,
|
||||||
glTexCoord2f(sourcerc.left, sourcerc.top);
|
drawrc.left, drawrc.top,
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1);
|
sourcerc.left, sourcerc.top,
|
||||||
glVertex2f(drawrc.left, drawrc.top);
|
0.0f, 1.0f,
|
||||||
|
drawrc.right, drawrc.top,
|
||||||
glTexCoord2f(sourcerc.right, sourcerc.top);
|
sourcerc.right, sourcerc.top,
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1);
|
1.0f, 1.0f,
|
||||||
glVertex2f(drawrc.right, drawrc.top);
|
drawrc.right, drawrc.bottom,
|
||||||
|
sourcerc.right, sourcerc.bottom,
|
||||||
glTexCoord2f(sourcerc.right, sourcerc.bottom);
|
1.0f, 0.0f
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0);
|
};
|
||||||
glVertex2f(drawrc.right, drawrc.bottom);
|
glBindBuffer(GL_ARRAY_BUFFER, s_VBO);
|
||||||
glEnd();
|
glBufferData(GL_ARRAY_BUFFER, 2*4*3*sizeof(GLfloat), vertices, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
s_cached_sourcerc = sourcerc;
|
||||||
|
s_cached_drawrc = drawrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(s_VAO);
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -628,6 +628,70 @@ void OpenGL_Shutdown()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint OpenGL_CompileProgram ( const char* vertexShader, const char* fragmentShader )
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
} else {
|
||||||
|
DEBUG_LOG(VIDEO, "GLSL vertex shader compiled:\n%s", vertexShader);
|
||||||
|
}
|
||||||
|
bool shader_errors = !Result;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
shader_errors |= !Result;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
glDeleteShader(vertexShaderID);
|
||||||
|
glDeleteShader(fragmentShaderID);
|
||||||
|
|
||||||
|
return programID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line)
|
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line)
|
||||||
{
|
{
|
||||||
GLint err = glGetError();
|
GLint err = glGetError();
|
||||||
|
|
|
@ -96,6 +96,9 @@ u32 OpenGL_GetBackbufferHeight();
|
||||||
// Set things
|
// Set things
|
||||||
void OpenGL_SetWindowText(const char *text);
|
void OpenGL_SetWindowText(const char *text);
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
GLuint OpenGL_CompileProgram(const char *vertexShader, const char *fragmentShader);
|
||||||
|
|
||||||
// Error reporting - use the convenient macros.
|
// Error reporting - use the convenient macros.
|
||||||
void OpenGL_ReportARBProgramError();
|
void OpenGL_ReportARBProgramError();
|
||||||
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line);
|
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line);
|
||||||
|
@ -126,4 +129,7 @@ extern CGprofile g_cgvProf, g_cgfProf;
|
||||||
// use GLSL shaders across the whole pipeline. Yikes!
|
// use GLSL shaders across the whole pipeline. Yikes!
|
||||||
//#define USE_DUAL_SOURCE_BLEND
|
//#define USE_DUAL_SOURCE_BLEND
|
||||||
|
|
||||||
|
// TODO: should be removed if we use glsl a lot
|
||||||
|
#define DEBUG_GLSL
|
||||||
|
|
||||||
#endif // _GLINIT_H_
|
#endif // _GLINIT_H_
|
||||||
|
|
|
@ -27,8 +27,9 @@
|
||||||
|
|
||||||
#define COMPILED_CODE_SIZE 4096
|
#define COMPILED_CODE_SIZE 4096
|
||||||
|
|
||||||
// TODO: this guy is never initialized
|
// TODO: Use this again for performance, but without VAO we never know exactly the last configuration
|
||||||
u32 s_prevcomponents; // previous state set
|
static u32 s_prevcomponents; // previous state set
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
|
@ -64,7 +65,6 @@ public:
|
||||||
|
|
||||||
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||||
virtual void SetupVertexPointers();
|
virtual void SetupVertexPointers();
|
||||||
virtual void EnableComponents(u32 components);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
|
@ -187,6 +187,7 @@ void GLVertexFormat::SetupVertexPointers() {
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
((void (*)())(void*)m_compiledCode)();
|
((void (*)())(void*)m_compiledCode)();
|
||||||
#else
|
#else
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer);
|
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer);
|
||||||
if (vtx_decl.num_normals >= 1) {
|
if (vtx_decl.num_normals >= 1) {
|
||||||
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0]));
|
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0]));
|
||||||
|
@ -219,34 +220,32 @@ void GLVertexFormat::SetupVertexPointers() {
|
||||||
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset));
|
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
void GLVertexFormat::EnableComponents(u32 components)
|
if (s_prevcomponents != m_components)
|
||||||
{
|
|
||||||
if (s_prevcomponents != components)
|
|
||||||
{
|
{
|
||||||
VertexManager::Flush();
|
// vertices
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
// matrices
|
// matrices
|
||||||
if ((components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX))
|
if ((m_components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX))
|
||||||
{
|
{
|
||||||
if (components & VB_HAS_POSMTXIDX)
|
if (m_components & VB_HAS_POSMTXIDX)
|
||||||
glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
||||||
else
|
else
|
||||||
glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// normals
|
// normals
|
||||||
if ((components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0))
|
if ((m_components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0))
|
||||||
{
|
{
|
||||||
if (components & VB_HAS_NRM0)
|
if (m_components & VB_HAS_NRM0)
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
else
|
else
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
}
|
}
|
||||||
if ((components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1))
|
if ((m_components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1))
|
||||||
{
|
{
|
||||||
if (components & VB_HAS_NRM1) {
|
if (m_components & VB_HAS_NRM1) {
|
||||||
glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
||||||
glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
||||||
}
|
}
|
||||||
|
@ -259,9 +258,9 @@ void GLVertexFormat::EnableComponents(u32 components)
|
||||||
// color
|
// color
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
if ((components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
|
if ((m_components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
|
||||||
{
|
{
|
||||||
if (components & (VB_HAS_COL0 << i))
|
if (m_components & (VB_HAS_COL0 << i))
|
||||||
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||||
else
|
else
|
||||||
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||||
|
@ -271,16 +270,16 @@ void GLVertexFormat::EnableComponents(u32 components)
|
||||||
// tex
|
// tex
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
if ((components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i)))
|
if ((m_components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i)))
|
||||||
{
|
{
|
||||||
glClientActiveTexture(GL_TEXTURE0 + i);
|
glClientActiveTexture(GL_TEXTURE0 + i);
|
||||||
if (components & (VB_HAS_UV0 << i))
|
if (m_components & (VB_HAS_UV0 << i))
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
else
|
else
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s_prevcomponents = components;
|
s_prevcomponents = m_components;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,16 @@
|
||||||
|
|
||||||
#include "GLUtil.h"
|
#include "GLUtil.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "RasterFont.h"
|
#include "RasterFont.h"
|
||||||
// globals
|
// globals
|
||||||
|
|
||||||
const GLubyte rasters[][13] = {
|
|
||||||
|
static const u32 char_width = 8;
|
||||||
|
static const u32 char_height = 13;
|
||||||
|
static const u32 char_offset = 32;
|
||||||
|
static const u32 char_count = 95;
|
||||||
|
|
||||||
|
const u8 rasters[char_count][char_height] = {
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},
|
||||||
|
@ -120,104 +124,163 @@ const GLubyte rasters[][13] = {
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *s_vertex_shader =
|
||||||
|
"attribute vec2 vertexPosition;\n"
|
||||||
|
"attribute vec2 texturePosition;\n"
|
||||||
|
"varying vec2 tpos;\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" gl_Position = vec4(vertexPosition,0,1);\n"
|
||||||
|
" tpos = texturePosition;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char *s_fragment_shader =
|
||||||
|
"#extension GL_ARB_texture_rectangle : enable\n"
|
||||||
|
"uniform sampler2DRect textureSampler;\n"
|
||||||
|
"uniform vec4 color;\n"
|
||||||
|
"varying vec2 tpos;\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" gl_FragColor = texture2DRect(textureSampler,tpos) * color;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
RasterFont::RasterFont()
|
RasterFont::RasterFont()
|
||||||
{
|
{
|
||||||
// set GL modes
|
// generate the texture
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glGenTextures(1, &texture);
|
||||||
// create the raster font
|
glBindTexture(GL_TEXTURE_RECTANGLE, texture);
|
||||||
fontOffset = glGenLists(128);
|
u32* texture_data = new u32[char_width*char_count*char_height];
|
||||||
for (int i = 32; i < 127; i++) {
|
for(u32 y=0; y<char_height; y++) {
|
||||||
glNewList(i + fontOffset, GL_COMPILE);
|
for(u32 c=0; c<char_count; c++) {
|
||||||
glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i - 32]);
|
for(u32 x=0; x<char_width; x++) {
|
||||||
glEndList();
|
bool pixel = rasters[c][y] & (1<<(char_width-x-1));
|
||||||
|
texture_data[char_width*char_count*y+char_width*c+x] = pixel ? -1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, char_width*char_count, char_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
|
||||||
temp_buffer = new char[TEMP_BUFFER_SIZE];
|
delete [] texture_data;
|
||||||
|
|
||||||
|
// generate shader
|
||||||
|
shader_program = OpenGL_CompileProgram(s_vertex_shader, s_fragment_shader);
|
||||||
|
|
||||||
|
// bound uniforms
|
||||||
|
glUseProgram(shader_program);
|
||||||
|
glUniform1i(glGetUniformLocation(shader_program,"textureSampler"), 0); // GL_TEXTURE0
|
||||||
|
uniform_color_id = glGetUniformLocation(shader_program,"color");
|
||||||
|
glUniform4f(uniform_color_id, 1, 1, 1, 1);
|
||||||
|
cached_color = -1;
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
|
// generate VBO & VAO
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "vertexPosition"));
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shader_program, "vertexPosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL);
|
||||||
|
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "texturePosition"));
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shader_program, "texturePosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterFont::~RasterFont()
|
RasterFont::~RasterFont()
|
||||||
{
|
{
|
||||||
glDeleteLists(fontOffset, 128);
|
glDeleteTextures(1, &texture);
|
||||||
delete [] temp_buffer;
|
glDeleteBuffers(1, &VBO);
|
||||||
|
glDeleteVertexArrays(1, &VAO);
|
||||||
|
glDeleteProgram(shader_program);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterFont::printString(const char *s, double x, double y, double z)
|
void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight, u32 color)
|
||||||
{
|
{
|
||||||
int length = (int)strlen(s);
|
int length = (int)strlen(text);
|
||||||
if (!length)
|
if (!length)
|
||||||
return;
|
return; // nothing to do
|
||||||
if (length >= TEMP_BUFFER_SIZE)
|
|
||||||
length = TEMP_BUFFER_SIZE - 1;
|
glBindVertexArray(VAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
// Sanitize string to avoid GL errors.
|
glBufferData(GL_ARRAY_BUFFER, length*4*6*sizeof(GLfloat), NULL, GL_STREAM_DRAW);
|
||||||
char *s2 = temp_buffer;
|
GLfloat *vertices = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||||
memcpy(s2, s, length);
|
|
||||||
s2[length] = 0;
|
int usage = 0;
|
||||||
for (int i = 0; i < length; i++) {
|
GLfloat delta_x = 2*char_width/GLfloat(bbWidth);
|
||||||
if (s2[i] < 32 || s2[i] > 126)
|
GLfloat delta_y = 2*char_height/GLfloat(bbHeight);
|
||||||
s2[i] = '!';
|
GLfloat border_x = 1*2/GLfloat(bbWidth);
|
||||||
}
|
GLfloat border_y = 2*2/GLfloat(bbHeight);
|
||||||
|
|
||||||
// go to the right spot
|
GLfloat x = start_x;
|
||||||
glRasterPos3d(x, y, z);
|
GLfloat y = start_y;
|
||||||
GL_REPORT_ERRORD();
|
|
||||||
|
for(int i=0; i<length; i++) {
|
||||||
glPushAttrib (GL_LIST_BIT);
|
u8 c = text[i];
|
||||||
glListBase(fontOffset);
|
|
||||||
glCallLists((GLsizei)strlen(s2), GL_UNSIGNED_BYTE, (GLubyte *) s2);
|
if(c == '\n') {
|
||||||
GL_REPORT_ERRORD();
|
|
||||||
glPopAttrib();
|
|
||||||
GL_REPORT_ERRORD();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
x = start_x;
|
||||||
t = temp;
|
y -= delta_y + border_y;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (*text == '\r')
|
|
||||||
{
|
// do not print spaces, they can be skipped easyly
|
||||||
t = temp;
|
if(c == ' ') {
|
||||||
|
x += delta_x + border_x;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (*text == '\t')
|
|
||||||
{
|
if(c < char_offset || c >= char_count+char_offset) continue;
|
||||||
//todo: add tabs every something like 4*char_width
|
|
||||||
*t = 0;
|
vertices[usage++] = x;
|
||||||
int cpos = (int)strlen(temp);
|
vertices[usage++] = y;
|
||||||
int newpos = (cpos + 4) & (~3);
|
vertices[usage++] = (c-char_offset)*char_width;
|
||||||
printString(temp, x, y, z);
|
vertices[usage++] = 0;
|
||||||
x = start_x + (char_width*newpos) * 2.0f / bbWidth;
|
|
||||||
t = temp;
|
vertices[usage++] = x+delta_x;
|
||||||
*t++ = ' ';
|
vertices[usage++] = y;
|
||||||
}
|
vertices[usage++] = (c-char_offset+1)*char_width;
|
||||||
else
|
vertices[usage++] = 0;
|
||||||
*t++ = *text;
|
|
||||||
|
vertices[usage++] = x+delta_x;
|
||||||
text++;
|
vertices[usage++] = y+delta_y;
|
||||||
|
vertices[usage++] = (c-char_offset+1)*char_width;
|
||||||
|
vertices[usage++] = char_height;
|
||||||
|
|
||||||
|
vertices[usage++] = x;
|
||||||
|
vertices[usage++] = y;
|
||||||
|
vertices[usage++] = (c-char_offset)*char_width;
|
||||||
|
vertices[usage++] = 0;
|
||||||
|
|
||||||
|
vertices[usage++] = x+delta_x;
|
||||||
|
vertices[usage++] = y+delta_y;
|
||||||
|
vertices[usage++] = (c-char_offset+1)*char_width;
|
||||||
|
vertices[usage++] = char_height;
|
||||||
|
|
||||||
|
vertices[usage++] = x;
|
||||||
|
vertices[usage++] = y+delta_y;
|
||||||
|
vertices[usage++] = (c-char_offset)*char_width;
|
||||||
|
vertices[usage++] = char_height;
|
||||||
|
|
||||||
|
x += delta_x + border_x;
|
||||||
}
|
}
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
// no printable char, so also nothing to do
|
||||||
|
if(!usage) return;
|
||||||
|
|
||||||
// ????
|
glUseProgram(shader_program);
|
||||||
if (t != text)
|
|
||||||
{
|
if(color != cached_color) {
|
||||||
*t = 0;
|
glUniform4f(uniform_color_id, ((color>>0)&0xff)/255.f,((color>>8)&0xff)/255.f,((color>>16)&0xff)/255.f,((color>>24)&0xff)/255.f);
|
||||||
printString(temp, x, y, z);
|
cached_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_RECTANGLE, texture);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, usage/4);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,20 +23,16 @@ public:
|
||||||
RasterFont();
|
RasterFont();
|
||||||
~RasterFont(void);
|
~RasterFont(void);
|
||||||
static int debug;
|
static int debug;
|
||||||
|
|
||||||
// some useful constants
|
|
||||||
enum {char_width = 10};
|
|
||||||
enum {char_height = 15};
|
|
||||||
|
|
||||||
// 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);
|
void printMultilineText(const char *text, double x, double y, double z, int bbWidth, int bbHeight, u32 color);
|
||||||
private:
|
private:
|
||||||
int fontOffset;
|
|
||||||
char *temp_buffer;
|
u32 VBO;
|
||||||
enum {TEMP_BUFFER_SIZE = 64 * 1024};
|
u32 VAO;
|
||||||
|
u32 texture;
|
||||||
|
u32 shader_program;
|
||||||
|
u32 uniform_color_id;
|
||||||
|
u32 cached_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _RASTERFONT_H_
|
#endif // _RASTERFONT_H_
|
||||||
|
|
|
@ -107,10 +107,14 @@ namespace OGL
|
||||||
|
|
||||||
// Declarations and definitions
|
// Declarations and definitions
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
int s_fps=0;
|
static int s_fps = 0;
|
||||||
|
static GLuint s_ShowEFBCopyRegions_VBO = 0;
|
||||||
|
static GLuint s_ShowEFBCopyRegions_VAO = 0;
|
||||||
|
static GLuint s_Swap_VBO = 0;
|
||||||
|
static GLuint s_Swap_VAO[2];
|
||||||
|
static TargetRectangle s_cached_targetRc;
|
||||||
|
|
||||||
|
static RasterFont* s_pfont = NULL;
|
||||||
RasterFont* s_pfont = NULL;
|
|
||||||
|
|
||||||
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
|
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
|
||||||
static int s_MSAASamples = 1;
|
static int s_MSAASamples = 1;
|
||||||
|
@ -126,9 +130,9 @@ static std::thread scrshotThread;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// EFB cache related
|
// EFB cache related
|
||||||
const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks.
|
static const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks.
|
||||||
const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up
|
static const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up
|
||||||
const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE;
|
static const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE;
|
||||||
static bool s_efbCacheValid[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT];
|
static bool s_efbCacheValid[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT];
|
||||||
static std::vector<u32> s_efbCache[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; // 2 for PEEK_Z and PEEK_COLOR
|
static std::vector<u32> s_efbCache[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; // 2 for PEEK_Z and PEEK_COLOR
|
||||||
|
|
||||||
|
@ -251,7 +255,16 @@ Renderer::Renderer()
|
||||||
OSDInternalH = 0;
|
OSDInternalH = 0;
|
||||||
|
|
||||||
s_fps=0;
|
s_fps=0;
|
||||||
|
s_ShowEFBCopyRegions_VBO = 0;
|
||||||
|
s_Swap_VBO = 0;
|
||||||
s_blendMode = 0;
|
s_blendMode = 0;
|
||||||
|
|
||||||
|
// should be invalid, so there will be an upload on the first call
|
||||||
|
s_cached_targetRc.bottom = -1;
|
||||||
|
s_cached_targetRc.top = -1;
|
||||||
|
s_cached_targetRc.left = -1;
|
||||||
|
s_cached_targetRc.right = -1;
|
||||||
|
|
||||||
|
|
||||||
InitFPSCounter();
|
InitFPSCounter();
|
||||||
|
|
||||||
|
@ -312,6 +325,13 @@ Renderer::Renderer()
|
||||||
bSuccess = false;
|
bSuccess = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GLEW_ARB_vertex_array_object)
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n"
|
||||||
|
"GPU: Does your video card support OpenGL 3.0?");
|
||||||
|
bSuccess = false;
|
||||||
|
}
|
||||||
|
|
||||||
s_bHaveFramebufferBlit = strstr(ptoken, "GL_EXT_framebuffer_blit") != NULL;
|
s_bHaveFramebufferBlit = strstr(ptoken, "GL_EXT_framebuffer_blit") != NULL;
|
||||||
s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL;
|
s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL;
|
||||||
|
|
||||||
|
@ -451,17 +471,46 @@ Renderer::Renderer()
|
||||||
cgGLSetDebugMode(GL_FALSE);
|
cgGLSetDebugMode(GL_FALSE);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// creating buffers
|
||||||
|
glGenBuffers(1, &s_ShowEFBCopyRegions_VBO);
|
||||||
|
glGenVertexArrays(1, &s_ShowEFBCopyRegions_VAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO);
|
||||||
|
glBindVertexArray( s_ShowEFBCopyRegions_VAO );
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glColorPointer (3, GL_FLOAT, sizeof(GLfloat)*5, (GLfloat*)NULL+2);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*5, NULL);
|
||||||
|
|
||||||
|
glGenBuffers(1, &s_Swap_VBO);
|
||||||
|
glGenVertexArrays(2, s_Swap_VAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_Swap_VBO);
|
||||||
|
glBindVertexArray(s_Swap_VAO[0]);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, 7*sizeof(GLfloat), NULL);
|
||||||
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+3);
|
||||||
|
|
||||||
|
glBindVertexArray(s_Swap_VAO[1]);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, 7*sizeof(GLfloat), NULL);
|
||||||
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+3);
|
||||||
|
glClientActiveTexture(GL_TEXTURE1);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+5);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glStencilFunc(GL_ALWAYS, 0, 0);
|
glStencilFunc(GL_ALWAYS, 0, 0);
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
|
||||||
glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); // Reset The Current Viewport
|
glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); // Reset The Current Viewport
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glClearDepth(1.0f);
|
glClearDepth(1.0f);
|
||||||
|
@ -478,11 +527,6 @@ Renderer::Renderer()
|
||||||
glBlendColorEXT(0, 0, 0, 0.5f);
|
glBlendColorEXT(0, 0, 0, 0.5f);
|
||||||
glClearDepth(1.0f);
|
glClearDepth(1.0f);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
// legacy multitexturing: select texture channel only.
|
// legacy multitexturing: select texture channel only.
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glClientActiveTexture(GL_TEXTURE0);
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -498,6 +542,13 @@ Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
g_Config.bRunning = false;
|
g_Config.bRunning = false;
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
|
||||||
|
glDeleteBuffers(1, &s_ShowEFBCopyRegions_VBO);
|
||||||
|
glDeleteVertexArrays(1, &s_ShowEFBCopyRegions_VAO);
|
||||||
|
glDeleteBuffers(1, &s_Swap_VBO);
|
||||||
|
glDeleteVertexArrays(2, s_Swap_VAO);
|
||||||
|
s_ShowEFBCopyRegions_VBO = 0;
|
||||||
|
|
||||||
delete s_pfont;
|
delete s_pfont;
|
||||||
s_pfont = 0;
|
s_pfont = 0;
|
||||||
|
|
||||||
|
@ -545,9 +596,15 @@ void Renderer::DrawDebugInfo()
|
||||||
// Set Line Size
|
// Set Line Size
|
||||||
glLineWidth(3.0f);
|
glLineWidth(3.0f);
|
||||||
|
|
||||||
glBegin(GL_LINES);
|
// 2*Coords + 3*Color
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, stats.efb_regions.size() * sizeof(GLfloat) * (2+3)*2*6, NULL, GL_STREAM_DRAW);
|
||||||
|
GLfloat *Vertices = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||||
|
|
||||||
// Draw EFB copy regions rectangles
|
// Draw EFB copy regions rectangles
|
||||||
|
int a = 0;
|
||||||
|
GLfloat color[3] = {0.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
for (std::vector<EFBRectangle>::const_iterator it = stats.efb_regions.begin();
|
for (std::vector<EFBRectangle>::const_iterator it = stats.efb_regions.begin();
|
||||||
it != stats.efb_regions.end(); ++it)
|
it != stats.efb_regions.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -558,22 +615,97 @@ void Renderer::DrawDebugInfo()
|
||||||
GLfloat x2 = (GLfloat) -1.0f + ((GLfloat)it->right / halfWidth);
|
GLfloat x2 = (GLfloat) -1.0f + ((GLfloat)it->right / halfWidth);
|
||||||
GLfloat y2 = (GLfloat) 1.0f - ((GLfloat)it->bottom / halfHeight);
|
GLfloat y2 = (GLfloat) 1.0f - ((GLfloat)it->bottom / halfHeight);
|
||||||
|
|
||||||
// Draw shadow of rect
|
Vertices[a++] = x;
|
||||||
glColor3f(0.0f, 0.0f, 0.0f);
|
Vertices[a++] = y;
|
||||||
glVertex2f(x, y - 0.01); glVertex2f(x2, y - 0.01);
|
Vertices[a++] = color[0];
|
||||||
glVertex2f(x, y2 - 0.01); glVertex2f(x2, y2 - 0.01);
|
Vertices[a++] = color[1];
|
||||||
glVertex2f(x + 0.005, y); glVertex2f(x + 0.005, y2);
|
Vertices[a++] = color[2];
|
||||||
glVertex2f(x2 + 0.005, y); glVertex2f(x2 + 0.005, y2);
|
|
||||||
|
Vertices[a++] = x2;
|
||||||
// Draw rect
|
Vertices[a++] = y;
|
||||||
glColor3f(0.0f, 1.0f, 1.0f);
|
Vertices[a++] = color[0];
|
||||||
glVertex2f(x, y); glVertex2f(x2, y);
|
Vertices[a++] = color[1];
|
||||||
glVertex2f(x, y2); glVertex2f(x2, y2);
|
Vertices[a++] = color[2];
|
||||||
glVertex2f(x, y); glVertex2f(x, y2);
|
|
||||||
glVertex2f(x2, y); glVertex2f(x2, y2);
|
|
||||||
|
Vertices[a++] = x2;
|
||||||
|
Vertices[a++] = y;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
Vertices[a++] = x2;
|
||||||
|
Vertices[a++] = y2;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
|
||||||
|
Vertices[a++] = x2;
|
||||||
|
Vertices[a++] = y2;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
Vertices[a++] = x;
|
||||||
|
Vertices[a++] = y2;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
|
||||||
|
Vertices[a++] = x;
|
||||||
|
Vertices[a++] = y2;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
Vertices[a++] = x;
|
||||||
|
Vertices[a++] = y;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
|
||||||
|
Vertices[a++] = x;
|
||||||
|
Vertices[a++] = y;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
Vertices[a++] = x2;
|
||||||
|
Vertices[a++] = y2;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
|
||||||
|
Vertices[a++] = x2;
|
||||||
|
Vertices[a++] = y;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
Vertices[a++] = x;
|
||||||
|
Vertices[a++] = y2;
|
||||||
|
Vertices[a++] = color[0];
|
||||||
|
Vertices[a++] = color[1];
|
||||||
|
Vertices[a++] = color[2];
|
||||||
|
|
||||||
|
// TO DO: build something nicer here
|
||||||
|
GLfloat temp = color[0];
|
||||||
|
color[0] = color[1];
|
||||||
|
color[1] = color[2];
|
||||||
|
color[2] = temp;
|
||||||
}
|
}
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
glEnd();
|
|
||||||
|
glBindVertexArray( s_ShowEFBCopyRegions_VAO );
|
||||||
|
glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// Restore Line Size
|
// Restore Line Size
|
||||||
glLineWidth(lSize);
|
glLineWidth(lSize);
|
||||||
|
@ -601,16 +733,13 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
||||||
const int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
|
const int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
|
||||||
const int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
|
const 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);
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
s_pfont->printMultilineText(text,
|
s_pfont->printMultilineText(text,
|
||||||
left * 2.0f / (float)nBackbufferWidth - 1,
|
left * 2.0f / (float)nBackbufferWidth - 1,
|
||||||
1 - top * 2.0f / (float)nBackbufferHeight,
|
1 - top * 2.0f / (float)nBackbufferHeight,
|
||||||
0, nBackbufferWidth, nBackbufferHeight);
|
0, nBackbufferWidth, nBackbufferHeight, color);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -1135,43 +1264,44 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
// Render to the real buffer now.
|
// Render to the real buffer now.
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
|
||||||
if (applyShader)
|
|
||||||
{
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glTexCoord2f(targetRc.left, targetRc.bottom);
|
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0);
|
|
||||||
glVertex2f(-1, -1);
|
|
||||||
|
|
||||||
glTexCoord2f(targetRc.left, targetRc.top);
|
if(!( s_cached_targetRc == targetRc)) {
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1);
|
GLfloat vertices[] = {
|
||||||
glVertex2f(-1, 1);
|
-1.0f, -1.0f, 1.0f,
|
||||||
|
(GLfloat)targetRc.left, (GLfloat)targetRc.bottom,
|
||||||
|
0.0f, 0.0f,
|
||||||
|
|
||||||
|
-1.0f, 1.0f, 1.0f,
|
||||||
|
(GLfloat)targetRc.left, (GLfloat)targetRc.top,
|
||||||
|
0.0f, 1.0f,
|
||||||
|
|
||||||
|
1.0f, 1.0f, 1.0f,
|
||||||
|
(GLfloat)targetRc.right, (GLfloat)targetRc.top,
|
||||||
|
1.0f, 1.0f,
|
||||||
|
|
||||||
|
1.0f, -1.0f, 1.0f,
|
||||||
|
(GLfloat)targetRc.right, (GLfloat)targetRc.bottom,
|
||||||
|
1.0f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_Swap_VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 4*7*sizeof(GLfloat), vertices, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
s_cached_targetRc = targetRc;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(s_Swap_VAO[applyShader]);
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
|
||||||
glTexCoord2f(targetRc.right, targetRc.top);
|
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1);
|
// TODO: this after merging with graphic_update
|
||||||
glVertex2f( 1, 1);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glTexCoord2f(targetRc.right, targetRc.bottom);
|
if(applyShader)
|
||||||
glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0);
|
|
||||||
glVertex2f( 1, -1);
|
|
||||||
glEnd();
|
|
||||||
PixelShaderCache::DisableShader();
|
PixelShaderCache::DisableShader();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glTexCoord2f(targetRc.left, targetRc.bottom);
|
|
||||||
glVertex2f(-1, -1);
|
|
||||||
|
|
||||||
glTexCoord2f(targetRc.left, targetRc.top);
|
|
||||||
glVertex2f(-1, 1);
|
|
||||||
|
|
||||||
glTexCoord2f(targetRc.right, targetRc.top);
|
|
||||||
glVertex2f( 1, 1);
|
|
||||||
|
|
||||||
glTexCoord2f(targetRc.right, targetRc.bottom);
|
|
||||||
glVertex2f( 1, -1);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
|
|
|
@ -56,6 +56,13 @@
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct VBOCache {
|
||||||
|
GLuint vbo;
|
||||||
|
GLuint vao;
|
||||||
|
TargetRectangle targetSource;
|
||||||
|
};
|
||||||
|
static std::map<u64,VBOCache> s_VBO;
|
||||||
|
|
||||||
static u32 s_TempFramebuffer = 0;
|
static u32 s_TempFramebuffer = 0;
|
||||||
|
|
||||||
static const GLint c_MinLinearFilter[8] = {
|
static const GLint c_MinLinearFilter[8] = {
|
||||||
|
@ -106,6 +113,8 @@ TextureCache::TCacheEntry::~TCacheEntry()
|
||||||
TextureCache::TCacheEntry::TCacheEntry()
|
TextureCache::TCacheEntry::TCacheEntry()
|
||||||
{
|
{
|
||||||
glGenTextures(1, &texture);
|
glGenTextures(1, &texture);
|
||||||
|
currmode.hex = 0;
|
||||||
|
currmode1.hex = 0;
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +127,9 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||||
// TODO: is this already done somewhere else?
|
// TODO: is this already done somewhere else?
|
||||||
TexMode0 &tm0 = bpmem.tex[stage >> 2].texMode0[stage & 3];
|
TexMode0 &tm0 = bpmem.tex[stage >> 2].texMode0[stage & 3];
|
||||||
TexMode1 &tm1 = bpmem.tex[stage >> 2].texMode1[stage & 3];
|
TexMode1 &tm1 = bpmem.tex[stage >> 2].texMode1[stage & 3];
|
||||||
SetTextureParameters(tm0, tm1);
|
|
||||||
|
if(currmode.hex != tm0.hex || currmode1.hex != tm1.hex)
|
||||||
|
SetTextureParameters(tm0, tm1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level)
|
bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level)
|
||||||
|
@ -304,13 +315,59 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
// should be unique enough, if not, vbo will "only" be uploaded to much
|
||||||
|
u64 targetSourceHash = u64(targetSource.left)<<48 | u64(targetSource.top)<<32 | u64(targetSource.right)<<16 | u64(targetSource.bottom);
|
||||||
|
std::map<u64, VBOCache>::iterator vbo_it = s_VBO.find(targetSourceHash);
|
||||||
|
|
||||||
|
if(vbo_it == s_VBO.end()) {
|
||||||
|
VBOCache item;
|
||||||
|
item.targetSource.bottom = -1;
|
||||||
|
item.targetSource.top = -1;
|
||||||
|
item.targetSource.left = -1;
|
||||||
|
item.targetSource.right = -1;
|
||||||
|
glGenBuffers(1, &item.vbo);
|
||||||
|
glGenVertexArrays(1, &item.vao);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, item.vbo);
|
||||||
|
glBindVertexArray(item.vao);
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*4, 0);
|
||||||
|
|
||||||
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*4, (GLfloat*)NULL + 2);
|
||||||
|
|
||||||
|
vbo_it = s_VBO.insert(std::pair<u64,VBOCache>(targetSourceHash, item)).first;
|
||||||
|
}
|
||||||
|
if(!(vbo_it->second.targetSource == targetSource)) {
|
||||||
|
GLfloat vertices[] = {
|
||||||
|
-1.f, 1.f,
|
||||||
|
(GLfloat)targetSource.left, (GLfloat)targetSource.bottom,
|
||||||
|
-1.f, -1.f,
|
||||||
|
(GLfloat)targetSource.left, (GLfloat)targetSource.top,
|
||||||
|
1.f, -1.f,
|
||||||
|
(GLfloat)targetSource.right, (GLfloat)targetSource.top,
|
||||||
|
1.f, 1.f,
|
||||||
|
(GLfloat)targetSource.right, (GLfloat)targetSource.bottom
|
||||||
|
};
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_it->second.vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
vbo_it->second.targetSource = targetSource;
|
||||||
|
}
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBindVertexArray(vbo_it->second.vao);
|
||||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1);
|
|
||||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1);
|
// TODO: this after merging with graphic_update
|
||||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1);
|
glBindVertexArray(0);
|
||||||
glEnd();
|
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -357,6 +414,9 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1)
|
void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1)
|
||||||
{
|
{
|
||||||
|
currmode = newmode;
|
||||||
|
currmode1 = newmode1;
|
||||||
|
|
||||||
// TODO: not used anywhere
|
// TODO: not used anywhere
|
||||||
TexMode0 mode = newmode;
|
TexMode0 mode = newmode;
|
||||||
//mode1 = newmode1;
|
//mode1 = newmode1;
|
||||||
|
@ -388,13 +448,24 @@ void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, co
|
||||||
(float)(1 << g_ActiveConfig.iMaxAnisotropy));
|
(float)(1 << g_ActiveConfig.iMaxAnisotropy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextureCache::TextureCache()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TextureCache::~TextureCache()
|
TextureCache::~TextureCache()
|
||||||
{
|
{
|
||||||
if (s_TempFramebuffer)
|
for(std::map<u64, VBOCache>::iterator it = s_VBO.begin(); it != s_VBO.end(); it++) {
|
||||||
|
glDeleteBuffers(1, &it->second.vbo);
|
||||||
|
glDeleteVertexArrays(1, &it->second.vao);
|
||||||
|
}
|
||||||
|
s_VBO.clear();
|
||||||
|
|
||||||
|
if (s_TempFramebuffer)
|
||||||
{
|
{
|
||||||
glDeleteFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer);
|
glDeleteFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer);
|
||||||
s_TempFramebuffer = 0;
|
s_TempFramebuffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::DisableStage(unsigned int stage)
|
void TextureCache::DisableStage(unsigned int stage)
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace OGL
|
||||||
class TextureCache : public ::TextureCache
|
class TextureCache : public ::TextureCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
TextureCache();
|
||||||
static void DisableStage(unsigned int stage);
|
static void DisableStage(unsigned int stage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -66,6 +67,8 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1);
|
void SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1);
|
||||||
|
TexMode0 currmode;
|
||||||
|
TexMode1 currmode1;
|
||||||
};
|
};
|
||||||
|
|
||||||
~TextureCache();
|
~TextureCache();
|
||||||
|
|
|
@ -57,6 +57,14 @@ static FRAGMENTSHADER s_yuyvToRgbProgram;
|
||||||
const u32 NUM_ENCODING_PROGRAMS = 64;
|
const u32 NUM_ENCODING_PROGRAMS = 64;
|
||||||
static FRAGMENTSHADER s_encodingPrograms[NUM_ENCODING_PROGRAMS];
|
static FRAGMENTSHADER s_encodingPrograms[NUM_ENCODING_PROGRAMS];
|
||||||
|
|
||||||
|
static GLuint s_encode_VBO = 0;
|
||||||
|
static GLuint s_encode_VAO = 0;
|
||||||
|
static GLuint s_decode_VBO = 0;
|
||||||
|
static GLuint s_decode_VAO = 0;
|
||||||
|
static TargetRectangle s_cached_sourceRc;
|
||||||
|
static int s_cached_srcWidth = 0;
|
||||||
|
static int s_cached_srcHeight = 0;
|
||||||
|
|
||||||
void CreateRgbToYuyvProgram()
|
void CreateRgbToYuyvProgram()
|
||||||
{
|
{
|
||||||
// Output is BGRA because that is slightly faster than RGBA.
|
// Output is BGRA because that is slightly faster than RGBA.
|
||||||
|
@ -140,9 +148,40 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
glGenFramebuffersEXT(1, &s_texConvFrameBuffer);
|
glGenFramebuffersEXT(1, &s_texConvFrameBuffer);
|
||||||
|
|
||||||
|
glGenBuffers(1, &s_encode_VBO );
|
||||||
|
glGenVertexArrays(1, &s_encode_VAO );
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_encode_VBO );
|
||||||
|
glBindVertexArray( s_encode_VAO );
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), NULL);
|
||||||
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 4*sizeof(GLfloat), (GLfloat*)NULL + 2);
|
||||||
|
s_cached_sourceRc.top = -1;
|
||||||
|
s_cached_sourceRc.bottom = -1;
|
||||||
|
s_cached_sourceRc.left = -1;
|
||||||
|
s_cached_sourceRc.right = -1;
|
||||||
|
|
||||||
|
glGenBuffers(1, &s_decode_VBO );
|
||||||
|
glGenVertexArrays(1, &s_decode_VAO );
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_decode_VBO );
|
||||||
|
glBindVertexArray( s_decode_VAO );
|
||||||
|
s_cached_srcWidth = -1;
|
||||||
|
s_cached_srcHeight = -1;
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*4, NULL);
|
||||||
|
glClientActiveTexture(GL_TEXTURE0);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glGenRenderbuffersEXT(1, &s_dstRenderBuffer);
|
glGenRenderbuffersEXT(1, &s_dstRenderBuffer);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
||||||
|
|
||||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, renderBufferWidth, renderBufferHeight);
|
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, renderBufferWidth, renderBufferHeight);
|
||||||
|
|
||||||
s_srcTextureWidth = 0;
|
s_srcTextureWidth = 0;
|
||||||
|
@ -162,6 +201,10 @@ void Shutdown()
|
||||||
glDeleteTextures(1, &s_srcTexture);
|
glDeleteTextures(1, &s_srcTexture);
|
||||||
glDeleteRenderbuffersEXT(1, &s_dstRenderBuffer);
|
glDeleteRenderbuffersEXT(1, &s_dstRenderBuffer);
|
||||||
glDeleteFramebuffersEXT(1, &s_texConvFrameBuffer);
|
glDeleteFramebuffersEXT(1, &s_texConvFrameBuffer);
|
||||||
|
glDeleteBuffers(1, &s_encode_VBO );
|
||||||
|
glDeleteVertexArrays(1, &s_encode_VAO );
|
||||||
|
glDeleteBuffers(1, &s_decode_VBO );
|
||||||
|
glDeleteVertexArrays(1, &s_decode_VAO );
|
||||||
|
|
||||||
s_rgbToYuyvProgram.Destroy();
|
s_rgbToYuyvProgram.Destroy();
|
||||||
s_yuyvToRgbProgram.Destroy();
|
s_yuyvToRgbProgram.Destroy();
|
||||||
|
@ -213,13 +256,33 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
|
||||||
|
|
||||||
PixelShaderCache::SetCurrentShader(shader.glprogid);
|
PixelShaderCache::SetCurrentShader(shader.glprogid);
|
||||||
|
|
||||||
// Draw...
|
GL_REPORT_ERRORD();
|
||||||
glBegin(GL_QUADS);
|
if(!(s_cached_sourceRc == sourceRc)) {
|
||||||
glTexCoord2f((float)sourceRc.left, (float)sourceRc.top); glVertex2f(-1,-1);
|
GLfloat vertices[] = {
|
||||||
glTexCoord2f((float)sourceRc.left, (float)sourceRc.bottom); glVertex2f(-1,1);
|
-1.f, -1.f,
|
||||||
glTexCoord2f((float)sourceRc.right, (float)sourceRc.bottom); glVertex2f(1,1);
|
(float)sourceRc.left, (float)sourceRc.top,
|
||||||
glTexCoord2f((float)sourceRc.right, (float)sourceRc.top); glVertex2f(1,-1);
|
-1.f, 1.f,
|
||||||
glEnd();
|
(float)sourceRc.left, (float)sourceRc.bottom,
|
||||||
|
1.f, 1.f,
|
||||||
|
(float)sourceRc.right, (float)sourceRc.bottom,
|
||||||
|
1.f, -1.f,
|
||||||
|
(float)sourceRc.right, (float)sourceRc.top
|
||||||
|
};
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_encode_VBO );
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
s_cached_sourceRc = sourceRc;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray( s_encode_VAO );
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// .. and then read back the results.
|
// .. and then read back the results.
|
||||||
|
@ -375,18 +438,41 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||||
PixelShaderCache::SetCurrentShader(s_yuyvToRgbProgram.glprogid);
|
PixelShaderCache::SetCurrentShader(s_yuyvToRgbProgram.glprogid);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
if(s_cached_srcHeight != srcHeight || s_cached_srcWidth != srcWidth) {
|
||||||
glTexCoord2f((float)srcFmtWidth, (float)srcHeight); glVertex2f(1,-1);
|
GLfloat vertices[] = {
|
||||||
glTexCoord2f((float)srcFmtWidth, 0); glVertex2f(1,1);
|
1.f, -1.f,
|
||||||
glTexCoord2f(0, 0); glVertex2f(-1,1);
|
(float)srcFmtWidth, (float)srcHeight,
|
||||||
glTexCoord2f(0, (float)srcHeight); glVertex2f(-1,-1);
|
1.f, 1.f,
|
||||||
glEnd();
|
(float)srcFmtWidth, 0.f,
|
||||||
|
-1.f, 1.f,
|
||||||
|
0.f, 0.f,
|
||||||
|
-1.f, -1.f,
|
||||||
|
0.f, (float)srcHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_decode_VBO );
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*4*4, vertices, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
s_cached_srcHeight = srcHeight;
|
||||||
|
s_cached_srcWidth = srcWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray( s_decode_VAO );
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
|
||||||
|
// TODO: this after merging with graphic_update
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// reset state
|
// reset state
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||||
TextureCache::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
|
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,6 @@ VertexManager::VertexManager()
|
||||||
// max_Index_size = MAXIBUFFERSIZE;
|
// max_Index_size = MAXIBUFFERSIZE;
|
||||||
//
|
//
|
||||||
//GL_REPORT_ERRORD();
|
//GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
GL_REPORT_ERRORD();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::CreateDeviceObjects()
|
void VertexManager::CreateDeviceObjects()
|
||||||
|
|
|
@ -101,12 +101,11 @@ void SWRenderer::RenderText(const char* pstr, int left, int top, u32 color)
|
||||||
{
|
{
|
||||||
int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
|
int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
|
||||||
int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
|
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,
|
s_pfont->printMultilineText(pstr,
|
||||||
left * 2.0f / (float)nBackbufferWidth - 1,
|
left * 2.0f / (float)nBackbufferWidth - 1,
|
||||||
1 - top * 2.0f / (float)nBackbufferHeight,
|
1 - top * 2.0f / (float)nBackbufferHeight,
|
||||||
0, nBackbufferWidth, nBackbufferHeight);
|
0, nBackbufferWidth, nBackbufferHeight, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SWRenderer::DrawDebugText()
|
void SWRenderer::DrawDebugText()
|
||||||
|
|
Loading…
Reference in New Issue