OpenGL Renderer:
- Do some small optimizations. - Move matrix transforms, texture scaling, and vertex color handling to the shaders. - Tons of code cleanup.
This commit is contained in:
parent
ad1c1e6a18
commit
d43c709c33
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2011 DeSmuME team
|
||||
Copyright (C) 2008-2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -29,11 +29,10 @@
|
|||
#include "debug.h"
|
||||
|
||||
#define VERT_INDEX_BUFFER_SIZE 8192
|
||||
CACHE_ALIGN float material_8bit_to_float[255] = {0};
|
||||
|
||||
bool (*oglrender_init)() = 0;
|
||||
bool (*oglrender_beginOpenGL)() = 0;
|
||||
void (*oglrender_endOpenGL)() = 0;
|
||||
bool (*oglrender_init)() = NULL;
|
||||
bool (*oglrender_beginOpenGL)() = NULL;
|
||||
void (*oglrender_endOpenGL)() = NULL;
|
||||
|
||||
static bool BEGINGL() {
|
||||
if(oglrender_beginOpenGL)
|
||||
|
@ -79,38 +78,61 @@ static void ENDGL() {
|
|||
|
||||
static DS_ALIGN(16) u8 GPU_screen3D [256*192*4];
|
||||
|
||||
static const unsigned short map3d_cull[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||
static const int texEnv[4] = { GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE };
|
||||
static const int depthFunc[2] = { GL_LESS, GL_EQUAL };
|
||||
static const GLenum map3d_cull[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||
static const GLint texEnv[4] = { GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE };
|
||||
static const GLenum depthFunc[2] = { GL_LESS, GL_EQUAL };
|
||||
|
||||
//derived values extracted from polyattr etc
|
||||
static bool wireframe=false, alpha31=false;
|
||||
static unsigned int polyID=0;
|
||||
static unsigned int depthFuncMode=0;
|
||||
static unsigned int envMode=0;
|
||||
static unsigned int lastEnvMode=0;
|
||||
static unsigned int cullingMask=0;
|
||||
static bool alphaDepthWrite;
|
||||
static unsigned int lightMask=0;
|
||||
static bool isTranslucent;
|
||||
/// 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 u32 textureFormat=0, texturePalette=0;
|
||||
static u32 stencilStateSet = -1;
|
||||
|
||||
static char *extString = NULL;
|
||||
|
||||
// ClearImage/Rear-plane (FBO)
|
||||
GLenum oglClearImageTextureID[2] = {0}; // 0 - image, 1 - depth
|
||||
GLuint oglClearImageBuffers = 0;
|
||||
GLuint oglClearImageRender[1] = {0};
|
||||
bool oglFBOdisabled = false;
|
||||
u32 *oglClearImageColor = NULL;
|
||||
float *oglClearImageDepth = NULL;
|
||||
u16 *oglClearImageColorTemp = NULL;
|
||||
u16 *oglClearImageDepthTemp = NULL;
|
||||
u32 oglClearImageScrollOld = 0;
|
||||
static GLenum oglClearImageTextureID[2] = {0}; // 0 - image, 1 - depth
|
||||
static GLuint oglClearImageBuffers = 0;
|
||||
static bool oglFBOdisabled = false;
|
||||
static u32 *oglClearImageColor = NULL;
|
||||
static float *oglClearImageDepth = NULL;
|
||||
static u16 *oglClearImageColorTemp = NULL;
|
||||
static u16 *oglClearImageDepthTemp = NULL;
|
||||
static u32 oglClearImageScrollOld = 0;
|
||||
|
||||
// Shader states
|
||||
static bool hasShaders = false;
|
||||
|
||||
static GLuint vertexShaderID;
|
||||
static GLuint fragmentShaderID;
|
||||
static GLuint shaderProgram;
|
||||
|
||||
static GLint uniformPolyAlpha;
|
||||
static GLint uniformTexScale;
|
||||
static GLint uniformHasTexture;
|
||||
static GLint uniformTextureBlendingMode;
|
||||
static GLint uniformWBuffer;
|
||||
|
||||
static bool hasTexture = false;
|
||||
static TexCacheItem* currTexture = NULL;
|
||||
|
||||
static GLfloat *color4fBuffer = NULL;
|
||||
static GLushort *vertIndexBuffer = NULL;
|
||||
|
||||
static CACHE_ALIGN GLfloat material_8bit_to_float[255] = {0};
|
||||
static const GLfloat divide5bitBy31LUT[32] = {0.0, 0.03225806451613, 0.06451612903226, 0.09677419354839,
|
||||
0.1290322580645, 0.1612903225806, 0.1935483870968, 0.2258064516129,
|
||||
0.258064516129, 0.2903225806452, 0.3225806451613, 0.3548387096774,
|
||||
0.3870967741935, 0.4193548387097, 0.4516129032258, 0.4838709677419,
|
||||
0.5161290322581, 0.5483870967742, 0.5806451612903, 0.6129032258065,
|
||||
0.6451612903226, 0.6774193548387, 0.7096774193548, 0.741935483871,
|
||||
0.7741935483871, 0.8064516129032, 0.8387096774194, 0.8709677419355,
|
||||
0.9032258064516, 0.9354838709677, 0.9677419354839, 1.0};
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
#define OGLEXT(x,y) x y = 0;
|
||||
|
@ -277,19 +299,6 @@ GLenum oglToonTableTextureID;
|
|||
} \
|
||||
}
|
||||
|
||||
bool hasShaders = false;
|
||||
|
||||
GLuint vertexShaderID;
|
||||
GLuint fragmentShaderID;
|
||||
GLuint shaderProgram;
|
||||
|
||||
static GLint hasTexLoc;
|
||||
static GLint texBlendLoc;
|
||||
static GLint oglWBuffer;
|
||||
static bool hasTexture = false;
|
||||
|
||||
static TexCacheItem* currTexture = NULL;
|
||||
|
||||
/* Shaders init */
|
||||
|
||||
static void createShaders()
|
||||
|
@ -360,20 +369,25 @@ static void OGLReset()
|
|||
|
||||
if(BEGINGL())
|
||||
{
|
||||
glUniform1i(hasTexLoc, 0);
|
||||
glUniform1i(texBlendLoc, 0);
|
||||
glUniform1i(oglWBuffer, 0);
|
||||
glUniform1f(uniformPolyAlpha, 1.0f);
|
||||
glUniform2f(uniformTexScale, 1.0f, 1.0f);
|
||||
glUniform1i(uniformHasTexture, 0);
|
||||
glUniform1i(uniformTextureBlendingMode, 0);
|
||||
glUniform1i(uniformWBuffer, 0);
|
||||
|
||||
ENDGL();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
memset(color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
|
||||
}
|
||||
|
||||
TexCache_Reset();
|
||||
if (currTexture)
|
||||
delete currTexture;
|
||||
currTexture = NULL;
|
||||
|
||||
// memset(GPU_screenStencil,0,sizeof(GPU_screenStencil));
|
||||
memset(GPU_screen3D,0,sizeof(GPU_screen3D));
|
||||
|
||||
if (!oglFBOdisabled)
|
||||
|
@ -385,7 +399,6 @@ static void OGLReset()
|
|||
oglClearImageScrollOld = 0;
|
||||
}
|
||||
|
||||
memset(color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
|
||||
memset(vertIndexBuffer, 0, VERT_INDEX_BUFFER_SIZE * sizeof(GLushort));
|
||||
}
|
||||
|
||||
|
@ -444,7 +457,7 @@ static char OGLInit(void)
|
|||
return 0;
|
||||
|
||||
for (u8 i = 0; i < 255; i++)
|
||||
material_8bit_to_float[i] = (float)(i<<2)/255.f;
|
||||
material_8bit_to_float[i] = (GLfloat)(i<<2)/255.f;
|
||||
|
||||
extString = (char*)glGetString(GL_EXTENSIONS);
|
||||
|
||||
|
@ -516,12 +529,12 @@ static char OGLInit(void)
|
|||
|
||||
loc = glGetUniformLocation(shaderProgram, "toonTable");
|
||||
glUniform1i(loc, 1);
|
||||
|
||||
hasTexLoc = glGetUniformLocation(shaderProgram, "hasTexture");
|
||||
|
||||
texBlendLoc = glGetUniformLocation(shaderProgram, "texBlending");
|
||||
|
||||
oglWBuffer = glGetUniformLocation(shaderProgram, "oglWBuffer");
|
||||
|
||||
uniformPolyAlpha = glGetUniformLocation(shaderProgram, "polyAlpha");
|
||||
uniformTexScale = glGetUniformLocation(shaderProgram, "texScale");
|
||||
uniformHasTexture = glGetUniformLocation(shaderProgram, "hasTexture");
|
||||
uniformTextureBlendingMode = glGetUniformLocation(shaderProgram, "texBlending");
|
||||
uniformWBuffer = glGetUniformLocation(shaderProgram, "oglWBuffer");
|
||||
}
|
||||
|
||||
//we want to use alpha destination blending so we can track the last-rendered alpha value
|
||||
|
@ -554,6 +567,14 @@ static char OGLInit(void)
|
|||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rgbToonTable[0]);
|
||||
gfx3d.state.invalidateToon = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Map the vertex list's colors with 4 floats per color. This is being done
|
||||
// because OpenGL needs 4-colors per vertex to support translucency. (The DS
|
||||
// uses 3-colors per vertex, and adds alpha through the poly, so we can't
|
||||
// simply reference the colors+alpha from just the vertices themselves.)
|
||||
color4fBuffer = new GLfloat[VERTLIST_SIZE * 4];
|
||||
}
|
||||
|
||||
// FBO
|
||||
oglFBOdisabled = (strstr(extString, "GL_ARB_framebuffer_object") == NULL)?true:false;
|
||||
|
@ -612,12 +633,6 @@ static char OGLInit(void)
|
|||
|
||||
ENDGL();
|
||||
|
||||
// Map the vertex list's colors with 4 floats per color. This is being done
|
||||
// because OpenGL needs 4-colors per vertex to support translucency. (The DS
|
||||
// uses 3-colors per vertex, and adds alpha through the poly, so we can't
|
||||
// simply reference the colors+alpha from just the vertices themselves.)
|
||||
color4fBuffer = new GLfloat[VERTLIST_SIZE * 4];
|
||||
|
||||
// Make our own vertex index buffer for primitive conversions. This is
|
||||
// necessary since OpenGL deprecates primitives like GL_QUADS and
|
||||
// GL_QUAD_STRIP in later versions. (Maybe we can also use the buffer for
|
||||
|
@ -631,9 +646,6 @@ static char OGLInit(void)
|
|||
|
||||
static void OGLClose()
|
||||
{
|
||||
delete [] color4fBuffer;
|
||||
color4fBuffer = NULL;
|
||||
|
||||
delete [] vertIndexBuffer;
|
||||
vertIndexBuffer = NULL;
|
||||
|
||||
|
@ -653,6 +665,11 @@ static void OGLClose()
|
|||
|
||||
hasShaders = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete [] color4fBuffer;
|
||||
color4fBuffer = NULL;
|
||||
}
|
||||
|
||||
//kill the tex cache to free all the texture ids
|
||||
TexCache_Reset();
|
||||
|
@ -710,25 +727,15 @@ static void texDeleteCallback(TexCacheItem* item)
|
|||
|
||||
static void setTexture(unsigned int format, unsigned int texpal)
|
||||
{
|
||||
textureFormat = format;
|
||||
texturePalette = texpal;
|
||||
|
||||
u32 textureMode = (unsigned short)((format>>26)&0x07);
|
||||
|
||||
if (format==0)
|
||||
if (format == 0 || currentTexParams.texFormat == TEXMODE_NONE)
|
||||
{
|
||||
if(hasShaders && hasTexture) { glUniform1i(hasTexLoc, 0); hasTexture = false; }
|
||||
return;
|
||||
}
|
||||
if (textureMode==0)
|
||||
{
|
||||
if(hasShaders && hasTexture) { glUniform1i(hasTexLoc, 0); hasTexture = false; }
|
||||
if(hasShaders && hasTexture) { glUniform1i(uniformHasTexture, 0); hasTexture = false; }
|
||||
return;
|
||||
}
|
||||
|
||||
if(hasShaders)
|
||||
{
|
||||
if(!hasTexture) { glUniform1i(hasTexLoc, 1); hasTexture = true; }
|
||||
if(!hasTexture) { glUniform1i(uniformHasTexture, 1); hasTexture = true; }
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
|
@ -765,53 +772,69 @@ static void setTexture(unsigned int format, unsigned int texpal)
|
|||
}
|
||||
|
||||
//in either case, we need to setup the tex mtx
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glScalef(currTexture->invSizeX, currTexture->invSizeY, 1.0f);
|
||||
|
||||
if (hasShaders)
|
||||
{
|
||||
glUniform2f(uniformTexScale, currTexture->invSizeX, currTexture->invSizeY);
|
||||
}
|
||||
else
|
||||
{
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glScalef(currTexture->invSizeX, currTexture->invSizeY, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//controls states:
|
||||
//glStencilFunc
|
||||
//glStencilOp
|
||||
//glColorMask
|
||||
static u32 stencilStateSet = -1;
|
||||
|
||||
static u32 polyalpha=0;
|
||||
|
||||
static void BeginRenderPoly()
|
||||
static void SetupPolygonRender(POLY *thePoly)
|
||||
{
|
||||
bool enableDepthWrite = true;
|
||||
|
||||
|
||||
// Get polygon info
|
||||
currentPolyAttr = thePoly->getAttributes();
|
||||
|
||||
polyAlpha = 1.0f;
|
||||
if (!currentPolyAttr.isWireframe && currentPolyAttr.isTranslucent)
|
||||
{
|
||||
polyAlpha = divide5bitBy31LUT[currentPolyAttr.alpha];
|
||||
}
|
||||
|
||||
if (hasShaders)
|
||||
{
|
||||
glUniform1f(uniformPolyAlpha, polyAlpha);
|
||||
}
|
||||
|
||||
cullingMode = map3d_cull[currentPolyAttr.surfaceCullingMode];
|
||||
depthFuncMode = depthFunc[currentPolyAttr.enableDepthTest];
|
||||
|
||||
// Set up texture
|
||||
if (gfx3d.renderState.enableTexturing)
|
||||
{
|
||||
currentTexParams = thePoly->getTexParams();
|
||||
setTexture(thePoly->texParam, thePoly->texPalette);
|
||||
}
|
||||
|
||||
// Set up rendering states
|
||||
xglDepthFunc (depthFuncMode);
|
||||
|
||||
// Cull face
|
||||
if (cullingMask == 0x03)
|
||||
if (cullingMode == 0)
|
||||
{
|
||||
xglDisable(GL_CULL_FACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
xglEnable(GL_CULL_FACE);
|
||||
glCullFace(map3d_cull[cullingMask]);
|
||||
}
|
||||
|
||||
if (gfx3d.renderState.enableTexturing)
|
||||
{
|
||||
setTexture(textureFormat, texturePalette);
|
||||
glCullFace(cullingMode);
|
||||
}
|
||||
|
||||
if(isTranslucent)
|
||||
enableDepthWrite = alphaDepthWrite;
|
||||
if(currentPolyAttr.isTranslucent)
|
||||
enableDepthWrite = currentPolyAttr.enableAlphaDepthWrite;
|
||||
|
||||
//handle shadow polys
|
||||
if(envMode == 3)
|
||||
if(currentPolyAttr.polygonMode == 3)
|
||||
{
|
||||
xglEnable(GL_STENCIL_TEST);
|
||||
if(polyID == 0) {
|
||||
if(currentPolyAttr.polygonID == 0) {
|
||||
enableDepthWrite = false;
|
||||
if(stencilStateSet!=0) {
|
||||
stencilStateSet = 0;
|
||||
|
@ -836,10 +859,10 @@ static void BeginRenderPoly()
|
|||
}
|
||||
} else {
|
||||
xglEnable(GL_STENCIL_TEST);
|
||||
if(isTranslucent)
|
||||
if(currentPolyAttr.isTranslucent)
|
||||
{
|
||||
stencilStateSet = 3;
|
||||
glStencilFunc(GL_NOTEQUAL,polyID,255);
|
||||
glStencilFunc(GL_NOTEQUAL,currentPolyAttr.polygonID,255);
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
|
||||
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
}
|
||||
|
@ -851,58 +874,32 @@ static void BeginRenderPoly()
|
|||
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv[envMode]);
|
||||
|
||||
if(hasShaders)
|
||||
|
||||
if(currentPolyAttr.polygonMode != lastEnvMode)
|
||||
{
|
||||
if(envMode != lastEnvMode)
|
||||
lastEnvMode = currentPolyAttr.polygonMode;
|
||||
|
||||
if(hasShaders)
|
||||
{
|
||||
lastEnvMode = envMode;
|
||||
|
||||
int _envModes[4] = {0, 1, (2 + gfx3d.renderState.shading), 0};
|
||||
glUniform1i(texBlendLoc, _envModes[envMode]);
|
||||
glUniform1i(uniformTextureBlendingMode, _envModes[currentPolyAttr.polygonMode]);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv[currentPolyAttr.polygonMode]);
|
||||
}
|
||||
}
|
||||
|
||||
xglDepthMask(enableDepthWrite?GL_TRUE:GL_FALSE);
|
||||
}
|
||||
|
||||
static void InstallPolygonAttrib(u32 val)
|
||||
{
|
||||
// Light enable/disable
|
||||
lightMask = (val&0xF);
|
||||
|
||||
// texture environment
|
||||
envMode = (val&0x30)>>4;
|
||||
|
||||
// overwrite depth on alpha pass
|
||||
alphaDepthWrite = BIT11(val)!=0;
|
||||
|
||||
// depth test function
|
||||
depthFuncMode = depthFunc[BIT14(val)];
|
||||
|
||||
// back face culling
|
||||
cullingMask = (val >> 6) & 0x03;
|
||||
|
||||
alpha31 = ((val>>16)&0x1F)==31;
|
||||
|
||||
// Alpha value, actually not well handled, 0 should be wireframe
|
||||
wireframe = ((val>>16)&0x1F)==0;
|
||||
|
||||
polyalpha = ((val>>16)&0x1F);
|
||||
|
||||
// polyID
|
||||
polyID = (val>>24)&0x3F;
|
||||
}
|
||||
|
||||
static void Control()
|
||||
{
|
||||
if (gfx3d.renderState.enableTexturing)
|
||||
{
|
||||
if (hasShaders)
|
||||
{
|
||||
glUniform1i(hasTexLoc, 1);
|
||||
glUniform1i(uniformHasTexture, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -913,7 +910,7 @@ static void Control()
|
|||
{
|
||||
if (hasShaders)
|
||||
{
|
||||
glUniform1i(hasTexLoc, 0);
|
||||
glUniform1i(uniformHasTexture, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -921,19 +918,22 @@ static void Control()
|
|||
}
|
||||
}
|
||||
|
||||
if(gfx3d.renderState.enableAlphaTest)
|
||||
// FIXME: alpha test should pass gfx3d.alphaTestRef==poly->getAlpha
|
||||
glAlphaFunc (GL_GREATER, gfx3d.renderState.alphaTestRef/31.f);
|
||||
else
|
||||
glAlphaFunc (GL_GREATER, 0);
|
||||
|
||||
if(gfx3d.renderState.enableAlphaBlending)
|
||||
if(gfx3d.renderState.enableAlphaTest && (gfx3d.renderState.alphaTestRef > 0))
|
||||
{
|
||||
glEnable (GL_BLEND);
|
||||
glAlphaFunc(GL_GEQUAL, divide5bitBy31LUT[gfx3d.renderState.alphaTestRef]);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable (GL_BLEND);
|
||||
glAlphaFunc(GL_GREATER, 0);
|
||||
}
|
||||
|
||||
if(gfx3d.renderState.enableAlphaBlending)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -941,8 +941,7 @@ static void Control()
|
|||
static void GL_ReadFramebuffer()
|
||||
{
|
||||
if(!BEGINGL()) return;
|
||||
// glReadPixels(0,0,256,192,GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, GPU_screenStencil);
|
||||
glReadPixels(0,0,256,192,GL_BGRA_EXT, GL_UNSIGNED_BYTE, GPU_screen3D);
|
||||
glReadPixels(0, 0, 256, 192, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GPU_screen3D);
|
||||
ENDGL();
|
||||
|
||||
//convert the pixels to a different format which is more convenient
|
||||
|
@ -1099,7 +1098,7 @@ static void OGLRender()
|
|||
gfx3d.state.invalidateToon = false;
|
||||
}
|
||||
|
||||
glUniform1i(oglWBuffer, gfx3d.renderState.wbuffer);
|
||||
glUniform1i(uniformWBuffer, gfx3d.renderState.wbuffer);
|
||||
}
|
||||
|
||||
xglDepthMask(GL_TRUE);
|
||||
|
@ -1111,14 +1110,15 @@ static void OGLRender()
|
|||
oglClearImageFBO();
|
||||
else
|
||||
{
|
||||
float clearColor[4] = {
|
||||
((float)(gfx3d.renderState.clearColor&0x1F))/31.0f,
|
||||
((float)((gfx3d.renderState.clearColor>>5)&0x1F))/31.0f,
|
||||
((float)((gfx3d.renderState.clearColor>>10)&0x1F))/31.0f,
|
||||
((float)((gfx3d.renderState.clearColor>>16)&0x1F))/31.0f,
|
||||
GLfloat clearColor[4] = {
|
||||
divide5bitBy31LUT[gfx3d.renderState.clearColor & 0x1F],
|
||||
divide5bitBy31LUT[(gfx3d.renderState.clearColor >> 5) & 0x1F],
|
||||
divide5bitBy31LUT[(gfx3d.renderState.clearColor >> 10) & 0x1F],
|
||||
divide5bitBy31LUT[(gfx3d.renderState.clearColor >> 16) & 0x1F]
|
||||
};
|
||||
|
||||
glClearColor(clearColor[0],clearColor[1],clearColor[2],clearColor[3]);
|
||||
glClearDepth((float)gfx3d.renderState.clearDepth / (float)0x00FFFFFF);
|
||||
glClearDepth((GLfloat)gfx3d.renderState.clearDepth / (GLfloat)0x00FFFFFF);
|
||||
clearFlag |= GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
|
@ -1133,10 +1133,11 @@ static void OGLRender()
|
|||
//render display list
|
||||
//TODO - properly doublebuffer the display lists
|
||||
{
|
||||
|
||||
u32 lastTextureFormat = 0, lastTexturePalette = 0, lastPolyAttr = 0, lastViewport = 0xFFFFFFFF;
|
||||
// int lastProjIndex = -1;
|
||||
|
||||
u32 lastTexParams = 0;
|
||||
u32 lastTexPalette = 0;
|
||||
u32 lastPolyAttr = 0;
|
||||
u32 lastViewport = 0xFFFFFFFF;
|
||||
unsigned int polyCount = gfx3d.polylist->count;
|
||||
unsigned int vertIndexCount = 0;
|
||||
GLenum polyPrimitive = 0;
|
||||
unsigned int polyType = 0;
|
||||
|
@ -1145,25 +1146,33 @@ static void OGLRender()
|
|||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
if (hasShaders)
|
||||
{
|
||||
glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VERT), &gfx3d.vertlist->list[0].color);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColorPointer(4, GL_FLOAT, 0, color4fBuffer);
|
||||
}
|
||||
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), &gfx3d.vertlist->list[0].texcoord);
|
||||
glColorPointer(4, GL_FLOAT, 0, color4fBuffer);
|
||||
glVertexPointer(4, GL_FLOAT, sizeof(VERT), &gfx3d.vertlist->list[0].coord);
|
||||
|
||||
for(int i=0;i<gfx3d.polylist->count;i++) {
|
||||
|
||||
for(unsigned int i = 0; i < polyCount; i++)
|
||||
{
|
||||
POLY *poly = &gfx3d.polylist->list[gfx3d.indexlist.list[i]];
|
||||
polyPrimitive = frm[poly->vtxFormat];
|
||||
polyType = poly->type;
|
||||
|
||||
//a very macro-level state caching approach:
|
||||
//these are the only things which control the GPU rendering state.
|
||||
if(i==0 || lastTextureFormat != poly->texParam || lastTexturePalette != poly->texPalette || lastPolyAttr != poly->polyAttr)
|
||||
if(lastPolyAttr != poly->polyAttr || lastTexParams != poly->texParam || lastTexPalette != poly->texPalette || i == 0)
|
||||
{
|
||||
isTranslucent = poly->isTranslucent();
|
||||
InstallPolygonAttrib(poly->polyAttr);
|
||||
lastTextureFormat = textureFormat = poly->texParam;
|
||||
lastTexturePalette = texturePalette = poly->texPalette;
|
||||
lastPolyAttr = poly->polyAttr;
|
||||
BeginRenderPoly();
|
||||
lastPolyAttr = poly->polyAttr;
|
||||
lastTexParams = poly->texParam;
|
||||
lastTexPalette = poly->texPalette;
|
||||
|
||||
SetupPolygonRender(poly);
|
||||
}
|
||||
|
||||
if(lastViewport != poly->viewport)
|
||||
|
@ -1174,38 +1183,60 @@ static void OGLRender()
|
|||
lastViewport = poly->viewport;
|
||||
}
|
||||
|
||||
// Consolidate the vertex color and the poly alpha to our internal color buffer
|
||||
// so that OpenGL can use it.
|
||||
GLfloat alpha = 1.0f;
|
||||
if (!wireframe && isTranslucent)
|
||||
// Set up vertices
|
||||
if (hasShaders)
|
||||
{
|
||||
alpha = (GLfloat)(poly->getAlpha() / 31.0f);
|
||||
}
|
||||
|
||||
for(unsigned int j = 0; j < polyType; j++)
|
||||
{
|
||||
GLushort vertIndex = poly->vertIndexes[j];
|
||||
VERT *vert = &gfx3d.vertlist->list[vertIndex];
|
||||
|
||||
color4fBuffer[(4*vertIndex)+0] = material_8bit_to_float[vert->color[0]];
|
||||
color4fBuffer[(4*vertIndex)+1] = material_8bit_to_float[vert->color[1]];
|
||||
color4fBuffer[(4*vertIndex)+2] = material_8bit_to_float[vert->color[2]];
|
||||
color4fBuffer[(4*vertIndex)+3] = alpha;
|
||||
|
||||
// While we're looping through our vertices, add each vertex index to
|
||||
// a buffer. For GL_QUADS and GL_QUAD_STRIP, we also add additional vertices
|
||||
// here to convert them to GL_TRIANGLES, which are much easier to work with
|
||||
// and won't be deprecated in future OpenGL versions.
|
||||
vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
if (polyPrimitive == GL_QUADS || polyPrimitive == GL_QUAD_STRIP)
|
||||
for(unsigned int j = 0; j < polyType; j++)
|
||||
{
|
||||
if (j == 2)
|
||||
GLushort vertIndex = poly->vertIndexes[j];
|
||||
|
||||
// While we're looping through our vertices, add each vertex index to
|
||||
// a buffer. For GL_QUADS and GL_QUAD_STRIP, we also add additional vertices
|
||||
// here to convert them to GL_TRIANGLES, which are much easier to work with
|
||||
// and won't be deprecated in future OpenGL versions.
|
||||
vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
if (polyPrimitive == GL_QUADS || polyPrimitive == GL_QUAD_STRIP)
|
||||
{
|
||||
vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
if (j == 2)
|
||||
{
|
||||
vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
}
|
||||
else if (j == 3)
|
||||
{
|
||||
vertIndexBuffer[vertIndexCount++] = poly->vertIndexes[0];
|
||||
}
|
||||
}
|
||||
else if (j == 3)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int j = 0; j < polyType; j++)
|
||||
{
|
||||
GLushort vertIndex = poly->vertIndexes[j];
|
||||
|
||||
// Consolidate the vertex color and the poly alpha to our internal color buffer
|
||||
// so that OpenGL can use it.
|
||||
VERT *vert = &gfx3d.vertlist->list[vertIndex];
|
||||
color4fBuffer[(4*vertIndex)+0] = material_8bit_to_float[vert->color[0]];
|
||||
color4fBuffer[(4*vertIndex)+1] = material_8bit_to_float[vert->color[1]];
|
||||
color4fBuffer[(4*vertIndex)+2] = material_8bit_to_float[vert->color[2]];
|
||||
color4fBuffer[(4*vertIndex)+3] = polyAlpha;
|
||||
|
||||
// While we're looping through our vertices, add each vertex index to
|
||||
// a buffer. For GL_QUADS and GL_QUAD_STRIP, we also add additional vertices
|
||||
// here to convert them to GL_TRIANGLES, which are much easier to work with
|
||||
// and won't be deprecated in future OpenGL versions.
|
||||
vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
if (polyPrimitive == GL_QUADS || polyPrimitive == GL_QUAD_STRIP)
|
||||
{
|
||||
vertIndexBuffer[vertIndexCount++] = poly->vertIndexes[0];
|
||||
if (j == 2)
|
||||
{
|
||||
vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
}
|
||||
else if (j == 3)
|
||||
{
|
||||
vertIndexBuffer[vertIndexCount++] = poly->vertIndexes[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1215,7 +1246,7 @@ static void OGLRender()
|
|||
// drawing more accurate this way, but it also allows GL_QUADS and
|
||||
// GL_QUAD_STRIP primitives to properly draw as wireframe without the
|
||||
// extra diagonal line.
|
||||
if (wireframe)
|
||||
if (currentPolyAttr.isWireframe)
|
||||
{
|
||||
polyPrimitive = GL_LINE_LOOP;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2011 DeSmuME team
|
||||
Copyright (C) 2008-2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -119,14 +119,89 @@ inline u32 gfx3d_extendDepth_15_to_24(u32 depth)
|
|||
else return depth<<9;
|
||||
}
|
||||
|
||||
#define TEXMODE_NONE 0
|
||||
#define TEXMODE_A3I5 1
|
||||
#define TEXMODE_I2 2
|
||||
#define TEXMODE_I4 3
|
||||
#define TEXMODE_I8 4
|
||||
#define TEXMODE_4X4 5
|
||||
#define TEXMODE_A5I3 6
|
||||
#define TEXMODE_16BPP 7
|
||||
// POLYGON ATTRIBUTES - BIT LOCATIONS
|
||||
enum
|
||||
{
|
||||
POLYGON_ATTR_ENABLE_LIGHT0_BIT = 0,
|
||||
POLYGON_ATTR_ENABLE_LIGHT1_BIT = 1,
|
||||
POLYGON_ATTR_ENABLE_LIGHT2_BIT = 2,
|
||||
POLYGON_ATTR_ENABLE_LIGHT3_BIT = 3,
|
||||
POLYGON_ATTR_MODE_BIT = 4, // Bits 4 - 5
|
||||
POLYGON_ATTR_ENABLE_BACK_SURFACE_BIT = 6,
|
||||
POLYGON_ATTR_ENABLE_FRONT_SURFACE_BIT = 7,
|
||||
// Bits 8 - 10 unused
|
||||
POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_BIT = 11,
|
||||
POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_BIT = 12,
|
||||
POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_BIT = 13,
|
||||
POLYGON_ATTR_ENABLE_DEPTH_TEST_BIT = 14,
|
||||
POLYGON_ATTR_ENABLE_FOG_BIT = 15,
|
||||
POLYGON_ATTR_ALPHA_BIT = 16, // Bits 16 - 20
|
||||
// Bits 21 - 23 unused
|
||||
POLYGON_ATTR_POLYGON_ID_BIT = 24, // Bits 24 - 29
|
||||
// Bits 30 - 31 unused
|
||||
};
|
||||
|
||||
// POLYGON ATTRIBUTES - BIT MASKS
|
||||
enum
|
||||
{
|
||||
POLYGON_ATTR_ENABLE_LIGHT0_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT0_BIT,
|
||||
POLYGON_ATTR_ENABLE_LIGHT1_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT1_BIT,
|
||||
POLYGON_ATTR_ENABLE_LIGHT2_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT2_BIT,
|
||||
POLYGON_ATTR_ENABLE_LIGHT3_MASK = 0x01 << POLYGON_ATTR_ENABLE_LIGHT3_BIT,
|
||||
POLYGON_ATTR_MODE_MASK = 0x03 << POLYGON_ATTR_MODE_BIT,
|
||||
POLYGON_ATTR_ENABLE_BACK_SURFACE_MASK = 0x01 << POLYGON_ATTR_ENABLE_BACK_SURFACE_BIT,
|
||||
POLYGON_ATTR_ENABLE_FRONT_SURFACE_MASK = 0x01 << POLYGON_ATTR_ENABLE_FRONT_SURFACE_BIT,
|
||||
POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_MASK = 0x01 << POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_BIT,
|
||||
POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_MASK = 0x01 << POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_BIT,
|
||||
POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_MASK = 0x01 << POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_BIT,
|
||||
POLYGON_ATTR_ENABLE_DEPTH_TEST_MASK = 0x01 << POLYGON_ATTR_ENABLE_DEPTH_TEST_BIT,
|
||||
POLYGON_ATTR_ENABLE_FOG_MASK = 0x01 << POLYGON_ATTR_ENABLE_FOG_BIT,
|
||||
POLYGON_ATTR_ALPHA_MASK = 0x1F << POLYGON_ATTR_ALPHA_BIT,
|
||||
POLYGON_ATTR_POLYGON_ID_MASK = 0x3F << POLYGON_ATTR_POLYGON_ID_BIT
|
||||
};
|
||||
|
||||
// TEXTURE PARAMETERS - BIT LOCATIONS
|
||||
enum
|
||||
{
|
||||
TEXTURE_PARAM_VRAM_OFFSET_BIT = 0, // Bits 0 - 15
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_S_BIT = 16,
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_T_BIT = 17,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_BIT = 18,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_BIT = 19,
|
||||
TEXTURE_PARAM_SIZE_S_BIT = 20, // Bits 20 - 22
|
||||
TEXTURE_PARAM_SIZE_T_BIT = 23, // Bits 23 - 25
|
||||
TEXTURE_PARAM_FORMAT_BIT = 26, // Bits 26 - 28
|
||||
TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_BIT = 29,
|
||||
TEXTURE_PARAM_COORD_TRANSFORM_MODE_BIT = 30 // Bits 30 - 31
|
||||
};
|
||||
|
||||
// TEXTURE PARAMETERS - BIT MASKS
|
||||
enum
|
||||
{
|
||||
TEXTURE_PARAM_VRAM_OFFSET_MASK = 0xFFFF << TEXTURE_PARAM_VRAM_OFFSET_BIT,
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_S_MASK = 0x01 << TEXTURE_PARAM_ENABLE_REPEAT_S_BIT,
|
||||
TEXTURE_PARAM_ENABLE_REPEAT_T_MASK = 0x01 << TEXTURE_PARAM_ENABLE_REPEAT_T_BIT,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_MASK = 0x01 << TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_BIT,
|
||||
TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_MASK = 0x01 << TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_BIT,
|
||||
TEXTURE_PARAM_SIZE_S_MASK = 0x07 << TEXTURE_PARAM_SIZE_S_BIT,
|
||||
TEXTURE_PARAM_SIZE_T_MASK = 0x07 << TEXTURE_PARAM_SIZE_T_BIT,
|
||||
TEXTURE_PARAM_FORMAT_MASK = 0x07 << TEXTURE_PARAM_FORMAT_BIT,
|
||||
TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_MASK = 0x01 << TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_BIT,
|
||||
TEXTURE_PARAM_COORD_TRANSFORM_MODE_MASK = 0x03 << TEXTURE_PARAM_COORD_TRANSFORM_MODE_BIT
|
||||
};
|
||||
|
||||
// TEXTURE PARAMETERS - FORMAT ID
|
||||
enum
|
||||
{
|
||||
TEXMODE_NONE = 0,
|
||||
TEXMODE_A3I5 = 1,
|
||||
TEXMODE_I2 = 2,
|
||||
TEXMODE_I4 = 3,
|
||||
TEXMODE_I8 = 4,
|
||||
TEXMODE_4X4 = 5,
|
||||
TEXMODE_A5I3 = 6,
|
||||
TEXMODE_16BPP = 7
|
||||
};
|
||||
|
||||
void gfx3d_init();
|
||||
void gfx3d_reset();
|
||||
|
@ -134,6 +209,43 @@ void gfx3d_reset();
|
|||
#define OSWRITE(x) os->fwrite((char*)&(x),sizeof((x)));
|
||||
#define OSREAD(x) is->fread((char*)&(x),sizeof((x)));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 enableLightFlags;
|
||||
bool enableLight0;
|
||||
bool enableLight1;
|
||||
bool enableLight2;
|
||||
bool enableLight3;
|
||||
u8 polygonMode;
|
||||
u8 surfaceCullingMode;
|
||||
bool enableRenderBackSurface;
|
||||
bool enableRenderFrontSurface;
|
||||
bool enableAlphaDepthWrite;
|
||||
bool enableRenderOnFarPlaneIntersect;
|
||||
bool enableRenderOneDot;
|
||||
bool enableDepthTest;
|
||||
bool enableRenderFog;
|
||||
bool isWireframe;
|
||||
bool isOpaque;
|
||||
bool isTranslucent;
|
||||
u8 alpha;
|
||||
u8 polygonID;
|
||||
} PolygonAttributes;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 VRAMOffset;
|
||||
bool enableRepeatS;
|
||||
bool enableRepeatT;
|
||||
bool enableMirroredRepeatS;
|
||||
bool enableMirroredRepeatT;
|
||||
u8 sizeS;
|
||||
u8 sizeT;
|
||||
u8 texFormat;
|
||||
bool enableTransparentColor0;
|
||||
u8 coordTransformMode;
|
||||
} PolygonTexParams;
|
||||
|
||||
struct POLY {
|
||||
int type; //tri or quad
|
||||
u8 vtxFormat;
|
||||
|
@ -150,24 +262,215 @@ struct POLY {
|
|||
if(d != -1) { vertIndexes[3] = d; type = 4; }
|
||||
else type = 3;
|
||||
}
|
||||
|
||||
|
||||
u8 getAttributeEnableLightFlags()
|
||||
{
|
||||
return ((polyAttr & (POLYGON_ATTR_ENABLE_LIGHT0_MASK |
|
||||
POLYGON_ATTR_ENABLE_LIGHT1_MASK |
|
||||
POLYGON_ATTR_ENABLE_LIGHT2_MASK |
|
||||
POLYGON_ATTR_ENABLE_LIGHT3_MASK)) >> POLYGON_ATTR_ENABLE_LIGHT0_BIT);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight0()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT0_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight1()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT1_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight2()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT2_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableLight3()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_LIGHT3_MASK) > 0);
|
||||
}
|
||||
|
||||
u8 getAttributePolygonMode()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_MODE_MASK) >> POLYGON_ATTR_MODE_BIT);
|
||||
}
|
||||
|
||||
u8 getAttributeEnableFaceCullingFlags()
|
||||
{
|
||||
return ((polyAttr & (POLYGON_ATTR_ENABLE_BACK_SURFACE_MASK |
|
||||
POLYGON_ATTR_ENABLE_FRONT_SURFACE_MASK)) >> POLYGON_ATTR_ENABLE_BACK_SURFACE_BIT);
|
||||
}
|
||||
|
||||
bool getAttributeEnableBackSurface()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_BACK_SURFACE_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableFrontSurface()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_FRONT_SURFACE_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableAlphaDepthWrite()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_ALPHA_DEPTH_WRITE_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableRenderOnFarPlaneIntersect()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_RENDER_ON_FAR_PLANE_INTERSECT_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableOneDotRender()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_ONE_DOT_RENDER_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableDepthTest()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_DEPTH_TEST_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getAttributeEnableFog()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ENABLE_FOG_MASK) > 0);
|
||||
}
|
||||
|
||||
u8 getAttributeAlpha()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_ALPHA_MASK) >> POLYGON_ATTR_ALPHA_BIT);
|
||||
}
|
||||
|
||||
u8 getAttributePolygonID()
|
||||
{
|
||||
return ((polyAttr & POLYGON_ATTR_POLYGON_ID_MASK) >> POLYGON_ATTR_POLYGON_ID_BIT);
|
||||
}
|
||||
|
||||
PolygonAttributes getAttributes()
|
||||
{
|
||||
PolygonAttributes theAttr;
|
||||
|
||||
theAttr.enableLightFlags = this->getAttributeEnableLightFlags();
|
||||
theAttr.enableLight0 = this->getAttributeEnableLight0();
|
||||
theAttr.enableLight1 = this->getAttributeEnableLight1();
|
||||
theAttr.enableLight2 = this->getAttributeEnableLight2();
|
||||
theAttr.enableLight3 = this->getAttributeEnableLight3();
|
||||
theAttr.polygonMode = this->getAttributePolygonMode();
|
||||
theAttr.surfaceCullingMode = this->getAttributeEnableFaceCullingFlags();
|
||||
theAttr.enableRenderBackSurface = this->getAttributeEnableBackSurface();
|
||||
theAttr.enableRenderFrontSurface = this->getAttributeEnableFrontSurface();
|
||||
theAttr.enableAlphaDepthWrite = this->getAttributeEnableAlphaDepthWrite();
|
||||
theAttr.enableRenderOnFarPlaneIntersect = this->getAttributeEnableRenderOnFarPlaneIntersect();
|
||||
theAttr.enableRenderOneDot = this->getAttributeEnableOneDotRender();
|
||||
theAttr.enableDepthTest = this->getAttributeEnableDepthTest();
|
||||
theAttr.enableRenderFog = this->getAttributeEnableFog();
|
||||
theAttr.alpha = this->getAttributeAlpha();
|
||||
theAttr.isWireframe = this->isWireframe();
|
||||
theAttr.isOpaque = this->isOpaque();
|
||||
theAttr.isTranslucent = this->isTranslucent();
|
||||
theAttr.polygonID = this->getAttributePolygonID();
|
||||
|
||||
return theAttr;
|
||||
}
|
||||
|
||||
u16 getTexParamVRAMOffset()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_VRAM_OFFSET_MASK) >> TEXTURE_PARAM_VRAM_OFFSET_BIT);
|
||||
}
|
||||
|
||||
bool getTexParamEnableRepeatS()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_REPEAT_S_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getTexParamEnableRepeatT()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_REPEAT_T_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getTexParamEnableMirroredRepeatS()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_S_MASK) > 0);
|
||||
}
|
||||
|
||||
bool getTexParamEnableMirroredRepeatT()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_MIRRORED_REPEAT_T_MASK) > 0);
|
||||
}
|
||||
|
||||
u8 getTexParamSizeS()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_SIZE_S_MASK) >> TEXTURE_PARAM_SIZE_S_BIT);
|
||||
}
|
||||
|
||||
u8 getTexParamSizeT()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_SIZE_T_MASK) >> TEXTURE_PARAM_SIZE_T_BIT);
|
||||
}
|
||||
|
||||
u8 getTexParamTexFormat()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_FORMAT_MASK) >> TEXTURE_PARAM_FORMAT_BIT);
|
||||
}
|
||||
|
||||
bool getTexParamEnableTransparentColor0()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_ENABLE_TRANSPARENT_COLOR0_MASK) > 0);
|
||||
}
|
||||
|
||||
u8 getTexParamCoordTransformMode()
|
||||
{
|
||||
return ((texParam & TEXTURE_PARAM_COORD_TRANSFORM_MODE_MASK) >> TEXTURE_PARAM_COORD_TRANSFORM_MODE_BIT);
|
||||
}
|
||||
|
||||
PolygonTexParams getTexParams()
|
||||
{
|
||||
PolygonTexParams theTexParams;
|
||||
|
||||
theTexParams.VRAMOffset = this->getTexParamVRAMOffset();
|
||||
theTexParams.enableRepeatS = this->getTexParamEnableRepeatS();
|
||||
theTexParams.enableRepeatT = this->getTexParamEnableRepeatT();
|
||||
theTexParams.enableMirroredRepeatS = this->getTexParamEnableMirroredRepeatS();
|
||||
theTexParams.enableMirroredRepeatT = this->getTexParamEnableMirroredRepeatT();
|
||||
theTexParams.sizeS = this->getTexParamSizeS();
|
||||
theTexParams.sizeT = this->getTexParamSizeT();
|
||||
theTexParams.texFormat = this->getTexParamTexFormat();
|
||||
theTexParams.enableTransparentColor0 = this->getTexParamEnableTransparentColor0();
|
||||
theTexParams.coordTransformMode = this->getTexParamCoordTransformMode();
|
||||
|
||||
return theTexParams;
|
||||
}
|
||||
|
||||
bool isWireframe()
|
||||
{
|
||||
return (this->getAttributeAlpha() == 0);
|
||||
}
|
||||
|
||||
bool isOpaque()
|
||||
{
|
||||
return (this->getAttributeAlpha() == 31);
|
||||
}
|
||||
|
||||
bool isTranslucent()
|
||||
{
|
||||
//alpha != 31 -> translucent
|
||||
//except for alpha 0 which is wireframe (unless it has a translucent tex)
|
||||
if((polyAttr&0x001F0000) != 0x001F0000 && (polyAttr&0x001F0000) != 0)
|
||||
// First, check if the polygon is wireframe or opaque.
|
||||
// If neither, then it must be translucent.
|
||||
if (!this->isWireframe() && !this->isOpaque())
|
||||
{
|
||||
return true;
|
||||
int texFormat = (texParam>>26)&7;
|
||||
|
||||
}
|
||||
|
||||
// Also check for translucent texture format.
|
||||
u8 texFormat = this->getTexParamTexFormat();
|
||||
|
||||
//a5i3 or a3i5 -> translucent
|
||||
if(texFormat==1 || texFormat==6)
|
||||
if(texFormat == TEXMODE_A3I5 || texFormat == TEXMODE_A5I3)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int getAlpha() { return (polyAttr>>16)&0x1F; }
|
||||
|
||||
void save(EMUFILE* os)
|
||||
{
|
||||
OSWRITE(type);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2008-2011 DeSmuME team
|
||||
Copyright (C) 2008-2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,12 +19,26 @@
|
|||
|
||||
/* Vertex shader */
|
||||
const char *vertexShader = {"\
|
||||
uniform float polyAlpha; \n\
|
||||
uniform vec2 texScale; \n\
|
||||
varying vec4 pos; \n\
|
||||
varying vec4 vtxColor; \n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n\
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; \n\
|
||||
gl_FrontColor = gl_Color; \n\
|
||||
mat4 projectionMtx = mat4( vec4(1.0, 0.0, 0.0, 0.0), \n\
|
||||
vec4(0.0, 1.0, 0.0, 0.0), \n\
|
||||
vec4(0.0, 0.0, 1.0, 0.0), \n\
|
||||
vec4(0.0, 0.0, 0.0, 1.0));\n\
|
||||
\n\
|
||||
mat4 texScaleMtx = mat4( vec4(texScale.x, 0.0, 0.0, 0.0), \n\
|
||||
vec4( 0.0, texScale.y, 0.0, 0.0), \n\
|
||||
vec4( 0.0, 0.0, 1.0, 0.0), \n\
|
||||
vec4( 0.0, 0.0, 0.0, 1.0)); \n\
|
||||
\n\
|
||||
vtxColor = vec4(gl_Color.rgb * 4.0, polyAlpha); \n\
|
||||
gl_Position = projectionMtx * gl_Vertex; \n\
|
||||
gl_TexCoord[0] = texScaleMtx * gl_MultiTexCoord0; \n\
|
||||
gl_FrontColor = vtxColor; \n\
|
||||
pos = gl_Position; \n\
|
||||
} \n\
|
||||
"};
|
||||
|
@ -37,6 +51,7 @@ const char *fragmentShader = {"\
|
|||
uniform int texBlending; \n\
|
||||
uniform int oglWBuffer; \n\
|
||||
varying vec4 pos; \n\
|
||||
varying vec4 vtxColor; \n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
vec4 texColor = vec4(1.0, 1.0, 1.0, 1.0); \n\
|
||||
|
@ -49,33 +64,33 @@ const char *fragmentShader = {"\
|
|||
flagColor = texColor; \n\
|
||||
if(texBlending == 0) \n\
|
||||
{ \n\
|
||||
flagColor = gl_Color * texColor; \n\
|
||||
flagColor = vtxColor * texColor; \n\
|
||||
} \n\
|
||||
else \n\
|
||||
if(texBlending == 1) \n\
|
||||
{ \n\
|
||||
if (texColor.a == 0.0 || hasTexture == 0) \n\
|
||||
flagColor.rgb = gl_Color.rgb;\n\
|
||||
flagColor.rgb = vtxColor.rgb;\n\
|
||||
else \n\
|
||||
if (texColor.a == 1.0) \n\
|
||||
flagColor.rgb = texColor.rgb;\n\
|
||||
else \n\
|
||||
flagColor.rgb = texColor.rgb * (1.0-texColor.a) + gl_Color.rgb * texColor.a;\n\
|
||||
flagColor.a = gl_Color.a; \n\
|
||||
flagColor.rgb = texColor.rgb * (1.0-texColor.a) + vtxColor.rgb * texColor.a;\n\
|
||||
flagColor.a = vtxColor.a; \n\
|
||||
} \n\
|
||||
else \n\
|
||||
if(texBlending == 2) \n\
|
||||
{ \n\
|
||||
vec3 toonColor = vec3(texture1D(toonTable, gl_Color.r).rgb); \n\
|
||||
vec3 toonColor = vec3(texture1D(toonTable, vtxColor.r).rgb); \n\
|
||||
flagColor.rgb = texColor.rgb * toonColor.rgb;\n\
|
||||
flagColor.a = texColor.a * gl_Color.a;\n\
|
||||
flagColor.a = texColor.a * vtxColor.a;\n\
|
||||
} \n\
|
||||
else \n\
|
||||
if(texBlending == 3) \n\
|
||||
{ \n\
|
||||
vec3 toonColor = vec3(texture1D(toonTable, gl_Color.r).rgb); \n\
|
||||
flagColor.rgb = texColor.rgb * gl_Color.rgb + toonColor.rgb; \n\
|
||||
flagColor.a = texColor.a * gl_Color.a; \n\
|
||||
vec3 toonColor = vec3(texture1D(toonTable, vtxColor.r).rgb); \n\
|
||||
flagColor.rgb = texColor.rgb * vtxColor.rgb + toonColor.rgb; \n\
|
||||
flagColor.a = texColor.a * vtxColor.a; \n\
|
||||
} \n\
|
||||
if (oglWBuffer == 1) \n\
|
||||
// TODO \n\
|
||||
|
|
Loading…
Reference in New Issue