#define STB_IMAGE_IMPLEMENTATION #define GLFW_INCLUDE_NONE #define GLAD_GL_IMPLEMENTATION #include #include #include #include #include #include #include "control.h" #include "cubes.h" #include "gen.h" #include "gl.h" #include "linmath.h" #include "stb_image.h" static const char *vertex_shader_text = "#version 330\n" "layout (location = 0) in vec3 v_pos;" "layout (location = 1) in vec3 v_off;" "uniform mat4 mvp;\n" "out vec2 v_tex;\n" "out vec3 v_pos_out;\n" "void main()\n" "{\n" " gl_Position = mvp * vec4(v_pos, 1.0);\n" " v_tex=vec2(v_off);\n" " v_pos_out=v_pos;\n" "}\n"; static const char *fragment_shader_text = "#version 330\n" "out vec4 color;\n" "in vec2 v_tex;\n" "in vec3 v_pos_out;\n" "uniform sampler2D sampler_tex;\n" "uniform vec3 center;\n" "uniform int use_shading;\n" "float dist;\n" "void main()\n" "{\n" //" color=vec4(v_tex.rg,0.5,0.5);\n" " if (v_tex.x < 0.0 || v_tex.y < 0.0 || texture(sampler_tex, v_tex).a " "== 0.0) { discard; }\n" " dist = distance(v_pos_out, center + vec3(8,8,8))/65;\n" " if (dist > 1.0) { dist = 1.0; }\n" " if (use_shading == 0) { dist = 0.0; }\n" " color=vec4(texture(sampler_tex, v_tex).rgb,1.0)*(1.0-(dist*dist)) + " "vec4(0.2,0.5,0.7,1.0)*(dist*dist);\n" "}\n"; int isCursor = 0; static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { /*if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE); */ if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { isCursor = glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; glfwSetInputMode(window, GLFW_CURSOR, isCursor ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_DISABLED); } } 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) { if (isCursor) return; cx = (x - width / 2.0) / -1000.0; cy = (y - height / 2.0) / -1000.0; cy = (cy > M_PI * 0.48) ? M_PI * 0.48 : ((cy < -M_PI * 0.48) ? -M_PI * 0.48 : cy); return; } struct args { int *cube_count; struct v3f **cube; struct v3f **text; struct v3f **cubeO; struct v3f **textO; vec3 pos; GLuint *vertex_buffer; int *is_render; int *i2; }; void *render_chunks(void *args) { struct args args2 = ((struct args *)args)[0]; int *cube_count = args2.cube_count; // printf("%i\n", *cube_count); GLuint *vertex_buffer = args2.vertex_buffer; *args2.is_render = 0; *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.is_render = 2; return NULL; } #define WinMain main int main(void) { if (!glfwInit()) exit(EXIT_FAILURE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow *window = glfwCreateWindow(640, 480, "VoxelTest", NULL, NULL); if (!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); gladLoadGL(glfwGetProcAddress); glfwSwapInterval(1); struct v3f *cube = malloc(CTRI_ALL); struct v3f *text = malloc(CTRI_ALL); struct v3f *cubeO = malloc(CTRI_ALL + UI_ALL * 18 * sizeof(struct v3f)); struct v3f *textO = malloc(CTRI_ALL + UI_ALL * 18 * sizeof(struct v3f)); int bleh = (CHUNK_DIAMETER_H) * (CHUNK_DIAMETER_V); int *i2 = calloc(CHUNK_ALL, sizeof(int)); GLuint vertex_buffer[2]; GLuint vertex_array; glGenVertexArrays(1, &vertex_array); glBindVertexArray(vertex_array); glGenBuffers(2, vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]); glBufferData(GL_ARRAY_BUFFER, CTRI_ALL + UI_ALL * 18 * sizeof(struct v3f), textO, GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct v3f), (void *)0); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); glBufferData(GL_ARRAY_BUFFER, CTRI_ALL + UI_ALL * 18 * sizeof(struct v3f), cubeO, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct v3f), (void *)0); GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); glCompileShader(vertex_shader); GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); glCompileShader(fragment_shader); GLuint program = glCreateProgram(); glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glLinkProgram(program); GLint tex_location = glGetUniformLocation(program, "sampler_tex"); GLint mvp_location = glGetUniformLocation(program, "mvp"); GLint center_location = glGetUniformLocation(program, "center"); GLint use_shading = glGetUniformLocation(program, "use_shading"); unsigned char *pixels; int tx, ty, ch; pixels = stbi_load("./test.png", &tx, &ty, &ch, 4); glClearColor(0.2f, 0.5f, 0.7f, 1.0f); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glfwSetKeyCallback(window, key_callback); glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetCursorPosCallback(window, cursor_position_callback); pos[0] = 10240; pos[1] = 48; pos[2] = 10240; FILE *fp = fopen("./db/position.dat", "rb"); int code = (fp) ? fread(&pos, sizeof(struct v3f), 1, fp) : 0; 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, -1); while (1) { if (state != gen_cube(pos[0], pos[1], pos[2], ch7, 0, -1)) break; pos[1] += (state ? 1 : -1); } pos[1] += 5; // int x = 0, y = 25, z = 0; glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); double frames = 0.0; pthread_t thread_id = 0; int is_render = 1; int last_render = 0; struct chunk chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, pos[2] / CHUNK_LENGTH, 0, 0); is_render = 2; vec3 dir_temp = {0, 0, 0}; vec3 direction; fr = 0; while (!glfwWindowShouldClose(window)) { glfwGetFramebufferSize(window, &width, &height); const float ratio = width / (float)height; glViewport(0, 0, width, height); glUseProgram(program); mat4x4 m, v, p, mvp; mat4x4_identity(m); mat4x4_perspective(p, 45.0 / 180.0 * M_PI, ratio, 0.1, 1000); vec3 direction; vec3_dup(direction, control_handler(cx, cy, pos, dir_temp, window, chunk).pos); vec3 dir_pos; vec3_scale(direction, direction, 100.0); vec3_add(dir_pos, direction, pos); vec3 up = {0, 1, 0}; mat4x4_look_at(v, pos, dir_pos, up); mat4x4_mul(mvp, p, v); mat4x4_mul(mvp, mvp, m); glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat *)&mvp); glUniform3fv(center_location, 1, (const GLfloat *)(&(pos[0]))); int ax = (int)(oldPos[0] / CHUNK_LENGTH) - (int)(pos[0] / CHUNK_LENGTH); 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) || fr == 1) { fr = 0; struct args args; args.cube_count = &cube_count; args.cube = &cube; args.text = &text; args.cubeO = &cubeO; args.textO = &textO; args.pos[0] = pos[0]; args.pos[1] = pos[1]; args.pos[2] = pos[2]; args.vertex_buffer = vertex_buffer; args.is_render = &is_render; args.i2 = i2; last_render = 40; if (thread_id == 0) { oldPos[0] = (int)(args.pos[0] / CHUNK_LENGTH) * CHUNK_LENGTH; oldPos[1] = (int)(args.pos[1] / CHUNK_LENGTH) * CHUNK_LENGTH; oldPos[2] = (int)(args.pos[2] / CHUNK_LENGTH) * CHUNK_LENGTH; pthread_create(&(thread_id), NULL, render_chunks, (void *)&(args)); } } last_render--; glfwSwapBuffers(window); glfwPollEvents(); if (is_render == 2) { 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); if (thread_id != 0) { pthread_join(thread_id, NULL); chunk = gen_chunk(pos[0] / CHUNK_LENGTH, pos[1] / CHUNK_LENGTH, pos[2] / CHUNK_LENGTH, 0, 0); } thread_id = 0; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, GL_TEXTURE0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx, ty, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); int val = CTRI_ALL; glBindVertexArray(vertex_array); glUniform1i(use_shading, 1); glDrawArrays(GL_TRIANGLES, 0, cube_count); glClear(GL_DEPTH_BUFFER_BIT); glUniform1i(use_shading, 0); int iz = CBLOCK_ALL * 18; cubes_rect(cubeO, &iz, -0.5, 0.5, -0.5, 0.5, 0, 0, 6); cubes_rect(textO, &iz, -0.5, 0.5, -0.5, 0.5, 1, 0, 6); mat4x4_identity(v); mat4x4_ortho(p, -ratio * 15, ratio * 15, -1.f * 15, 1.f * 15, 1.0f, -1.0f); mat4x4_mul(mvp, p, v); mat4x4_mul(mvp, mvp, m); glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat *)&mvp); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]); glBufferSubData(GL_ARRAY_BUFFER, CTRI_ALL, (long)6 * sizeof(struct v3f), &textO[iz]); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); glBufferSubData(GL_ARRAY_BUFFER, CTRI_ALL, (long)6 * sizeof(struct v3f), &cubeO[iz]); glBindVertexArray(vertex_array); glDrawArrays(GL_TRIANGLES, CBLOCK_ALL * 18, 6); } if (fp) { fclose(fp); } fp = fopen("./db/position.dat", "wb"); if (fp) { fwrite(&pos, sizeof(struct v3f), 1, fp); fclose(fp); } free(cube); free(text); free(cubeO); free(textO); free(i2); gen_free(); cubes_free(); glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); }