OpenGL Renderer:
- Small optimization to texture handling. - Rewrite console info strings for better reading, and also prefix all lines with "OpenGL:". - Report basic GPU info in the console on init. - Check for a minimum OpenGL header version of v2.0 and a minimum OpenGL GPU version of v1.2. (Note that these requirements were always implied by the code, but now we can explicitly check for them.) - Do even more code cleanup.
This commit is contained in:
parent
9e1837dc4b
commit
c0181e741d
|
@ -78,6 +78,16 @@ static void ENDGL() {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Check minimum OpenGL header version
|
||||||
|
#if !defined(GL_VERSION_2_0)
|
||||||
|
#error OpenGL requires v2.0 headers or later.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Define minimum OpenGL version for GPU
|
||||||
|
#define OGL_MINIMUM_GPU_VERSION_REQUIRED_MAJOR 1
|
||||||
|
#define OGL_MINIMUM_GPU_VERSION_REQUIRED_MINOR 2
|
||||||
|
#define OGL_MINIMUM_GPU_VERSION_REQUIRED_REVISION 0
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "MMU.h"
|
#include "MMU.h"
|
||||||
|
@ -109,17 +119,9 @@ static bool isReadPixelsWorking = false;
|
||||||
static Task oglReadPixelsTask;
|
static Task oglReadPixelsTask;
|
||||||
|
|
||||||
// Polygon Info
|
// Polygon Info
|
||||||
static PolygonAttributes currentPolyAttr;
|
|
||||||
static PolygonTexParams currentTexParams;
|
|
||||||
static GLenum depthFuncMode = 0;
|
|
||||||
static unsigned int lastEnvMode = 0;
|
|
||||||
static GLenum cullingMode = 0;
|
|
||||||
static GLfloat polyAlpha = 1.0f;
|
static GLfloat polyAlpha = 1.0f;
|
||||||
|
|
||||||
static u32 stencilStateSet = -1;
|
|
||||||
|
|
||||||
// OpenGL Feature Support
|
// OpenGL Feature Support
|
||||||
static char *extString = NULL;
|
|
||||||
static bool isVBOSupported = false;
|
static bool isVBOSupported = false;
|
||||||
static bool isPBOSupported = false;
|
static bool isPBOSupported = false;
|
||||||
static bool isFBOSupported = false;
|
static bool isFBOSupported = false;
|
||||||
|
@ -309,7 +311,7 @@ static void* execReadPixelsTask(void *arg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glReadPixels(0, 0, 256, 192, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixBuffer);
|
glReadPixels(0, 0, 256, 192, GL_BGRA, GL_UNSIGNED_BYTE, pixBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENDGL();
|
ENDGL();
|
||||||
|
@ -368,7 +370,7 @@ static void _xglDisable(GLenum cap) {
|
||||||
CTASSERT((cap-0x0B00)<0x100); \
|
CTASSERT((cap-0x0B00)<0x100); \
|
||||||
_xglDisable(cap); }
|
_xglDisable(cap); }
|
||||||
|
|
||||||
#define NOSHADERS(s) { isShaderSupported = false; INFO("Shaders aren't supported on your system, using fixed pipeline\n(%s)\n", s); return; }
|
#define NOSHADERS(s) { isShaderSupported = false; INFO("%s\nOpenGL: Disabling shaders and using fixed-function pipeline. Some emulation features will be disabled.\n", s); return; }
|
||||||
|
|
||||||
#define SHADER_COMPCHECK(s, t) { \
|
#define SHADER_COMPCHECK(s, t) { \
|
||||||
GLint status = GL_TRUE; \
|
GLint status = GL_TRUE; \
|
||||||
|
@ -380,10 +382,10 @@ static void _xglDisable(GLenum cap) {
|
||||||
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &logSize); \
|
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &logSize); \
|
||||||
log = new GLchar[logSize]; \
|
log = new GLchar[logSize]; \
|
||||||
glGetShaderInfoLog(s, logSize, &logSize, log); \
|
glGetShaderInfoLog(s, logSize, &logSize, log); \
|
||||||
INFO("SEVERE : FAILED TO COMPILE GL SHADER : %s\n", log); \
|
INFO("OpenGL: SEVERE - FAILED TO COMPILE SHADER : %s\n", log); \
|
||||||
delete[] log; \
|
delete[] log; \
|
||||||
if(s)glDeleteShader(s); \
|
if(s)glDeleteShader(s); \
|
||||||
NOSHADERS("Failed to compile the "t" shader."); \
|
NOSHADERS("OpenGL: Failed to compile the "t" shader."); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,22 +399,22 @@ static void _xglDisable(GLenum cap) {
|
||||||
glGetProgramiv(p, GL_INFO_LOG_LENGTH, &logSize); \
|
glGetProgramiv(p, GL_INFO_LOG_LENGTH, &logSize); \
|
||||||
log = new GLchar[logSize]; \
|
log = new GLchar[logSize]; \
|
||||||
glGetProgramInfoLog(p, logSize, &logSize, log); \
|
glGetProgramInfoLog(p, logSize, &logSize, log); \
|
||||||
INFO("SEVERE : FAILED TO LINK GL SHADER PROGRAM : %s\n", log); \
|
INFO("OpenGL: SEVERE - FAILED TO LINK SHADER PROGRAM : %s\n", log); \
|
||||||
delete[] log; \
|
delete[] log; \
|
||||||
if(s1)glDeleteShader(s1); \
|
if(s1)glDeleteShader(s1); \
|
||||||
if(s2)glDeleteShader(s2); \
|
if(s2)glDeleteShader(s2); \
|
||||||
NOSHADERS("Failed to link the shader program."); \
|
NOSHADERS("OpenGL: Failed to link the shader program."); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shaders init */
|
/* Shaders init */
|
||||||
|
|
||||||
static void createShaders()
|
static void createShaders(const char *oglExtensionString)
|
||||||
{
|
{
|
||||||
isShaderSupported = true;
|
isShaderSupported = true;
|
||||||
|
|
||||||
#ifdef HAVE_LIBOSMESA
|
#ifdef HAVE_LIBOSMESA
|
||||||
NOSHADERS("Shaders aren't supported by OSMesa.");
|
NOSHADERS("OpenGL: Shaders aren't supported by OSMesa.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This check is just plain wrong. */
|
/* This check is just plain wrong. */
|
||||||
|
@ -429,18 +431,18 @@ static void createShaders()
|
||||||
NOSHADERS("Shaders aren't supported by your system.");*/
|
NOSHADERS("Shaders aren't supported by your system.");*/
|
||||||
|
|
||||||
#if !defined(GL_ARB_shader_objects) || !defined(GL_ARB_vertex_shader) || !defined(GL_ARB_fragment_shader) || !defined(GL_ARB_vertex_program)
|
#if !defined(GL_ARB_shader_objects) || !defined(GL_ARB_vertex_shader) || !defined(GL_ARB_fragment_shader) || !defined(GL_ARB_vertex_program)
|
||||||
NOSHADERS("Shaders aren't supported by your system.");
|
NOSHADERS("OpenGL: Shaders are unsupported.");
|
||||||
#else
|
#else
|
||||||
if ((strstr(extString, "GL_ARB_shader_objects") == NULL) ||
|
if ((strstr(oglExtensionString, "GL_ARB_shader_objects") == NULL) ||
|
||||||
(strstr(extString, "GL_ARB_vertex_shader") == NULL) ||
|
(strstr(oglExtensionString, "GL_ARB_vertex_shader") == NULL) ||
|
||||||
(strstr(extString, "GL_ARB_fragment_shader") == NULL) ||
|
(strstr(oglExtensionString, "GL_ARB_fragment_shader") == NULL) ||
|
||||||
(strstr(extString, "GL_ARB_vertex_program") == NULL) )
|
(strstr(oglExtensionString, "GL_ARB_vertex_program") == NULL) )
|
||||||
NOSHADERS("Shaders aren't supported by your system.");
|
NOSHADERS("OpenGL: Shaders are unsupported.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||||
if(!vertexShaderID)
|
if(!vertexShaderID)
|
||||||
NOSHADERS("Failed to create the vertex shader.");
|
NOSHADERS("OpenGL: Failed to create the vertex shader.");
|
||||||
|
|
||||||
glShaderSource(vertexShaderID, 1, (const GLchar**)&vertexShader, NULL);
|
glShaderSource(vertexShaderID, 1, (const GLchar**)&vertexShader, NULL);
|
||||||
glCompileShader(vertexShaderID);
|
glCompileShader(vertexShaderID);
|
||||||
|
@ -448,7 +450,7 @@ static void createShaders()
|
||||||
|
|
||||||
fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
if(!fragmentShaderID)
|
if(!fragmentShaderID)
|
||||||
NOSHADERS("Failed to create the fragment shader.");
|
NOSHADERS("OpenGL: Failed to create the fragment shader.");
|
||||||
|
|
||||||
glShaderSource(fragmentShaderID, 1, (const GLchar**)&fragmentShader, NULL);
|
glShaderSource(fragmentShaderID, 1, (const GLchar**)&fragmentShader, NULL);
|
||||||
glCompileShader(fragmentShaderID);
|
glCompileShader(fragmentShaderID);
|
||||||
|
@ -456,7 +458,7 @@ static void createShaders()
|
||||||
|
|
||||||
shaderProgram = glCreateProgram();
|
shaderProgram = glCreateProgram();
|
||||||
if(!shaderProgram)
|
if(!shaderProgram)
|
||||||
NOSHADERS("Failed to create the shader program.");
|
NOSHADERS("OpenGL: Failed to create the shader program.");
|
||||||
|
|
||||||
glAttachShader(shaderProgram, vertexShaderID);
|
glAttachShader(shaderProgram, vertexShaderID);
|
||||||
glAttachShader(shaderProgram, fragmentShaderID);
|
glAttachShader(shaderProgram, fragmentShaderID);
|
||||||
|
@ -471,7 +473,7 @@ static void createShaders()
|
||||||
glValidateProgram(shaderProgram);
|
glValidateProgram(shaderProgram);
|
||||||
glUseProgram(shaderProgram);
|
glUseProgram(shaderProgram);
|
||||||
|
|
||||||
INFO("Successfully created OpenGL shaders.\n");
|
INFO("OpenGL: Successfully created shaders.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================
|
//=================================================
|
||||||
|
@ -565,6 +567,62 @@ static void expandFreeTextures()
|
||||||
freeTextureIds.push(oglTempTextureID[i]);
|
freeTextureIds.push(oglTempTextureID[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool OGLIsMinimumVersionSupported(const char *oglVersionString)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
size_t versionStringLength = 0;
|
||||||
|
|
||||||
|
if (oglVersionString == NULL)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, check for the dot in the revision string. There should be at
|
||||||
|
// least one present.
|
||||||
|
const char *versionStrEnd = strstr(oglVersionString, ".");
|
||||||
|
if (versionStrEnd == NULL)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, check for the space before the vendor-specific info (if present).
|
||||||
|
versionStrEnd = strstr(oglVersionString, " ");
|
||||||
|
if (versionStrEnd == NULL)
|
||||||
|
{
|
||||||
|
// If a space was not found, then the vendor-specific info is not present,
|
||||||
|
// and therefore the entire string must be the version number.
|
||||||
|
versionStringLength = strlen(oglVersionString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If a space was found, then the vendor-specific info is present,
|
||||||
|
// and therefore the version number is everything before the space.
|
||||||
|
versionStringLength = versionStrEnd - oglVersionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the version substring and parse it.
|
||||||
|
char *versionSubstring = (char *)malloc(versionStringLength * sizeof(char));
|
||||||
|
strncpy(versionSubstring, oglVersionString, versionStringLength);
|
||||||
|
|
||||||
|
unsigned int major = 0;
|
||||||
|
unsigned int minor = 0;
|
||||||
|
unsigned int revision = 0;
|
||||||
|
|
||||||
|
sscanf(versionSubstring, "%u.%u.%u", &major, &minor, &revision);
|
||||||
|
|
||||||
|
if ( (major > OGL_MINIMUM_GPU_VERSION_REQUIRED_MAJOR) ||
|
||||||
|
(major >= OGL_MINIMUM_GPU_VERSION_REQUIRED_MAJOR && minor > OGL_MINIMUM_GPU_VERSION_REQUIRED_MINOR) ||
|
||||||
|
(major >= OGL_MINIMUM_GPU_VERSION_REQUIRED_MAJOR && minor >= OGL_MINIMUM_GPU_VERSION_REQUIRED_MINOR && revision >= OGL_MINIMUM_GPU_VERSION_REQUIRED_REVISION) )
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(versionSubstring);
|
||||||
|
versionSubstring = NULL;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static char OGLInit(void)
|
static char OGLInit(void)
|
||||||
{
|
{
|
||||||
if(!oglrender_init)
|
if(!oglrender_init)
|
||||||
|
@ -575,11 +633,25 @@ static char OGLInit(void)
|
||||||
if(!BEGINGL())
|
if(!BEGINGL())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Get OpenGL info
|
||||||
|
const char *oglVendorString = (const char *)glGetString(GL_VENDOR);
|
||||||
|
const char *oglRendererString = (const char *)glGetString(GL_RENDERER);
|
||||||
|
const char *oglVersionString = (const char *)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
if (!OGLIsMinimumVersionSupported(oglVersionString))
|
||||||
|
{
|
||||||
|
INFO("OpenGL: GPU does not support OpenGL v%u.%u.%u or later.\n[GPU Info - Version: %s, Vendor: %s, Renderer: %s]\n",
|
||||||
|
OGL_MINIMUM_GPU_VERSION_REQUIRED_MAJOR, OGL_MINIMUM_GPU_VERSION_REQUIRED_MINOR, OGL_MINIMUM_GPU_VERSION_REQUIRED_REVISION,
|
||||||
|
oglVersionString, oglVendorString, oglRendererString);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
glViewport(0, 0, 256, 192);
|
glViewport(0, 0, 256, 192);
|
||||||
if (glGetError() != GL_NO_ERROR)
|
if (glGetError() != GL_NO_ERROR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
extString = (char*)glGetString(GL_EXTENSIONS);
|
const char *oglExtensionString = (const char *)glGetString(GL_EXTENSIONS);
|
||||||
|
|
||||||
for (u8 i = 0; i < 255; i++)
|
for (u8 i = 0; i < 255; i++)
|
||||||
material_8bit_to_float[i] = (GLfloat)(i<<2)/255.f;
|
material_8bit_to_float[i] = (GLfloat)(i<<2)/255.f;
|
||||||
|
@ -655,7 +727,7 @@ static char OGLInit(void)
|
||||||
#if !defined(GL_ARB_vertex_buffer_object)
|
#if !defined(GL_ARB_vertex_buffer_object)
|
||||||
isVBOSupported = false;
|
isVBOSupported = false;
|
||||||
#else
|
#else
|
||||||
isVBOSupported = (strstr(extString, "GL_ARB_vertex_buffer_object") == NULL) ? false : true;
|
isVBOSupported = (strstr(oglExtensionString, "GL_ARB_vertex_buffer_object") == NULL) ? false : true;
|
||||||
#endif
|
#endif
|
||||||
if (isVBOSupported)
|
if (isVBOSupported)
|
||||||
{
|
{
|
||||||
|
@ -669,7 +741,7 @@ static char OGLInit(void)
|
||||||
#if !defined(GL_ARB_pixel_buffer_object)
|
#if !defined(GL_ARB_pixel_buffer_object)
|
||||||
isPBOSupported = false;
|
isPBOSupported = false;
|
||||||
#else
|
#else
|
||||||
isPBOSupported = (strstr(extString, "GL_ARB_pixel_buffer_object") == NULL) ? false : true;
|
isPBOSupported = (strstr(oglExtensionString, "GL_ARB_pixel_buffer_object") == NULL) ? false : true;
|
||||||
#endif
|
#endif
|
||||||
if (isPBOSupported)
|
if (isPBOSupported)
|
||||||
{
|
{
|
||||||
|
@ -705,7 +777,7 @@ static char OGLInit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shader Setup
|
// Shader Setup
|
||||||
createShaders();
|
createShaders(oglExtensionString);
|
||||||
if(isShaderSupported)
|
if(isShaderSupported)
|
||||||
{
|
{
|
||||||
// The toon table is a special 1D texture where each pixel corresponds
|
// The toon table is a special 1D texture where each pixel corresponds
|
||||||
|
@ -715,12 +787,15 @@ static char OGLInit(void)
|
||||||
// will be on texture unit 0).
|
// will be on texture unit 0).
|
||||||
glGenTextures (1, &oglToonTableTextureID);
|
glGenTextures (1, &oglToonTableTextureID);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_1D, oglToonTableTextureID);
|
glBindTexture(GL_TEXTURE_1D, oglToonTableTextureID);
|
||||||
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); //clamp so that we dont run off the edges due to 1.0 -> [0,31] math
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //clamp so that we dont run off the edges due to 1.0 -> [0,31] math
|
||||||
glBindTexture(GL_TEXTURE_1D, 0);
|
glBindTexture(GL_TEXTURE_1D, 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
memcpy(currentToonTable16, gfx3d.renderState.u16ToonTable, sizeof(currentToonTable16));
|
memcpy(currentToonTable16, gfx3d.renderState.u16ToonTable, sizeof(currentToonTable16));
|
||||||
toonTableNeedsUpdate = true;
|
toonTableNeedsUpdate = true;
|
||||||
|
|
||||||
|
@ -760,8 +835,8 @@ static char OGLInit(void)
|
||||||
#else
|
#else
|
||||||
isVAOSupported = ( !isVBOSupported ||
|
isVAOSupported = ( !isVBOSupported ||
|
||||||
!isShaderSupported ||
|
!isShaderSupported ||
|
||||||
(strstr(extString, "GL_ARB_vertex_array_object") == NULL &&
|
(strstr(oglExtensionString, "GL_ARB_vertex_array_object") == NULL &&
|
||||||
strstr(extString, "GL_APPLE_vertex_array_object") == NULL) ) ? false : true;
|
strstr(oglExtensionString, "GL_APPLE_vertex_array_object") == NULL) ) ? false : true;
|
||||||
#endif
|
#endif
|
||||||
if (isVAOSupported)
|
if (isVAOSupported)
|
||||||
{
|
{
|
||||||
|
@ -786,9 +861,9 @@ static char OGLInit(void)
|
||||||
!defined(GL_EXT_packed_depth_stencil) )
|
!defined(GL_EXT_packed_depth_stencil) )
|
||||||
isFBOSupported = false;
|
isFBOSupported = false;
|
||||||
#else
|
#else
|
||||||
isFBOSupported = ( (strstr(extString, "GL_ARB_framebuffer_object") == NULL) && (strstr(extString, "GL_EXT_framebuffer_object") == NULL ||
|
isFBOSupported = ( (strstr(oglExtensionString, "GL_ARB_framebuffer_object") == NULL) && (strstr(oglExtensionString, "GL_EXT_framebuffer_object") == NULL ||
|
||||||
strstr(extString, "GL_EXT_framebuffer_blit") == NULL ||
|
strstr(oglExtensionString, "GL_EXT_framebuffer_blit") == NULL ||
|
||||||
strstr(extString, "GL_EXT_packed_depth_stencil") == NULL) ) ? false : true;
|
strstr(oglExtensionString, "GL_EXT_packed_depth_stencil") == NULL) ) ? false : true;
|
||||||
#endif
|
#endif
|
||||||
if (isFBOSupported)
|
if (isFBOSupported)
|
||||||
{
|
{
|
||||||
|
@ -798,19 +873,18 @@ static char OGLInit(void)
|
||||||
glBindTexture(GL_TEXTURE_2D, oglClearImageTextureID[0]);
|
glBindTexture(GL_TEXTURE_2D, oglClearImageTextureID[0]);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, oglClearImageTextureID[1]);
|
glBindTexture(GL_TEXTURE_2D, oglClearImageTextureID[1]);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, 256, 192, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, 256, 192, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
|
|
||||||
|
|
||||||
// FBO - init
|
// FBO - init
|
||||||
glGenFramebuffersEXT(1, &oglClearImageBuffers);
|
glGenFramebuffersEXT(1, &oglClearImageBuffers);
|
||||||
|
@ -819,10 +893,10 @@ static char OGLInit(void)
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, oglClearImageTextureID[1], 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, oglClearImageTextureID[1], 0);
|
||||||
|
|
||||||
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)==GL_FRAMEBUFFER_COMPLETE_EXT)
|
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)==GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
INFO("Successfully created OpenGL Framebuffer object (FBO)\n");
|
INFO("OpenGL: Successfully created framebuffer objects.\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INFO("Failed to created OpenGL Framebuffer objects (FBO): ClearImage emulation disabled\n");
|
INFO("OpenGL: Failed to created framebuffer objects. Some emulation features will be disabled.\n");
|
||||||
isFBOSupported = false;
|
isFBOSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +908,7 @@ static char OGLInit(void)
|
||||||
oglClearImageDepthTemp = new u16[256*192];
|
oglClearImageDepthTemp = new u16[256*192];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
INFO("OpenGL: graphics card not supports Framebuffer objects (FBO) - ClearImage emulation disabled\n");
|
INFO("OpenGL: Framebuffer objects are unsupported. Some emulation features will be disabled.\n");
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
@ -862,6 +936,8 @@ static char OGLInit(void)
|
||||||
|
|
||||||
// Initialization finished -- reset the renderer
|
// Initialization finished -- reset the renderer
|
||||||
OGLReset();
|
OGLReset();
|
||||||
|
INFO("OpenGL: Initialized successfully.\n[GPU Info - Version: %s, Vendor: %s, Renderer: %s]\n",
|
||||||
|
oglVersionString, oglVendorString, oglRendererString);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -975,23 +1051,49 @@ static void texDeleteCallback(TexCacheItem* item)
|
||||||
currTexture = NULL;
|
currTexture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setTexture(u32 format, u32 texpal)
|
static void SetupTexture(POLY *thePoly)
|
||||||
{
|
{
|
||||||
if (format == 0 || currentTexParams.texFormat == TEXMODE_NONE)
|
PolygonTexParams params = thePoly->getTexParams();
|
||||||
|
|
||||||
|
// Check if we need to use textures
|
||||||
|
if (thePoly->texParam == 0 || params.texFormat == TEXMODE_NONE || !gfx3d.renderState.enableTexturing)
|
||||||
{
|
{
|
||||||
if(isShaderSupported && hasTexture) { glUniform1i(uniformHasTexture, GL_FALSE); hasTexture = false; }
|
if (hasTexture)
|
||||||
|
{
|
||||||
|
hasTexture = false;
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
if (isShaderSupported)
|
||||||
|
{
|
||||||
|
glUniform1i(uniformHasTexture, GL_FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isShaderSupported)
|
// Enable textures if they weren't already enabled
|
||||||
|
if (!hasTexture)
|
||||||
{
|
{
|
||||||
if(!hasTexture) { glUniform1i(uniformHasTexture, GL_TRUE); hasTexture = true; }
|
hasTexture = true;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
if (isShaderSupported)
|
||||||
|
{
|
||||||
|
glUniform1i(uniformHasTexture, GL_TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// texCacheUnit.TexCache_SetTexture<TexFormat_32bpp>(format, texpal);
|
// texCacheUnit.TexCache_SetTexture<TexFormat_32bpp>(format, texpal);
|
||||||
TexCacheItem* newTexture = TexCache_SetTexture(TexFormat_32bpp,format,texpal);
|
TexCacheItem* newTexture = TexCache_SetTexture(TexFormat_32bpp, thePoly->texParam, thePoly->texPalette);
|
||||||
if(newTexture != currTexture)
|
if(newTexture != currTexture)
|
||||||
{
|
{
|
||||||
currTexture = newTexture;
|
currTexture = newTexture;
|
||||||
|
@ -1004,13 +1106,12 @@ static void setTexture(u32 format, u32 texpal)
|
||||||
freeTextureIds.pop();
|
freeTextureIds.pop();
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D,(GLuint)currTexture->texid);
|
glBindTexture(GL_TEXTURE_2D,(GLuint)currTexture->texid);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (BIT16(currTexture->texformat) ? (BIT18(currTexture->texformat)?GL_MIRRORED_REPEAT:GL_REPEAT) : GL_CLAMP));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (BIT17(currTexture->texformat) ? (BIT19(currTexture->texformat)?GL_MIRRORED_REPEAT:GL_REPEAT) : GL_CLAMP));
|
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||||
currTexture->sizeX, currTexture->sizeY, 0,
|
currTexture->sizeX, currTexture->sizeY, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, currTexture->decoded);
|
GL_RGBA, GL_UNSIGNED_BYTE, currTexture->decoded);
|
||||||
|
@ -1035,17 +1136,18 @@ static void setTexture(u32 format, u32 texpal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetupPolygonRender(POLY *thePoly)
|
static void SetupPolygon(POLY *thePoly)
|
||||||
{
|
{
|
||||||
GLboolean enableDepthWrite = GL_TRUE;
|
static unsigned int lastTexBlendMode = 0;
|
||||||
|
static int lastStencilState = -1;
|
||||||
|
|
||||||
// Get polygon info
|
PolygonAttributes attr = thePoly->getAttributes();
|
||||||
currentPolyAttr = thePoly->getAttributes();
|
|
||||||
|
|
||||||
polyAlpha = 1.0f;
|
// Set up alpha value
|
||||||
if (!currentPolyAttr.isWireframe && currentPolyAttr.isTranslucent)
|
polyAlpha = 1.0f;
|
||||||
|
if (!attr.isWireframe && attr.isTranslucent)
|
||||||
{
|
{
|
||||||
polyAlpha = divide5bitBy31LUT[currentPolyAttr.alpha];
|
polyAlpha = divide5bitBy31LUT[attr.alpha];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isShaderSupported)
|
if (isShaderSupported)
|
||||||
|
@ -1053,20 +1155,11 @@ static void SetupPolygonRender(POLY *thePoly)
|
||||||
glUniform1f(uniformPolyAlpha, polyAlpha);
|
glUniform1f(uniformPolyAlpha, polyAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
cullingMode = map3d_cull[currentPolyAttr.surfaceCullingMode];
|
// Set up depth test mode
|
||||||
depthFuncMode = depthFunc[currentPolyAttr.enableDepthTest];
|
xglDepthFunc(depthFunc[attr.enableDepthTest]);
|
||||||
|
|
||||||
// Set up texture
|
|
||||||
if (gfx3d.renderState.enableTexturing)
|
|
||||||
{
|
|
||||||
currentTexParams = thePoly->getTexParams();
|
|
||||||
setTexture(thePoly->texParam, thePoly->texPalette);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up rendering states
|
|
||||||
xglDepthFunc(depthFuncMode);
|
|
||||||
|
|
||||||
// Cull face
|
// Set up culling mode
|
||||||
|
GLenum cullingMode = map3d_cull[attr.surfaceCullingMode];
|
||||||
if (cullingMode == 0)
|
if (cullingMode == 0)
|
||||||
{
|
{
|
||||||
xglDisable(GL_CULL_FACE);
|
xglDisable(GL_CULL_FACE);
|
||||||
|
@ -1076,22 +1169,25 @@ static void SetupPolygonRender(POLY *thePoly)
|
||||||
xglEnable(GL_CULL_FACE);
|
xglEnable(GL_CULL_FACE);
|
||||||
glCullFace(cullingMode);
|
glCullFace(cullingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(currentPolyAttr.isTranslucent && !currentPolyAttr.enableAlphaDepthWrite)
|
// Set up depth write
|
||||||
|
GLboolean enableDepthWrite = GL_TRUE;
|
||||||
|
if(attr.isTranslucent && !attr.enableAlphaDepthWrite)
|
||||||
{
|
{
|
||||||
enableDepthWrite = GL_FALSE;
|
enableDepthWrite = GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//handle shadow polys
|
// Handle shadow polys. Do this after checking for depth write, since shadow polys
|
||||||
if(currentPolyAttr.polygonMode == 3)
|
// can change this too.
|
||||||
|
if(attr.polygonMode == 3)
|
||||||
{
|
{
|
||||||
xglEnable(GL_STENCIL_TEST);
|
xglEnable(GL_STENCIL_TEST);
|
||||||
if(currentPolyAttr.polygonID == 0)
|
if(attr.polygonID == 0)
|
||||||
{
|
{
|
||||||
enableDepthWrite = GL_FALSE;
|
enableDepthWrite = GL_FALSE;
|
||||||
if(stencilStateSet != 0)
|
if(lastStencilState != 0)
|
||||||
{
|
{
|
||||||
stencilStateSet = 0;
|
lastStencilState = 0;
|
||||||
//when the polyID is zero, we are writing the shadow mask.
|
//when the polyID is zero, we are writing the shadow mask.
|
||||||
//set stencilbuf = 1 where the shadow volume is obstructed by geometry.
|
//set stencilbuf = 1 where the shadow volume is obstructed by geometry.
|
||||||
//do not write color or depth information.
|
//do not write color or depth information.
|
||||||
|
@ -1103,9 +1199,9 @@ static void SetupPolygonRender(POLY *thePoly)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enableDepthWrite = GL_TRUE;
|
enableDepthWrite = GL_TRUE;
|
||||||
if(stencilStateSet != 1)
|
if(lastStencilState != 1)
|
||||||
{
|
{
|
||||||
stencilStateSet = 1;
|
lastStencilState = 1;
|
||||||
//when the polyid is nonzero, we are drawing the shadow poly.
|
//when the polyid is nonzero, we are drawing the shadow poly.
|
||||||
//only draw the shadow poly where the stencilbuf==1.
|
//only draw the shadow poly where the stencilbuf==1.
|
||||||
//I am not sure whether to update the depth buffer here--so I chose not to.
|
//I am not sure whether to update the depth buffer here--so I chose not to.
|
||||||
|
@ -1118,64 +1214,65 @@ static void SetupPolygonRender(POLY *thePoly)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xglEnable(GL_STENCIL_TEST);
|
xglEnable(GL_STENCIL_TEST);
|
||||||
if(currentPolyAttr.isTranslucent)
|
if(attr.isTranslucent)
|
||||||
{
|
{
|
||||||
stencilStateSet = 3;
|
lastStencilState = 3;
|
||||||
glStencilFunc(GL_NOTEQUAL,currentPolyAttr.polygonID,255);
|
glStencilFunc(GL_NOTEQUAL,attr.polygonID,255);
|
||||||
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
|
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
|
||||||
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||||
}
|
}
|
||||||
else if(stencilStateSet != 2)
|
else if(lastStencilState != 2)
|
||||||
{
|
{
|
||||||
stencilStateSet = 2;
|
lastStencilState = 2;
|
||||||
glStencilFunc(GL_ALWAYS,64,255);
|
glStencilFunc(GL_ALWAYS,64,255);
|
||||||
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
|
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
|
||||||
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(currentPolyAttr.polygonMode != lastEnvMode)
|
xglDepthMask(enableDepthWrite);
|
||||||
|
|
||||||
|
// Set up texture blending mode
|
||||||
|
if(attr.polygonMode != lastTexBlendMode)
|
||||||
{
|
{
|
||||||
lastEnvMode = currentPolyAttr.polygonMode;
|
lastTexBlendMode = attr.polygonMode;
|
||||||
|
|
||||||
if(isShaderSupported)
|
if(isShaderSupported)
|
||||||
{
|
{
|
||||||
int _envModes[4] = {0, 1, (2 + gfx3d.renderState.shading), 0};
|
int _envModes[4] = {0, 1, (2 + gfx3d.renderState.shading), 0};
|
||||||
GLint texBlendMode = _envModes[currentPolyAttr.polygonMode];
|
GLint texBlendMode = _envModes[attr.polygonMode];
|
||||||
|
|
||||||
glUniform1i(uniformTextureBlendingMode, texBlendMode);
|
glUniform1i(uniformTextureBlendingMode, texBlendMode);
|
||||||
|
|
||||||
|
// Update the toon table if necessary
|
||||||
if ( toonTableNeedsUpdate && (texBlendMode == 2 || texBlendMode == 3) )
|
if ( toonTableNeedsUpdate && (texBlendMode == 2 || texBlendMode == 3) )
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_1D, oglToonTableTextureID);
|
glBindTexture(GL_TEXTURE_1D, oglToonTableTextureID);
|
||||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, currentToonTable16);
|
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, currentToonTable16);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
toonTableNeedsUpdate = false;
|
toonTableNeedsUpdate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv[currentPolyAttr.polygonMode]);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv[attr.polygonMode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xglDepthMask(enableDepthWrite);
|
static void SetupViewport(POLY *thePoly)
|
||||||
|
{
|
||||||
|
VIEWPORT viewport;
|
||||||
|
viewport.decode(thePoly->viewport);
|
||||||
|
glViewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Control()
|
static void Control()
|
||||||
{
|
{
|
||||||
if (isShaderSupported)
|
if (isShaderSupported)
|
||||||
{
|
{
|
||||||
if (gfx3d.renderState.enableTexturing)
|
|
||||||
{
|
|
||||||
glUniform1i(uniformHasTexture, GL_TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glUniform1i(uniformHasTexture, GL_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gfx3d.renderState.enableAlphaTest)
|
if(gfx3d.renderState.enableAlphaTest)
|
||||||
{
|
{
|
||||||
glUniform1i(uniformEnableAlphaTest, GL_TRUE);
|
glUniform1i(uniformEnableAlphaTest, GL_TRUE);
|
||||||
|
@ -1189,15 +1286,6 @@ static void Control()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gfx3d.renderState.enableTexturing)
|
|
||||||
{
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gfx3d.renderState.enableAlphaTest && (gfx3d.renderState.alphaTestRef > 0))
|
if(gfx3d.renderState.enableAlphaTest && (gfx3d.renderState.alphaTestRef > 0))
|
||||||
{
|
{
|
||||||
glAlphaFunc(GL_GEQUAL, divide5bitBy31LUT[gfx3d.renderState.alphaTestRef]);
|
glAlphaFunc(GL_GEQUAL, divide5bitBy31LUT[gfx3d.renderState.alphaTestRef]);
|
||||||
|
@ -1236,7 +1324,7 @@ static void GL_ReadFramebuffer()
|
||||||
if(!BEGINGL()) return;
|
if(!BEGINGL()) return;
|
||||||
|
|
||||||
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboRenderDataID[bufferIndex]);
|
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboRenderDataID[bufferIndex]);
|
||||||
glReadPixels(0, 0, 256, 192, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0);
|
glReadPixels(0, 0, 256, 192, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||||
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
||||||
|
|
||||||
ENDGL();
|
ENDGL();
|
||||||
|
@ -1453,26 +1541,26 @@ static void OGLRender()
|
||||||
polyPrimitive = frm[poly->vtxFormat];
|
polyPrimitive = frm[poly->vtxFormat];
|
||||||
polyType = poly->type;
|
polyType = poly->type;
|
||||||
|
|
||||||
//a very macro-level state caching approach:
|
// Set up the polygon if it changed
|
||||||
//these are the only things which control the GPU rendering state.
|
if(lastPolyAttr != poly->polyAttr || i == 0)
|
||||||
if(lastPolyAttr != poly->polyAttr ||
|
|
||||||
lastTexParams != poly->texParam ||
|
|
||||||
lastTexPalette != poly->texPalette ||
|
|
||||||
i == 0)
|
|
||||||
{
|
{
|
||||||
lastPolyAttr = poly->polyAttr;
|
lastPolyAttr = poly->polyAttr;
|
||||||
lastTexParams = poly->texParam;
|
SetupPolygon(poly);
|
||||||
lastTexPalette = poly->texPalette;
|
|
||||||
|
|
||||||
SetupPolygonRender(poly);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastViewport != poly->viewport)
|
// Set up the texture if it changed
|
||||||
|
if (lastTexParams != poly->texParam || lastTexPalette != poly->texPalette || i == 0)
|
||||||
|
{
|
||||||
|
lastTexParams = poly->texParam;
|
||||||
|
lastTexPalette = poly->texPalette;
|
||||||
|
SetupTexture(poly);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the viewport if it changed
|
||||||
|
if(lastViewport != poly->viewport || i == 0)
|
||||||
{
|
{
|
||||||
VIEWPORT viewport;
|
|
||||||
viewport.decode(poly->viewport);
|
|
||||||
glViewport(viewport.x,viewport.y,viewport.width,viewport.height);
|
|
||||||
lastViewport = poly->viewport;
|
lastViewport = poly->viewport;
|
||||||
|
SetupViewport(poly);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up vertices
|
// Set up vertices
|
||||||
|
@ -1564,7 +1652,7 @@ static void OGLRender()
|
||||||
// drawing more accurate this way, but it also allows GL_QUADS and
|
// drawing more accurate this way, but it also allows GL_QUADS and
|
||||||
// GL_QUAD_STRIP primitives to properly draw as wireframe without the
|
// GL_QUAD_STRIP primitives to properly draw as wireframe without the
|
||||||
// extra diagonal line.
|
// extra diagonal line.
|
||||||
if (currentPolyAttr.isWireframe)
|
if (poly->isWireframe())
|
||||||
{
|
{
|
||||||
polyPrimitive = GL_LINE_LOOP;
|
polyPrimitive = GL_LINE_LOOP;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue