Add support for normal map loading. (Note that normal map rendering is still not supported by shaders.) Patch reviewed by Safety0ff.

master
Per Inge Mathisen 2011-05-22 13:57:53 +02:00
parent a42e26864d
commit 8aca9437a4
6 changed files with 69 additions and 8 deletions

View File

@ -6,8 +6,9 @@ varying vec3 normal, lightDir, eyeVec;
uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform vec4 teamcolour;
uniform int tcmask;
uniform int tcmask, normalmap;
uniform int fogEnabled;
void main(void)

View File

@ -531,6 +531,7 @@ static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataE
s->nShadowEdges = 0;
s->texpage = iV_TEX_INVALID;
s->tcmaskpage = iV_TEX_INVALID;
s->normalpage = iV_TEX_INVALID;
memset(s->material, 0, sizeof(s->material));
s->material[LIGHT_AMBIENT][3] = 1.0f;
s->material[LIGHT_DIFFUSE][3] = 1.0f;
@ -633,7 +634,7 @@ iIMDShape *iV_ProcessIMD( const char **ppFileData, const char *FileDataEnd )
{
const char *pFileName = GetLastResourceFilename(); // Last loaded texture page filename
const char *pFileData = *ppFileData;
char buffer[PATH_MAX], texfile[PATH_MAX];
char buffer[PATH_MAX], texfile[PATH_MAX], normalfile[PATH_MAX];
int cnt, nlevels;
iIMDShape *shape, *psShape;
UDWORD level;
@ -641,6 +642,8 @@ iIMDShape *iV_ProcessIMD( const char **ppFileData, const char *FileDataEnd )
uint32_t imd_flags;
bool bTextured = false;
memset(normalfile, 0, sizeof(normalfile));
if (sscanf(pFileData, "%255s %d%n", buffer, &imd_version, &cnt) != 2)
{
debug(LOG_ERROR, "iV_ProcessIMD %s bad version: (%s)", pFileName, buffer);
@ -727,6 +730,45 @@ iIMDShape *iV_ProcessIMD( const char **ppFileData, const char *FileDataEnd )
bTextured = true;
}
if (strncmp(buffer, "NORMALMAP", 9) == 0)
{
char ch, texType[PATH_MAX];
int i;
/* the first parameter for textures is always ignored; which is why we ignore
* nlevels read in above */
ch = *pFileData++;
// Run up to the dot or till the buffer is filled. Leave room for the extension.
for (i = 0; i < PATH_MAX-5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i)
{
normalfile[i] = ch;
}
normalfile[i] = '\0';
if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1)
{
debug(LOG_ERROR, "iV_ProcessIMD %s normal map info corrupt: %s", pFileName, buffer);
return NULL;
}
pFileData += cnt;
if (strcmp(texType, "png") != 0)
{
debug(LOG_ERROR, "iV_ProcessIMD %s: only png normal maps supported", pFileName);
return NULL;
}
sstrcat(normalfile, ".png");
/* -Now- read in LEVELS directive */
if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
{
debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer);
return NULL;
}
pFileData += cnt;
}
if (strncmp(buffer, "LEVELS", 6) != 0)
{
debug(LOG_ERROR, "iV_ProcessIMD: expecting 'LEVELS' directive (%s)", buffer);
@ -758,6 +800,13 @@ iIMDShape *iV_ProcessIMD( const char **ppFileData, const char *FileDataEnd )
if (bTextured)
{
int texpage = iV_GetTexture(texfile);
int normalpage = iV_TEX_INVALID;
if (normalfile[0] != '\0')
{
debug(LOG_WARNING, "Loading normal map %s for %s", normalfile, pFileName);
normalpage = iV_GetTexture(normalfile);
}
ASSERT_OR_RETURN(NULL, texpage >= 0, "%s could not load tex page %s", pFileName, texfile);
@ -765,6 +814,7 @@ iIMDShape *iV_ProcessIMD( const char **ppFileData, const char *FileDataEnd )
for (psShape = shape; psShape != NULL; psShape = psShape->next)
{
psShape->texpage = texpage;
psShape->normalpage = normalpage;
}
// check if model should use team colour mask

View File

@ -80,6 +80,7 @@ struct iIMDShape
unsigned int flags;
int texpage;
int tcmaskpage;
int normalpage;
int sradius, radius;
Vector3i min, max;

View File

@ -171,7 +171,7 @@ static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELI
{
pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON);
light = false;
pie_ActivateShader(SHADER_BUTTON, teamcolour, shape->tcmaskpage);
pie_ActivateShader(SHADER_BUTTON, teamcolour, shape->tcmaskpage, shape->normalpage);
}
pie_SetRendMode(REND_OPAQUE);
}
@ -183,7 +183,7 @@ static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELI
glMaterialfv(GL_FRONT, GL_SPECULAR, shape->material[LIGHT_SPECULAR]);
glMaterialf(GL_FRONT, GL_SHININESS, shape->shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, shape->material[LIGHT_EMISSIVE]);
pie_ActivateShader(SHADER_COMPONENT, teamcolour, shape->tcmaskpage);
pie_ActivateShader(SHADER_COMPONENT, teamcolour, shape->tcmaskpage, shape->normalpage);
}
if (pieFlag & pie_HEIGHT_SCALED) // construct

View File

@ -42,7 +42,7 @@ static IMAGEFILE* MouseCursors = NULL;
static uint16_t MouseCursorIDs[CURSOR_MAX];
static GLuint shaderProgram[SHADER_MAX];
static GLfloat shaderStretch = 0;
static GLint locTeam, locStretch, locTCMask, locFog;
static GLint locTeam, locStretch, locTCMask, locFog, locNormalMap;
static SHADER_MODE currentShaderMode = SHADER_NONE;
unsigned int pieStateCount = 0; // Used in pie_GetResetCounts
static RENDER_STATE rendStates;
@ -320,25 +320,28 @@ void pie_SetShaderStretchDepth(float stretch)
shaderStretch = stretch;
}
void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpage)
void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpage, int normalpage)
{
GLfloat colour4f[4];
if (shaderMode != currentShaderMode)
{
GLint locTex0, locTex1;
GLint locTex0, locTex1, locTex2;
glUseProgram(shaderProgram[shaderMode]);
locTex0 = glGetUniformLocation(shaderProgram[shaderMode], "Texture0");
locTex1 = glGetUniformLocation(shaderProgram[shaderMode], "Texture1");
locTex2 = glGetUniformLocation(shaderProgram[shaderMode], "Texture2");
locTeam = glGetUniformLocation(shaderProgram[shaderMode], "teamcolour");
locStretch = glGetUniformLocation(shaderProgram[shaderMode], "stretch");
locTCMask = glGetUniformLocation(shaderProgram[shaderMode], "tcmask");
locNormalMap = glGetUniformLocation(shaderProgram[shaderMode], "normalmap");
locFog = glGetUniformLocation(shaderProgram[shaderMode], "fogEnabled");
// These never change
glUniform1i(locTex0, 0);
glUniform1i(locTex1, 1);
glUniform1i(locTex2, 2);
currentShaderMode = shaderMode;
}
@ -347,6 +350,7 @@ void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpag
glUniform4fv(locTeam, 1, &colour4f[0]);
glUniform1f(locStretch, shaderStretch);
glUniform1i(locTCMask, maskpage != iV_TEX_INVALID);
glUniform1i(locNormalMap, normalpage != iV_TEX_INVALID);
glUniform1i(locFog, rendStates.fog);
if (maskpage != iV_TEX_INVALID)
@ -354,6 +358,11 @@ void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpag
glActiveTexture(GL_TEXTURE1);
pie_SetTexturePage(maskpage);
}
if (normalpage != iV_TEX_INVALID)
{
glActiveTexture(GL_TEXTURE2);
pie_SetTexturePage(normalpage);
}
glActiveTexture(GL_TEXTURE0);
#ifdef _DEBUG

View File

@ -90,7 +90,7 @@ extern void pie_ShowMouse(bool visible);
bool pie_LoadShaders(void);
// Actual shaders (we do not want to export these calls)
void pie_DeactivateShader(void);
void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpage);
void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpage, int normalpage);
void pie_SetShaderStretchDepth(float stretch);
/* Errors control routine */