use immutable vbos, because we can.
add stof to the lua logic. fix an issue where q3bsp cvars were not registered in The Wastes build config leaving it subject to the worst of q3map2's lightmap allocation logic. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5236 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
3c4b5fabb6
commit
2de26a93f7
8 changed files with 107 additions and 15 deletions
|
@ -6133,7 +6133,7 @@ void Host_Init (quakeparms_t *parms)
|
|||
Plug_Initialise(false);
|
||||
#endif
|
||||
|
||||
#ifdef Q2BSPS
|
||||
#if defined(Q2BSPS) || defined(Q3BSPS)
|
||||
CM_Init();
|
||||
#endif
|
||||
#ifdef TERRAIN
|
||||
|
|
|
@ -6182,15 +6182,20 @@ void GLBE_DrawWorld (batch_t **worldbatches)
|
|||
|
||||
void GLBE_VBO_Begin(vbobctx_t *ctx, size_t maxsize)
|
||||
{
|
||||
COM_AssertMainThread("GLBE_VBO_Begin");
|
||||
COM_AssertMainThread("GLBE_VBO_Begin"); //actually, we should probably just build this in memory and throw it to the main thread as needed, but we still need some buffers indexes. I guess we could build a list of varrays. the other option is to just create a large persistant-mapped buffer, and then just append+reuse from any thread, but that makes destruction messy.
|
||||
|
||||
ctx->maxsize = maxsize;
|
||||
ctx->pos = 0;
|
||||
ctx->fallback = NULL;
|
||||
if (qglBufferDataARB)
|
||||
if (qglBufferStorage)
|
||||
{
|
||||
ctx->vboid[0] = 0;
|
||||
ctx->vboid[1] = 0;
|
||||
ctx->vboid[0] = ctx->vboid[1] = 0;
|
||||
qglGenBuffersARB(2, ctx->vboid);
|
||||
ctx->fallback = BZ_Malloc(maxsize);
|
||||
}
|
||||
else if (qglBufferDataARB)
|
||||
{
|
||||
ctx->vboid[0] = ctx->vboid[1] = 0;
|
||||
qglGenBuffersARB(2, ctx->vboid);
|
||||
GL_SelectVBO(ctx->vboid[0]);
|
||||
//WARNING: in emscripten/webgl, we should probably not pass null.
|
||||
|
@ -6201,7 +6206,13 @@ void GLBE_VBO_Begin(vbobctx_t *ctx, size_t maxsize)
|
|||
}
|
||||
void GLBE_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray)
|
||||
{
|
||||
if (ctx->fallback)
|
||||
if (qglBufferStorage)
|
||||
{
|
||||
memcpy((char*)ctx->fallback + ctx->pos, data, size);
|
||||
varray->gl.vbo = ctx->vboid[0];
|
||||
varray->gl.addr = (void*)ctx->pos;
|
||||
}
|
||||
else if (ctx->fallback)
|
||||
{
|
||||
memcpy((char*)ctx->fallback + ctx->pos, data, size);
|
||||
varray->gl.vbo = 0;
|
||||
|
@ -6220,7 +6231,18 @@ void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earr
|
|||
{
|
||||
if (ctx->pos > ctx->maxsize)
|
||||
Sys_Error("BE_VBO_Finish: too much data given\n");
|
||||
if (ctx->fallback)
|
||||
if (qglBufferStorage)
|
||||
{
|
||||
GL_SelectVBO(ctx->vboid[0]);
|
||||
qglBufferStorage(GL_ARRAY_BUFFER_ARB, ctx->pos, ctx->fallback, 0);
|
||||
BZ_Free(ctx->fallback);
|
||||
ctx->fallback = NULL;
|
||||
GL_SelectEBO(ctx->vboid[1]);
|
||||
qglBufferStorage(GL_ELEMENT_ARRAY_BUFFER_ARB, esize, edata, 0);
|
||||
earray->gl.vbo = ctx->vboid[1];
|
||||
earray->gl.addr = NULL;
|
||||
}
|
||||
else if (ctx->fallback)
|
||||
{
|
||||
void *d = BZ_Malloc(esize);
|
||||
memcpy(d, edata, esize);
|
||||
|
|
|
@ -154,7 +154,7 @@ static void Mod_BatchList_f(void)
|
|||
#endif
|
||||
Con_Printf(" %s lm=(%i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->maxmeshes);
|
||||
else
|
||||
Con_Printf(" %s lm=%i surfs=%u verts=%i indexes=%i\n", batch->texture->shader->name, batch->lightmap[0], batch->maxmeshes, batch->vbo->vertcount, batch->vbo->indexcount);
|
||||
Con_Printf(" %s lm=%i surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->maxmeshes);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,10 +156,19 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
|
|||
|
||||
GLBE_SetupVAO(vbo, vaodynamic, vaostatic);
|
||||
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vsize, vdata, GL_STATIC_DRAW_ARB);
|
||||
if (elementsize>0)
|
||||
if (qglBufferStorage)
|
||||
{ //gl4.4 allows us to explicitly create device-only vbos
|
||||
qglBufferStorage(GL_ARRAY_BUFFER_ARB, vsize, vdata, 0);
|
||||
if (elementsize>0)
|
||||
qglBufferStorage(GL_ELEMENT_ARRAY_BUFFER_ARB, elementsize, edata, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementsize, edata, GL_STATIC_DRAW_ARB);
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vsize, vdata, GL_STATIC_DRAW_ARB);
|
||||
if (elementsize>0)
|
||||
{
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementsize, edata, GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -194,6 +194,8 @@ GLboolean (APIENTRY *qglUnmapBufferARB)(GLenum target);
|
|||
void *(APIENTRY *qglMapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
|
||||
#endif
|
||||
|
||||
void (APIENTRY *qglBufferStorage)(GLenum target, GLsizeiptr size, const GLvoid *data, GLbitfield flags);
|
||||
|
||||
void (APIENTRY *qglTexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); //gl4.2
|
||||
void (APIENTRY *qglTexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); //gl4.2
|
||||
FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImage;
|
||||
|
@ -870,6 +872,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
|
||||
gl_config.arb_texture_cube_map = GL_CheckExtension("GL_ARB_texture_cube_map");
|
||||
|
||||
qglBufferStorage = NULL;
|
||||
#if !defined(GL_STATIC)
|
||||
/*vbos, were made core in gl1.5 or gles2.0*/
|
||||
if ((gl_config.gles && gl_config.glversion >= 2) || (!gl_config.gles && (gl_major_version > 1 || (gl_major_version == 1 && gl_minor_version >= 5))))
|
||||
|
@ -905,7 +908,13 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
|
||||
//ARB_map_buffer_range: core in gl3.0/gles3.0, the extension is backported, and thus no ARB postfix on functions.
|
||||
qglMapBufferRange = (void *)getglext("glMapBufferRange");
|
||||
|
||||
if (qglBufferSubDataARB && qglMapBufferRange)
|
||||
#endif
|
||||
{
|
||||
if ((!gl_config.gles && gl_config.glversion >= 4.4) || GL_CheckExtension("GL_ARB_buffer_storage"))
|
||||
qglBufferStorage = (void *)getglext("glBufferStorage"); //no arb postfix even with the extension form of it.
|
||||
}
|
||||
|
||||
#ifdef GL_STATIC
|
||||
gl_config.arb_shader_objects = true;
|
||||
|
|
|
@ -735,7 +735,9 @@ extern GLboolean (APIENTRY *qglUnmapBufferARB)(GLenum target);
|
|||
#ifndef GL_MAP_READ_BIT
|
||||
#define GL_MAP_READ_BIT 1
|
||||
#endif
|
||||
void *(APIENTRY *qglMapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
|
||||
extern void *(APIENTRY *qglMapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
|
||||
|
||||
extern void (APIENTRY *qglBufferStorage)(GLenum target, GLsizeiptr size, const GLvoid *data, GLbitfield flags);
|
||||
|
||||
#endif
|
||||
extern void (APIENTRY *qglGenQueriesARB)(GLsizei n, GLuint *ids);
|
||||
|
|
|
@ -83,7 +83,7 @@ luaextragloballist
|
|||
typedef struct
|
||||
{
|
||||
int type;
|
||||
ptrdiff_t offset;
|
||||
quintptr_t offset;
|
||||
char *name;
|
||||
bucket_t buck;
|
||||
} luafld_t;
|
||||
|
@ -330,6 +330,7 @@ static void lua_pushedict(lua_State *L, struct edict_s *ent)
|
|||
lua_rawgetp(L, LUA_REGISTRYINDEX, ent);
|
||||
}
|
||||
|
||||
/*
|
||||
static void lua_debugstack(lua_State *L)
|
||||
{
|
||||
int idx;
|
||||
|
@ -377,6 +378,7 @@ static void lua_debugstack(lua_State *L)
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void *my_lua_alloc (void *ud, void *ptr, size_t osize, size_t nsize)
|
||||
{
|
||||
|
@ -496,6 +498,50 @@ static int bi_lua_tostring(lua_State *L)
|
|||
#define bi_lua_vtos bi_lua_tostring
|
||||
#define bi_lua_ftos bi_lua_tostring
|
||||
|
||||
//taken from lua's baselib.c, with dependancies reduced a little.
|
||||
static int bi_lua_tonumber(lua_State *L)
|
||||
{
|
||||
// if (lua_type(L, 1) == LUA_TNONE)
|
||||
// luaL_argerror(L, narg, "value expected");
|
||||
if (luaL_callmeta(L, 1, "__tonumber"))
|
||||
return 1;
|
||||
switch (lua_type(L, 1))
|
||||
{
|
||||
case LUA_TSTRING:
|
||||
lua_pushnumber(L, atof(lua_tostring(L, 1)));
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
lua_pushvalue(L, 1);
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
lua_pushnumber(L, lua_toboolean(L, 1));
|
||||
break;
|
||||
case LUA_TNIL:
|
||||
lua_pushnumber(L, 0);
|
||||
break;
|
||||
case LUA_TTABLE:
|
||||
//special check for things that look like vectors.
|
||||
lua_getfield(L, 1, "x");
|
||||
lua_getfield(L, 1, "y");
|
||||
lua_getfield(L, 1, "z");
|
||||
if (lua_type(L, -3) == LUA_TNUMBER && lua_type(L, -2) == LUA_TNUMBER && lua_type(L, -1) == LUA_TNUMBER)
|
||||
{
|
||||
vec3_t v = {lua_tonumberx(L, -3, NULL), lua_tonumberx(L, -2, NULL), lua_tonumberx(L, -1, NULL)};
|
||||
lua_pushnumber(L, DotProduct(v,v));
|
||||
return 1;
|
||||
}
|
||||
lua_getfield(L, 1, "entnum");
|
||||
if (lua_type(L, -1) == LUA_TNUMBER)
|
||||
return 1;
|
||||
//fallthrough
|
||||
default:
|
||||
lua_pushfstring(L, "%s: %p", lua_typename(L, lua_type(L, 1)), lua_topointer(L, 1));
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#define bi_lua_stof bi_lua_tonumber
|
||||
|
||||
static int my_lua_panic(lua_State *L)
|
||||
{
|
||||
const char *s = lua_tolstring(L, -1, NULL);
|
||||
|
@ -2185,7 +2231,7 @@ static int bi_lua_objerror (lua_State *L)
|
|||
int i;
|
||||
const void *ud = lua_topointer(L, -2);
|
||||
for (i = 0; i < countof(lua.entflds); i++)
|
||||
if (lua.entflds[i].offset == (ptrdiff_t)ud)
|
||||
if (lua.entflds[i].offset == (quintptr_t)ud)
|
||||
break;
|
||||
|
||||
if (i == countof(lua.entflds))
|
||||
|
@ -2285,12 +2331,15 @@ static void my_lua_registerbuiltins(lua_State *L)
|
|||
//standard lua library replacement
|
||||
//this avoids the risk of including any way to access os.execute etc, or other file access.
|
||||
registerfuncn(tostring); //standardish
|
||||
registerfuncn(tonumber); //standardish
|
||||
registerfuncn(type); //standardish
|
||||
registerfuncn(print); //'standard' lua print, except prints to console. WARNING: this adds an implicit \n. Use conprint for the quake-style version.
|
||||
registerfuncn(require); //'standard'ish, except uses quake's filesystem instead of reading random system paths.
|
||||
#ifdef LIBLUA_STATIC
|
||||
registerfuncn(pairs);
|
||||
#endif
|
||||
lua_pushnil(L); lua_setglobal(L, "dofile"); //violates our sandbox
|
||||
lua_pushnil(L); lua_setglobal(L, "loadfile"); //violates our sandbox
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushcclosure(L, bi_lua_fabs, 0); lua_setfield(L, -2, "abs");
|
||||
|
@ -2432,6 +2481,7 @@ static void my_lua_registerbuiltins(lua_State *L)
|
|||
registerfuncd(aim); //original implementation nudges v_forward up or down so that keyboard players can still play.
|
||||
registerfunc(vtos);
|
||||
registerfunc(ftos);
|
||||
registerfunc(stof);
|
||||
|
||||
//registerfunc(PRECACHE_VWEP_MODEL);
|
||||
//registerfunc(SETPAUSE);
|
||||
|
|
|
@ -5657,7 +5657,7 @@ void SV_Init (quakeparms_t *parms)
|
|||
#endif
|
||||
NET_Init ();
|
||||
COM_Init ();
|
||||
#ifdef Q2BSPS
|
||||
#if defined(Q2BSPS) || defined(Q3BSPS)
|
||||
CM_Init();
|
||||
#endif
|
||||
#ifdef TERRAIN
|
||||
|
|
Loading…
Reference in a new issue