Initial push of GLES and GLUtil file breakup.

This commit is contained in:
Ryan Houdek
2012-12-17 14:54:20 -06:00
parent 0811311604
commit b78f5debe6
17 changed files with 582 additions and 810 deletions
+6
View File
@@ -218,6 +218,12 @@ if(FASTLOG)
add_definitions(-DDEBUGFAST)
endif()
option(USE_GLES "Enables GLES, disables OGL" OFF)
if(USE_GLES)
message("GLES rendering enabled")
add_definitions(-DUSE_GLES)
add_definitions(-DUSE_EGL)
endif()
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE)
########################################
@@ -22,7 +22,9 @@
#include "../../../Plugins/Plugin_VideoDX9/Src/VideoBackend.h"
#include "../../../Plugins/Plugin_VideoDX11/Src/VideoBackend.h"
#endif
#ifndef USE_GLES
#include "../../../Plugins/Plugin_VideoOGL/Src/VideoBackend.h"
#endif
#include "../../../Plugins/Plugin_VideoSoftware/Src/VideoBackend.h"
std::vector<VideoBackend*> g_available_video_backends;
@@ -52,7 +54,9 @@ void VideoBackend::PopulateList()
if (IsGteVista())
g_available_video_backends.push_back(new DX11::VideoBackend);
#endif
#ifndef USE_GLES
g_available_video_backends.push_back(new OGL::VideoBackend);
#endif
g_available_video_backends.push_back(new SW::VideoSoftware);
g_video_backend = g_available_video_backends.front();
+5 -1
View File
@@ -191,7 +191,11 @@ set(SRCS Src/ActionReplay.cpp
Src/PowerPC/JitCommon/JitCache.cpp
Src/PowerPC/JitCommon/Jit_Util.cpp)
set(LIBS bdisasm inputcommon videoogl videosoftware sfml-network)
set(LIBS bdisasm inputcommon videosoftware sfml-network)
if(NOT USE_GLES)
set(LIBS ${LIBS} videoogl)
endif()
if(WIN32)
set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Win32.cpp Src/stdafx.cpp
+24 -3
View File
@@ -8,7 +8,6 @@ set(LIBS core
z
sfml-network
${GTK2_LIBRARIES}
${OPENGL_LIBRARIES}
${XRANDR_LIBRARIES}
${X11_LIBRARIES})
@@ -31,7 +30,8 @@ if(LIBAV_FOUND)
endif()
if(wxWidgets_FOUND)
set(SRCS Src/ARCodeAddEdit.cpp
set(SRCS
Src/ARCodeAddEdit.cpp
Src/AboutDolphin.cpp
Src/CheatsWindow.cpp
Src/ConfigMain.cpp
@@ -79,7 +79,28 @@ if(wxWidgets_FOUND)
set(WXLIBS ${wxWidgets_LIBRARIES})
else()
set(SRCS Src/MainNoGUI.cpp)
set(SRCS
Src/MainNoGUI.cpp)
endif()
if(USE_EGL)
set(SRCS ${SRCS}
Src/VideoInterface/EGL.cpp
)
else()
if(WIN32)
set(SRCS ${SRCS}
Src/VideoInterface/GLW.cpp
)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(SRCS ${SRCS}
Src/VideoInterface/AGL.cpp
)
else()
set(SRCS ${SRCS}
Src/VideoInterface/GLX.cpp
)
endif()
endif()
if(WIN32)
+3 -1
View File
@@ -1,3 +1,5 @@
add_subdirectory(Plugin_VideoOGL)
if(NOT USE_GLES)
add_subdirectory(Plugin_VideoOGL)
endif()
add_subdirectory(Plugin_VideoSoftware)
# TODO: Add other backends here!
+13 -2
View File
@@ -12,11 +12,22 @@ set(SRCS Src/FramebufferManager.cpp
Src/VertexManager.cpp)
set(LIBS videocommon
GLEW
SOIL
common
${OPENGL_LIBRARIES}
${X11_LIBRARIES})
if(USE_EGL)
set(LIBS ${LIBS}
EGL)
endif()
if(USE_GLES)
set(LIBS ${LIBS}
GLESv2)
else()
set(LIBS ${LIBS}
GLEW
${OPENGL_LIBRARIES})
endif()
if(wxWidgets_FOUND)
set(LIBS ${LIBS} ${wxWidgets_LIBRARIES})
File diff suppressed because it is too large Load Diff
+7 -61
View File
@@ -20,26 +20,7 @@
#include "VideoConfig.h"
#include "MathUtil.h"
#include "Thread.h"
#ifdef _WIN32
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/wglew.h>
#elif defined HAVE_X11 && HAVE_X11
#include <GL/glxew.h>
#include <GL/gl.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#elif defined __APPLE__
#include <GL/glew.h>
#import <AppKit/AppKit.h>
#endif
#if defined USE_WX && USE_WX
#include "wx/wx.h"
#include "wx/glcanvas.h"
#endif
#include "GLVideoInterface.h"
#ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils
#define GL_DEPTH_STENCIL_EXT 0x84F9
@@ -52,49 +33,11 @@
#include <sys/types.h>
typedef struct {
#if defined(USE_WX) && USE_WX
wxGLCanvas *glCanvas;
wxGLContext *glCtxt;
wxPanel *panel;
#elif defined(__APPLE__)
NSWindow *cocoaWin;
NSOpenGLContext *cocoaCtx;
#elif defined(HAVE_X11) && HAVE_X11
int screen;
Window win;
Window parent;
// dpy used for glx stuff, evdpy for window events etc.
// evdpy is to be used by XEventThread only
Display *dpy, *evdpy;
XVisualInfo *vi;
GLXContext ctx;
XSetWindowAttributes attr;
std::thread xEventThread;
int x, y;
unsigned int width, height;
#endif
} GLWindow;
void InitInterface();
extern GLWindow GLWin;
#endif
// Public OpenGL util
// Initialization / upkeep
bool OpenGL_Create(void *&);
void OpenGL_Shutdown();
void OpenGL_Update();
bool OpenGL_MakeCurrent();
void OpenGL_SwapBuffers();
// Get status
u32 OpenGL_GetBackbufferWidth();
u32 OpenGL_GetBackbufferHeight();
// Set things
void OpenGL_SetWindowText(const char *text);
// Helpers
GLuint OpenGL_CompileProgram(const char *vertexShader, const char *fragmentShader);
// Error reporting - use the convenient macros.
void OpenGL_ReportARBProgramError();
@@ -126,4 +69,7 @@ extern CGprofile g_cgvProf, g_cgfProf;
// use GLSL shaders across the whole pipeline. Yikes!
//#define USE_DUAL_SOURCE_BLEND
// TODO: should be removed if we use glsl a lot
#define DEBUG_GLSL
#endif // _GLINIT_H_
@@ -323,8 +323,8 @@ Renderer::Renderer()
return; // TODO: fail
// Decide frambuffer size
s_backbuffer_width = (int)OpenGL_GetBackbufferWidth();
s_backbuffer_height = (int)OpenGL_GetBackbufferHeight();
s_backbuffer_width = (int)GLInterface->GetBackBufferWidth();
s_backbuffer_height = (int)GLInterface->GetBackBufferHeight();
// Handle VSync on/off
#ifdef __APPLE__
@@ -521,7 +521,7 @@ Renderer::~Renderer()
void Renderer::DrawDebugInfo()
{
// Reset viewport for drawing text
glViewport(0, 0, OpenGL_GetBackbufferWidth(), OpenGL_GetBackbufferHeight());
glViewport(0, 0, GLInterface->GetBackBufferWidth(), GLInterface->GetBackBufferHeight());
// Draw various messages on the screen, like FPS, statistics, etc.
char debugtext_buffer[8192];
char *p = debugtext_buffer;
@@ -598,8 +598,8 @@ void Renderer::DrawDebugInfo()
void Renderer::RenderText(const char *text, int left, int top, u32 color)
{
const int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
const int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
const int nBackbufferWidth = (int)GLInterface->GetBackBufferWidth();
const 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);
@@ -1294,7 +1294,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
SetWindowSize(fbWidth, fbHeight);
OpenGL_Update(); // just updates the render window position and the backbuffer size
GLInterface->Update(); // just updates the render window position and the backbuffer size
bool xfbchanged = false;
@@ -1308,8 +1308,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
}
bool WindowResized = false;
int W = (int)OpenGL_GetBackbufferWidth();
int H = (int)OpenGL_GetBackbufferHeight();
int W = (int)GLInterface->GetBackBufferWidth();
int H = (int)GLInterface->GetBackBufferHeight();
if (W != s_backbuffer_width || H != s_backbuffer_height || s_LastEFBScale != g_ActiveConfig.iEFBScale)
{
WindowResized = true;
@@ -1354,7 +1354,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
GL_REPORT_ERRORD();
// Copy the rendered frame to the real window
OpenGL_SwapBuffers();
GLInterface->SwapBuffers();
GL_REPORT_ERRORD();
+4 -3
View File
@@ -165,7 +165,8 @@ bool VideoBackend::Initialize(void *&window_handle)
g_Config.VerifyValidity();
UpdateActiveConfig();
if (!OpenGL_Create(window_handle))
InitInterface();
if (!GLInterface->CreateWindow(window_handle))
return false;
s_BackendInitialized = true;
@@ -177,7 +178,7 @@ bool VideoBackend::Initialize(void *&window_handle)
// Run from the graphics thread
void VideoBackend::Video_Prepare()
{
OpenGL_MakeCurrent();
GLInterface->MakeCurrent();
g_renderer = new Renderer;
@@ -236,7 +237,7 @@ void VideoBackend::Shutdown()
g_renderer = NULL;
g_texture_cache = NULL;
}
OpenGL_Shutdown();
GLInterface->Shutdown();
}
}
@@ -26,13 +26,25 @@ if(wxWidgets_FOUND)
endif(wxWidgets_FOUND)
set(LIBS videocommon
GLEW
SOIL
common
${OPENGL_LIBRARIES}
${X11_LIBRARIES}
${wxWidgets_LIBRARIES})
if(USE_EGL)
set(LIBS ${LIBS}
EGL)
endif()
if(USE_GLES)
set(SRCS ${SRCS}
../Plugin_VideoOGL/Src/GLUtil.cpp)
set(LIBS ${LIBS}
GLESv2)
else()
set(LIBS ${LIBS}
GLEW
${OPENGL_LIBRARIES})
endif()
if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin"))
set(LIBS ${LIBS} clrun)
endif()
@@ -25,7 +25,6 @@
#include "DebugUtil.h"
#include "HwRasterizer.h"
#include "SWCommandProcessor.h"
#include "../../Plugin_VideoOGL/Src/GLUtil.h"
#include "HW/Memmap.h"
#include "Core.h"
@@ -33,7 +32,7 @@ namespace EfbCopy
{
void CopyToXfb()
{
OpenGL_Update(); // just updates the render window position and the backbuffer size
GLInterface->Update(); // just updates the render window position and the backbuffer size
if (!g_SWVideoConfig.bHwRasterizer)
{
@@ -26,6 +26,17 @@
#include "DebugUtil.h"
#define TEMP_SIZE (1024*1024*4)
#ifdef USE_GLES
#define PREC "highp"
#define TEX2D GL_TEXTURE_2D
#define TEXTYPE "sampler2D"
#define TEXFUNC "texture2D"
#else
#define PREC
#define TEX2D GL_TEXTURE_RECTANGLE_ARB
#define TEXTYPE "sampler2DRect"
#define TEXFUNC "texture2DRect"
#endif
namespace HwRasterizer
{
@@ -35,6 +46,75 @@ namespace HwRasterizer
u8 *temp;
// Programs
static GLuint colProg, texProg, clearProg;
// Color
static GLint col_apos = -1, col_atex = -1;
// Tex
static GLint tex_apos = -1, tex_atex = -1, tex_utex = -1;
// Clear shader
static GLint clear_apos = -1, clear_ucol = -1;
void CreateShaders()
{
// Color Vertices
static const char *fragcolText =
"varying " PREC " vec4 TexCoordOut;\n"
"void main() {\n"
" gl_FragColor = TexCoordOut;\n"
"}\n";
// Texture Vertices
static const char *fragtexText =
"varying " PREC " vec4 TexCoordOut;\n"
"uniform " TEXTYPE " Texture;\n"
"void main() {\n"
" " PREC " vec4 tmpcolor;\n"
" tmpcolor = " TEXFUNC "(Texture, TexCoordOut.xy);\n"
" gl_FragColor = tmpcolor;\n"
"}\n";
// Clear shader
static const char *fragclearText =
"uniform vec4 Color;\n"
"void main() {\n"
" gl_FragColor = Color;\n"
"}\n";
// Generic passthrough vertice shaders
static const char *vertShaderText =
"attribute vec4 pos;\n"
"attribute vec4 TexCoordIn;\n "
"varying vec4 TexCoordOut;\n "
"void main() {\n"
" gl_Position = pos;\n"
" TexCoordOut = TexCoordIn;\n"
"}\n";
static const char *vertclearText =
"attribute vec4 pos;\n"
"void main() {\n"
" gl_Position = pos;\n"
"}\n";
// Color Program
colProg = OpenGL_CompileProgram(vertShaderText, fragcolText);
// Texture Program
texProg = OpenGL_CompileProgram(vertShaderText, fragtexText);
// Clear Program
clearProg = OpenGL_CompileProgram(vertclearText, fragclearText);
// Color attributes
col_apos = glGetAttribLocation(colProg, "pos");
col_atex = glGetAttribLocation(colProg, "TexCoordIn");
// Texture attributes
tex_apos = glGetAttribLocation(texProg, "pos");
tex_atex = glGetAttribLocation(texProg, "TexCoordIn");
tex_utex = glGetUniformLocation(texProg, "Texture");
// Clear attributes
clear_apos = glGetAttribLocation(clearProg, "pos");
clear_ucol = glGetUniformLocation(clearProg, "Color");
}
void Init()
{
efbHalfWidth = EFB_WIDTH / 2.0f;
@@ -42,23 +122,72 @@ namespace HwRasterizer
temp = (u8*)AllocateMemoryPages(TEMP_SIZE);
}
void Shutdown()
{
glDeleteProgram(colProg);
glDeleteProgram(texProg);
glDeleteProgram(clearProg);
}
void Prepare()
{
//legacy multitexturing: select texture channel only.
glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
#ifndef USE_GLES
glShadeModel(GL_SMOOTH);
glDisable(GL_BLEND);
glClearDepth(1.0f);
glEnable(GL_SCISSOR_TEST);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClientActiveTexture(GL_TEXTURE0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glStencilFunc(GL_ALWAYS, 0, 0);
glDisable(GL_STENCIL_TEST);
#endif
// used by hw rasterizer if it enables blending and depth test
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_LEQUAL);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
CreateShaders();
GL_REPORT_ERRORD();
}
static float width, height;
void LoadTexture()
{
FourTexUnits &texUnit = bpmem.tex[0];
u32 imageAddr = texUnit.texImage3[0].image_base;
// Texture Rectangle uses pixel coordinates
// While GLES uses texture coordinates
#ifdef USE_GLES
width = texUnit.texImage0[0].width;
height = texUnit.texImage0[0].height;
#else
width = 1;
height = 1;
#endif
TexCacheEntry &cacheEntry = textures[imageAddr];
cacheEntry.Update();
GL_REPORT_ERRORD();
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, cacheEntry.texture);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, texUnit.texMode0[0].mag_filter ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, (texUnit.texMode0[0].min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
glBindTexture(TEX2D, cacheEntry.texture);
glTexParameteri(TEX2D, GL_TEXTURE_MAG_FILTER, texUnit.texMode0[0].mag_filter ? GL_LINEAR : GL_NEAREST);
glTexParameteri(TEX2D, GL_TEXTURE_MIN_FILTER, (texUnit.texMode0[0].min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
GL_REPORT_ERRORD();
}
void BeginTriangles()
{
// disabling depth test sometimes allows more things to be visible
GL_REPORT_ERRORD();
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
@@ -66,51 +195,121 @@ namespace HwRasterizer
if (hasTexture)
LoadTexture();
GL_REPORT_ERRORD();
}
void EndTriangles()
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glBindTexture(TEX2D, 0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}
void DrawColorVertex(OutputVertexData *v)
void DrawColorVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
{
glColor3ub(v->color[0][OutputVertexData::RED_C], v->color[0][OutputVertexData::GRN_C], v->color[0][OutputVertexData::BLU_C]);
glVertex3f(v->screenPosition.x / efbHalfWidth - 1.0f, 1.0f - v->screenPosition.y / efbHalfHeight, v->screenPosition.z / (float)0x00ffffff);
float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f;
float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight);
float z0 = v0->screenPosition.z / (float)0x00ffffff;
float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f;
float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight);
float z1 = v1->screenPosition.z / (float)0x00ffffff;
float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f;
float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight);
float z2 = v2->screenPosition.z / (float)0x00ffffff;
float r0 = v0->color[0][OutputVertexData::RED_C] / 255.0f;
float g0 = v0->color[0][OutputVertexData::GRN_C] / 255.0f;
float b0 = v0->color[0][OutputVertexData::BLU_C] / 255.0f;
float r1 = v1->color[0][OutputVertexData::RED_C] / 255.0f;
float g1 = v1->color[0][OutputVertexData::GRN_C] / 255.0f;
float b1 = v1->color[0][OutputVertexData::BLU_C] / 255.0f;
float r2 = v2->color[0][OutputVertexData::RED_C] / 255.0f;
float g2 = v2->color[0][OutputVertexData::GRN_C] / 255.0f;
float b2 = v2->color[0][OutputVertexData::BLU_C] / 255.0f;
static const GLfloat verts[3][3] = {
{ x0, y0, z0 },
{ x1, y1, z1 },
{ x2, y2, z2 }
};
static const GLfloat col[3][4] = {
{ r0, g0, b0, 0.1f },
{ r1, g1, b1, 0.1f },
{ r2, g2, b2, 0.1f }
};
{
glUseProgram(colProg);
glEnableVertexAttribArray(col_apos);
glEnableVertexAttribArray(col_atex);
glVertexAttribPointer(col_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
glVertexAttribPointer(col_atex, 4, GL_FLOAT, GL_FALSE, 0, col);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(col_atex);
glDisableVertexAttribArray(col_apos);
}
GL_REPORT_ERRORD();
}
void DrawTextureVertex(OutputVertexData *v)
void DrawTextureVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
{
float s = v->texCoords[0].x;
float t = v->texCoords[0].y;
glTexCoord2f(s, t);
float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f;
float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight);
float z0 = v0->screenPosition.z;
float x = (v->screenPosition.x / efbHalfWidth) - 1.0f;
float y = 1.0f - (v->screenPosition.y / efbHalfHeight);
float z = v->screenPosition.z;
glVertex3f(x, y, z);
float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f;
float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight);
float z1 = v1->screenPosition.z;
float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f;
float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight);
float z2 = v2->screenPosition.z;
float s0 = v0->texCoords[0].x / width;
float t0 = v0->texCoords[0].y / height;
float s1 = v1->texCoords[0].x / width;
float t1 = v1->texCoords[0].y / height;
float s2 = v2->texCoords[0].x / width;
float t2 = v2->texCoords[0].y / width;
static const GLfloat verts[3][3] = {
{ x0, y0, z0 },
{ x1, y1, z1 },
{ x2, y2, z2 }
};
static const GLfloat tex[3][2] = {
{ s0, t0 },
{ s1, t1 },
{ s2, t2 }
};
{
glUseProgram(texProg);
glEnableVertexAttribArray(tex_apos);
glEnableVertexAttribArray(tex_atex);
glVertexAttribPointer(tex_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
glVertexAttribPointer(tex_atex, 2, GL_FLOAT, GL_FALSE, 0, tex);
glUniform1i(tex_utex, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(tex_atex);
glDisableVertexAttribArray(tex_apos);
}
GL_REPORT_ERRORD();
}
void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
{
glBegin(GL_TRIANGLES);
if (hasTexture)
{
DrawTextureVertex(v0);
DrawTextureVertex(v1);
DrawTextureVertex(v2);
}
else
{
DrawColorVertex(v0);
DrawColorVertex(v1);
DrawColorVertex(v2);
}
glEnd();
}
if (hasTexture)
DrawTextureVertex(v0, v1, v2);
else
DrawColorVertex(v0, v1, v2);
}
void Clear()
{
@@ -124,17 +323,21 @@ namespace HwRasterizer
GLfloat right = (GLfloat)(left + bpmem.copyTexSrcWH.x + 1) / efbHalfWidth - 1.0f;
GLfloat bottom = 1.0f - (GLfloat)(top + bpmem.copyTexSrcWH.y + 1) / efbHalfHeight;
GLfloat depth = (GLfloat)bpmem.clearZValue / (GLfloat)0x00ffffff;
glBegin(GL_QUADS);
glColor4ub(r, g, b, a);
glVertex3f(left, top, depth);
glColor4ub(r, g, b, a);
glVertex3f(right, top, depth);
glColor4ub(r, g, b, a);
glVertex3f(right, bottom, depth);
glColor4ub(r, g, b, a);
glVertex3f(left, bottom, depth);
glEnd();
static const GLfloat verts[4][3] = {
{ left, top, depth },
{ right, top, depth },
{ right, bottom, depth },
{ left, bottom, depth }
};
{
glUseProgram(clearProg);
glVertexAttribPointer(clear_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
glUniform4f(clear_ucol, r, g, b, a);
glEnableVertexAttribArray(col_apos);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(col_apos);
}
GL_REPORT_ERRORD();
}
TexCacheEntry::TexCacheEntry()
@@ -158,9 +361,14 @@ namespace HwRasterizer
DebugUtil::GetTextureBGRA(temp, 0, 0, width, height);
glGenTextures(1, (GLuint *)&texture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, (GLsizei)width, (GLsizei)height, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp);
}
glBindTexture(TEX2D, texture);
#ifdef USE_GLES
glTexImage2D(TEX2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);
#else
glTexImage2D(TEX2D, 0, GL_RGBA8, (GLsizei)width, (GLsizei)height, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp);
#endif
GL_REPORT_ERRORD();
}
void TexCacheEntry::Destroy()
{
@@ -28,6 +28,9 @@ struct OutputVertexData;
namespace HwRasterizer
{
void Init();
void Shutdown();
void Prepare();
void BeginTriangles();
void EndTriangles();
@@ -16,17 +16,35 @@
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include <math.h>
#include "../../Plugin_VideoOGL/Src/GLUtil.h"
#include "../../Plugin_VideoOGL/Src/RasterFont.h"
#include "SWRenderer.h"
#include "SWStatistics.h"
#include "../../Plugin_VideoOGL/Src/RasterFont.h"
#define VSYNC_ENABLED 0
static GLuint s_RenderTarget = 0;
static GLint attr_pos = -1, attr_tex = -1;
static GLint uni_tex = -1;
static GLuint program;
#ifdef USE_GLES
#define PREC "highp"
#define TEX2D GL_TEXTURE_2D
#define TEXTYPE "sampler2D"
#define TEXFUNC "texture2D"
#else
#define PREC
#define TEX2D GL_TEXTURE_RECTANGLE_ARB
#define TEXTYPE "sampler2DRect"
#define TEXFUNC "texture2DRect"
#endif
#ifndef USE_GLES
RasterFont* s_pfont = NULL;
#endif
void SWRenderer::Init()
{
@@ -34,79 +52,68 @@ void SWRenderer::Init()
void SWRenderer::Shutdown()
{
glDeleteProgram(program);
glDeleteTextures(1, &s_RenderTarget);
#ifndef USE_GLES
delete s_pfont;
s_pfont = 0;
#endif
}
delete s_pfont;
s_pfont = 0;
void CreateShaders()
{
static const char *fragShaderText =
"varying " PREC " vec2 TexCoordOut;\n"
"uniform " TEXTYPE " Texture;\n"
"void main() {\n"
" " PREC " vec4 tmpcolor;\n"
" tmpcolor = " TEXFUNC "(Texture, TexCoordOut);\n"
" gl_FragColor = tmpcolor;\n"
"}\n";
static const char *vertShaderText =
"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()
{
OpenGL_MakeCurrent();
// Init extension support.
if (glewInit() != GLEW_OK) {
ERROR_LOG(VIDEO, "glewInit() failed!Does your video card support OpenGL 2.x?");
return;
}
// Handle VSync on/off
#ifdef _WIN32
if (WGLEW_EXT_swap_control)
wglSwapIntervalEXT(VSYNC_ENABLED);
else
ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)Does your video card support OpenGL 2.x?");
#elif defined(HAVE_X11) && HAVE_X11
if (glXSwapIntervalSGI)
glXSwapIntervalSGI(VSYNC_ENABLED);
else
ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)");
#endif
glStencilFunc(GL_ALWAYS, 0, 0);
// used by hw rasterizer if it enables blending and depth test
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_SCISSOR_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST);
//glDisable(GL_SCISSOR_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
s_pfont = new RasterFont();
// legacy multitexturing: select texture channel only.
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glGenTextures(1, &s_RenderTarget);
CreateShaders();
#ifndef USE_GLES
s_pfont = new RasterFont();
glEnable(GL_TEXTURE_RECTANGLE_ARB);
#endif
GL_REPORT_ERRORD();
}
void SWRenderer::RenderText(const char* pstr, int left, int top, u32 color)
{
int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
int nBackbufferWidth = (int)GLInterface->GetBackBufferWidth();
int nBackbufferHeight = (int)GLInterface->GetBackBufferHeight();
#ifndef USE_GLES
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);
s_pfont->printMultilineText(pstr,
left * 2.0f / (float)nBackbufferWidth - 1,
1 - top * 2.0f / (float)nBackbufferHeight,
0, nBackbufferWidth, nBackbufferHeight);
#endif
}
void SWRenderer::DrawDebugText()
@@ -139,31 +146,56 @@ void SWRenderer::DrawDebugText()
void SWRenderer::DrawTexture(u8 *texture, int width, int height)
{
GLsizei glWidth = (GLsizei)OpenGL_GetBackbufferWidth();
GLsizei glHeight = (GLsizei)OpenGL_GetBackbufferHeight();
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_RECTANGLE_ARB, s_RenderTarget);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(TEX2D, s_RenderTarget);
GL_REPORT_ERRORD();
glTexImage2D(TEX2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexParameteri(TEX2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(TEX2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GLfloat u_max = (GLfloat)width;
GLfloat v_max = (GLfloat)glHeight;
glBegin(GL_QUADS);
glTexCoord2f(0, v_max); glVertex2f(-1, -1);
glTexCoord2f(0, 0); glVertex2f(-1, 1);
glTexCoord2f(u_max, 0); glVertex2f( 1, 1);
glTexCoord2f(u_max, v_max); glVertex2f( 1, -1);
glEnd();
static const GLfloat verts[4][2] = {
{ -1, -1}, // Left top
{ -1, 1}, // left bottom
{ 1, 1}, // right bottom
{ 1, -1} // right top
};
//Texture rectangle uses pixel coordinates
#ifndef USE_GLES
static const GLfloat texverts[4][2] = {
{0, v_max},
{0, 0},
{u_max, 0},
{u_max, v_max}
};
#else
static const GLfloat texverts[4][2] = {
{0, 1},
{0, 0},
{1, 0},
{1, 1}
};
#endif
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);
glActiveTexture(GL_TEXTURE0);
glUniform1i(uni_tex, 0);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(attr_pos);
glDisableVertexAttribArray(attr_tex);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glBindTexture(TEX2D, 0);
GL_REPORT_ERRORD();
}
void SWRenderer::SwapBuffer()
@@ -172,15 +204,13 @@ void SWRenderer::SwapBuffer()
glFlush();
OpenGL_SwapBuffers();
GLInterface->SwapBuffers();
GL_REPORT_ERRORD();
swstats.ResetFrame();
// Clear framebuffer
glClearColor(0, 0, 0, 0);
glClearDepth(1.0);
#ifndef USE_GLES
glClearDepth(1.0f);
#endif
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GL_REPORT_ERRORD();
@@ -51,7 +51,7 @@ void SWVideoConfig::Load(const char* ini_file)
iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0); // Hardware
iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, false);
iniFile.Get("Rendering", "HwRasterizer", &bHwRasterizer, false);
iniFile.Get("Rendering", "HwRasterizer", &bHwRasterizer, true);
iniFile.Get("Info", "ShowStats", &bShowStats, false);
@@ -40,6 +40,8 @@
#include "VideoBackend.h"
#include "Core.h"
#define VSYNC_ENABLED 0
namespace SW
{
@@ -69,8 +71,9 @@ void VideoSoftware::ShowConfig(void *_hParent)
bool VideoSoftware::Initialize(void *&window_handle)
{
g_SWVideoConfig.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_software.ini").c_str());
InitInterface();
if (!OpenGL_Create(window_handle))
if (!GLInterface->CreateWindow(window_handle))
{
INFO_LOG(VIDEO, "%s", "SWRenderer::Create failed\n");
return false;
@@ -83,8 +86,10 @@ bool VideoSoftware::Initialize(void *&window_handle)
OpcodeDecoder::Init();
Clipper::Init();
Rasterizer::Init();
HwRasterizer::Init();
SWRenderer::Init();
if (g_SWVideoConfig.bHwRasterizer)
HwRasterizer::Init();
else
SWRenderer::Init();
DebugUtil::Init();
return true;
@@ -124,14 +129,44 @@ void VideoSoftware::EmuStateChange(EMUSTATE_CHANGE newState)
void VideoSoftware::Shutdown()
{
SWRenderer::Shutdown();
OpenGL_Shutdown();
if (g_SWVideoConfig.bHwRasterizer)
HwRasterizer::Shutdown();
else
SWRenderer::Shutdown();
GLInterface->Shutdown();
}
// This is called after Video_Initialize() from the Core
void VideoSoftware::Video_Prepare()
{
SWRenderer::Prepare();
{
GLInterface->MakeCurrent();
// Init extension support.
{
#ifndef USE_GLES
if (glewInit() != GLEW_OK) {
ERROR_LOG(VIDEO, "glewInit() failed!Does your video card support OpenGL 2.x?");
return;
}
// Handle VSync on/off
#ifdef _WIN32
if (WGLEW_EXT_swap_control)
wglSwapIntervalEXT(VSYNC_ENABLED);
else
ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)Does your video card support OpenGL 2.x?");
#elif defined(HAVE_X11) && HAVE_X11
if (glXSwapIntervalSGI)
glXSwapIntervalSGI(VSYNC_ENABLED);
else
ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)");
#endif
#endif
}
if (g_SWVideoConfig.bHwRasterizer)
HwRasterizer::Prepare();
else
SWRenderer::Prepare();
INFO_LOG(VIDEO, "Video backend initialized.");
}
@@ -273,20 +308,7 @@ writeFn32 VideoSoftware::Video_PEWrite32()
// Draw messages on top of the screen
unsigned int VideoSoftware::PeekMessages()
{
#ifdef _WIN32
// TODO: peekmessage
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
#else
return false;
#endif
return GLInterface->PeekMessages();
}
// Show the current FPS
@@ -294,7 +316,7 @@ void VideoSoftware::UpdateFPSDisplay(const char *text)
{
char temp[100];
snprintf(temp, sizeof temp, "%s | Software | %s", scm_rev_str, text);
OpenGL_SetWindowText(temp);
GLInterface->UpdateFPSDisplay(temp);
}
}