@@ 7,13 7,45 @@ in uint packedData;
out vec3 texCoord;
out vec3 lightness;
+uniform ivec3 aa[6*4] = ivec3[6*4](
+ ivec3(0, 0, 0),
+ ivec3(1, 0, 0),
+ ivec3(1, 1, 0),
+ ivec3(0, 1, 0),
+
+ ivec3(0, 0, 0),
+ ivec3(0, 1, 0),
+ ivec3(1, 1, 0),
+ ivec3(1, 0, 0),
+
+ ivec3(0, 0, 0),
+ ivec3(0, 0, 1),
+ ivec3(1, 0, 1),
+ ivec3(1, 0, 0),
+
+ ivec3(0, 0, 0),
+ ivec3(1, 0, 0),
+ ivec3(1, 0, 1),
+ ivec3(0, 0, 1),
+
+ ivec3(0, 0, 0),
+ ivec3(0, 0, 1),
+ ivec3(0, 1, 1),
+ ivec3(0, 1, 0),
+
+ ivec3(0, 0, 0),
+ ivec3(0, 1, 0),
+ ivec3(0, 1, 1),
+ ivec3(0, 0, 1)
+);
+
void main(){
- uvec4 pos = uvec4(packedData & 0x1Fu, (packedData >> 5) & 0x1Fu, (packedData >> 10) & 0x1Fu, 1);
- uvec2 taxis[3] = uvec2[3](pos.xy, pos.xz, pos.zy);
uint flag = (packedData >> 24) & 0x7u;
- vec3 tex = vec3(uvec3(taxis[flag >> 1], (packedData >> 16) & 0xFFu));
-
+ ivec3 a = aa[int(flag) * 4 + gl_VertexID];
+ ivec4 pos = ivec4(int(packedData & 0x1Fu) + a.x, int((packedData >> 5) & 0x1Fu) + a.y, int((packedData >> 10) & 0x1Fu) + a.z, 1);
+ ivec2 taxis[3] = ivec2[3](ivec2(pos.x, -pos.y), pos.xz, ivec2(pos.z, -pos.y));
+ ivec3 tex = ivec3(taxis[flag >> 1], (packedData >> 16) & 0xFFu);
gl_Position = matMVP * (vec4(pos) + vec4(transPos,0.0));
- texCoord = tex;
+ texCoord = vec3(tex) * vec3(0.5, 0.5, 1);
lightness = sideTints[flag];
}
@@ 43,8 43,7 @@
#define EDGE (CHUNK_SIZE-1)
#define CUBE_FACES 6
-#define VERTICES_PER_FACE 4
-vertexPacked blockMeshBuffer[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * CUBE_FACES * VERTICES_PER_FACE / 2];
+vertexPacked blockMeshBuffer[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * CUBE_FACES / 2];
u16 blockMeshSideEnd[sideMAX];
int chunksGeneratedThisFrame = 0;
@@ 94,64 93,53 @@ static void chunkAddFront(blockId b,u8 x,u8 y,u8 z, u8 w, u8 h, u8 d) {
const u8 bt = blocks[b].tex[sideFront];
vertexPacked *vp = &blockMeshBuffer[blockMeshSideEnd[sideFront]];
*vp++ = mkVertex(x ,y ,z+d,0,h,bt,sideFront);
- *vp++ = mkVertex(x+w,y ,z+d,w,h,bt,sideFront);
- *vp++ = mkVertex(x+w,y+h,z+d,w,0,bt,sideFront);
- *vp++ = mkVertex(x ,y+h,z+d,0,0,bt,sideFront);
- blockMeshSideEnd[sideFront] += VERTICES_PER_FACE;
+ (void) w; (void) h; (void) d;
+ blockMeshSideEnd[sideFront] += 1;
}
static void chunkAddBack(blockId b,u8 x,u8 y,u8 z, u8 w, u8 h, u8 d) {
(void)d;
const u8 bt = blocks[b].tex[sideBack];
vertexPacked *vp = &blockMeshBuffer[blockMeshSideEnd[sideBack]];
*vp++ = mkVertex(x ,y ,z ,0,h,bt,sideBack);
- *vp++ = mkVertex(x ,y+h,z ,0,0,bt,sideBack);
- *vp++ = mkVertex(x+w,y+h,z ,w,0,bt,sideBack);
- *vp++ = mkVertex(x+w,y ,z ,w,h,bt,sideBack);
- blockMeshSideEnd[sideBack] += VERTICES_PER_FACE;
+ (void) w; (void) h; (void) d;
+ blockMeshSideEnd[sideBack] += 1;
}
static void chunkAddTop(blockId b,u8 x,u8 y,u8 z, u8 w, u8 h, u8 d) {
const u8 bt = blocks[b].tex[sideTop];
vertexPacked *vp = &blockMeshBuffer[blockMeshSideEnd[sideTop]];
*vp++ = mkVertex(x ,y+h,z ,0,0,bt,sideTop);
- *vp++ = mkVertex(x ,y+h,z+d,0,d,bt,sideTop);
- *vp++ = mkVertex(x+w,y+h,z+d,w,d,bt,sideTop);
- *vp++ = mkVertex(x+w,y+h,z ,w,0,bt,sideTop);
- blockMeshSideEnd[sideTop] += VERTICES_PER_FACE;
+ (void) w; (void) h; (void) d;
+ blockMeshSideEnd[sideTop] += 1;
}
static void chunkAddBottom(blockId b,u8 x,u8 y,u8 z, u8 w, u8 h, u8 d) {
(void)h;
const u8 bt = blocks[b].tex[sideBottom];
vertexPacked *vp = &blockMeshBuffer[blockMeshSideEnd[sideBottom]];
*vp++ = mkVertex(x ,y ,z ,0,0,bt,sideBottom);
- *vp++ = mkVertex(x+w,y ,z ,w,0,bt,sideBottom);
- *vp++ = mkVertex(x+w,y ,z+d,w,d,bt,sideBottom);
- *vp++ = mkVertex(x ,y ,z+d,0,d,bt,sideBottom);
- blockMeshSideEnd[sideBottom] += VERTICES_PER_FACE;
+ (void) w; (void) h; (void) d;
+ blockMeshSideEnd[sideBottom] += 1;
}
static void chunkAddLeft(blockId b,u8 x,u8 y,u8 z, u8 w, u8 h, u8 d) {
(void)w;
const u8 bt = blocks[b].tex[sideLeft];
vertexPacked *vp = &blockMeshBuffer[blockMeshSideEnd[sideLeft]];
*vp++ = mkVertex(x ,y ,z ,0,h,bt,sideLeft);
- *vp++ = mkVertex(x ,y ,z+d,d,h,bt,sideLeft);
- *vp++ = mkVertex(x ,y+h,z+d,d,0,bt,sideLeft);
- *vp++ = mkVertex(x ,y+h,z ,0,0,bt,sideLeft);
- blockMeshSideEnd[sideLeft] += VERTICES_PER_FACE;
+ (void) w; (void) h; (void) d;
+ blockMeshSideEnd[sideLeft] += 1;
}
static void chunkAddRight(blockId b,u8 x,u8 y,u8 z, u8 w, u8 h, u8 d) {
const u8 bt = blocks[b].tex[sideRight];
vertexPacked *vp = &blockMeshBuffer[blockMeshSideEnd[sideRight]];
*vp++ = mkVertex(x+w,y ,z ,0,h,bt,sideRight);
- *vp++ = mkVertex(x+w,y+h,z ,0,0,bt,sideRight);
- *vp++ = mkVertex(x+w,y+h,z+d,d,0,bt,sideRight);
- *vp++ = mkVertex(x+w,y ,z+d,d,h,bt,sideRight);
- blockMeshSideEnd[sideRight] += VERTICES_PER_FACE;
+ (void) w; (void) h; (void) d;
+ blockMeshSideEnd[sideRight] += 1;
}
// genmesh avg. 0.677ms
// chunkVert: 4246K
static void chunkOptimizePlane(u32 plane[CHUNK_SIZE][CHUNK_SIZE]){
+ return;
for(int y=CHUNK_SIZE-1;y>=0;y--){
for(int x=CHUNK_SIZE-1;x>=0;x--){
if((x < CHUNK_SIZE-1) && (plane[x][y]) && ((plane[x][y] & 0xFF00FF) == (plane[x+1][y] & 0xFF00FF))){
@@ 37,39 37,22 @@ struct chunkvertbuf {
};
u16 vboSize; // size of vbo in vertices
u8 flags;
- u16 sideIdxStart[sideMAX],sideIdxCount[sideMAX]; // offset and count of side indices within the (sub)buffer
- u16 idxCount; // total number of indices, used when all sides are drawn
+ u16 sideFaceStart[sideMAX],sideFaceCount[sideMAX]; // offset and count of side faces within the (sub)buffer
+ u16 faceCount; // total number of faces, used when all sides are drawn
};
static u32 allocatedGlBufferBytes;
-static GLuint indexBuffer;
static void setVAOFormatPacked(){
glVertexAttribIPointer(SHADER_ATTRIDX_PACKED, 1, GL_UNSIGNED_INT, sizeof(vertexPacked), NULL);
+ glVertexAttribDivisor(SHADER_ATTRIDX_PACKED, 1);
glEnableVertexAttribArray(SHADER_ATTRIDX_PACKED);
}
#define CUBE_FACES 6
#define VERTICES_PER_FACE 4
-#define INDICES_PER_FACE 5
void chunkvertbufInit(){
allocatedGlBufferBytes = 0;
- glGenBuffers(1, &indexBuffer);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
- gfxObjectLabel(GL_BUFFER, indexBuffer, "Chunk vertex IBO");
- const GLsizei indexCount = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * CUBE_FACES * INDICES_PER_FACE / 2;
- u16 *indicesRaw = malloc(indexCount * sizeof(u16));
- u16 *indices = indicesRaw;
- const GLsizei indexMax = indexCount/INDICES_PER_FACE - 1;
- for(GLsizei i=0;i<indexMax;++i){
- *indices++ = i*4 + 0;
- *indices++ = i*4 + 1;
- *indices++ = i*4 + 2;
- *indices++ = i*4 + 3;
- *indices++ = 0xFFFF;
- }
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(u16), indicesRaw, GL_STATIC_DRAW);
- free(indicesRaw);
}
u32 chunkvertbufUsedBytes(){
@@ 115,9 98,7 @@ void chunkvertbufFree(struct chunk *c){
c->vertbuf = NULL;
}
-
-#define VTX_TO_IDX_COUNT(x) (x*INDICES_PER_FACE/VERTICES_PER_FACE)
-void chunkvertbufUpdate(chunk *c, vertexPacked *vertices, u16 sideVtxCounts[sideMAX]) {
+void chunkvertbufUpdate(chunk *c, vertexPacked *vertices, u16 sideFaceCounts[sideMAX]) {
struct chunkvertbuf *v = c->vertbuf;
if(v == NULL) {
c->vertbuf = v = chunkvertbufAlloc();
@@ 126,15 107,15 @@ void chunkvertbufUpdate(chunk *c, vertexPacked *vertices, u16 sideVtxCounts[side
// Compute where the geometry for each side starts and how long it is
// in the chunk's packed vertex buffer.
- u16 vtxCount = 0;
+ u16 faceCount = 0;
for(side sideIndex=0;sideIndex<sideMAX;sideIndex++){
- v->sideIdxStart[sideIndex] = VTX_TO_IDX_COUNT(vtxCount);
- v->sideIdxCount[sideIndex] = VTX_TO_IDX_COUNT(sideVtxCounts[sideIndex]);
- vtxCount += sideVtxCounts[sideIndex];
+ v->sideFaceStart[sideIndex] = faceCount;
+ v->sideFaceCount[sideIndex] = sideFaceCounts[sideIndex];
+ faceCount += sideFaceCounts[sideIndex];
}
- v->idxCount = VTX_TO_IDX_COUNT(vtxCount);
+ v->faceCount = faceCount;
- if(vtxCount == 0){
+ if(faceCount == 0){
// Empty chunk, don't allocate or update anything (except the counts themselves)
return;
}
@@ 144,7 125,6 @@ void chunkvertbufUpdate(chunk *c, vertexPacked *vertices, u16 sideVtxCounts[side
gfxObjectLabel(GL_VERTEX_ARRAY, v->vao, "Chunk %d,%d,%d VAO", c->x, c->y, c->z);
}
glBindVertexArray(v->vao);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
if(!v->vbo){
glGenBuffers(1, &v->vbo);
@@ 154,28 134,28 @@ void chunkvertbufUpdate(chunk *c, vertexPacked *vertices, u16 sideVtxCounts[side
// Upload to the GPU, doing partial updates if possible.
const u32 vertexSize = sizeof(vertexPacked);
- if(gfxUseSubData && (vtxCount <= v->vboSize)){
- glBufferSubData(GL_ARRAY_BUFFER,0,vertexSize * vtxCount,vertices); // Todo Measure performance impact of this!
+ if(gfxUseSubData && (faceCount <= v->vboSize)){
+ glBufferSubData(GL_ARRAY_BUFFER,0,vertexSize * faceCount,vertices); // Todo Measure performance impact of this!
}else{
allocatedGlBufferBytes -= vertexSize * v->vboSize;
- glBufferData(GL_ARRAY_BUFFER,vertexSize * vtxCount,vertices,GL_STATIC_DRAW);
- allocatedGlBufferBytes += vertexSize * vtxCount;
- v->vboSize = vtxCount;
+ glBufferData(GL_ARRAY_BUFFER,vertexSize * faceCount,vertices,GL_STATIC_DRAW);
+ allocatedGlBufferBytes += vertexSize * faceCount;
+ v->vboSize = faceCount;
setVAOFormatPacked();
}
}
void chunkvertbufDrawOne(struct chunk *c, sideMask mask){
struct chunkvertbuf *v = c->vertbuf;
- if(v->vao == 0 || v->idxCount == 0){return;}
+ if(v->vao == 0 || v->faceCount == 0){return;}
uint bufOffset = 0;
shaderTransform(sBlockMesh,c->x-subBlockViewOffset.x,c->y-subBlockViewOffset.y,c->z-subBlockViewOffset.z);
glBindVertexArray(v->vao);
- if(mask == sideMaskALL || !glIsMultiDrawAvailable){
- glDrawElements(GL_TRIANGLE_FAN,v->idxCount,GL_UNSIGNED_SHORT,NULL);
- vboTrisCount += v->idxCount / 3;
+ if(true || mask == sideMaskALL || !glIsMultiDrawAvailable){
+ glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, VERTICES_PER_FACE, v->faceCount);
+ vboTrisCount += v->faceCount * 2;
drawCallCount++;
}else{
// We need one face less max, otherwise it would mean mask == sideMaskALL
@@ 185,8 165,8 @@ void chunkvertbufDrawOne(struct chunk *c, sideMask mask){
bool reuseLastSide = false;
for(side sideIndex = 0; sideIndex < sideMAX; sideIndex++){
if(mask & (1 << sideIndex)){
- const uint cFirst = bufOffset + c->vertbuf->sideIdxStart[sideIndex];
- const uint cCount = c->vertbuf->sideIdxCount[sideIndex];
+ const uint cFirst = bufOffset + c->vertbuf->sideFaceStart[sideIndex];
+ const uint cCount = c->vertbuf->sideFaceCount[sideIndex];
if(cCount == 0){continue;}
vboTrisCount += cCount / 3;
if(reuseLastSide){