[0.2.1-12] fixed non-VBO VAs; made the code more GLES-friendly

This commit is contained in:
Ben Russell (300178622) 2015-02-23 09:50:22 +13:00
parent 3c6ab81ea2
commit 90c70a9350
8 changed files with 111 additions and 53 deletions

View File

@ -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
},

View File

@ -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.

View File

@ -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;

View File

@ -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"},
}

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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;