openmohaa/code/renderergl1/tr_sprite.c

217 lines
6.7 KiB
C
Raw Normal View History

2023-05-08 14:33:37 +02:00
/*
===========================================================================
Copyright (C) 2010 su44
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// tr_sprite.c - MoHAA sprite system
#include "tr_local.h"
/*
=====================
SPR_RegisterSprite
=====================
*/
sprite_t *SPR_RegisterSprite(const char *name)
{
image_t *spriteImage;
shader_t *shader;
sprite_t *spr;
char shadername[256];
COM_StripExtension(name,shadername,sizeof(shadername));
2023-05-09 19:13:37 +02:00
shader = R_FindShader(shadername,-1,qfalse,qfalse,qfalse,qfalse);
2023-05-08 14:33:37 +02:00
if(shader) {
spriteImage = 0;
2023-05-09 19:13:37 +02:00
if(shader->unfoggedStages[0])
spriteImage = shader->unfoggedStages[0]->bundle[0].image[0];
2023-05-08 14:33:37 +02:00
if ( !spriteImage ) {
ri.Printf(1, "Could not find image for sprite in shader %s\n", name);
return 0;
}
spr = ri.Hunk_Alloc(sizeof(sprite_t), h_dontcare);
2023-05-08 14:33:37 +02:00
spr->height = spriteImage->height;
spr->width = spriteImage->width;
spr->origin_x = spr->width * 0.5;
spr->origin_y = spr->height * 0.5;
spr->shader = shader;
spr->scale = spr->shader->sprite.scale;
return spr;
}
return 0;
}
2023-05-29 14:27:36 +02:00
static int CullSprite(const vec3_t* points) {
int i, j;
for (i = 0; i < backEnd.viewParms.fog.extrafrustums + 4; i++) {
for (j = 0; j < 4; j++) {
if (DotProduct(points[j], backEnd.viewParms.frustum[i].normal) - backEnd.viewParms.frustum[i].dist > 0.0f) {
break;
}
}
if (j == 4) {
return CULL_CLIP;
}
}
return CULL_IN;
}
2023-05-08 14:33:37 +02:00
/*
=====================
RB_DrawSprite
=====================
*/
void RB_DrawSprite( const refSprite_t *spr ) {
2023-05-29 14:27:36 +02:00
model_t* model;
vec3_t norm;
vec3_t up, right;
vec3_t points[4];
float org_x, org_y;
float scale;
if (!spr->hModel)
{
ri.Printf(PRINT_WARNING, "No model found for Sprite\n");
return;
}
model = tr.models;
if (spr->hModel > 0 && spr->hModel < tr.numModels) {
model = &tr.models[spr->hModel];
}
scale = spr->scale * model->d.sprite->scale;
switch (model->d.sprite->shader->sprite.type)
{
case SPRITE_PARALLEL_ORIENTED:
{
float invmag;
float cr, sr;
int i;
invmag = 1.0 / sqrt(spr->axis[1][2] * spr->axis[1][2] + spr->axis[1][1] * spr->axis[1][1]);
cr = invmag * spr->axis[1][1];
sr = invmag * spr->axis[1][2];
for (i = 0; i < 3; i++)
{
up[i] = backEnd.viewParms.ori.axis[2][i] * cr - backEnd.viewParms.ori.axis[1][i] * sr;
right[i] = backEnd.viewParms.ori.axis[1][i] * cr + backEnd.viewParms.ori.axis[2][i] * sr;
}
}
break;
case SPRITE_PARALLEL:
VectorCopy(backEnd.viewParms.ori.axis[2], up);
if (!backEnd.viewParms.isMirror) {
VectorNegate(backEnd.viewParms.ori.axis[1], right);
} else {
VectorCopy(backEnd.viewParms.ori.axis[1], right);
}
break;
case SPRITE_ORIENTED:
VectorCopy(spr->axis[1], right);
VectorCopy(spr->axis[2], up);
break;
case SPRITE_PARALLEL_UPRIGHT:
VectorCopy(backEnd.viewParms.ori.axis[0], norm);
VectorCopy(backEnd.viewParms.ori.axis[1], right);
VectorCopy(backEnd.viewParms.ori.axis[2], up);
if (backEnd.viewParms.ori.axis[0][2] > 0.999) {
return;
} else if (backEnd.viewParms.ori.axis[0][2] < -0.999) {
return;
}
VectorSet(up, 0.0f, 0.0f, 1.0f);
VectorSet(right, backEnd.viewParms.ori.axis[0][1], -backEnd.viewParms.ori.axis[0][0], 0.0f);
VectorNormalize(right);
VectorSet(norm, -right[1], right[0], 0.0f);
break;
}
org_x = model->d.sprite->origin_x * scale;
org_y = model->d.sprite->origin_y * scale;
VectorScale(up, org_y, up);
VectorScale(right, org_x, right);
points[0][0] = spr->origin[0] + up[0] - right[0];
points[1][0] = spr->origin[0] + up[0] + right[0];
points[2][0] = spr->origin[0] - up[0] - right[0];
points[3][0] = spr->origin[0] - up[0] + right[0];
points[0][1] = spr->origin[1] + up[1] - right[1];
points[1][1] = spr->origin[1] + up[1] + right[1];
points[2][1] = spr->origin[1] - up[1] - right[1];
points[3][1] = spr->origin[1] - up[1] + right[1];
points[0][2] = spr->origin[2] + up[2] - right[2];
points[1][2] = spr->origin[2] + up[2] + right[2];
points[2][2] = spr->origin[2] - up[2] - right[2];
points[3][2] = spr->origin[2] - up[2] + right[2];
if (CullSprite(points) == CULL_OUT) {
return;
}
RB_CHECKOVERFLOW(4, 6);
memcpy(tess.vertexColors[tess.numVertexes], spr->shaderRGBA, sizeof(byte) * 4);
memcpy(tess.vertexColors[tess.numVertexes + 1], spr->shaderRGBA, sizeof(byte) * 4);
memcpy(tess.vertexColors[tess.numVertexes + 2], spr->shaderRGBA, sizeof(byte) * 4);
memcpy(tess.vertexColors[tess.numVertexes + 3], spr->shaderRGBA, sizeof(byte) * 4);
tess.vertexColorValid = qtrue;
tess.texCoords[tess.numVertexes][0][0] = 0.0f;
tess.texCoords[tess.numVertexes][0][1] = 0.0f;
tess.texCoords[tess.numVertexes + 1][0][0] = 1.0f;
tess.texCoords[tess.numVertexes + 1][0][1] = 0.0f;
tess.texCoords[tess.numVertexes + 2][0][0] = 0.0f;
tess.texCoords[tess.numVertexes + 2][0][1] = 1.0f;
tess.texCoords[tess.numVertexes + 3][0][0] = 1.0f;
tess.texCoords[tess.numVertexes + 3][0][1] = 1.0f;
tess.xyz[tess.numVertexes][0] = points[0][0];
tess.xyz[tess.numVertexes][1] = points[0][1];
tess.xyz[tess.numVertexes][2] = points[0][2];
tess.xyz[tess.numVertexes + 1][0] = points[1][0];
tess.xyz[tess.numVertexes + 1][1] = points[1][1];
tess.xyz[tess.numVertexes + 1][2] = points[1][2];
tess.xyz[tess.numVertexes + 2][0] = points[2][0];
tess.xyz[tess.numVertexes + 2][1] = points[2][1];
tess.xyz[tess.numVertexes + 2][2] = points[2][2];
tess.xyz[tess.numVertexes + 3][0] = points[3][0];
tess.xyz[tess.numVertexes + 3][1] = points[3][1];
tess.xyz[tess.numVertexes + 3][2] = points[3][2];
tess.indexes[tess.numIndexes] = tess.numVertexes + 2;
tess.indexes[tess.numIndexes + 1] = tess.numVertexes + 1;
tess.indexes[tess.numIndexes + 2] = tess.numVertexes;
tess.indexes[tess.numIndexes + 3] = tess.numVertexes + 2;
tess.indexes[tess.numIndexes + 4] = tess.numVertexes + 3;
tess.indexes[tess.numIndexes + 5] = tess.numVertexes + 1;
tess.numVertexes += 4;
tess.numIndexes += 6;
2023-05-08 14:33:37 +02:00
}