Skip to content

Instantly share code, notes, and snippets.

@Phildo
Last active May 24, 2022 21:58
Show Gist options
  • Save Phildo/2de52d752074ad091ba38842d0776702 to your computer and use it in GitHub Desktop.
Save Phildo/2de52d752074ad091ba38842d0776702 to your computer and use it in GitHub Desktop.
/*
This file attempts to use stb_voxel_render.h to minimally create a voxel mesh.
The resuting mesh should be a simple voxel sphere w/ 32 unit diameter.
(This will serve as the testing ground for implementing GL_EXT_multiview into
stb_voxel_render.h, whose progress can be found on the voxel_vr branch of this fork:
https://github.com/Phildo/stb/tree/voxel_vr )
*/
#define STBVOX_CONFIG_MODE 0
#define STBVOX_CONFIG_DISABLE_TEX2
#define STB_VOXEL_RENDER_IMPLEMENTATION
#include "stb_voxel_render.h"
//shorthands for autotyping/sizing mallocs
#define tmalloc(t,s) (t *)malloc(sizeof(t)*(size_t)s);
#define ntmalloc(t,v,s) t *v = (t *)malloc(sizeof(t)*(size_t)s);
stbvox_mesh_maker mm;
char *getVoxelVertShader()
{
return stbvox_get_vertex_shader();
}
char *getVoxelFragShader()
{
return stbvox_get_fragment_shader();
}
void initVoxel()
{
stbvox_init_mesh_maker(&mm);
}
size_t getVoxelBufferMSize()
{
return stbvox_get_buffer_size_per_quad(&mm, 0)/6;
}
size_t getVoxelMesh(void **buffer)
{
size_t ms = 32; //rendered mesh size ("ms*ms*ms cube")
size_t bs = ms + 2; //required buffer size (to access +-1 in all dim)
size_t bsx_stride = bs * bs;
size_t bsy_stride = bs;
size_t bsz_stride = 1; //required
size_t bslen = bs * bs * bs;
stbvox_set_default_mesh(&mm, 0);
stbvox_set_input_stride(&mm, (int)bsx_stride, (int)bsy_stride);
stbvox_set_input_range(&mm, 0, 0, 0, (int)ms, (int)ms, (int)ms);
int buffer_count = stbvox_get_buffer_count(&mm);
int buffer_size_per_quad = stbvox_get_buffer_size_per_quad(&mm, 0);
size_t buffer_len = buffer_size_per_quad * bslen * 6; //can't have more quads than every-face-of-every-voxel!
*buffer = malloc(buffer_len);
stbvox_reset_buffers(&mm);
stbvox_set_buffer(&mm, 0, 0, *buffer, buffer_len);
stbvox_input_description* input_description;
input_description = stbvox_get_input_description(&mm);
//*input_description = {};
memset(input_description,0,sizeof(input_description));
size_t types = 2;
unsigned char full_height = STBVOX_MAKE_VHEIGHT(
STBVOX_VERTEX_HEIGHT_1,
STBVOX_VERTEX_HEIGHT_1,
STBVOX_VERTEX_HEIGHT_1,
STBVOX_VERTEX_HEIGHT_1
);
//allocate pallettes
input_description->block_geometry = tmalloc(unsigned char, types);
input_description->block_tex1 = tmalloc(unsigned char, types);
input_description->block_tex1_face = (unsigned char (*)[6])malloc(sizeof(unsigned char (*)[6])*types);
input_description->block_color = tmalloc(unsigned char, types);
input_description->block_vheight = tmalloc(unsigned char, types);
input_description->block_selector = tmalloc(unsigned char, types);
//define block type 0 [empty]
input_description->block_geometry[0] = STBVOX_MAKE_GEOMETRY(STBVOX_GEOM_empty, 0, full_height);
input_description->block_tex1[0] = 0;
for(size_t i = 0; i < 6; i++) input_description->block_tex1_face[0][i] = 0;
input_description->block_color[0] = STBVOX_MAKE_COLOR(0,0,0);
input_description->block_vheight[0] = full_height;
input_description->block_selector[0] = 0;
//define block type 1 [solid]
input_description->block_geometry[1] = STBVOX_MAKE_GEOMETRY(STBVOX_GEOM_solid, 0, full_height);
input_description->block_tex1[1] = 0;
for(size_t i = 0; i < 6; i++) input_description->block_tex1_face[1][i] = 0;
input_description->block_color[1] = STBVOX_MAKE_COLOR(0,1,0);
input_description->block_vheight[1] = full_height;
input_description->block_selector[1] = 0;
//define 3d data [sphere volume]
ntmalloc(unsigned char, lighting, bslen);
ntmalloc(stbvox_block_type, blocktype, bslen);
float mr = (float)ms / 2.0f;
float br = (float)bs / 2.0f;
for(int x = 0; x < bs; x++)
{
for(int y = 0; y < bs; y++)
{
for(int z = 0; z < bs; z++)
{
int i = bsx_stride * x + bsy_stride * y + bsz_stride * z;
float fx = x - br;
float fy = y - br;
float fz = z - br;
if(fx * fx + fy * fy + fz * fz < mr * mr)
{
blocktype[i] = 1;
lighting[i] = STBVOX_MAKE_LIGHTING(1);
}
else
blocktype[i] = 0;
}
}
}
size_t offset_i = bsx_stride * 1 + bsy_stride * 1 + bsz_stride * 1; //[1][1][1], to allow for meshgen to query outside bounds
input_description->blocktype = &blocktype[offset_i];
input_description->lighting = &lighting[offset_i];
if(!stbvox_make_mesh(&mm))
{
; //bad!
}
else
{
; //good!
}
stbvox_set_mesh_coordinates(&mm, 0, 0, 0);
float bounds[2][3];
stbvox_get_bounds(&mm, bounds);
float transform[3][3];
stbvox_get_transform(&mm, transform);
int quad_count = stbvox_get_quad_count(&mm, 0);
//rendering
stbvox_uniform_info uinfo;
int uinfor = stbvox_get_uniform_info(&uinfo, 0);
free(input_description->block_geometry);
free(input_description->block_tex1);
free(input_description->block_tex1_face);
free(input_description->block_color);
free(input_description->block_vheight);
free(input_description->block_selector);
free(lighting);
free(blocktype);
return quad_count;
}
size_t getVoxelIndexBuff(size_t quads, uint32_t **buffer)
{
size_t length = quads*6;
if(buffer)
{
*buffer = tmalloc(uint32_t,length);
uint32_t v = 0;
for(size_t i = 0; i < length; i+=6)
{
(*buffer)[i+0] = v + 0;
(*buffer)[i+1] = v + 1;
(*buffer)[i+2] = v + 2;
(*buffer)[i+3] = v + 1;
(*buffer)[i+4] = v + 3;
(*buffer)[i+5] = v + 2;
v += 4;
}
}
return length;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment