#include #define GLAD_GL_IMPLEMENTATION #include "gl.h" #define GLFW_INCLUDE_NONE #include #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include #include "const.h" #include "cubes.h" #include "linmath.h" #include #include #include 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" "void main()\n" "{\n" " gl_Position = mvp * vec4(v_pos, 1.0);\n" " v_tex=vec2(v_off);\n" "}\n"; static const char *fragment_shader_text = "#version 330\n" "out vec4 color;\n" "in vec2 v_tex;\n" "uniform sampler2D sampler_tex;\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) { discard; }\n" " color=vec4(texture(sampler_tex, v_tex).rgb,0.5);\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 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 / 2) ? M_PI / 2 : ((cy < -M_PI / 2) ? -M_PI / 2 : cy); return; } struct args { int *cube_count; Vertex **cube; Vertex **text; vec3 pos; GLuint *vertex_buffer; int *is_render; }; 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 = gen_cubes(*args2.cube, *args2.text, args2.pos[0] / CHUNK_LENGTH, args2.pos[1] / CHUNK_LENGTH, args2.pos[2] / CHUNK_LENGTH, 0, 0); *args2.is_render = 2; return NULL; } 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, "OpenGL Triangle", NULL, NULL); if (!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); gladLoadGL(glfwGetProcAddress); glfwSwapInterval(1); Vertex *cube = malloc(CTRI_ALL); Vertex *text = malloc(CTRI_ALL); int cube_count = gen_cubes(cube, text, 1024 / CHUNK_LENGTH, 64 / CHUNK_LENGTH, 1024 / CHUNK_LENGTH, 0,1); 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, text, GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)0); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); glBufferData(GL_ARRAY_BUFFER, CTRI_ALL, cube, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (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"); unsigned char *pixels; int tx, ty, ch; pixels = stbi_load("./test.png", &tx, &ty, &ch, 3); glClearColor(0.2f, 0.5f, 0.7f, 1.0f); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, cursor_position_callback); vec3 pos = {1024, 64, 1024}; // int x = 0, y = 25, z = 0; glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); double frames = 0.0; pthread_t thread_id; int is_render = 1; glfwSetTime(7.5); while (!glfwWindowShouldClose(window)) { vec3 oldPos = {pos[0], pos[1], pos[2]}; 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 = {cosf(cy) * sinf(cx), sinf(cy), cosf(cy) * cosf(cx)}; vec3 right = {sinf(cx - 3.14f / 2.0f), 0, cosf(cx - 3.14f / 2.0f)}; if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { vec3_add(pos, pos, direction); } if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { vec3_sub(pos, pos, direction); } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { vec3_add(pos, pos, right); } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { vec3_sub(pos, pos, right); } vec3 dir_pos; vec3_add(dir_pos, direction, pos); vec3 up = {0, 1, 0}; // vec3_mul_cross(up, right, direction); 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); 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) && frames > 4.0) { struct args args; args.cube_count = &cube_count; args.cube = &cube; args.text = &text; 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; if (thread_id != 0) pthread_join(thread_id, NULL); pthread_create(&(thread_id), NULL, render_chunks, (void *)&(args)); frames = 0; glfwSetTime(0); } frames = glfwGetTime(); //Sprintf("%f\n", frames); glfwSwapBuffers(window); glfwPollEvents(); if (is_render == 2) { glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]); glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count*sizeof(Vertex), text); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count*sizeof(Vertex), cube); is_render = 1; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, GL_TEXTURE0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx, ty, 0, GL_RGB, 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); glDrawArrays(GL_TRIANGLES, 0, cube_count); } free(cube); free(text); glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); }