fteqw/engine/d3d/d3d_rmain.c

965 lines
24 KiB
C

#include "quakedef.h"
#ifdef D3DQUAKE
#include "d3dquake.h"
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
extern mleaf_t *r_viewleaf2, *r_oldviewleaf2;
extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
extern qbyte areabits[MAX_Q2MAP_AREAS/8];
int r_visframecount;
entity_t r_worldentity;
refdef_t r_refdef;
vec3_t r_origin, vpn, vright, vup;
extern float r_projection_matrix[16];
extern float r_view_matrix[16];
//mplane_t frustum[4];
vec3_t modelorg;
entity_t *currententity;
extern cvar_t gl_mindist;
void (D3D_R_DeInit) (void)
{
}
void (D3D_R_ReInit) (void)
{
}
void (D3D_R_Init) (void)
{
D3D_R_ReInit();
}
//most of this is a direct copy from gl
void (D3D_SetupFrame) (void)
{
mleaf_t *leaf;
vec3_t temp;
GLR_AnimateLight();
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
r_framecount++;
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin);
if (!r_viewleaf)
{
}
else if (r_viewleaf->contents == Q1CONTENTS_EMPTY)
{ //look down a bit
VectorCopy (r_origin, temp);
temp[2] -= 16;
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA)
r_viewleaf2 = leaf;
else
r_viewleaf2 = NULL;
}
else if (r_viewleaf->contents <= Q1CONTENTS_WATER && r_viewleaf->contents >= Q1CONTENTS_LAVA)
{ //in water, look up a bit.
VectorCopy (r_origin, temp);
temp[2] += 16;
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents == Q1CONTENTS_EMPTY)
r_viewleaf2 = leaf;
else
r_viewleaf2 = NULL;
}
else
r_viewleaf2 = NULL;
if (r_viewleaf)
V_SetContentsColor (r_viewleaf->contents);
}
void D3D_SetupViewPort(void)
{
float screenaspect;
int glwidth = vid.width, glheight=vid.height;
int x, x2, y2, y, w, h;
float fov_x, fov_y;
D3DVIEWPORT7 vport;
D3D_GetBufferSize(&glwidth, &glheight);
//
// set up viewpoint
//
x = r_refdef.vrect.x * glwidth/(int)vid.width;
x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/(int)vid.width;
y = (/*vid.height-*/r_refdef.vrect.y) * glheight/(int)vid.height;
y2 = ((int)/*vid.height - */(r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/(int)vid.height;
// fudge around because of frac screen scale
if (x > 0)
x--;
if (x2 < glwidth)
x2++;
if (y < 0)
y--;
if (y2 < glheight)
y2++;
w = x2 - x;
h = y2 - y;
/* if (envmap)
{
x = y2 = 0;
w = h = 256;
}
*/
vport.dwX = x;
vport.dwY = y;
vport.dwWidth = w;
vport.dwHeight = h;
vport.dvMinZ = 0;
vport.dvMaxZ = 1;
pD3DDev->lpVtbl->SetViewport(pD3DDev, &vport);
fov_x = r_refdef.fov_x;//+sin(cl.time)*5;
fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5;
if (r_waterwarp.value<0 && r_viewleaf->contents <= Q1CONTENTS_WATER)
{
fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
}
screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
// if (r_refdef.useperspective)
{
/* if ((!r_shadows.value || !gl_canstencil) && gl_maxdist.value>256)//gl_nv_range_clamp)
{
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
// yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect;
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI;
// MYgluPerspective (yfov, screenaspect, 4, 4096);
MYgluPerspective (fov_x, fov_y, gl_mindist.value, gl_maxdist.value);
}
else*/
{
GL_InfinatePerspective(fov_x, fov_y, gl_mindist.value);
}
}
/* else
{
if (gl_maxdist.value>=1)
GL_ParallelPerspective(-fov_x/2, fov_x/2, fov_y/2, -fov_y/2, -gl_maxdist.value, gl_maxdist.value);
else
GL_ParallelPerspective(0, r_refdef.vrect.width, 0, r_refdef.vrect.height, -9999, 9999);
}*/
Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX*)r_projection_matrix);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX*)r_view_matrix);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
}
qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer);
//fixme: direct copy from gl (apart from lightmaps)
static void D3D7_RecursiveWorldNode (mnode_t *node)
{
int c, side;
mplane_t *plane;
msurface_t *surf, **mark;
mleaf_t *pleaf;
double dot;
int shift;
start:
if (node->contents == Q1CONTENTS_SOLID)
return; // solid
if (node->visframe != r_visframecount)
return;
if (R_CullBox (node->minmaxs, node->minmaxs+3))
return;
// if a leaf node, draw stuff
if (node->contents < 0)
{
pleaf = (mleaf_t *)node;
mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces;
if (c)
{
do
{
(*mark++)->visframe = r_framecount;
} while (--c);
}
// deal with model fragments in this leaf
if (pleaf->efrags)
R_StoreEfrags (&pleaf->efrags);
return;
}
// node is just a decision point, so go down the apropriate sides
// find which side of the node we are on
plane = node->plane;
switch (plane->type)
{
case PLANE_X:
dot = modelorg[0] - plane->dist;
break;
case PLANE_Y:
dot = modelorg[1] - plane->dist;
break;
case PLANE_Z:
dot = modelorg[2] - plane->dist;
break;
default:
dot = DotProduct (modelorg, plane->normal) - plane->dist;
break;
}
if (dot >= 0)
side = 0;
else
side = 1;
// recurse down the children, front side first
D3D7_RecursiveWorldNode (node->children[side]);
// draw stuff
c = node->numsurfaces;
if (c)
{
surf = cl.worldmodel->surfaces + node->firstsurface;
shift = 0;//GLR_LightmapShift(cl.worldmodel);
// if (dot < 0 -BACKFACE_EPSILON)
// side = SURF_PLANEBACK;
// else if (dot > BACKFACE_EPSILON)
// side = 0;
{
for ( ; c ; c--, surf++)
{
if (surf->visframe != r_framecount)
continue;
// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)))
// continue; // wrong side
D3DR_RenderDynamicLightmaps (surf, shift);
// if sorting by texture, just store it out
/* if (surf->flags & SURF_DRAWALPHA)
{ // add to the translucent chain
surf->nextalphasurface = r_alpha_surfaces;
r_alpha_surfaces = surf;
surf->ownerent = &r_worldentity;
}
else
*/ {
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
}
}
}
}
// recurse down the back side
// GLR_RecursiveWorldNode (node->children[!side]);
node = node->children[!side];
goto start;
}
struct {
float x, y, z;
// unsigned colour;
float wms, wmt;
float lms, lmt;
} worldvert[64];
void D3D_DrawTextureChains(void)
{
texture_t *t;
msurface_t *s;
vec3_t *xyz;
vec2_t *wm;
vec2_t *lm;
mesh_t *m;
int i;
int v;
int lmnum;
extern int skytexturenum; // index in cl.loadmodel, not gl texture object
if (skytexturenum>=0)
{
t = currentmodel->textures[skytexturenum];
if (t)
{
s = t->texturechain;
if (s)
{
t->texturechain = NULL;
D3D7_DrawSkyChain (s);
}
}
}
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
for (i = 0; i < currentmodel->numtextures; i++)
{
t = currentmodel->textures[i];
if (!t)
continue; //happens on e1m2
s = t->texturechain;
if (!s)
continue;
t->texturechain = NULL;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)t->gl_texturenum);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
while(s)
{
m = s->mesh;
if (m)
{
lmnum = s->lightmaptexturenum;
if (lmnum >= 0)
{
if (lightmap[lmnum]->modified)
{
DDSURFACEDESC2 desc;
desc.dwSize = sizeof(desc);
lightmap_d3dtextures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL);
memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4);
/* {
int i;
unsigned char *c;
unsigned char v;
c = desc.lpSurface;
for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++)
{
v = rand();
*c++ = v;
*c++ = v;
*c++ = v;
c++;
}
}*/
lightmap_d3dtextures[lmnum]->lpVtbl->Unlock(lightmap_d3dtextures[lmnum], NULL);
lightmap[lmnum]->modified = false;
}
pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[lmnum]);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_TEXCOORDINDEX, 1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
}
else
{
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
//pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
xyz = m->xyz_array;
wm = m->st_array;
lm = m->lmst_array;
for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++)
{
worldvert[v].x = (*xyz)[0];
worldvert[v].y = (*xyz)[1];
worldvert[v].z = (*xyz)[2];
// worldvert[v].colour = 0;
worldvert[v].wms = (*wm)[0];
worldvert[v].wmt = (*wm)[1];
worldvert[v].lms = (*lm)[0];
worldvert[v].lmt = (*lm)[1];
}
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0);
}
s = s->texturechain;
}
}
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
}
void D3D_BaseBModelTextures(entity_t *e)
{
texture_t *t;
msurface_t *s;
vec3_t *xyz;
vec2_t *wm;
vec2_t *lm;
mesh_t *m;
int i;
int v;
float matrix[16];
int lmnum = -1;
currentmodel = e->model;
for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++)
{
t = R_TextureAnimation(s->texinfo->texture);
{
m = s->mesh;
if (m)
D3DR_RenderDynamicLightmaps (s, 0);
}
}
Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++)
{
t = R_TextureAnimation(s->texinfo->texture);
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)t->gl_texturenum);
pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[s->lightmaptexturenum]);
{
m = s->mesh;
if (m)
{
if (lmnum != s->lightmaptexturenum)
{
lmnum = s->lightmaptexturenum;
if (lmnum >= 0)
{
if (lightmap[lmnum]->modified)
{
DDSURFACEDESC2 desc;
desc.dwSize = sizeof(desc);
lightmap_d3dtextures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL);
memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4);
/* {
int i;
unsigned char *c;
unsigned char v;
c = desc.lpSurface;
for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++)
{
v = rand();
*c++ = v;
*c++ = v;
*c++ = v;
c++;
}
}*/
lightmap_d3dtextures[lmnum]->lpVtbl->Unlock(lightmap_d3dtextures[lmnum], NULL);
lightmap[lmnum]->modified = false;
}
pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[lmnum]);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_TEXCOORDINDEX, 1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
}
else
{
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
}
xyz = m->xyz_array;
wm = m->st_array;
lm = m->lmst_array;
for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++)
{
worldvert[v].x = (*xyz)[0];
worldvert[v].y = (*xyz)[1];
worldvert[v].z = (*xyz)[2];
// worldvert[v].colour = 0;
worldvert[v].wms = (*wm)[0];
worldvert[v].wmt = (*wm)[1];
worldvert[v].lms = (*lm)[0];
worldvert[v].lmt = (*lm)[1];
}
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0);
}
}
}
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix);
}
typedef struct {
float pos[3];
int colour;
float tc[2];
} d3dvert_t;
/*
================
R_GetSpriteFrame
================
*/
/*
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, numframes, frame;
float *pintervals, fullinterval, targettime, time;
psprite = currententity->model->cache.data;
frame = currententity->frame;
if ((frame >= psprite->numframes) || (frame < 0))
{
Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name);
frame = 0;
}
if (psprite->frames[frame].type == SPR_SINGLE)
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if (psprite->frames[frame].type == SPR_ANGLED)
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7];
}
else
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1];
time = currententity->frame1time;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by 0
targettime = time - ((int)(time / fullinterval)) * fullinterval;
for (i=0 ; i<(numframes-1) ; i++)
{
if (pintervals[i] > targettime)
break;
}
pspriteframe = pspritegroup->frames[i];
}
return pspriteframe;
}
*/
static void D3D_DrawSpriteModel (entity_t *e)
{
vec3_t point;
mspriteframe_t *frame;
vec3_t forward, right, up;
msprite_t *psprite;
qbyte coloursb[4];
d3dvert_t d3dvert[4];
index_t vertindexes[6] = {
0, 1, 2,
0, 2, 3
};
if (!e->model)
return;
if (e->flags & RF_NODEPTHTEST)
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS);
// don't even bother culling, because it's just a single
// polygon without a surface cache
frame = R_GetSpriteFrame (e);
psprite = e->model->cache.data;
// frame = 0x05b94140;
switch(psprite->type)
{
case SPR_ORIENTED:
// bullet marks on walls
AngleVectors (e->angles, forward, right, up);
break;
case SPR_FACING_UPRIGHT:
up[0] = 0;up[1] = 0;up[2]=1;
right[0] = e->origin[1] - r_origin[1];
right[1] = -(e->origin[0] - r_origin[0]);
right[2] = 0;
VectorNormalize (right);
break;
case SPR_VP_PARALLEL_UPRIGHT:
up[0] = 0;up[1] = 0;up[2]=1;
VectorCopy (vright, right);
break;
default:
case SPR_VP_PARALLEL:
//normal sprite
VectorCopy(vup, up);
VectorCopy(vright, right);
break;
}
up[0]*=e->scale;
up[1]*=e->scale;
up[2]*=e->scale;
right[0]*=e->scale;
right[1]*=e->scale;
right[2]*=e->scale;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)frame->gl_texturenum);
/* {
extern int gldepthfunc;
qglDepthFunc(gldepthfunc);
qglDepthMask(0);
if (gldepthmin == 0.5)
qglCullFace ( GL_BACK );
else
qglCullFace ( GL_FRONT );
GL_TexEnv(GL_MODULATE);
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglDisable (GL_ALPHA_TEST);
qglDisable(GL_BLEND);
}*/
/* if (e->flags & Q2RF_ADDATIVE)
{
qglEnable(GL_BLEND);
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
else if (e->shaderRGBAf[3]<1 || gl_blendsprites.value)
{
qglEnable(GL_BLEND);
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
else
qglEnable (GL_ALPHA_TEST);
*/
d3dvert[0].colour = 0xffffffff;
d3dvert[0].tc[0] = 0;
d3dvert[0].tc[1] = 1;
VectorMA (e->origin, frame->down, up, point);
VectorMA (point, frame->left, right, d3dvert[0].pos);
d3dvert[1].colour = 0xffffffff;
d3dvert[1].tc[0] = 0;
d3dvert[1].tc[0] = 0;
VectorMA (e->origin, frame->up, up, point);
VectorMA (point, frame->left, right, d3dvert[1].pos);
d3dvert[2].colour = 0xffffffff;
d3dvert[2].tc[0] = 1;
d3dvert[2].tc[1] = 0;
VectorMA (e->origin, frame->up, up, point);
VectorMA (point, frame->right, right, d3dvert[2].pos);
d3dvert[3].colour = 0xffffffff;
d3dvert[3].tc[0] = 1;
d3dvert[3].tc[1] = 1;
VectorMA (e->origin, frame->down, up, point);
VectorMA (point, frame->right, right, d3dvert[3].pos);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLEFAN, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dvert, 4, vertindexes, 6, 0);
if (e->flags & RF_NODEPTHTEST)
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
// if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us!
// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
//==================================================================================
void D3DR_DrawSprite(void *e, void *parm)
{
currententity = e;
D3D_DrawSpriteModel (currententity);
// P_FlushRenderer();
}
qboolean D3D_ShouldDraw(void)
{
{
if (currententity->flags & Q2RF_EXTERNALMODEL)
return false;
// if (currententity->keynum == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1)))
// return false;
// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum])
// continue;
if (!Cam_DrawPlayer(r_refdef.currentplayernum, currententity->keynum-1))
return false;
}
return true;
}
void D3DR_DrawEntitiesOnList (void)
{
int i;
if (!r_drawentities.value)
return;
// draw sprites seperately, because of alpha blending
for (i=0 ; i<cl_numvisedicts ; i++)
{
currententity = &cl_visedicts[i];
if (!D3D_ShouldDraw())
continue;
switch (currententity->rtype)
{
case RT_SPRITE:
RQ_AddDistReorder(D3DR_DrawSprite, currententity, NULL, currententity->origin);
continue;
#ifdef Q3SHADERS
case RT_BEAM:
case RT_RAIL_RINGS:
case RT_LIGHTNING:
R_DrawLightning(currententity);
continue;
case RT_RAIL_CORE:
R_DrawRailCore(currententity);
continue;
#endif
case RT_MODEL: //regular model
break;
case RT_PORTALSURFACE:
continue; //this doesn't do anything anyway, does it?
default:
case RT_POLY: //these are a little painful, we need to do them some time... just not yet.
continue;
}
if (currententity->flags & Q2RF_BEAM)
{
// R_DrawBeam(currententity);
continue;
}
if (!currententity->model)
continue;
if (cl.lerpents && (cls.allow_anyparticles || currententity->visframe)) //allowed or static
{
/* if (gl_part_flame.value)
{
if (currententity->model->engineflags & MDLF_ENGULPHS)
continue;
}*/
}
switch (currententity->model->type)
{
case mod_alias:
// if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
D3D_DrawAliasModel ();
break;
#ifdef HALFLIFEMODELS
case mod_halflife:
R_DrawHLModel (currententity);
break;
#endif
case mod_brush:
// if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
D3D_BaseBModelTextures (currententity);
break;
case mod_sprite:
RQ_AddDistReorder(D3DR_DrawSprite, currententity, NULL, currententity->origin);
break;
/*
#ifdef TERRAIN
case mod_heightmap:
D3D_DrawHeightmapModel(currententity);
break;
#endif
*/
default:
break;
}
}
{
float m_identity[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)m_identity);
}
}
void D3D_DrawWorld(void)
{
RSpeedLocals();
entity_t ent;
memset (&ent, 0, sizeof(ent));
ent.model = cl.worldmodel;
currentmodel = cl.worldmodel;
VectorCopy (r_refdef.vieworg, modelorg);
currententity = &ent;
#ifdef TERRAIN
if (currentmodel->type == mod_heightmap)
GL_DrawHeightmapModel(currententity);
else
#endif
{
// qglColor3f (1,1,1);
//#ifdef QUAKE2
// R_ClearSkyBox ();
//#endif
RSpeedRemark();
/*
#ifdef Q2BSPS
if (ent.model->fromgame == fg_quake2 || ent.model->fromgame == fg_quake3)
{
int leafnum;
int clientarea;
#ifdef QUAKE2
if (cls.protocol == CP_QUAKE2) //we can get server sent info
memcpy(areabits, cl.q2frame.areabits, sizeof(areabits));
else
#endif
{ //generate the info each frame.
leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg);
clientarea = CM_LeafArea (cl.worldmodel, leafnum);
CM_WriteAreaBits(cl.worldmodel, areabits, clientarea);
}
#ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3)
{
D3D7_LeafWorldNode ();
}
else
#endif
D3D7_RecursiveQ2WorldNode (cl.worldmodel->nodes);
}
else
#endif
*/
D3D7_RecursiveWorldNode (cl.worldmodel->nodes);
RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n"));
// if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable)
D3D_DrawTextureChains();
// else
// DrawTextureChains (cl.worldmodel, 1, r_refdef.vieworg);
//qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// GLR_LessenStains();
}
}
void D3D_R_RenderScene(void)
{
if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap))
r_refdef.flags |= Q2RDF_NOWORLDMODEL;
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
R_MarkLeaves (); // done here so we know if we're in water
D3D_DrawWorld (); // adds static entities to the list
}
D3DR_DrawEntitiesOnList ();
P_DrawParticles();
}
void (D3D_R_RenderView) (void)
{
D3D_SetupFrame();
D3D_SetupViewPort();
R_SetFrustum();
D3D_R_RenderScene();
}
#endif