diff --git a/ref/dx2/r_context.c b/ref/dx2/r_context.c index 783208c6..a5f121fa 100644 --- a/ref/dx2/r_context.c +++ b/ref/dx2/r_context.c @@ -17,6 +17,7 @@ GNU General Public License for more details. #define INITGUID #include "r_local.h" #include "xash3d_mathlib.h" +#include "crtlib.h" //#pragma comment(lib, "ddraw.lib") //TODO COM_GetProcAddress @@ -229,8 +230,10 @@ static int RefGetParm( int parm, int arg ) case PARM_TEX_SKYBOX: Assert(arg >= 0 && arg < 6); return tr.skyboxTextures[arg]; +#endif case PARM_TEX_SKYTEXNUM: return tr.skytexturenum; +#if 0 case PARM_TEX_LIGHTMAP: arg = bound(0, arg, MAX_LIGHTMAPS - 1); return tr.lightmapTextures[arg]; @@ -347,6 +350,25 @@ static qboolean R_SpeedsMessage( char *out, size_t size ) static void R_NewMap( void ) { + model_t *WORLDMODEL = (gp_cl->models[1]); + + tr.skytexturenum = -1; + + // clearing texture chains + for( int i = 0; i < WORLDMODEL->numtextures; i++ ) + { + if( !WORLDMODEL->textures[i] ) + continue; + + texture_t *tx = WORLDMODEL->textures[i]; + + if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == ( tx->height * 2 )) + tr.skytexturenum = i; + + tx->texturechain = NULL; + } + + GL_BuildLightmaps(); if (gEngfuncs.drawFuncs->R_NewMap != NULL) gEngfuncs.drawFuncs->R_NewMap(); diff --git a/ref/dx2/r_d3d.c b/ref/dx2/r_d3d.c index a1597343..9c08c3dc 100644 --- a/ref/dx2/r_d3d.c +++ b/ref/dx2/r_d3d.c @@ -343,7 +343,7 @@ void GL_SetupAttributes( int safegl ) void GL_InitExtensions( void ) { - ; + tr.framecount = tr.visframecount = 1; } void GL_ClearExtensions( void ) diff --git a/ref/dx2/r_local.h b/ref/dx2/r_local.h index 593409b7..4aa8d628 100644 --- a/ref/dx2/r_local.h +++ b/ref/dx2/r_local.h @@ -168,11 +168,18 @@ typedef struct int grayTexture; int blackTexture; int cinTexture; // cinematic texture + + int skytexturenum; // index into model_t::textures + // entity lists draw_list_t draw_stack[MAX_DRAW_STACK]; int draw_stack_pos; draw_list_t *draw_list; + // matrix states + qboolean modelviewIdentity; + + int visframecount; // PVS frame int realframecount; // not including viewpasses int framecount; @@ -180,6 +187,10 @@ typedef struct qboolean fResetVis; double frametime; // special frametime for multipass rendering (will set to 0 on a nextview) + float blend; // global blend value + + // cull info + vec3_t modelorg; // relative to viewpoint // get from engine world_static_t *world; @@ -219,6 +230,28 @@ extern dx_context_t dxc; extern ref_api_t gEngfuncs; extern ref_client_t *gp_cl; + +static inline cl_entity_t *CL_GetEntityByIndex( int index ) +{ + if( unlikely( index < 0 || index >= tr.max_entities || !tr.entities )) + return NULL; + + return &tr.entities[index]; +} + +static inline model_t *CL_ModelHandle( int index ) +{ + if( unlikely( index < 0 || index >= gp_cl->nummodels )) + return NULL; + + return gp_cl->models[index]; +} + +static inline intptr_t ENGINE_GET_PARM( int parm ) +{ + return ( *gEngfuncs.EngineGetParm )( ( parm ), 0 ); +} + const char *dxResultToStr( HRESULT r ); #define DXCheckRet(DST, CALL) \ @@ -306,6 +339,7 @@ void Matrix4x4_CreateModelview( matrix4x4 out ); void GL_SubdivideSurface( model_t *mod, msurface_t *fa ); void GL_OrthoBounds( const float *mins, const float *maxs ); byte *Mod_GetCurrentVis( void ); +void GL_BuildLightmaps( void ); extern convar_t r_novis; extern convar_t r_nocull; diff --git a/ref/dx2/r_surf.c b/ref/dx2/r_surf.c index 9dd37805..1e27a6e4 100644 --- a/ref/dx2/r_surf.c +++ b/ref/dx2/r_surf.c @@ -14,6 +14,8 @@ GNU General Public License for more details. */ #include "r_local.h" +#include "xash3d_mathlib.h" + void GL_OrthoBounds( const float *mins, const float *maxs ) { @@ -25,7 +27,210 @@ byte *Mod_GetCurrentVis( void ) return NULL; } + +void R_LightmapCoord( const vec3_t v, const msurface_t *surf, const float sample_size, vec2_t coords ) +{ + const mextrasurf_t *info = surf->info; + float s, t; + +#define BLOCK_SIZE 256 + + s = DotProduct( v, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0]; + s += surf->light_s * sample_size; + s += sample_size * 0.5f; + s /= BLOCK_SIZE * sample_size; + + t = DotProduct( v, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1]; + t += surf->light_t * sample_size; + t += sample_size * 0.5f; + t /= BLOCK_SIZE * sample_size; + +#undef BLOCK_SIZE + + Vector2Set( coords, s, t ); +} + +static void R_TextureCoord( const vec3_t v, const msurface_t *surf, vec2_t coords ) +{ + const mtexinfo_t *info = surf->texinfo; + float s, t; + + s = DotProduct( v, info->vecs[0] ); + t = DotProduct( v, info->vecs[1] ); + + if( !FBitSet( surf->flags, SURF_DRAWTURB )) + { + s = ( s + info->vecs[0][3] ) / info->texture->width; + t = ( t + info->vecs[1][3] ) / info->texture->height; + } + + Vector2Set( coords, s, t ); +} + +static void R_GetEdgePosition( const model_t *mod, const msurface_t *fa, int i, vec3_t vec ) +{ + const int lindex = mod->surfedges[fa->firstedge + i]; + + if( FBitSet( mod->flags, MODEL_QBSP2 )) + { + const medge32_t *pedges = mod->edges32; + + if( lindex > 0 ) + VectorCopy( mod->vertexes[pedges[lindex].v[0]].position, vec ); + else + VectorCopy( mod->vertexes[pedges[-lindex].v[1]].position, vec ); + } + else + { + const medge16_t *pedges = mod->edges16; + + if( lindex > 0 ) + VectorCopy( mod->vertexes[pedges[lindex].v[0]].position, vec ); + else + VectorCopy( mod->vertexes[pedges[-lindex].v[1]].position, vec ); + } +} + void GL_SubdivideSurface( model_t *mod, msurface_t *fa ) { ; } + +/* +================ +GL_BuildPolygonFromSurface +================ +*/ +static int GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) +{ + int i, lnumverts, nColinElim = 0; + float sample_size; + texture_t *tex; + dx_texture_t *dxt; + glpoly2_t *poly; + + if( !mod || !fa->texinfo || !fa->texinfo->texture ) + return nColinElim; // bad polygon ? + + if( FBitSet( fa->flags, SURF_CONVEYOR ) && fa->texinfo->texture->gl_texturenum != 0 ) + { + dxt = R_GetTexture( fa->texinfo->texture->gl_texturenum ); + tex = fa->texinfo->texture; + Assert( dxt != NULL && tex != NULL ); + + // update conveyor widths for keep properly speed of scrolling + dxt->srcWidth = tex->width; + dxt->srcHeight = tex->height; + } + + sample_size = gEngfuncs.Mod_SampleSizeForFace( fa ); + + // reconstruct the polygon + lnumverts = fa->numedges; + + // detach if already created, reconstruct again + poly = fa->polys; + fa->polys = NULL; + + // quake simple models (healthkits etc) need to be reconstructed their polys because LM coords has changed after the map change + poly = Mem_Realloc( mod->mempool, poly, sizeof( glpoly2_t ) + lnumverts * VERTEXSIZE * sizeof( float )); + poly->next = fa->polys; + poly->flags = fa->flags; + fa->polys = poly; + poly->numverts = lnumverts; + + for( i = 0; i < lnumverts; i++ ) + { + R_GetEdgePosition( mod, fa, i, poly->verts[i] ); + R_TextureCoord( poly->verts[i], fa, &poly->verts[i][3] ); + R_LightmapCoord( poly->verts[i], fa, sample_size, &poly->verts[i][5] ); + } + + // TODO or not TODO gl_keeptjunctions? + + poly->numverts = lnumverts; + return nColinElim; +} + + +/* +================== +GL_BuildLightmaps + +Builds the lightmap texture +with all the surfaces from all brush models +================== +*/ +void GL_BuildLightmaps( void ) +{ + int i, j, nColinElim = 0; + model_t *m; +#if 0 + // release old lightmaps + for( i = 0; i < MAX_LIGHTMAPS; i++ ) + { + if( !tr.lightmapTextures[i] ) break; + GL_FreeTexture( tr.lightmapTextures[i] ); + } + + memset( tr.lightmapTextures, 0, sizeof( tr.lightmapTextures )); +#endif + memset( &RI, 0, sizeof( RI )); +#if 0 + // update the lightmap blocksize + if( FBitSet( gp_host->features, ENGINE_LARGE_LIGHTMAPS ) || tr.world->version == QBSP2_VERSION || r_large_lightmaps.value ) + tr.block_size = BLOCK_SIZE_MAX; + else tr.block_size = BLOCK_SIZE_DEFAULT; + + skychain = NULL; +#endif + tr.framecount = tr.visframecount = 1; // no dlight cache + //gl_lms.current_lightmap_texture = 0; + tr.modelviewIdentity = false; + tr.realframecount = 1; +#if 0 + // setup the texture for dlights + R_InitDlightTexture(); + + // setup all the lightstyles + CL_RunLightStyles((lightstyle_t *)ENGINE_GET_PARM( PARM_GET_LIGHTSTYLES_PTR )); + + LM_InitBlock(); +#endif + for( i = 0; i < gp_cl->nummodels; i++ ) + { + if(( m = CL_ModelHandle( i + 1 )) == NULL ) + continue; + + if( m->name[0] == '*' || m->type != mod_brush ) + continue; + + for( j = 0; j < m->numsurfaces; j++ ) + { + // clearing all decal chains + m->surfaces[j].pdecals = NULL; + m->surfaces[j].visframe = 0; + + //GL_CreateSurfaceLightmap( m->surfaces + j, m ); + + if( m->surfaces[j].flags & SURF_DRAWTURB ) + continue; + + nColinElim += GL_BuildPolygonFromSurface( m, m->surfaces + j ); + } + + // clearing visframe + for( j = 0; j < m->numleafs; j++ ) + m->leafs[j+1].visframe = 0; + for( j = 0; j < m->numnodes; j++ ) + m->nodes[j].visframe = 0; + } + + //LM_UploadBlock( false ); + + if( gEngfuncs.drawFuncs->GL_BuildLightmaps ) + { + // build lightmaps on the client-side + gEngfuncs.drawFuncs->GL_BuildLightmaps( ); + } +}