diff --git a/clsave/config.json b/clsave/config.json index c94237d..fd103ae 100644 --- a/clsave/config.json +++ b/clsave/config.json @@ -34,6 +34,7 @@ "gl_frustum_cull": true, "gl_occlusion_cull": 0, "gl_flip_quads": true, + "gl_expand_quads": false, "gl_vsync": true, "gl_vbo": true }, diff --git a/docs/setup_json.txt b/docs/setup_json.txt index e84fb73..1bfce9e 100644 --- a/docs/setup_json.txt +++ b/docs/setup_json.txt @@ -60,7 +60,6 @@ clsave/config.json: "gl_shaders" enables GLSL shaders (default: true). If your card does not support these, it SHOULD fall back. If you are having issues, you can turn these off. - NOTE: not supported yet - this will be ignored. "gl_frustum_cull" enables 2D-space frustum culling for chunks (default: true) Set this to "false" if the artifacts are digging your head in, @@ -70,6 +69,12 @@ clsave/config.json: Enable this if you have smooth lighting enabled and it looks like you have dark squares at each of the corners. + "gl_expand_quads" forces the engine to render quads as two triangles. + Enabling this makes the engine ignore gl_flip_quads. + If your driver internally changes quads to tris, this may improve speed, + but Intel GPUs can handle the quad format directly, and this will slow them down. + This was mostly added to make porting to GLES easier. + "gl_vbo" enables vertex buffer objects (default: true) May fail on older computers. Enable for a faster FPS. It is recommended you disable these on old Intel integrated GPUs. diff --git a/include/common.h b/include/common.h index 88a886f..c18be6e 100644 --- a/include/common.h +++ b/include/common.h @@ -23,7 +23,7 @@ #define VERSION_X 2 #define VERSION_Y 1 #define VERSION_A 0 -#define VERSION_Z 11 +#define VERSION_Z 12 // Remember to bump "Z" basically every time you change the engine! // Remember to bump the version in Lua too! // Remember to document API changes in a new version! @@ -534,6 +534,7 @@ extern int gl_quality; extern int gl_vsync; extern int gl_frustum_cull; extern int gl_flip_quads; +extern int gl_expand_quads; extern int gl_chunk_size; extern int gl_visible_chunks; extern int gl_chunks_tesselated_per_frame; diff --git a/pkg/base/version.lua b/pkg/base/version.lua index 48b0932..d29ef97 100644 --- a/pkg/base/version.lua +++ b/pkg/base/version.lua @@ -20,9 +20,9 @@ -- Thanks. --GM VERSION_ENGINE = { - cmp={0,2,1,0,11}, - num=8421376+11, - str="0.2.1-11", + cmp={0,2,1,0,12}, + num=8421376+12, + str="0.2.1-12", } --error(""..common.version.num) @@ -156,6 +156,7 @@ VERSION_BUGS = { {renderer="gl", intro=8421376+8, fix=8421376+9, msg="[OpenGL] Map and PMF normals not emitted for shaders"}, {renderer="gl", intro=8421376+7, fix=8421376+9, msg="[OpenGL] Normal information for VAs overrides colour information by mistake"}, {intro=nil, fix=8421376+10, msg="Segfault when blitting without a screen, even image-to-image"}, +{renderer="gl", intro=nil, fix=8421376+12, msg="VAs broken when VBOs disabled"}, } diff --git a/src/gl/render.c b/src/gl/render.c index 8d5da7d..c5e81f8 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -527,7 +527,10 @@ void render_map_visible_chunks_draw(map_t *map, float fx, float fy, float fz, fl glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - glDrawArrays(GL_QUADS, 0, chunk->vbo_arr_len); + glDrawArrays((gl_expand_quads + ? GL_TRIANGLES + : GL_QUADS), + 0, chunk->vbo_arr_len); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); @@ -776,35 +779,33 @@ void render_update_vbo(float **arr, int *len, int *max, int newlen) xlen = newlen + 10; } - if(gl_shaders) - { - *arr = (float*)realloc(*arr, xlen*sizeof(float)*9); - } else { - *arr = (float*)realloc(*arr, xlen*sizeof(float)*6); - } + int vals_per_point = (gl_shaders ? 9 : 6); + *arr = (float*)realloc(*arr, xlen*sizeof(float)*vals_per_point); *max = xlen; } +#define EXPAND_QUAD \ + if(gl_expand_quads) \ + { \ + memcpy(arr, arr-vals_per_point*4, vals_per_point*sizeof(float)); \ + memcpy(arr+vals_per_point, arr-vals_per_point*2, vals_per_point*sizeof(float)); \ + arr += vals_per_point*2; \ + } + void render_gl_cube_pmf(model_bone_t *bone, float x, float y, float z, float r, float g, float b, float rad) { int i; float ua,ub,uc; float va,vb,vc; - if(gl_shaders) - { - render_update_vbo(&(bone->vbo_arr), &(bone->vbo_arr_len), &(bone->vbo_arr_max), bone->vbo_arr_len+4*9); - } else { - render_update_vbo(&(bone->vbo_arr), &(bone->vbo_arr_len), &(bone->vbo_arr_max), bone->vbo_arr_len+4*6); - } + int points_per_quad = (gl_expand_quads ? 6 : 4); + int vals_per_point = (gl_shaders ? 9 : 6); + + render_update_vbo(&(bone->vbo_arr), &(bone->vbo_arr_len), &(bone->vbo_arr_max), + bone->vbo_arr_len+points_per_quad*vals_per_point); float *arr = bone->vbo_arr; - if(gl_shaders) - { - arr += bone->vbo_arr_len*9; - } else { - arr += bone->vbo_arr_len*6; - } - bone->vbo_arr_len += 4*6; + arr += bone->vbo_arr_len*vals_per_point; + bone->vbo_arr_len += points_per_quad*6; for(i = 0; i < 3; i++) { @@ -835,6 +836,8 @@ void render_gl_cube_pmf(model_bone_t *bone, float x, float y, float z, float r, ARR_ADD(x+rad*(ua+va),y+rad*(ub+vb),z+rad*(uc+vc)); ARR_ADD(x+rad*va,y+rad*vb,z+rad*vc); + EXPAND_QUAD; + nx = -nx; ny = -ny; nz = -nz; @@ -845,6 +848,8 @@ void render_gl_cube_pmf(model_bone_t *bone, float x, float y, float z, float r, ARR_ADD(x+rad*(1-va),y+rad*(1-vb),z+rad*(1-vc)); ARR_ADD(x+rad*(1-ua-va),y+rad*(1-ub-vb),z+rad*(1-uc-vc)); ARR_ADD(x+rad*(1-ua),y+rad*(1-ub),z+rad*(1-uc)); + + EXPAND_QUAD; #undef ARR_ADD } } @@ -856,6 +861,9 @@ void render_gl_cube_map(map_t *map, map_chunk_t *chunk, float x, float y, float float va,vb,vc; float average_light_vertex1, average_light_vertex2, average_light_vertex3, average_light_vertex4; + int points_per_quad = (gl_expand_quads ? 6 : 4); + int vals_per_point = (gl_shaders ? 9 : 6); + float *arr = chunk->vbo_arr; /* Quads rendering explained (sort of) @@ -982,15 +990,10 @@ void render_gl_cube_map(map_t *map, map_chunk_t *chunk, float x, float y, float /* check visibility of the face (is face exposed to air ?) */ if (render_map_get_block_at(map, x - ub, y - uc, z - ua) == 0) { - render_update_vbo(&(chunk->vbo_arr), &(chunk->vbo_arr_len), &(chunk->vbo_arr_max), chunk->vbo_arr_len+4); + render_update_vbo(&(chunk->vbo_arr), &(chunk->vbo_arr_len), &(chunk->vbo_arr_max), chunk->vbo_arr_len+points_per_quad); arr = chunk->vbo_arr; - if(gl_shaders) - { - arr += chunk->vbo_arr_len*9; - } else { - arr += chunk->vbo_arr_len*6; - } - chunk->vbo_arr_len += 4; + arr += chunk->vbo_arr_len*vals_per_point; + chunk->vbo_arr_len += points_per_quad; if (screen_smooth_lighting) { @@ -1063,6 +1066,8 @@ void render_gl_cube_map(map_t *map, map_chunk_t *chunk, float x, float y, float cb = render_darken_color(cb, average_light_vertex1); ARR_ADD(x,y,z); + EXPAND_QUAD; + } else { /* Quad 1 normal */ @@ -1094,6 +1099,8 @@ void render_gl_cube_map(map_t *map, map_chunk_t *chunk, float x, float y, float cb = render_darken_color(cb, average_light_vertex4); ARR_ADD(x+rad*va,y+rad*vb,z+rad*vc); + EXPAND_QUAD; + } } @@ -1104,15 +1111,10 @@ void render_gl_cube_map(map_t *map, map_chunk_t *chunk, float x, float y, float /* check visibility of the face (is face exposed to air ?) */ if (render_map_get_block_at(map, x + vc, y + va, z + vb) == 0) { - render_update_vbo(&(chunk->vbo_arr), &(chunk->vbo_arr_len), &(chunk->vbo_arr_max), chunk->vbo_arr_len+4); + render_update_vbo(&(chunk->vbo_arr), &(chunk->vbo_arr_len), &(chunk->vbo_arr_max), chunk->vbo_arr_len+points_per_quad); arr = chunk->vbo_arr; - if(gl_shaders) - { - arr += chunk->vbo_arr_len*9; - } else { - arr += chunk->vbo_arr_len*6; - } - chunk->vbo_arr_len += 4; + arr += chunk->vbo_arr_len*vals_per_point; + chunk->vbo_arr_len += points_per_quad; if (screen_smooth_lighting) { @@ -1183,6 +1185,8 @@ void render_gl_cube_map(map_t *map, map_chunk_t *chunk, float x, float y, float cb = render_darken_color(cb, average_light_vertex1); ARR_ADD(x+rad,y+rad,z+rad); + EXPAND_QUAD; + } else { /* Quad 2 normal */ @@ -1214,6 +1218,8 @@ void render_gl_cube_map(map_t *map, map_chunk_t *chunk, float x, float y, float cb = render_darken_color(cb, average_light_vertex4); ARR_ADD(x+rad*(1-ua),y+rad*(1-ub),z+rad*(1-uc)); + EXPAND_QUAD; + } } #undef ARR_ADD @@ -1339,6 +1345,9 @@ void render_pmf_bone(uint32_t *pixels, int width, int height, int pitch, camera_ { int i; + int points_per_quad = (gl_expand_quads ? 6 : 4); + int vals_per_point = (gl_shaders ? 9 : 6); + glPushMatrix(); if(islocal) glLoadIdentity(); @@ -1382,13 +1391,7 @@ void render_pmf_bone(uint32_t *pixels, int width, int height, int pitch, camera_ if(bone->vbo != 0) { glBindBuffer(GL_ARRAY_BUFFER, bone->vbo); - if(gl_shaders) - { - glBufferData(GL_ARRAY_BUFFER, sizeof(float)*9*bone->vbo_arr_len, bone->vbo_arr, GL_STATIC_DRAW); - } else { - glBufferData(GL_ARRAY_BUFFER, sizeof(float)*6*bone->vbo_arr_len, bone->vbo_arr, GL_STATIC_DRAW); - - } + glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vals_per_point*bone->vbo_arr_len, bone->vbo_arr, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } } @@ -1420,7 +1423,7 @@ void render_pmf_bone(uint32_t *pixels, int width, int height, int pitch, camera_ glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); if(gl_shaders) glEnableClientState(GL_NORMAL_ARRAY); - glDrawArrays(GL_QUADS, 0, bone->vbo_arr_len); + glDrawArrays((gl_expand_quads ? GL_TRIANGLES : GL_QUADS), 0, bone->vbo_arr_len); if(gl_shaders) glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); @@ -1544,15 +1547,15 @@ void render_vertex_array(uint32_t *pixels, int width, int height, int pitch, cam glTexCoord2f(-1.0f, -1.0f); if(va->vbo == 0) { - glVertexPointer(va->vertex_size, GL_FLOAT, sizeof(float)*va->stride, va->data + sizeof(float)*va->vertex_offs); - if(va->color_offs != -1) glColorPointer(va->color_size, GL_FLOAT, sizeof(float)*va->stride, va->data+sizeof(float)*va->color_offs); - if(va->normal_offs != -1) glNormalPointer(GL_FLOAT, sizeof(float)*va->stride, va->data+sizeof(float)*va->normal_offs); + glVertexPointer(va->vertex_size, GL_FLOAT, sizeof(float)*va->stride, va->data + va->vertex_offs); + if(va->color_offs != -1) glColorPointer(va->color_size, GL_FLOAT, sizeof(float)*va->stride, va->data+va->color_offs); + if(va->normal_offs != -1) glNormalPointer(GL_FLOAT, sizeof(float)*va->stride, va->data+va->normal_offs); if(va->texcoord_count >= 1) for(i = 0; i < va->texcoord_count || i < img_count; i++) { glClientActiveTexture(GL_TEXTURE0 + i); glActiveTexture(GL_TEXTURE0 + i); - glTexCoordPointer(va->texcoord_size[i%va->texcoord_count], GL_FLOAT, sizeof(float)*va->stride, va->data+sizeof(float)*va->texcoord_offs[i%va->texcoord_count]); + glTexCoordPointer(va->texcoord_size[i%va->texcoord_count], GL_FLOAT, sizeof(float)*va->stride, va->data+va->texcoord_offs[i%va->texcoord_count]); } } else { glBindBuffer(GL_ARRAY_BUFFER, va->vbo); diff --git a/src/gl/render_img.c b/src/gl/render_img.c index 5f57ca9..2f11d87 100644 --- a/src/gl/render_img.c +++ b/src/gl/render_img.c @@ -48,6 +48,7 @@ void render_blit_img_toimg(uint32_t *pixels, int width, int height, int pitch, img_t *src, int dx, int dy, int bw, int bh, int sx, int sy, uint32_t color, float scalex, float scaley); +GLuint vbo_img = 0; void render_blit_img(uint32_t *pixels, int width, int height, int pitch, img_t *src, int dx, int dy, int bw, int bh, int sx, int sy, uint32_t color, float scalex, float scaley) { @@ -110,12 +111,51 @@ void render_blit_img(uint32_t *pixels, int width, int height, int pitch, sy2 /= scaley; glColor4f(((color>>16)&255)/255.0f,((color>>8)&255)/255.0f,((color)&255)/255.0f,((color>>24)&255)/255.0f); + GLfloat va[6*5] = { + sx1, sy1, dx1, dy1, 1.0f, + sx1, sy2, dx1, dy2, 1.0f, + sx2, sy1, dx2, dy1, 1.0f, + sx2, sy1, dx2, dy1, 1.0f, + sx1, sy2, dx1, dy2, 1.0f, + sx2, sy2, dx2, dy2, 1.0f, + + }; + if(vbo_img == 0 && GL_ARB_vertex_buffer_object && gl_use_vbo) + { + glGenBuffers(1, &(vbo_img)); + + } + + if(vbo_img != 0) + { + glBindBuffer(GL_ARRAY_BUFFER, vbo_img); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*5*6, va, GL_STATIC_DRAW); + glVertexPointer(3, GL_FLOAT, sizeof(GLfloat)*5, ((GLfloat *)0) + 2); + glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*5, ((GLfloat *)0) + 0); + + } else { + glVertexPointer(3, GL_FLOAT, sizeof(GLfloat)*5, va + 2); + glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*5, va + 0); + } + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDrawArrays(GL_TRIANGLES, 0, 6); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + if(vbo_img != 0) + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + /* glBegin(GL_QUADS); glTexCoord2f(sx1, sy1); glVertex3f(dx1, dy1, 1.0f); glTexCoord2f(sx1, sy2); glVertex3f(dx1, dy2, 1.0f); glTexCoord2f(sx2, sy2); glVertex3f(dx2, dy2, 1.0f); glTexCoord2f(sx2, sy1); glVertex3f(dx2, dy1, 1.0f); glEnd(); + */ glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/src/lua.c b/src/lua.c index 4b33c00..2f4e04c 100644 --- a/src/lua.c +++ b/src/lua.c @@ -558,6 +558,12 @@ int icelua_init(void) if(!lua_isnil(Lc, -1)) gl_flip_quads = v; lua_pop(Lc, 1); + lua_getfield(Lc, -1, "gl_expand_quads"); + v = lua_toboolean(Lc, -1); + if(!lua_isnil(Lc, -1)) gl_expand_quads = v; + lua_pop(Lc, 1); + if(gl_expand_quads) gl_flip_quads = 0; + lua_getfield(Lc, -1, "gl_frustum_cull"); v = lua_toboolean(Lc, -1); if(!lua_isnil(Lc, -1)) gl_frustum_cull = v; diff --git a/src/main.c b/src/main.c index c1f2856..0f0b42f 100644 --- a/src/main.c +++ b/src/main.c @@ -42,6 +42,7 @@ int gl_vsync = 1; int gl_frustum_cull = 1; int gl_occlusion_cull = 1; int gl_flip_quads = 0; +int gl_expand_quads = 0; int gl_max_texunits = 1; int gl_shaders = 1;