Portals, skyspheres, particles, lighting, texture clamps work.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3651 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2010-11-11 18:22:49 +00:00
parent ba3d1ecf28
commit 5f71f6d355
16 changed files with 486 additions and 102 deletions

View file

@ -518,6 +518,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_blend";
defaultshader =
"{\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc blend\n"
@ -532,6 +533,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_bc";
defaultshader =
"{\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc GL_SRC_COLOR GL_ONE_MINUS_SRC_COLOR\n"
@ -546,6 +548,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_add";
defaultshader =
"{\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc GL_SRC_ALPHA GL_ONE\n"
@ -560,6 +563,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_invmod";
defaultshader =
"{\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc GL_ZERO GL_ONE_MINUS_SRC_COLOR\n"
@ -574,6 +578,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
namepostfix = "_sub";
defaultshader =
"{\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_COLOR\n"

View file

@ -132,7 +132,6 @@ extern "C" {
#include "net.h"
#include "protocol.h"
#include "cmd.h"
#if 1//ndef SERVERONLY
#include "wad.h"
#include "screen.h"
#include "sbar.h"
@ -140,17 +139,10 @@ extern "C" {
#include "merged.h"
#include "render.h"
#include "client.h"
#endif
#include "gl_model.h"
#include "vm.h"
//#if defined(GLQUAKE)
#include "gl_model.h"
//#else
//#include "model.h"
//#endif
#ifdef PEXT_BULLETENS
#include "r_bulleten.h"
#endif

View file

@ -2082,7 +2082,7 @@ void Surf_DrawWorld (void)
RSpeedRemark();
#ifdef Q2BSPS
if (currententity->model->fromgame == fg_quake2 || currententity->model->fromgame == fg_quake3)
if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)
{
int leafnum;
int clientarea;
@ -2132,7 +2132,8 @@ void Surf_DrawWorld (void)
/*FIXME: move this away*/
Surf_LessenStains();
if (cl.worldmodel->fromgame == fg_quake || cl.worldmodel->fromgame == fg_halflife)
Surf_LessenStains();
Surf_CleanChains();
}

View file

@ -31,6 +31,9 @@ extern int r_framecount;
struct msurface_s;
struct batch_s;
struct model_s;
struct texnums_s;
struct texture_s;
static const texid_t r_nulltex = {0};
#define TEXVALID(t) ((t).num!=0)
@ -155,16 +158,16 @@ extern struct texture_s *r_notexture_mip;
extern entity_t r_worldentity;
//gl_alias.c
void R_GAlias_DrawBatch(struct batch_s *batch);
void R_GAlias_GenerateBatches(entity_t *e, struct batch_s **batches);
void R_LightArraysByte(vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals);
void R_LightArraysByte_BGR(vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals);
void R_LightArrays(vecV_t *coords, vec4_t *colours, int vertcount, vec3_t *normals);
void R_DrawSkyChain (struct batch_s *batch); /*called from the backend, and calls back into it*/
struct texnums_s R_InitSky (struct texture_s *mt, qbyte *src); /*generate q1 sky texnums*/
//r_surf.c
struct model_s;
struct msurface_s;
void Surf_DrawWorld(void);
void Surf_GenBrushBatches(struct batch_s **batches, entity_t *ent);
void Surf_StainSurf(struct msurface_s *surf, float *parms);
@ -412,7 +415,7 @@ extern cvar_t r_xflip;
#endif
extern cvar_t gl_maxdist;
extern cvar_t gl_clear;
extern cvar_t r_clear;
extern cvar_t gl_poly;
extern cvar_t gl_affinemodels;
extern cvar_t gl_nohwblend;

View file

@ -266,6 +266,8 @@ cvar_t gl_lightmap_shift = SCVARF ("gl_lightmap_shift", "0",
cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1",
CVAR_ARCHIVE);
cvar_t r_clear = CVARAF("r_clear","0",
"gl_clear", 0);
cvar_t gl_max_size = SCVARF ("gl_max_size", "1024", CVAR_RENDERERLATCH);
cvar_t gl_maxshadowlights = SCVARF ("gl_maxshadowlights", "2",
CVAR_ARCHIVE);
@ -369,9 +371,6 @@ void GLRenderer_Init(void)
Cvar_Register (&r_mirroralpha, GLRENDEREROPTIONS);
Cvar_Register (&r_norefresh, GLRENDEREROPTIONS);
Cvar_Register (&gl_clear, GLRENDEREROPTIONS);
Cvar_Register (&gl_affinemodels, GLRENDEREROPTIONS);
Cvar_Register (&gl_nohwblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblend, GLRENDEREROPTIONS);
@ -604,6 +603,7 @@ void Renderer_Init(void)
Cvar_Register (&r_fastskycolour, GRAPHICALNICETIES);
Cvar_Register (&r_wateralpha, GRAPHICALNICETIES);
Cvar_Register (&r_clear, GLRENDEREROPTIONS);
Cvar_Register (&gl_max_size, GLRENDEREROPTIONS);
Cvar_Register (&gl_maxdist, GLRENDEREROPTIONS);
Cvar_Register (&gl_miptexLevel, GRAPHICALNICETIES);

View file

@ -898,7 +898,7 @@ avec3_t shadelight;
#include <xmmintrin.h>
#endif
void R_LightArraysByte(vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals)
void R_LightArraysByte_BGR(vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals)
{
extern cvar_t r_vertexdlights;
int i;
@ -908,8 +908,13 @@ void R_LightArraysByte(vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3
byte_vec4_t ambientlightb;
byte_vec4_t shadelightb;
VectorScale(ambientlight, 255, ambientlightb);
VectorScale(shadelight, 255, shadelightb);
for (i = 0; i < 3; i++)
{
l = ambientlight[2-i]*255;
ambientlightb[i] = bound(0, l, 255);
l = shadelight[2-i]*255;
shadelightb[i] = bound(0, l, 255);
}
if (ambientlightb[0] == shadelightb[0] && ambientlightb[1] == shadelightb[1] && ambientlightb[2] == shadelightb[2])
{

View file

@ -1364,7 +1364,7 @@ qboolean CMod_LoadFaces (lump_t *l)
i = LittleLong(in->lightofs);
if (i == -1)
out->samples = NULL;
#ifdef GLQUAKE
#if defined(GLQUAKE) || defined(D3DQUAKE)
else if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D)
out->samples = loadmodel->lightdata + i;
#endif
@ -3835,7 +3835,8 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.NativeContents = CM_NativeContents;
break;
#if defined(GLQUAKE)
#if defined(GLQUAKE) || defined(D3DQUAKE)
case QR_DIRECT3D:
case QR_OPENGL:
// load into heap
#ifndef SERVERONLY

View file

@ -128,6 +128,7 @@ typedef struct
unsigned int lastpasscount;
texid_t curtex[MAX_TMUS];
unsigned int tmuflags[MAX_TMUS];
mesh_t **meshlist;
unsigned int nummeshes;
@ -494,7 +495,6 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
case T_GEN_ANIMMAP:
BindTexture(tu, pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes].ptr);
break;
/*fixme*/
case T_GEN_SINGLEMAP:
BindTexture(tu, pass->anim_frames[0].ptr);
break;
@ -513,18 +513,39 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
break;
}
/*lightmaps don't use mipmaps*/
if (pass->flags & SHADER_PASS_NOMIPMAP)
if ((pass->flags ^ shaderstate.tmuflags[tu]) & SHADER_PASS_CLAMP)
{
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
shaderstate.tmuflags[tu] ^= SHADER_PASS_CLAMP;
if (pass->flags & SHADER_PASS_CLAMP)
{
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
}
else
{
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
}
}
else
if ((pass->flags ^ shaderstate.tmuflags[tu]) & SHADER_PASS_NOMIPMAP)
{
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
shaderstate.tmuflags[tu] ^= SHADER_PASS_NOMIPMAP;
/*lightmaps don't use mipmaps*/
if (pass->flags & SHADER_PASS_NOMIPMAP)
{
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
}
else
{
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
}
}
switch (pass->blendmode)
@ -689,7 +710,7 @@ static void colourgenbyte(const shaderpass_t *pass, int cnt, const byte_vec4_t *
}
else
{
R_LightArraysByte(mesh->xyz_array, dst, cnt, mesh->normals_array);
R_LightArraysByte_BGR(mesh->xyz_array, dst, cnt, mesh->normals_array);
}
break;
case RGB_GEN_WAVE:
@ -855,10 +876,10 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa
}
}
else if (m->colors4f_array &&
(pass->rgbgen == RGB_GEN_VERTEX) ||
((pass->rgbgen == RGB_GEN_VERTEX) ||
(pass->rgbgen == RGB_GEN_EXACT_VERTEX) ||
(pass->rgbgen == RGB_GEN_ONE_MINUS_VERTEX) ||
(pass->alphagen == ALPHA_GEN_VERTEX))
(pass->alphagen == ALPHA_GEN_VERTEX)))
{
for (vertcount = 0, mno = 0; mno < shaderstate.nummeshes; mno++)
{
@ -1396,6 +1417,33 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
return true;
}
static void BE_Cull(unsigned int cullflags)
{
cullflags |= r_refdef.flipcull;
if (shaderstate.curcull != cullflags)
{
shaderstate.curcull = cullflags;
if (shaderstate.curcull & 1)
{
if (shaderstate.curcull & SHADER_CULL_FRONT)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CW);
else if (shaderstate.curcull & SHADER_CULL_BACK)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CCW);
else
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_NONE);
}
else
{
if (shaderstate.curcull & SHADER_CULL_FRONT)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CCW);
else if (shaderstate.curcull & SHADER_CULL_BACK)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CW);
else
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_NONE);
}
}
}
static void BE_DrawMeshChain_Internal(void)
{
unsigned int vertcount, idxcount, idxfirst;
@ -1406,16 +1454,7 @@ static void BE_DrawMeshChain_Internal(void)
unsigned int passno = 0;
shaderpass_t *pass = shaderstate.curshader->passes;
if (shaderstate.curcull != (shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK)))
{
shaderstate.curcull = shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK);
if (shaderstate.curcull & SHADER_CULL_FRONT)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CCW);
else if (shaderstate.curcull & SHADER_CULL_BACK)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CW);
else
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_NONE);
}
BE_Cull(shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK));
for (mno = 0, vertcount = 0, idxcount = 0; mno < shaderstate.nummeshes; mno++)
{
@ -1452,18 +1491,36 @@ static void BE_DrawMeshChain_Internal(void)
}
d3dcheck(IDirect3DIndexBuffer9_Unlock(shaderstate.dynidx_buff));
d3dcheck(IDirect3DDevice9_SetIndices(pD3DDev9, shaderstate.dynidx_buff));
/*now go through and flush each pass*/
for (passno = 0; passno < shaderstate.curshader->numpasses; passno += pass->numMergedPasses)
if (shaderstate.mode == BEM_DEPTHONLY)
{
if (!BE_DrawMeshChain_SetupPass(pass+passno, vertcount))
continue;
#ifdef BENCH
shaderstate.bench.draws++;
if (shaderstate.bench.clamp && shaderstate.bench.clamp < shaderstate.bench.draws)
continue;
#endif
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_COLORWRITEENABLE, 0);
/*deactivate any extras*/
for (passno = 0; passno < shaderstate.lastpasscount; )
{
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+passno, NULL, 0, 0));
BindTexture(passno, NULL);
d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, passno, D3DTSS_COLOROP, D3DTOP_DISABLE));
passno++;
}
shaderstate.lastpasscount = 0;
d3dcheck(IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, vertcount, idxfirst, idxcount/3));
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA);
}
else
{
/*now go through and flush each pass*/
for (passno = 0; passno < shaderstate.curshader->numpasses; passno += pass->numMergedPasses)
{
if (!BE_DrawMeshChain_SetupPass(pass+passno, vertcount))
continue;
#ifdef BENCH
shaderstate.bench.draws++;
if (shaderstate.bench.clamp && shaderstate.bench.clamp < shaderstate.bench.draws)
continue;
#endif
d3dcheck(IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, vertcount, idxfirst, idxcount/3));
}
}
}
@ -1712,6 +1769,8 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
float mv[16];
float m[16];
shaderstate.curentity = e;
m[0] = e->axis[0][0];
m[1] = e->axis[0][1];
m[2] = e->axis[0][2];
@ -1808,7 +1867,7 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
}
}
static void BE_SubmitBatch(batch_t *batch)
void BE_SubmitBatch(batch_t *batch)
{
shaderstate.nummeshes = batch->meshes - batch->firstmesh;
if (!shaderstate.nummeshes)
@ -1818,8 +1877,8 @@ static void BE_SubmitBatch(batch_t *batch)
return;
if (shaderstate.curentity != batch->ent)
{
shaderstate.curentity = batch->ent;
BE_RotateForEntity(batch->ent, batch->ent->model);
shaderstate.curtime = r_refdef.time - shaderstate.curentity->shaderTime;
}
shaderstate.meshlist = batch->mesh + batch->firstmesh;
shaderstate.curshader = batch->shader;
@ -1845,6 +1904,7 @@ void BE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_t
void BE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums)
{
shaderstate.curtime = realtime;
shaderstate.curshader = shader;
shaderstate.curtexnums = texnums?texnums:&shader->defaulttextures;
shaderstate.curlightmap = r_nulltex;
@ -2073,8 +2133,8 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->shader->flags & SHADER_SKY)
{
// if (shaderstate.mode == BEM_STANDARD)
// R_DrawSkyChain (batch);
if (shaderstate.mode == BEM_STANDARD)
R_DrawSkyChain (batch);
continue;
}
@ -2082,6 +2142,298 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
}
}
/*generates a new modelview matrix, as well as vpn vectors*/
static void R_MirrorMatrix(plane_t *plane)
{
float mirror[16];
float view[16];
float result[16];
vec3_t pnorm;
VectorNegate(plane->normal, pnorm);
mirror[0] = 1-2*pnorm[0]*pnorm[0];
mirror[1] = -2*pnorm[0]*pnorm[1];
mirror[2] = -2*pnorm[0]*pnorm[2];
mirror[3] = 0;
mirror[4] = -2*pnorm[1]*pnorm[0];
mirror[5] = 1-2*pnorm[1]*pnorm[1];
mirror[6] = -2*pnorm[1]*pnorm[2] ;
mirror[7] = 0;
mirror[8] = -2*pnorm[2]*pnorm[0];
mirror[9] = -2*pnorm[2]*pnorm[1];
mirror[10] = 1-2*pnorm[2]*pnorm[2];
mirror[11] = 0;
mirror[12] = -2*pnorm[0]*plane->dist;
mirror[13] = -2*pnorm[1]*plane->dist;
mirror[14] = -2*pnorm[2]*plane->dist;
mirror[15] = 1;
view[0] = vpn[0];
view[1] = vpn[1];
view[2] = vpn[2];
view[3] = 0;
view[4] = -vright[0];
view[5] = -vright[1];
view[6] = -vright[2];
view[7] = 0;
view[8] = vup[0];
view[9] = vup[1];
view[10] = vup[2];
view[11] = 0;
view[12] = r_refdef.vieworg[0];
view[13] = r_refdef.vieworg[1];
view[14] = r_refdef.vieworg[2];
view[15] = 1;
VectorMA(r_refdef.vieworg, 0.25, plane->normal, r_refdef.pvsorigin);
Matrix4_Multiply(mirror, view, result);
vpn[0] = result[0];
vpn[1] = result[1];
vpn[2] = result[2];
vright[0] = -result[4];
vright[1] = -result[5];
vright[2] = -result[6];
vup[0] = result[8];
vup[1] = result[9];
vup[2] = result[10];
r_refdef.vieworg[0] = result[12];
r_refdef.vieworg[1] = result[13];
r_refdef.vieworg[2] = result[14];
}
static entity_t *R_NearestPortal(plane_t *plane)
{
int i;
entity_t *best = NULL;
float dist, bestd = 0;
for (i = 0; i < cl_numvisedicts; i++)
{
if (cl_visedicts[i].rtype == RT_PORTALSURFACE)
{
dist = DotProduct(cl_visedicts[i].origin, plane->normal)-plane->dist;
dist = fabs(dist);
if (dist < 64 && (!best || dist < bestd))
best = &cl_visedicts[i];
}
}
return best;
}
static void TransformCoord(vec3_t in, vec3_t planea[3], vec3_t planeo, vec3_t viewa[3], vec3_t viewo, vec3_t result)
{
int i;
vec3_t local;
vec3_t transformed;
float d;
local[0] = in[0] - planeo[0];
local[1] = in[1] - planeo[1];
local[2] = in[2] - planeo[2];
VectorClear(transformed);
for ( i = 0 ; i < 3 ; i++ )
{
d = DotProduct(local, planea[i]);
VectorMA(transformed, d, viewa[i], transformed);
}
result[0] = transformed[0] + viewo[0];
result[1] = transformed[1] + viewo[1];
result[2] = transformed[2] + viewo[2];
}
static void TransformDir(vec3_t in, vec3_t planea[3], vec3_t viewa[3], vec3_t result)
{
int i;
float d;
vec3_t tmp;
VectorCopy(in, tmp);
VectorClear(result);
for ( i = 0 ; i < 3 ; i++ )
{
d = DotProduct(tmp, planea[i]);
VectorMA(result, d, viewa[i], result);
}
}
static R_RenderScene(void)
{
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_refdef.m_projection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view);
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
Surf_DrawWorld();
}
static void R_DrawPortal(batch_t *batch, batch_t **blist)
{
entity_t *view;
float glplane[4];
plane_t plane;
refdef_t oldrefdef;
mesh_t *mesh = batch->mesh[batch->firstmesh];
int sort;
if (r_refdef.recurse)
return;
VectorCopy(mesh->normals_array[0], plane.normal);
plane.dist = DotProduct(mesh->xyz_array[0], plane.normal);
//if we're too far away from the surface, don't draw anything
if (batch->shader->flags & SHADER_AGEN_PORTAL)
{
/*there's a portal alpha blend on that surface, that fades out after this distance*/
if (DotProduct(r_refdef.vieworg, plane.normal)-plane.dist > batch->shader->portaldist)
return;
}
//if we're behind it, then also don't draw anything.
if (DotProduct(r_refdef.vieworg, plane.normal)-plane.dist < 0)
return;
view = R_NearestPortal(&plane);
//if (!view)
// return;
oldrefdef = r_refdef;
r_refdef.recurse = true;
r_refdef.externalview = true;
if (!view || VectorCompare(view->origin, view->oldorigin))
{
r_refdef.flipcull ^= true;
R_MirrorMatrix(&plane);
}
else
{
float d;
vec3_t paxis[3], porigin, vaxis[3], vorg;
void PerpendicularVector( vec3_t dst, const vec3_t src );
/*calculate where the surface is meant to be*/
VectorCopy(mesh->normals_array[0], paxis[0]);
PerpendicularVector(paxis[1], paxis[0]);
CrossProduct(paxis[0], paxis[1], paxis[2]);
d = DotProduct(view->origin, plane.normal) - plane.dist;
VectorMA(view->origin, -d, paxis[0], porigin);
/*grab the camera origin*/
VectorNegate(view->axis[0], vaxis[0]);
VectorNegate(view->axis[1], vaxis[1]);
VectorCopy(view->axis[2], vaxis[2]);
VectorCopy(view->oldorigin, vorg);
VectorCopy(vorg, r_refdef.pvsorigin);
/*rotate it a bit*/
RotatePointAroundVector(vaxis[1], vaxis[0], view->axis[1], sin(realtime)*4);
CrossProduct(vaxis[0], vaxis[1], vaxis[2]);
TransformCoord(oldrefdef.vieworg, paxis, porigin, vaxis, vorg, r_refdef.vieworg);
TransformDir(vpn, paxis, vaxis, vpn);
TransformDir(vright, paxis, vaxis, vright);
TransformDir(vup, paxis, vaxis, vup);
}
Matrix4_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg);
VectorAngles(vpn, vup, r_refdef.viewangles);
VectorCopy(r_refdef.vieworg, r_origin);
/*FIXME: the batch stuff should be done in renderscene*/
/*fixup the first mesh index*/
for (sort = 0; sort < SHADER_SORT_COUNT; sort++)
for (batch = blist[sort]; batch; batch = batch->next)
{
batch->firstmesh = batch->meshes;
}
/*FIXME: can we get away with stenciling the screen?*/
/*Add to frustum culling instead of clip planes?*/
glplane[0] = plane.normal[0];
glplane[1] = plane.normal[1];
glplane[2] = plane.normal[2];
glplane[3] = -plane.dist;
IDirect3DDevice9_SetClipPlane(pD3DDev9, 0, glplane);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0);
R_RenderScene();
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CLIPPLANEENABLE, 0);
for (sort = 0; sort < SHADER_SORT_COUNT; sort++)
for (batch = blist[sort]; batch; batch = batch->next)
{
batch->firstmesh = 0;
}
r_refdef = oldrefdef;
/*broken stuff*/
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_refdef.m_projection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view);
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
}
static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
{
batch_t *batch, *old;
int i;
/*attempt to draw portal shaders*/
if (shaderstate.mode == BEM_STANDARD)
{
for (i = 0; i < 2; i++)
{
for (batch = i?dynamiclist:worldlist[SHADER_SORT_PORTAL]; batch; batch = batch->next)
{
if (batch->meshes == batch->firstmesh)
continue;
if (batch->buildmeshes)
batch->buildmeshes(batch);
else
batch->shader = R_TextureAnimation(batch->ent->framestate.g[FS_REG].frame[0], batch->texture)->shader;
/*draw already-drawn portals as depth-only, to ensure that their contents are not harmed*/
BE_SelectMode(BEM_DEPTHONLY, 0);
for (old = worldlist[SHADER_SORT_PORTAL]; old && old != batch; old = old->next)
{
if (old->meshes == old->firstmesh)
continue;
BE_SubmitBatch(old);
}
if (!old)
{
for (old = dynamiclist; old != batch; old = old->next)
{
if (old->meshes == old->firstmesh)
continue;
BE_SubmitBatch(old);
}
}
BE_SelectMode(BEM_STANDARD, 0);
R_DrawPortal(batch, worldlist);
/*clear depth again*/
IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0);
}
}
}
}
void BE_SubmitMeshes (qboolean drawworld, batch_t **blist)
{
model_t *model = cl.worldmodel;
@ -2091,8 +2443,8 @@ void BE_SubmitMeshes (qboolean drawworld, batch_t **blist)
{
if (drawworld)
{
// if (i == SHADER_SORT_PORTAL && !r_noportals.ival && !r_refdef.recurse)
// BE_SubmitMeshesPortals(model->batches, blist[i]);
if (i == SHADER_SORT_PORTAL /*&& !r_noportals.ival*/ && !r_refdef.recurse)
BE_SubmitMeshesPortals(model->batches, blist[i]);
BE_SubmitMeshesSortList(model->batches[i]);
}
@ -2105,6 +2457,8 @@ void BE_DrawWorld (qbyte *vis)
batch_t *batches[SHADER_SORT_COUNT];
RSpeedLocals();
shaderstate.curentity = NULL;
if (!r_refdef.recurse)
{
if (shaderstate.wbatch > shaderstate.maxwbatches)
@ -2119,8 +2473,6 @@ void BE_DrawWorld (qbyte *vis)
BE_GenModelBatches(batches);
shaderstate.curtime = realtime;
if (vis)
{
BE_UploadLightmaps(false);

View file

@ -198,7 +198,7 @@ static LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_32(d3dtexture_t *tex, unsigned in
return (LPDIRECT3DBASETEXTURE9)newsurf;
}
static LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8(d3dtexture_t *tex, unsigned char *data, int width, int height, int flags, enum uploadfmt fmt)
static LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8(d3dtexture_t *tex, unsigned char *data, unsigned int *pal32, int width, int height, int flags, enum uploadfmt fmt)
{
static unsigned trans[1024*1024];
int i, s;
@ -218,11 +218,11 @@ static LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8(d3dtexture_t *tex, unsigned cha
p = data[i];
noalpha = true;
if (p > 255-vid.fullbright)
trans[i] = d_8to24rgbtable[p];
trans[i] = pal32[p];
else
{
noalpha = false;
trans[i] = d_8to24rgbtable[p] & 0x00ffffff;
trans[i] = pal32[p] & 0x00ffffff;
}
}
}
@ -238,7 +238,7 @@ static LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8(d3dtexture_t *tex, unsigned cha
trans[i] = 0;
}
else
trans[i] = d_8to24rgbtable[p];
trans[i] = pal32[p];
}
switch(fmt)
@ -291,14 +291,14 @@ static LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8(d3dtexture_t *tex, unsigned cha
{
for (i=(s&~3)-4 ; i>=0 ; i-=4)
{
trans[i] = d_8to24rgbtable[data[i]];
trans[i+1] = d_8to24rgbtable[data[i+1]];
trans[i+2] = d_8to24rgbtable[data[i+2]];
trans[i+3] = d_8to24rgbtable[data[i+3]];
trans[i] = pal32[data[i]];
trans[i+1] = pal32[data[i+1]];
trans[i+2] = pal32[data[i+2]];
trans[i+3] = pal32[data[i+3]];
}
for (i=s&~3 ; i<s ; i++) //wow, funky
{
trans[i] = d_8to24rgbtable[data[i]];
trans[i] = pal32[data[i]];
}
}
return D3D9_LoadTexture_32(tex, trans, width, height, flags);
@ -348,7 +348,7 @@ texid_t D3D9_LoadTexture (char *identifier, int width, int height, enum uploadfm
case TF_H2_TRANS8_0:
case TF_H2_T4A4:
case TF_TRANS8_FULLBRIGHT:
tid.ptr = D3D9_LoadTexture_8(tex, data, width, height, flags, fmt);
tid.ptr = D3D9_LoadTexture_8(tex, data, d_8to24rgbtable, width, height, flags, fmt);
return tid;
case TF_RGBA32:
tid.ptr = D3D9_LoadTexture_32(tex, data, width, height, flags);
@ -372,11 +372,22 @@ texid_t D3D9_FindTexture (char *identifier)
texid_t D3D9_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags)
{
return r_nulltex;
d3dtexture_t *tex = d3d_lookup_texture(identifier);
tex->tex.ptr = D3D9_LoadTexture_8(tex, data, (unsigned int *)palette32, width, height, flags, TF_SOLID8);
return tex->tex;
}
texid_t D3D9_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags)
{
return r_nulltex;
unsigned int pal32[256];
int i;
for (i = 0; i < 256; i++)
{
pal32[i] = 0x00000000 |
(palette24[i*3+2]<<24) |
(palette24[i*3+1]<<8) |
(palette24[i*3+0]<<0);
}
return D3D9_LoadTexture8Pal32(identifier, width, height, data, pal32, flags);
}
#endif

View file

@ -1122,17 +1122,24 @@ static void D3D9_SetupViewPort(void)
screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
Matrix4_Projection_Inf(r_refdef.m_projection, fov_x, fov_y, gl_mindist.value);
/*view matrix*/
Matrix4_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg);
d3d9error(IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view));
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_refdef.m_projection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view);
/*d3d projection matricies scale depth to 0 to 1*/
Matrix4_Projection_Inf(r_refdef.m_projection, fov_x, fov_y, gl_mindist.value/2);
d3d9error(IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_refdef.m_projection));
/*ogl projection matricies scale depth to -1 to 1, and I would rather my code used consistant culling*/
Matrix4_Projection_Inf(r_refdef.m_projection, fov_x, fov_y, gl_mindist.value);
}
static void (D3D9_R_RenderView) (void)
{
D3D9_SetupViewPort();
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET| D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
if (r_clear.ival && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
else
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
RQ_BeginFrame();
Surf_DrawWorld();

View file

@ -327,7 +327,7 @@ extern cvar_t r_glsl_offsetmapping, r_noportals;
#endif
static void BE_SendPassBlendAndDepth(unsigned int sbits);
static void BE_SubmitBatch(batch_t *batch);
void BE_SubmitBatch(batch_t *batch);
struct {
//internal state
@ -2641,7 +2641,7 @@ void BE_DrawPolys(qboolean decalsset)
BE_DrawMesh_Single(cl_stris[i].shader, &m, NULL, &cl_stris[i].shader->defaulttextures);
}
}
static void BE_SubmitBatch(batch_t *batch)
void BE_SubmitBatch(batch_t *batch)
{
model_t *model = cl.worldmodel;
int lm;

View file

@ -74,7 +74,6 @@ cvar_t r_norefresh = SCVAR("r_norefresh","0");
extern cvar_t gl_part_flame;
extern cvar_t r_bloom;
cvar_t gl_clear = SCVAR("gl_clear","0");
cvar_t gl_affinemodels = SCVAR("gl_affinemodels","0");
cvar_t gl_playermip = SCVAR("gl_playermip","0");
cvar_t gl_reporttjunctions = SCVAR("gl_reporttjunctions","0");
@ -1404,7 +1403,7 @@ void R_Clear (void)
/*tbh, this entire function should be in the backend*/
GL_ForceDepthWritable();
{
if (gl_clear.value && !r_secondaryview && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
if (r_clear.ival && !r_secondaryview && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
qglClear (GL_DEPTH_BUFFER_BIT);

View file

@ -1122,6 +1122,7 @@ static void Shaderpass_ClampMap (shader_t *shader, shaderpass_t *pass, char **pt
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = Shader_FindImage (token, flags | IF_CLAMP);
pass->texgen = T_GEN_SINGLEMAP;
pass->flags |= SHADER_PASS_CLAMP;
if (!TEXVALID(pass->anim_frames[0]))
{

View file

@ -458,6 +458,9 @@ static void GL_SkyForceDepth(batch_t *batch)
static void GL_DrawSkySphere (batch_t *batch, shader_t *shader)
{
static entity_t skyent;
batch_t b;
mesh_t *m;
float time = cl.gametime+realtime-cl.gametimemark;
float skydist = gl_maxdist.value;
@ -465,18 +468,28 @@ static void GL_DrawSkySphere (batch_t *batch, shader_t *shader)
skydist=gl_skyboxdist.value;
skydist/=16;
#ifdef GLQUAKE
BE_SelectEntity(&r_worldentity);
//scale sky sphere and place around view origin.
qglPushMatrix();
qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]);
qglScalef(skydist, skydist, skydist);
VectorCopy(r_refdef.vieworg, skyent.origin);
skyent.axis[0][0] = skydist;
skyent.axis[0][1] = 0;
skyent.axis[0][3] = 0;
skyent.axis[1][0] = 0;
skyent.axis[1][1] = skydist;
skyent.axis[1][2] = 0;
skyent.axis[2][0] = 0;
skyent.axis[2][1] = 0;
skyent.axis[2][2] = skydist;
skyent.scale = 1;
//FIXME: We should use the skybox clipping code and split the sphere into 6 sides.
gl_skyspherecalc(2);
BE_DrawMesh_Single(shader, &skymesh, NULL, &batch->shader->defaulttextures);
qglPopMatrix();
#endif
b = *batch;
b.meshes = 1;
b.firstmesh = 0;
m = &skymesh;
b.mesh = &m;
b.ent = &skyent;
b.shader = shader;
BE_SubmitBatch(&b);
}

View file

@ -291,14 +291,6 @@ void FTE_DEPRECATED R_BackendInit(void);
void FTE_DEPRECATED R_IBrokeTheArrays(void);
#endif
//
// gl_warp.c
//
void R_DrawSkyChain (batch_t *batch); /*called from the backend, and calls back into it*/
texnums_t R_InitSky (texture_t *mt, qbyte *src); /*generate q1 sky texnums*/
//
// gl_draw.c
//

View file

@ -211,6 +211,7 @@ typedef struct shaderpass_s {
enum {
SHADER_PASS_NOMIPMAP = 1<<1,
SHADER_PASS_CLAMP = 1<<2,
SHADER_PASS_NOCOLORARRAY = 1<< 3,
//FIXME: remove these
@ -402,6 +403,7 @@ void BE_SelectMode(backendmode_t mode, unsigned int flags);
Rules for using a list: Every mesh must be part of the same VBO, shader, lightmap, and must have the same pointers set*/
void BE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **mesh, vbo_t *vbo, texnums_t *texnums);
void BE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums);
void BE_SubmitBatch(batch_t *batch);
batch_t *BE_GetTempBatch(void);
//Asks the backend to invoke DrawMeshChain for each surface, and to upload lightmaps as required