mempool_t *r_main_mempool;
rtexturepool_t *r_main_texturepool;
-static int r_textureframe = 0; ///< used only by R_GetCurrentTexture
+int r_textureframe = 0; ///< used only by R_GetCurrentTexture, incremented per view and per UI render
static qboolean r_loadnormalmap;
static qboolean r_loadgloss;
cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
-cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps (DEPRECATED)"};
-cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier (DEPRECATED)"};
-#define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
-
cvar_t r_fullbright_directed = {0, "r_fullbright_directed", "0", "render fullbright things (unlit worldmodel and EF_FULLBRIGHT entities, but not fullbright shaders) using a constant light direction instead to add more depth while keeping uniform brightness"};
cvar_t r_fullbright_directed_ambient = {0, "r_fullbright_directed_ambient", "0.5", "ambient light multiplier for directed fullbright"};
cvar_t r_fullbright_directed_diffuse = {0, "r_fullbright_directed_diffuse", "0.75", "diffuse light multiplier for directed fullbright"};
{"combined", "glsl", builtinshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"},
{"combined", "glsl", builtinshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
{"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"},
- {"combined", "glsl", builtinshaderstrings, "#define MODE_FAKELIGHT\n", " fakelight"},
{"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
{"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
{"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
geomstrings_list[geomstrings_count++] = sourcestring;
fragstrings_list[fragstrings_count++] = sourcestring;
+ // we don't currently use geometry shaders for anything, so just empty the list
+ geomstrings_count = 0;
+
// compile the shader program
if (vertstrings_count + geomstrings_count + fragstrings_count)
p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
{
if (!r_glsl_permutation->compiled)
{
- Con_DPrintf("Compiling shader mode %u permutation %u\n", mode, permutation);
+ Con_DPrintf("Compiling shader mode %u permutation %llx\n", mode, permutation);
R_GLSL_CompilePermutation(perm, mode, permutation);
}
if (!r_glsl_permutation->program)
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
if (t->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- if (FAKELIGHT_ENABLED)
- {
- // fake lightmapping (q1bsp, q3bsp, fullbright map)
- mode = SHADERMODE_FAKELIGHT;
- permutation |= SHADERPERMUTATION_DIFFUSE;
- if (VectorLength2(t->render_lightmap_specular) > 0)
- permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
- }
- else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
+ if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
{
// deluxemapping (light direction texture)
if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
case RENDERPATH_GL32:
case RENDERPATH_GLES2:
RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
- R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
- R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
- R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
- R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
- R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
- R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, rsurface.batchskeletalindex4ub_vertexbuffer, rsurface.batchskeletalindex4ub_bufferoffset);
- R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, rsurface.batchskeletalweight4ub_vertexbuffer, rsurface.batchskeletalweight4ub_bufferoffset);
+ RSurf_UploadBuffersForBatch();
// this has to be after RSurf_PrepareVerticesForBatch
if (rsurface.batchskeletaltransform3x4buffer)
permutation |= SHADERPERMUTATION_SKELETAL;
skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
{
skinframe_t *item;
+ int compareflags = textureflags & TEXF_IMPORTANTBITS;
int hashindex;
char basename[MAX_QPATH];
hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
for (item = r_skinframe.hash[hashindex];item;item = item->next)
- if (!strcmp(item->basename, basename) && (comparecrc < 0 || (item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)))
+ if (!strcmp(item->basename, basename) &&
+ item->textureflags == compareflags &&
+ item->comparewidth == comparewidth &&
+ item->compareheight == compareheight &&
+ item->comparecrc == comparecrc)
break;
if (!item)
item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
memset(item, 0, sizeof(*item));
strlcpy(item->basename, basename, sizeof(item->basename));
- item->textureflags = textureflags & ~TEXF_FORCE_RELOAD;
+ item->textureflags = compareflags;
item->comparewidth = comparewidth;
item->compareheight = compareheight;
item->comparecrc = comparecrc;
r_skinframe.hash[hashindex] = item;
}
else if (textureflags & TEXF_FORCE_RELOAD)
- {
- if (!add)
- return NULL;
R_SkinFrame_PurgeSkinFrame(item);
- }
R_SkinFrame_MarkUsed(item);
return item;
return NULL;
// return an existing skinframe if already loaded
- // if loading of the first image fails, don't make a new skinframe as it
- // would cause all future lookups of this to be missing
- skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, -1, false);
+ skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
if (skinframe && skinframe->base)
return skinframe;
+ // if the skinframe doesn't exist this will create it
return R_SkinFrame_LoadExternal_SkinFrame(skinframe, name, textureflags, complain, fallbacknotexture);
}
R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
#ifndef USE_GLES2
//Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->base)
+ if (r_savedds && skinframe->base)
R_SaveTextureDDSFile(skinframe->base, va(vabuf, sizeof(vabuf), "dds/%s.dds", skinframe->basename), r_texture_dds_save.integer < 2, skinframe->hasalpha);
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog)
+ if (r_savedds && skinframe->fog)
R_SaveTextureDDSFile(skinframe->fog, va(vabuf, sizeof(vabuf), "dds/%s_mask.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
#endif
}
Mem_Free(pixels);
}
#ifndef USE_GLES2
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap)
+ if (r_savedds && skinframe->nmap)
R_SaveTextureDDSFile(skinframe->nmap, va(vabuf, sizeof(vabuf), "dds/%s_norm.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
#endif
}
{
skinframe->glow = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
#ifndef USE_GLES2
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
+ if (r_savedds && skinframe->glow)
R_SaveTextureDDSFile(skinframe->glow, va(vabuf, sizeof(vabuf), "dds/%s_glow.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
#endif
Mem_Free(pixels);pixels = NULL;
{
skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
#ifndef USE_GLES2
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
+ if (r_savedds && skinframe->gloss)
R_SaveTextureDDSFile(skinframe->gloss, va(vabuf, sizeof(vabuf), "dds/%s_gloss.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
#endif
Mem_Free(pixels);
{
skinframe->pants = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_pants", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
#ifndef USE_GLES2
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
+ if (r_savedds && skinframe->pants)
R_SaveTextureDDSFile(skinframe->pants, va(vabuf, sizeof(vabuf), "dds/%s_pants.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
#endif
Mem_Free(pixels);
{
skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_shirt", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
#ifndef USE_GLES2
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
+ if (r_savedds && skinframe->shirt)
R_SaveTextureDDSFile(skinframe->shirt, va(vabuf, sizeof(vabuf), "dds/%s_shirt.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
#endif
Mem_Free(pixels);
{
skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_reflect", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
#ifndef USE_GLES2
- if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
+ if (r_savedds && skinframe->reflect)
R_SaveTextureDDSFile(skinframe->reflect, va(vabuf, sizeof(vabuf), "dds/%s_reflect.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
#endif
Mem_Free(pixels);
return skinframe;
}
-// this is only used by .spr32 sprites, HL .spr files, HL .bsp files
-skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, qboolean sRGB)
+skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, int comparewidth, int compareheight, int comparecrc, qboolean sRGB)
{
int i;
skinframe_t *skinframe;
return NULL;
// if already loaded just return it, otherwise make a new skinframe
- skinframe = R_SkinFrame_Find(name, textureflags, width, height, (!(textureflags & TEXF_FORCE_RELOAD) && skindata) ? CRC_Block(skindata, width*height*4) : -1, true);
+ skinframe = R_SkinFrame_Find(name, textureflags, comparewidth, compareheight, comparecrc, true);
if (skinframe->base)
return skinframe;
textureflags &= ~TEXF_FORCE_RELOAD;
return NULL;
// if already loaded just return it, otherwise make a new skinframe
- skinframe = R_SkinFrame_Find(name, textureflags, width, height, (!(textureflags & TEXF_FORCE_RELOAD) && skindata) ? CRC_Block(skindata, width*height) : -1, true);
+ skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
if (skinframe->base)
return skinframe;
//textureflags &= ~TEXF_FORCE_RELOAD;
}
}
- return R_SkinFrame_LoadInternalBGRA("notexture", TEXF_FORCENEAREST, pix[0][0], 16, 16, false);
+ return R_SkinFrame_LoadInternalBGRA("notexture", TEXF_FORCENEAREST, pix[0][0], 16, 16, 0, 0, 0, false);
}
skinframe_t *R_SkinFrame_LoadInternalUsingTexture(const char *name, int textureflags, rtexture_t *tex, int width, int height, qboolean sRGB)
if (cls.state == ca_dedicated)
return NULL;
// if already loaded just return it, otherwise make a new skinframe
- skinframe = R_SkinFrame_Find(name, textureflags, width, height, (textureflags & TEXF_FORCE_RELOAD) ? -1 : 0, true);
+ skinframe = R_SkinFrame_Find(name, textureflags, width, height, 0, true);
if (skinframe->base)
return skinframe;
textureflags &= ~TEXF_FORCE_RELOAD;
r_uniformbufferalignment = 32;
r_loaddds = r_texture_dds_load.integer != 0;
- r_savedds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_save.integer;
+ r_savedds = vid.support.ext_texture_compression_s3tc && r_texture_dds_save.integer;
switch(vid.renderpath)
{
case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- Cvar_SetValueQuick(&r_textureunits, vid.texunits);
+ Cvar_SetValueQuick(&r_textureunits, MAX_TEXTUREUNITS);
Cvar_SetValueQuick(&gl_combine, 1);
Cvar_SetValueQuick(&r_glsl, 1);
r_loadnormalmap = true;
{
case RENDERPATH_GL32:
case RENDERPATH_GLES2:
-#if defined(GL_SAMPLES_PASSED_ARB) && !defined(USE_GLES2)
+#if defined(GL_SAMPLES_PASSED) && !defined(USE_GLES2)
if (r_maxqueries)
- qglDeleteQueriesARB(r_maxqueries, r_queries);
+ qglDeleteQueries(r_maxqueries, r_queries);
#endif
break;
}
Cvar_RegisterVariable(&r_fullbrights);
Cvar_RegisterVariable(&r_wateralpha);
Cvar_RegisterVariable(&r_dynamic);
- Cvar_RegisterVariable(&r_fakelight);
- Cvar_RegisterVariable(&r_fakelight_intensity);
Cvar_RegisterVariable(&r_fullbright_directed);
Cvar_RegisterVariable(&r_fullbright_directed_ambient);
Cvar_RegisterVariable(&r_fullbright_directed_diffuse);
Mod_RenderInit();
}
-/*
-===============
-GL_Init
-===============
-*/
-#ifndef USE_GLES2
-extern char *ENGINE_EXTENSIONS;
-void GL_Init (void)
-{
- gl_renderer = (const char *)qglGetString(GL_RENDERER);
- gl_vendor = (const char *)qglGetString(GL_VENDOR);
- gl_version = (const char *)qglGetString(GL_VERSION);
- gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
-
- if (!gl_extensions)
- gl_extensions = "";
- if (!gl_platformextensions)
- gl_platformextensions = "";
-
- Con_Printf("GL_VENDOR: %s\n", gl_vendor);
- Con_Printf("GL_RENDERER: %s\n", gl_renderer);
- Con_Printf("GL_VERSION: %s\n", gl_version);
- Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
- Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
-
- VID_CheckExtensions();
-
- // LordHavoc: report supported extensions
-#ifdef CONFIG_MENU
- Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
-#else
- Con_DPrintf("\nQuakeC extensions for server and client: %s\n", vm_sv_extensions );
-#endif
-
- // clear to black (loading plaque will be seen over this)
- GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0);
-}
-#endif
-
int R_CullBox(const vec3_t mins, const vec3_t maxs)
{
int i;
r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
r_refdef.scene.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
- if (FAKELIGHT_ENABLED)
- {
- r_refdef.scene.lightmapintensity *= r_fakelight_intensity.value;
- }
- else if (r_refdef.scene.worldmodel)
+ if (r_refdef.scene.worldmodel)
{
r_refdef.scene.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale;
}
t->render_rtlight_specular[q] = 0;
}
}
- else if (FAKELIGHT_ENABLED)
- {
- // no modellight if using fakelight for the map
- t->currentmaterialflags = (t->currentmaterialflags | MATERIALFLAG_NORTLIGHT) & ~(MATERIALFLAG_MODELLIGHT);
- for (q = 0; q < 3; q++)
- {
- t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
- t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q];
- t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale;
- t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale;
- t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale;
- t->render_lightmap_ambient[q] = 0;
- t->render_lightmap_diffuse[q] = 0;
- t->render_lightmap_specular[q] = 0;
- t->render_rtlight_diffuse[q] = 0;
- t->render_rtlight_specular[q] = 0;
- }
- }
else if ((rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT)) || rsurface.modeltexcoordlightmap2f == NULL)
{
// ambient + single direction light (modellight)
r_refdef.stats[r_stat_batch_entitystatic_triangles] += model->surfmesh.num_triangles;
}
rsurface.modelvertex3f = model->surfmesh.data_vertex3f;
- rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f;
+ rsurface.modelvertex3f_vertexbuffer = model->surfmesh.data_vertex3f_vertexbuffer;
+ rsurface.modelvertex3f_bufferoffset = model->surfmesh.data_vertex3f_bufferoffset;
rsurface.modelsvector3f = model->surfmesh.data_svector3f;
- rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f;
+ rsurface.modelsvector3f_vertexbuffer = model->surfmesh.data_svector3f_vertexbuffer;
+ rsurface.modelsvector3f_bufferoffset = model->surfmesh.data_svector3f_bufferoffset;
rsurface.modeltvector3f = model->surfmesh.data_tvector3f;
- rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f;
+ rsurface.modeltvector3f_vertexbuffer = model->surfmesh.data_tvector3f_vertexbuffer;
+ rsurface.modeltvector3f_bufferoffset = model->surfmesh.data_tvector3f_bufferoffset;
rsurface.modelnormal3f = model->surfmesh.data_normal3f;
- rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f;
+ rsurface.modelnormal3f_vertexbuffer = model->surfmesh.data_normal3f_vertexbuffer;
+ rsurface.modelnormal3f_bufferoffset = model->surfmesh.data_normal3f_bufferoffset;
rsurface.modelgeneratedvertex = false;
}
rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f;
- rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f;
+ rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.data_lightmapcolor4f_vertexbuffer;
+ rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.data_lightmapcolor4f_bufferoffset;
rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f;
- rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f;
+ rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.data_texcoordtexture2f_vertexbuffer;
+ rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.data_texcoordtexture2f_bufferoffset;
rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f;
- rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
+ rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.data_texcoordlightmap2f_vertexbuffer;
+ rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.data_texcoordlightmap2f_bufferoffset;
rsurface.modelskeletalindex4ub = model->surfmesh.data_skeletalindex4ub;
- rsurface.modelskeletalindex4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelskeletalindex4ub_bufferoffset = model->surfmesh.vbooffset_skeletalindex4ub;
+ rsurface.modelskeletalindex4ub_vertexbuffer = model->surfmesh.data_skeletalindex4ub_vertexbuffer;
+ rsurface.modelskeletalindex4ub_bufferoffset = model->surfmesh.data_skeletalindex4ub_bufferoffset;
rsurface.modelskeletalweight4ub = model->surfmesh.data_skeletalweight4ub;
- rsurface.modelskeletalweight4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelskeletalweight4ub_bufferoffset = model->surfmesh.vbooffset_skeletalweight4ub;
+ rsurface.modelskeletalweight4ub_vertexbuffer = model->surfmesh.data_skeletalweight4ub_vertexbuffer;
+ rsurface.modelskeletalweight4ub_bufferoffset = model->surfmesh.data_skeletalweight4ub_bufferoffset;
rsurface.modelelement3i = model->surfmesh.data_element3i;
rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer;
rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset;
return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
}
+void RSurf_UploadBuffersForBatch(void)
+{
+ // upload buffer data for generated vertex data (dynamicvertex case) or index data (copytriangles case) and models that lack it to begin with (e.g. DrawQ_FlushUI)
+ // note that if rsurface.batchvertex3f_vertexbuffer is NULL, dynamicvertex is forced as we don't account for the proper base vertex here.
+ if (rsurface.batchvertex3f && !rsurface.batchvertex3f_vertexbuffer)
+ rsurface.batchvertex3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f, R_BUFFERDATA_VERTEX, &rsurface.batchvertex3f_bufferoffset);
+ if (rsurface.batchsvector3f && !rsurface.batchsvector3f_vertexbuffer)
+ rsurface.batchsvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchsvector3f_bufferoffset);
+ if (rsurface.batchtvector3f && !rsurface.batchtvector3f_vertexbuffer)
+ rsurface.batchtvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchtvector3f_bufferoffset);
+ if (rsurface.batchnormal3f && !rsurface.batchnormal3f_vertexbuffer)
+ rsurface.batchnormal3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f, R_BUFFERDATA_VERTEX, &rsurface.batchnormal3f_bufferoffset);
+ if (rsurface.batchlightmapcolor4f && !rsurface.batchlightmapcolor4f_vertexbuffer)
+ rsurface.batchlightmapcolor4f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[4]), rsurface.batchlightmapcolor4f, R_BUFFERDATA_VERTEX, &rsurface.batchlightmapcolor4f_bufferoffset);
+ if (rsurface.batchtexcoordtexture2f && !rsurface.batchtexcoordtexture2f_vertexbuffer)
+ rsurface.batchtexcoordtexture2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordtexture2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordtexture2f_bufferoffset);
+ if (rsurface.batchtexcoordlightmap2f && !rsurface.batchtexcoordlightmap2f_vertexbuffer)
+ rsurface.batchtexcoordlightmap2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordlightmap2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordlightmap2f_bufferoffset);
+ if (rsurface.batchskeletalindex4ub && !rsurface.batchskeletalindex4ub_vertexbuffer)
+ rsurface.batchskeletalindex4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalindex4ub_bufferoffset);
+ if (rsurface.batchskeletalweight4ub && !rsurface.batchskeletalweight4ub_vertexbuffer)
+ rsurface.batchskeletalweight4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalweight4ub_bufferoffset);
+
+ if (rsurface.batchelement3s && !rsurface.batchelement3s_indexbuffer)
+ rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
+ else if (rsurface.batchelement3i && !rsurface.batchelement3i_indexbuffer)
+ rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
+
+ R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
+ R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
+ R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
+ R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
+ R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
+ R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
+ R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, rsurface.batchskeletalindex4ub_vertexbuffer, rsurface.batchskeletalindex4ub_bufferoffset);
+ R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, rsurface.batchskeletalweight4ub_vertexbuffer, rsurface.batchskeletalweight4ub_bufferoffset);
+}
+
static void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, int numelements, int adjust)
{
int i;
// check if any dynamic vertex processing must occur
dynamicvertex = false;
+ // we must use vertexbuffers for rendering, we can upload vertex buffers
+ // easily enough but if the basevertex is non-zero it becomes more
+ // difficult, so force dynamicvertex path in that case - it's suboptimal
+ // but the most optimal case is to have the geometry sources provide their
+ // own anyway.
+ if (!rsurface.modelvertex3f_vertexbuffer && firstvertex != 0)
+ dynamicvertex = true;
+
// a cvar to force the dynamic vertex path to be taken, for debugging
if (r_batch_debugdynamicvertexpath.integer)
{
for (i = 0;i < numtriangles*3;i++)
rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
}
- // upload buffer data for the copytriangles batch
- if (rsurface.batchelement3s)
- rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
- else if (rsurface.batchelement3i)
- rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
}
else
{
}
}
}
-
- // upload buffer data for the dynamic batch
- if (rsurface.batchvertex3f)
- rsurface.batchvertex3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f, R_BUFFERDATA_VERTEX, &rsurface.batchvertex3f_bufferoffset);
- if (rsurface.batchsvector3f)
- rsurface.batchsvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchsvector3f_bufferoffset);
- if (rsurface.batchtvector3f)
- rsurface.batchtvector3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f, R_BUFFERDATA_VERTEX, &rsurface.batchtvector3f_bufferoffset);
- if (rsurface.batchnormal3f)
- rsurface.batchnormal3f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f, R_BUFFERDATA_VERTEX, &rsurface.batchnormal3f_bufferoffset);
- if (rsurface.batchlightmapcolor4f)
- rsurface.batchlightmapcolor4f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[4]), rsurface.batchlightmapcolor4f, R_BUFFERDATA_VERTEX, &rsurface.batchlightmapcolor4f_bufferoffset);
- if (rsurface.batchtexcoordtexture2f)
- rsurface.batchtexcoordtexture2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordtexture2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordtexture2f_bufferoffset);
- if (rsurface.batchtexcoordlightmap2f)
- rsurface.batchtexcoordlightmap2f_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(float[2]), rsurface.batchtexcoordlightmap2f, R_BUFFERDATA_VERTEX, &rsurface.batchtexcoordlightmap2f_bufferoffset);
- if (rsurface.batchskeletalindex4ub)
- rsurface.batchskeletalindex4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalindex4ub_bufferoffset);
- if (rsurface.batchskeletalweight4ub)
- rsurface.batchskeletalweight4ub_vertexbuffer = R_BufferData_Store(rsurface.batchnumvertices * sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, R_BUFFERDATA_VERTEX, &rsurface.batchskeletalweight4ub_bufferoffset);
- if (rsurface.batchelement3s)
- rsurface.batchelement3s_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(short[3]), rsurface.batchelement3s, R_BUFFERDATA_INDEX16, &rsurface.batchelement3s_bufferoffset);
- else if (rsurface.batchelement3i)
- rsurface.batchelement3i_indexbuffer = R_BufferData_Store(rsurface.batchnumtriangles * sizeof(int[3]), rsurface.batchelement3i, R_BUFFERDATA_INDEX32, &rsurface.batchelement3i_bufferoffset);
}
void RSurf_DrawBatch(void)
endsurface = min(i + MESHQUEUE_TRANSPARENT_BATCHSIZE, numsurfaces);
texturenumsurfaces = 0;
texturesurfacelist[texturenumsurfaces++] = surface;
- if(FAKELIGHT_ENABLED)
- {
- rsurface.lightmaptexture = NULL;
- rsurface.deluxemaptexture = NULL;
- rsurface.uselightmaptexture = false;
- for (;j < endsurface;j++)
- {
- surface = rsurface.modelsurfaces + surfacelist[j];
- if (texture != surface->texture)
- break;
- texturesurfacelist[texturenumsurfaces++] = surface;
- }
- }
- else
- {
rsurface.lightmaptexture = surface->lightmaptexture;
rsurface.deluxemaptexture = surface->deluxemaptexture;
rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
break;
texturesurfacelist[texturenumsurfaces++] = surface;
}
- }
// render the range of surfaces
R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
}
RSurf_DrawBatch();
}
-static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
+static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass, qboolean ui)
{
CHECKGLERROR
- if (depthonly)
+ if (ui)
+ R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
+ else if (depthonly)
R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist);
else if (prepass)
{
CHECKGLERROR
}
-static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
+static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass, qboolean ui)
{
int i, j;
texture_t *texture;
;
continue;
}
- if(FAKELIGHT_ENABLED || depthonly || prepass)
+ if(depthonly || prepass)
{
rsurface.lightmaptexture = NULL;
rsurface.deluxemaptexture = NULL;
;
}
// render the range of surfaces
- R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass);
+ R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass, ui);
}
R_FrameData_ReturnToMark();
}
int r_maxsurfacelist = 0;
const msurface_t **r_surfacelist = NULL;
-void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
+void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass, qboolean ui)
{
int i, j, endj, flagsmask;
dp_model_t *model = ent->model;
r_surfacelist[numsurfacelist++] = surfaces + j;
}
}
+ else if (ui)
+ {
+ // for ui we have to preserve the order of surfaces
+ for (i = 0; i < model->nummodelsurfaces; i++)
+ r_surfacelist[numsurfacelist++] = surfaces + model->firstmodelsurface + i;
+ }
else
{
// add all surfaces
}
}
- R_QueueModelSurfaceList(ent, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
+ R_QueueModelSurfaceList(ent, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass, ui);
// add to stats if desired
if (r_speeds.integer && !skysurfaces && !depthonly)
offsetx = 0.5f * width * vid_conwidth.value / vid.width;
offsety = 0;
}
- surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_VERTEXCOLOR), true);
+ surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX), true);
e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r1, g1, b1, alpha1);
e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r2, g2, b2, alpha2);
e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r2, g2, b2, alpha2);