diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 41cd7aa3a..a51b90da6 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -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 diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 56268f5fb..6d5c5c997 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -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); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index cb8dbacaa..24b8d1cbf 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -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++; } } diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index 2f0fe04ee..a536ed450 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -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; diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 5d09b8f9d..f65277a9d 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -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; diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index f09a3e5dd..1fd6fbd56 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -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); diff --git a/engine/server/pr_lua.c b/engine/server/pr_lua.c index 6b85d4304..52259a17e 100644 --- a/engine/server/pr_lua.c +++ b/engine/server/pr_lua.c @@ -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); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 020babc51..d5af188a3 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -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