src/chunk/lodmesh.c
/*
Generates a low def mesh for a chunk by sampling the height function n+1 points a side
Equivalently, makes N^2 quads
*/
Generates a low def mesh for a chunk by sampling the height function n+1 points a side
Equivalently, makes N^2 quads
Generates a low def mesh for a chunk by sampling the height function n + 1 points a side Equivalently makes N^2 quads
lodmesh lodmesh_generate(struct osn_context *osn, noise2d_params p, int s, int cx, int cz) {
    float *buf = 0;
    float ox = LODMESH_CHUNK_RADIX * cx;
    float oz = LODMESH_CHUNK_RADIX * cz;
    for (int x = 0; x < s; x++) {
        for (int z = 0; z < s; z++) {
            vec3s v1 = {0};
            vec3s v2 = {0};
            vec3s v3 = {0};
            vec3s v1c = {0};
            vec3s v2c = {0};
            vec3s v3c = {0};
            v1.x = ox + ((float)x*LODMESH_CHUNK_RADIX) / s;
            v1.z = oz + ((float)z*LODMESH_CHUNK_RADIX) / s;
            v1.y = generate_height(osn, v1.x, v1.z, p);
            v2.x = ox + ((float)(x+1)*LODMESH_CHUNK_RADIX) / s;
            v2.z = oz + (float)(z*LODMESH_CHUNK_RADIX) / s;
            v2.y = generate_height(osn, v2.x, v2.z, p);
            v3.x = ox + ((float)x*LODMESH_CHUNK_RADIX) / s;
            v3.z = oz + ((float)(z+1)*LODMESH_CHUNK_RADIX) / s;
            v3.y = generate_height(osn, v3.x, v3.z, p);
            v1.y = max(v1.y, p.water_below_height);
            v2.y = max(v2.y, p.water_below_height);
            v3.y = max(v3.y, p.water_below_height);
            vec3s n = calc_normal(v2, v1, v3);
            buf = push_vertex(buf, v2, n, p);
            buf = push_vertex(buf, v1, n, p);
            buf = push_vertex(buf, v3, n, p);
            v1.x = ox + ((float)(x+1)*LODMESH_CHUNK_RADIX) / s;
            v1.z = oz + ((float)(z+1)*LODMESH_CHUNK_RADIX) / s;
            v1.y = generate_height(osn, v1.x, v1.z, p);
            v1.y = max(v1.y, p.water_below_height);
            n = calc_normal(v1, v2, v3);
            buf = push_vertex(buf, v1, n, p);
            buf = push_vertex(buf, v2, n, p);
            buf = push_vertex(buf, v3, n, p);
        }
    }
    lodmesh m = {0};
    m.key = (int32_t_pair) {cx,cz};
    const int attribs_per_vertex = 9;
    const int floats_per_triangle = attribs_per_vertex*3;
    m.num_triangles = arrlen(buf) / floats_per_triangle;
    glGenVertexArrays(1, &m.vao);
    glGenBuffers(1, &m.vbo);
    glBindVertexArray(m.vao);
    glBindBuffer(GL_ARRAY_BUFFER, m.vbo);
    glBufferData(GL_ARRAY_BUFFER, arrlen(buf) * sizeof(float), buf, GL_STATIC_DRAW);
    const float stride = attribs_per_vertex * sizeof(float);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, stride, (void*)(3*sizeof(float)));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, stride, (void*)(6*sizeof(float)));
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    arrfree(buf);
    return m;
}
lodmesh lodmesh_generate ( struct osn_context * osn , noise2d_params p , int s , int cx , int cz ) { float * buf = 0 ; float ox = LODMESH_CHUNK_RADIX * cx ; float oz = LODMESH_CHUNK_RADIX * cz ; for ( int x = 0 ; x < s ; x ++ ) { for ( int z = 0 ; z < s ; z ++ ) { vec3s v1 = { 0 } ; vec3s v2 = { 0 } ; vec3s v3 = { 0 } ; vec3s v1c = { 0 } ; vec3s v2c = { 0 } ; vec3s v3c = { 0 } ; v1 . x = ox + ( ( float ) x * LODMESH_CHUNK_RADIX ) / s ; v1 . z = oz + ( ( float ) z * LODMESH_CHUNK_RADIX ) / s ; v1 . y = generate_height ( osn , v1 . x , v1 . z , p ) ; v2 . x = ox + ( ( float ) ( x + 1 ) * LODMESH_CHUNK_RADIX ) / s ; v2 . z = oz + ( float ) ( z * LODMESH_CHUNK_RADIX ) / s ; v2 . y = generate_height ( osn , v2 . x , v2 . z , p ) ; v3 . x = ox + ( ( float ) x * LODMESH_CHUNK_RADIX ) / s ; v3 . z = oz + ( ( float ) ( z + 1 ) * LODMESH_CHUNK_RADIX ) / s ; v3 . y = generate_height ( osn , v3 . x , v3 . z , p ) ; v1 . y = max ( v1 . y , p . water_below_height ) ; v2 . y = max ( v2 . y , p . water_below_height ) ; v3 . y = max ( v3 . y , p . water_below_height ) ; vec3s n = calc_normal ( v2 , v1 , v3 ) ; buf = push_vertex ( buf , v2 , n , p ) ; buf = push_vertex ( buf , v1 , n , p ) ; buf = push_vertex ( buf , v3 , n , p ) ; v1 . x = ox + ( ( float ) ( x + 1 ) * LODMESH_CHUNK_RADIX ) / s ; v1 . z = oz + ( ( float ) ( z + 1 ) * LODMESH_CHUNK_RADIX ) / s ; v1 . y = generate_height ( osn , v1 . x , v1 . z , p ) ; v1 . y = max ( v1 . y , p . water_below_height ) ; n = calc_normal ( v1 , v2 , v3 ) ; buf = push_vertex ( buf , v1 , n , p ) ; buf = push_vertex ( buf , v2 , n , p ) ; buf = push_vertex ( buf , v3 , n , p ) ; } } lodmesh m = { 0 } ; m . key = ( int32_t_pair ) { cx , cz } ; const int attribs_per_vertex = 9 ; const int floats_per_triangle = attribs_per_vertex * 3 ; m . num_triangles = arrlen ( buf ) / floats_per_triangle ; glGenVertexArrays ( 1 , & m . vao ) ; glGenBuffers ( 1 , & m . vbo ) ; glBindVertexArray ( m . vao ) ; glBindBuffer ( GL_ARRAY_BUFFER , m . vbo ) ; glBufferData ( GL_ARRAY_BUFFER , arrlen ( buf ) * sizeof ( float ) , buf , GL_STATIC_DRAW ) ; const float stride = attribs_per_vertex * sizeof ( float ) ; glVertexAttribPointer ( 0 , 3 , GL_FLOAT , GL_FALSE , stride , ( void * ) 0 ) ; glEnableVertexAttribArray ( 0 ) ; glVertexAttribPointer ( 1 , 3 , GL_FLOAT , GL_FALSE , stride , ( void * ) ( 3 * sizeof ( float ) ) ) ; glEnableVertexAttribArray ( 2 ) ; glVertexAttribPointer ( 2 , 3 , GL_FLOAT , GL_FALSE , stride , ( void * ) ( 6 * sizeof ( float ) ) ) ; glEnableVertexAttribArray ( 1 ) ; glBindBuffer ( GL_ARRAY_BUFFER , 0 ) ; glBindVertexArray ( 0 ) ; arrfree ( buf ) ; return m ; }
Generates a low def mesh for a chunk by sampling the height function n+1 points a side
Equivalently, makes N^2 quads
Generates a low def mesh for a chunk by sampling the height function n + 1 points a side Equivalently makes N^2 quads
// figure out x and z of each coordinate // lower triangle // upper triangle /*
            v2.x = ox + ((float)(x+1)*LODMESH_CHUNK_RADIX) / s;
            v2.z = oz + (float)(z*LODMESH_CHUNK_RADIX) / s;
            v2.y = generate_height(osn, v2.x, v2.z, p);

            v3.x = ox + ((float)x*LODMESH_CHUNK_RADIX) / s;
            v3.z = oz + ((float)(z+1)*LODMESH_CHUNK_RADIX) / s;
            v3.y = generate_height(osn, v3.x, v3.z, p);
*/ //            v2.y = max(v2.y, p.water_below_height); //            v3.y = max(v3.y, p.water_below_height); // upload to gpu // position // colour // normal