place / break blocks

This commit is contained in:
onezplpl 2024-07-18 11:06:32 -04:00
parent fb639f96c3
commit 227d642be6
No known key found for this signature in database
GPG key ID: 7EC026A136F9EEC3
7 changed files with 191 additions and 55 deletions

View file

@ -2,6 +2,7 @@
#include "gen.h"
#include "linmath.h"
#include <GLFW/glfw3.h>
#include <stdio.h>
int is_space;
@ -33,7 +34,7 @@ int collision(struct chunk chunk, vec3 pos, vec3 dir_temp, int col, int n) {
}
struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp,
GLFWwindow *window, struct chunk chunk) {
GLFWwindow *window, struct chunk chunk) {
vec3 direction = {cosf(cy) * sinf(cx) * 0.1, sinf(cy) * 0.1,
cosf(cy) * cosf(cx) * 0.1};
vec3 right = {sinf(cx - 3.14f / 2.0f) * 0.1, 0,
@ -52,10 +53,6 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp,
vec3_add(dir_temp, dir_temp, front);
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
vec3_add(dir_temp, dir_temp, direction);
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
vec3_add(dir_temp, dir_temp, right);
}
@ -71,7 +68,7 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp,
for (int a = -2; a < 0; a++) {
off[1] = a;
col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2],
chunk, 0);
chunk, 0, -1);
}
vec3_add(pos, pos, dir_temp);
@ -80,8 +77,8 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp,
col = 0;
for (int a = -2; a < 0; a++) {
off[1] = a;
col = col || gen_cube(pos[0] + off[0], pos[1] + off[1],
pos[2] + off[2], chunk, 0);
col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2],
chunk, 0, -1);
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
@ -101,4 +98,66 @@ struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp,
vec3_dup(dirOut.pos, direction);
return dirOut;
}
struct v3f control_rtrace(double cx, double cy, vec3 pos, int mode) {
struct chunk placeChunk;
vec3 direction = {cosf(cy) * sinf(cx) * 0.1, sinf(cy) * 0.1,
cosf(cy) * cosf(cx) * 0.1};
vec3 temp_pos;
vec3 temp_dir;
vec3_dup(temp_pos, pos);
for (int i = 0; i < CHUNK_LENGTH * 4; i++) {
double xd =
fabs(direction[0]) / (((direction[0] > 0) ? (1.0 - fmod(temp_pos[0], 1))
: fmod(temp_pos[0], 1)) +
0.01);
double yd =
fabs(direction[1]) / (((direction[1] > 0) ? (1.0 - fmod(temp_pos[1], 1))
: fmod(temp_pos[1], 1)) +
0.01);
double zd =
fabs(direction[2]) / (((direction[2] > 0) ? (1.0 - fmod(temp_pos[2], 1))
: fmod(temp_pos[2], 1)) +
0.01);
if (xd > yd && xd > zd && !isnan(xd)) {
vec3_scale(temp_dir, direction, fabs(1 / xd + 0.01));
} else if (yd > zd && !isnan(yd)) {
vec3_scale(temp_dir, direction, fabs(1 / yd + 0.01));
} else if (!isnan(zd)) {
vec3_scale(temp_dir, direction, fabs(1 / zd + 0.01));
}
vec3_add(temp_pos, temp_pos, temp_dir);
if (gen_cube(temp_pos[0],temp_pos[1],temp_pos[2],placeChunk,0,-1) != 0) {
if (mode == 0) vec3_sub(temp_pos,temp_pos,temp_dir);
break;
}
}
struct v3f out_pos;
vec3_dup(out_pos.pos, temp_pos);
return out_pos;
}
void control_lclick(double cx, double cy, vec3 pos) {
struct v3f highlighted = control_rtrace(cx, cy, pos, 1);
struct chunk placeChunk;
int cube = gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,-1);
if (cube == 0) return;
gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,0);
}
void control_rclick(double cx, double cy, vec3 pos) {
struct v3f highlighted = control_rtrace(cx, cy, pos, 0);
struct chunk placeChunk;
int cube = gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,-1);
if (cube != 0) return;
gen_cube(highlighted.pos[0],highlighted.pos[1],highlighted.pos[2],placeChunk,0,1);
}

View file

@ -5,4 +5,6 @@
#include <GLFW/glfw3.h>
struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp,
GLFWwindow *window, struct chunk chunk);
void control_lclick(double cx, double cy, vec3 pos);
void control_rclick(double cx, double cy, vec3 pos);
#endif

20
cubes.c
View file

@ -30,8 +30,8 @@ void cubes_face(struct v3f *cube, int i, int x, int y, int z, int x2, int y2,
if (is_text) {
a.pos[i]--;
int exists = 0;
int type = gen_cube(x, y, z, dat, ci);
int typeB = gen_cube(a.pos[0], a.pos[1], a.pos[2], dat, ci);
int type = gen_cube(x, y, z, dat, ci, -1);
int typeB = gen_cube(a.pos[0], a.pos[1], a.pos[2], dat, ci, -1);
exists = ((!!type) != (!!typeB));
a2.pos[0] = exists ? TEXT_GAP_H * (type ? (type - 1) : (typeB - 1)) : -1.0;
@ -136,6 +136,17 @@ void *cubes_chunk(void *args) {
void cubes_free() { free(chunk_old); }
void cubes_refresh(int x, int y, int z, struct chunk dat) {
for (int i = 0; i < CHUNK_ALL; i++) {
if (chunk_old[i].exists != 0 && chunk_old[i].x == x &&
chunk_old[i].y == y && chunk_old[i].z == z) {
chunk_old[i].exists = 0;
gen_save(dat);
return;
}
}
}
int cubes_vert(struct v3f *cube, struct v3f *text, struct v3f *cubeO,
struct v3f *textO, int x, int y, int z, int is_purge, int *i2) {
struct v3f noth = {{-1, -1, -1}};
@ -199,10 +210,9 @@ int cubes_vert(struct v3f *cube, struct v3f *text, struct v3f *cubeO,
old_chunk.y == pos.pos[1] / CHUNK_LENGTH &&
old_chunk.z == pos.pos[2] / CHUNK_LENGTH && old_chunk.exists != 0);
if (cached) {
thread_return[a2] = i2[a2 / a3];
thread_return[a2] = i2[a2 / a3] - 6;
thread_id[a2] = -1;
} else if (pos.pos[0] < 0 || pos.pos[1] < 0 || pos.pos[2] < 0 ||
pos.pos[1] < ((y - CHUNK_LENGTH * CHUNK_RADIUS_V) * 1.05)) {
} else if (pos.pos[0] < 0 || pos.pos[1] < 0 || pos.pos[2] < 0) {
thread_return[a2] = -1;
thread_id[a2] = -1;
} else {

View file

@ -39,7 +39,8 @@ struct v2f {
};
int cubes_vert(struct v3f *cube, struct v3f *text, struct v3f *cubeO,
struct v3f *textO, int x, int y, int z, int is_purge, int *i2);
struct v3f *textO, int x, int y, int z, int is_purge, int *i2);
void cubes_free();
void cubes_refresh(int x, int y, int z, struct chunk dat);
#endif

76
gen.c
View file

@ -1,3 +1,4 @@
#include "gen.h"
#include "cubes.h"
#include "noise.h"
#include <stdio.h>
@ -8,6 +9,37 @@ struct chunk *chunks = NULL;
int lastI = 0;
int prevExists = 0;
void gen_save(struct chunk chunk) {
char fname[1024];
snprintf(fname, 1023, "./db/chunk_%i_%i_%i.dat", chunk.x, chunk.y, chunk.z);
if (chunk.exists == 0)
return;
FILE *fp = fopen(fname, "wb");
if (!fp) {
return;
}
fwrite(&chunk, sizeof(struct chunk), 1, fp);
fclose(fp);
return;
}
struct chunk gen_find(int x, int y, int z) {
struct chunk chunk;
for (int j = 0; j < CBUF_ALL; j++) {
int i = j;
chunk = chunks[i];
if ((chunk).x == x && (chunk).y == y && (chunk).z == z &&
(chunk).exists != 0) {
return chunk;
}
}
chunk = (gen_chunk(x, y, z, 0, 0));
return chunk;
}
struct chunk gen_chunk(int x, int y, int z, int ci, int h) {
struct chunk *chunks2 = chunks; // &chunks[CBUF_ALL * ci];
@ -47,6 +79,10 @@ struct chunk gen_chunk(int x, int y, int z, int ci, int h) {
}
}
if (chunk.exists == 1 && chunk.x != x && chunk.y != y && chunk.z != z) {
gen_save(chunk);
}
char fname[1024];
snprintf(fname, 1023, "./db/chunk_%i_%i_%i.dat", x, y, z);
@ -62,9 +98,8 @@ struct chunk gen_chunk(int x, int y, int z, int ci, int h) {
chunk.exists = 1;
return chunk;
}
}
if (!fp) {
fp = fopen(fname, "wb");
} else if (fp) {
fclose(fp);
}
lastI = i;
@ -82,12 +117,7 @@ struct chunk gen_chunk(int x, int y, int z, int ci, int h) {
chunks2[i] = chunk;
if (!fp) {
return chunk;
}
fwrite(&chunk, sizeof(struct chunk), 1, fp);
fclose(fp);
gen_save(chunk);
return chunk;
}
@ -98,21 +128,33 @@ void gen_init() {
}
}
void gen_free() { free(chunks); }
void gen_free() {
for (int i = 0; i < CHUNK_ALL; i++) {
gen_save(chunks[i]);
}
free(chunks);
}
int gen_cube(int x, int y, int z, struct chunk dat, int ci) {
int gen_cube(int x, int y, int z, struct chunk dat, int ci, int val) {
if (x < 0 || y < 0 || z < 0)
return 0;
if (dat.exists == 0 || dat.x != (x / CHUNK_LENGTH) ||
if (val != -1) {
dat = gen_find((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), (z / CHUNK_LENGTH));
} else if (dat.exists == 0 || dat.x != (x / CHUNK_LENGTH) ||
dat.y != (y / CHUNK_LENGTH) || dat.z != (z / CHUNK_LENGTH)) {
dat = gen_chunk((x / CHUNK_LENGTH), (y / CHUNK_LENGTH),
(z / CHUNK_LENGTH), ci, dat.exists);
dat = gen_chunk((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), (z / CHUNK_LENGTH),
ci, dat.exists);
prevExists = dat.exists;
}
int h = dat.blocks[(y % CHUNK_LENGTH) + (z % CHUNK_LENGTH) * CHUNK_LENGTH +
(x % CHUNK_LENGTH) * CHUNK_LENGTH * CHUNK_LENGTH];
int *h = &dat.blocks[(y % CHUNK_LENGTH) + (z % CHUNK_LENGTH) * CHUNK_LENGTH +
(x % CHUNK_LENGTH) * CHUNK_LENGTH * CHUNK_LENGTH];
return h;
if (val != -1) {
*h = val;
cubes_refresh(x / CHUNK_LENGTH, y / CHUNK_LENGTH, z / CHUNK_LENGTH, dat);
}
return *h;
}

3
gen.h
View file

@ -2,8 +2,9 @@
#define V_GEN_H
#include "cubes.h"
int gen_cube(int x, int y, int z, struct chunk dat, int ci);
int gen_cube(int x, int y, int z, struct chunk dat, int ci, int val);
struct chunk gen_chunk(int x, int y, int z, int ci, int h);
void gen_init();
void gen_free();
void gen_save(struct chunk chunk);
#endif

67
main.c
View file

@ -9,12 +9,12 @@
#include <stdio.h>
#include <stdlib.h>
#include "control.h"
#include "cubes.h"
#include "gen.h"
#include "gl.h"
#include "linmath.h"
#include "stb_image.h"
#include "control.h"
static const char *vertex_shader_text =
"#version 330\n"
@ -64,6 +64,21 @@ static void key_callback(GLFWwindow *window, int key, int scancode, int action,
double cx = 0;
double cy = 0;
int fr = 0;
vec3 pos;
void mouse_button_callback(GLFWwindow *window, int button, int action,
int mods) {
if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) {
fr = 1;
control_rclick(cx, cy, pos);
}
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
fr = 1;
control_lclick(cx, cy, pos);
}
}
int width, height;
static void cursor_position_callback(GLFWwindow *window, double x, double y) {
@ -99,8 +114,8 @@ void *render_chunks(void *args) {
*cube_count =
cubes_vert(*args2.cube, *args2.text, *args2.cubeO, *args2.textO,
args2.pos[0] / CHUNK_LENGTH, args2.pos[1] / CHUNK_LENGTH,
args2.pos[2] / CHUNK_LENGTH, 0, args2.i2);
args2.pos[0] / CHUNK_LENGTH, args2.pos[1] / CHUNK_LENGTH,
args2.pos[2] / CHUNK_LENGTH, 0, args2.i2);
*args2.is_render = 2;
@ -134,8 +149,6 @@ int main(void) {
int bleh = (CHUNK_DIAMETER_H) * (CHUNK_DIAMETER_V);
int *i2 = calloc(bleh, sizeof(int));
int cube_count = cubes_vert(cube, text, cubeO, textO, 10240 / CHUNK_LENGTH,
64 / CHUNK_LENGTH, 10240 / CHUNK_LENGTH, 1, i2);
GLuint vertex_buffer[2];
GLuint vertex_array;
@ -183,16 +196,23 @@ int main(void) {
glEnable(GL_DEPTH_TEST);
glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetCursorPosCallback(window, cursor_position_callback);
vec3 pos = {10240, 48, 10240};
pos[0] = 10240;
pos[1] = 48;
pos[2] = 10240;
int cube_count =
cubes_vert(cube, text, cubeO, textO, pos[0] / CHUNK_LENGTH,
pos[1] / CHUNK_LENGTH, pos[2] / CHUNK_LENGTH, 1, i2);
vec3 oldPos = {0, 0, 0};
struct chunk ch7;
ch7.exists = 0;
int state = gen_cube(pos[0], pos[1], pos[2], ch7, 0);
int state = gen_cube(pos[0], pos[1], pos[2], ch7, 0, -1);
while (1) {
if (state != gen_cube(pos[0], pos[1], pos[2], ch7, 0))
if (state != gen_cube(pos[0], pos[1], pos[2], ch7, 0, -1))
break;
pos[1] += (state ? 1 : -1);
}
@ -209,12 +229,14 @@ int main(void) {
int last_render = 0;
struct chunk chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH,
pos[2] / CHUNK_LENGTH, 0, 0);
pos[2] / CHUNK_LENGTH, 0, 0);
vec3 dir_temp = {0, 0, 0};
vec3 direction;
fr = 1;
while (!glfwWindowShouldClose(window)) {
glfwGetFramebufferSize(window, &width, &height);
@ -228,12 +250,10 @@ int main(void) {
mat4x4_identity(m);
mat4x4_perspective(p, 45.0 / 180.0 * M_PI, ratio, 0.1, 1000);
// TODO: make control code its own thing
vec3 direction;
vec3_dup(direction,control_handler(cx, cy, pos, dir_temp,
window, chunk).pos);
vec3_dup(direction,
control_handler(cx, cy, pos, dir_temp, window, chunk).pos);
vec3 dir_pos;
vec3_scale(direction, direction, 100.0);
@ -252,7 +272,8 @@ int main(void) {
int ay = (int)(oldPos[1] / CHUNK_LENGTH) - (int)(pos[1] / CHUNK_LENGTH);
int az = (int)(oldPos[2] / CHUNK_LENGTH) - (int)(pos[2] / CHUNK_LENGTH);
if ((ax != 0 || ay != 0 || az != 0) && last_render < 0) {
if (((ax != 0 || ay != 0 || az != 0) && last_render < 0) || fr == 1) {
fr = 0;
struct args args;
args.cube_count = &cube_count;
@ -283,17 +304,17 @@ int main(void) {
glfwPollEvents();
if (is_render == 2) {
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count * sizeof(struct v3f),
textO); // text);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count * sizeof(struct v3f),
cubeO); // cube);
if (thread_id != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0,
(long)cube_count * sizeof(struct v3f), textO);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0,
(long)cube_count * sizeof(struct v3f), cubeO);
pthread_join(thread_id, NULL);
chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH,
pos[2] / CHUNK_LENGTH, 0, 0);
pos[2] / CHUNK_LENGTH, 0, 0);
}
thread_id = 0;
}