mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-17 23:21:22 +00:00
Merge branch 'ogl-model-uv-adjust' into 'next'
Re-adjust model UVs when sprite texture dimensions change See merge request STJr/SRB2!1068
This commit is contained in:
commit
060f46653d
4 changed files with 100 additions and 29 deletions
|
@ -1177,6 +1177,7 @@ static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t
|
|||
return spr2;
|
||||
}
|
||||
|
||||
// Adjust texture coords of model to fit into a patch's max_s and max_t
|
||||
static void adjustTextureCoords(model_t *model, GLPatch_t *gpatch)
|
||||
{
|
||||
int i;
|
||||
|
@ -1185,24 +1186,35 @@ static void adjustTextureCoords(model_t *model, GLPatch_t *gpatch)
|
|||
int j;
|
||||
mesh_t *mesh = &model->meshes[i];
|
||||
int numVertices;
|
||||
float *uvPtr = mesh->uvs;
|
||||
float *uvReadPtr = mesh->originaluvs;
|
||||
float *uvWritePtr;
|
||||
|
||||
// i dont know if this is actually possible, just logical conclusion of structure in CreateModelVBOs
|
||||
if (!mesh->frames && !mesh->tinyframes) return;
|
||||
if (!mesh->frames && !mesh->tinyframes) continue;
|
||||
|
||||
if (mesh->frames) // again CreateModelVBO and CreateModelVBOTiny iterate like this so I'm gonna do that too
|
||||
numVertices = mesh->numTriangles * 3;
|
||||
else
|
||||
numVertices = mesh->numVertices;
|
||||
|
||||
// if originaluvs points to uvs, we need to allocate new memory for adjusted uvs
|
||||
// the old uvs are kept around for use in possible readjustments
|
||||
if (mesh->uvs == mesh->originaluvs)
|
||||
mesh->uvs = Z_Malloc(numVertices * 2 * sizeof(float), PU_STATIC, NULL);
|
||||
|
||||
uvWritePtr = mesh->uvs;
|
||||
|
||||
// fix uvs (texture coordinates) to take into account that the actual texture
|
||||
// has empty space added until the next power of two
|
||||
for (j = 0; j < numVertices; j++)
|
||||
{
|
||||
*uvPtr++ *= gpatch->max_s;
|
||||
*uvPtr++ *= gpatch->max_t;
|
||||
*uvWritePtr++ = *uvReadPtr++ * gpatch->max_s;
|
||||
*uvWritePtr++ = *uvReadPtr++ * gpatch->max_t;
|
||||
}
|
||||
}
|
||||
// Save the values we adjusted the uvs for
|
||||
model->max_s = gpatch->max_s;
|
||||
model->max_t = gpatch->max_t;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1226,6 +1238,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
if (spr->precip)
|
||||
return false;
|
||||
|
||||
// Lactozilla: Disallow certain models from rendering
|
||||
if (!HWR_AllowModel(spr->mobj))
|
||||
return false;
|
||||
|
||||
memset(&p, 0x00, sizeof(FTransform));
|
||||
|
||||
// MD2 colormap fix
|
||||
|
@ -1330,10 +1346,13 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
if (md2->model)
|
||||
{
|
||||
md2_printModelInfo(md2->model);
|
||||
// if model uses sprite patch as texture, then
|
||||
// If model uses sprite patch as texture, then
|
||||
// adjust texture coordinates to take power of two textures into account
|
||||
if (!gpatch || !gpatch->mipmap->format)
|
||||
adjustTextureCoords(md2->model, spr->gpatch);
|
||||
// note down the max_s and max_t that end up in the VBO
|
||||
md2->model->vbo_max_s = md2->model->max_s;
|
||||
md2->model->vbo_max_t = md2->model->max_t;
|
||||
HWD.pfnCreateModelVBOs(md2->model);
|
||||
}
|
||||
else
|
||||
|
@ -1344,10 +1363,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
}
|
||||
}
|
||||
|
||||
// Lactozilla: Disallow certain models from rendering
|
||||
if (!HWR_AllowModel(spr->mobj))
|
||||
return false;
|
||||
|
||||
//HWD.pfnSetBlend(blend); // This seems to actually break translucency?
|
||||
finalscale = md2->scale;
|
||||
//Hurdler: arf, I don't like that implementation at all... too much crappy
|
||||
|
@ -1391,6 +1406,14 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
{
|
||||
// Sprite
|
||||
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
// Check if sprite dimensions are different from previously used sprite.
|
||||
// If so, uvs need to be readjusted.
|
||||
// Comparing floats with the != operator here should be okay because they
|
||||
// are just copies of glpatches' max_s and max_t values.
|
||||
// Instead of the != operator, memcmp is used to avoid a compiler warning.
|
||||
if (memcmp(&(gpatch->max_s), &(md2->model->max_s), sizeof(md2->model->max_s)) != 0 ||
|
||||
memcmp(&(gpatch->max_t), &(md2->model->max_t), sizeof(md2->model->max_t)) != 0)
|
||||
adjustTextureCoords(md2->model, gpatch);
|
||||
HWR_GetMappedPatch(gpatch, spr->colormap);
|
||||
}
|
||||
|
||||
|
|
|
@ -221,6 +221,15 @@ model_t *LoadModel(const char *filename, int ztag)
|
|||
material->shininess = 25.0f;
|
||||
}
|
||||
|
||||
// Set originaluvs to point to uvs
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
model->meshes[i].originaluvs = model->meshes[i].uvs;
|
||||
|
||||
model->max_s = 1.0;
|
||||
model->max_t = 1.0;
|
||||
model->vbo_max_s = 1.0;
|
||||
model->vbo_max_t = 1.0;
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,11 @@ typedef struct mesh_s
|
|||
int numTriangles;
|
||||
|
||||
float *uvs;
|
||||
// if uv adjustment is needed, uvs is changed to point to adjusted ones and
|
||||
// this one retains the originals
|
||||
// note: this member has been added with the assumption that models are never freed.
|
||||
// (UnloadModel is called by nobody at the time of writing.)
|
||||
float *originaluvs;
|
||||
float *lightuvs;
|
||||
|
||||
int numFrames;
|
||||
|
@ -99,6 +104,15 @@ typedef struct model_s
|
|||
char *framenames;
|
||||
boolean interpolate[256];
|
||||
modelspr2frames_t *spr2frames;
|
||||
|
||||
// the max_s and max_t values that the uvs are currently adjusted to
|
||||
// (if a sprite is used as a texture)
|
||||
float max_s;
|
||||
float max_t;
|
||||
// These are the values that the uvs in the VBO have been adjusted to.
|
||||
// If they are not same as max_s and max_t, then the VBO won't be used.
|
||||
float vbo_max_s;
|
||||
float vbo_max_t;
|
||||
} model_t;
|
||||
|
||||
extern int numModels;
|
||||
|
|
|
@ -2535,6 +2535,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
|
||||
boolean useTinyFrames;
|
||||
|
||||
boolean useVBO = true;
|
||||
|
||||
int i;
|
||||
|
||||
// Because otherwise, scaling the screen negatively vertically breaks the lighting
|
||||
|
@ -2678,6 +2680,15 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
if (useTinyFrames)
|
||||
pglScalef(1 / 64.0f, 1 / 64.0f, 1 / 64.0f);
|
||||
|
||||
// Don't use the VBO if it does not have the correct texture coordinates.
|
||||
// (Can happen when model uses a sprite as a texture and the sprite changes)
|
||||
// Comparing floats with the != operator here should be okay because they
|
||||
// are just copies of glpatches' max_s and max_t values.
|
||||
// Instead of the != operator, memcmp is used to avoid a compiler warning.
|
||||
if (memcmp(&(model->vbo_max_s), &(model->max_s), sizeof(model->max_s)) != 0 ||
|
||||
memcmp(&(model->vbo_max_t), &(model->max_t), sizeof(model->max_t)) != 0)
|
||||
useVBO = false;
|
||||
|
||||
pglEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
|
@ -2694,13 +2705,23 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
|
||||
if (!nextframe || fpclassify(pol) == FP_ZERO)
|
||||
{
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID);
|
||||
pglVertexPointer(3, GL_SHORT, sizeof(vbotiny_t), BUFFER_OFFSET(0));
|
||||
pglNormalPointer(GL_BYTE, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short)*3));
|
||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(char) * 6));
|
||||
if (useVBO)
|
||||
{
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID);
|
||||
pglVertexPointer(3, GL_SHORT, sizeof(vbotiny_t), BUFFER_OFFSET(0));
|
||||
pglNormalPointer(GL_BYTE, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short)*3));
|
||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(char) * 6));
|
||||
|
||||
pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices);
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices);
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pglVertexPointer(3, GL_SHORT, 0, frame->vertices);
|
||||
pglNormalPointer(GL_BYTE, 0, frame->normals);
|
||||
pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs);
|
||||
pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2736,21 +2757,25 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
|
||||
if (!nextframe || fpclassify(pol) == FP_ZERO)
|
||||
{
|
||||
// Zoom! Take advantage of just shoving the entire arrays to the GPU.
|
||||
/* pglVertexPointer(3, GL_FLOAT, 0, frame->vertices);
|
||||
pglNormalPointer(GL_FLOAT, 0, frame->normals);
|
||||
pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs);
|
||||
pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);*/
|
||||
if (useVBO)
|
||||
{
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID);
|
||||
pglVertexPointer(3, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(0));
|
||||
pglNormalPointer(GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 3));
|
||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 6));
|
||||
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID);
|
||||
pglVertexPointer(3, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(0));
|
||||
pglNormalPointer(GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 3));
|
||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 6));
|
||||
|
||||
pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
|
||||
// No tinyframes, no mesh indices
|
||||
//pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices);
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
|
||||
// No tinyframes, no mesh indices
|
||||
//pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices);
|
||||
pglBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pglVertexPointer(3, GL_FLOAT, 0, frame->vertices);
|
||||
pglNormalPointer(GL_FLOAT, 0, frame->normals);
|
||||
pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs);
|
||||
pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue