Add source files
This commit is contained in:
parent
5332bec419
commit
fa97efdce6
4
Makefile
Normal file
4
Makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
all:
|
||||||
|
gcc -Iinclude/ src/app.c src/camera.c src/main.c src/game.c src/utils.c -lSDL2 -lGL -lm -lSDL2_image -o test -Wall
|
||||||
|
debug:
|
||||||
|
gcc -Iinclude/ src/app.c src/camera.c src/main.c src/game.c src/utils.c -lSDL2 -lGL -lm -lSDL2_image -o test -Wall -g
|
BIN
assets/block.png
Normal file
BIN
assets/block.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
80
include/app.h
Normal file
80
include/app.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifndef APP_H
|
||||||
|
#define APP_H
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include "camera.h"
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define SPEED 5
|
||||||
|
#define GRAVITY 10
|
||||||
|
|
||||||
|
#define VIEWPORT_RATIO (16.0 / 9.0)
|
||||||
|
#define VIEWPORT_ASPECT 50.0
|
||||||
|
|
||||||
|
typedef unsigned int uint;
|
||||||
|
|
||||||
|
#define CHUNK_MAX_X 16
|
||||||
|
#define CHUNK_MAX_Y 16
|
||||||
|
#define CHUNK_MAX_Z 128
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLOCKTYPE_AIR,
|
||||||
|
BLOCKTYPE_GRASS,
|
||||||
|
BLOCKTYPE_DIRT,
|
||||||
|
BLOCKTYPE_STONE,
|
||||||
|
} Block_type;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Block_type type;
|
||||||
|
bool visible;
|
||||||
|
} Block;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec3f start_pos;
|
||||||
|
Block blocks[CHUNK_MAX_X][CHUNK_MAX_Y][CHUNK_MAX_Z];
|
||||||
|
GLuint id;
|
||||||
|
} Chunk;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool is_running;
|
||||||
|
SDL_Window *window;
|
||||||
|
SDL_GLContext context;
|
||||||
|
Camera camera;
|
||||||
|
double frame_time;
|
||||||
|
SDL_Surface *surface;
|
||||||
|
GLuint tid;
|
||||||
|
unsigned int chunk_count;
|
||||||
|
Chunk *chunks;
|
||||||
|
} App;
|
||||||
|
|
||||||
|
bool chunk_is_block_neighboring_block(Chunk* chunk, vec3i pos);
|
||||||
|
void chunk_set_blocks_visibility(Chunk* chunk);
|
||||||
|
void chunk_create_displayl(App *app, Chunk *chunk);
|
||||||
|
void chunk_render(Chunk* chunk);
|
||||||
|
|
||||||
|
bool is_block(Block b);
|
||||||
|
|
||||||
|
int app_get_current_chunk_index(App *app);
|
||||||
|
|
||||||
|
bool app_check_collision(App *app);
|
||||||
|
|
||||||
|
void init_app(App *app, uint w, uint h);
|
||||||
|
|
||||||
|
void init_opengl();
|
||||||
|
|
||||||
|
void handle_events(App *app);
|
||||||
|
|
||||||
|
void draw_cube(App *app, float x, float y, float z);
|
||||||
|
|
||||||
|
void reshape(GLsizei width, GLsizei height);
|
||||||
|
|
||||||
|
void update_app(App* app);
|
||||||
|
|
||||||
|
float calc_frame_time(struct timespec *start, struct timespec *end);
|
||||||
|
|
||||||
|
#endif
|
51
include/camera.h
Normal file
51
include/camera.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Camera, as a moving point with direction
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct Camera
|
||||||
|
{
|
||||||
|
vec3f position;
|
||||||
|
vec3f rotation;
|
||||||
|
vec3f speed;
|
||||||
|
} Camera;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the camera to the start position.
|
||||||
|
*/
|
||||||
|
void init_camera(Camera* camera);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the position of the camera.
|
||||||
|
*/
|
||||||
|
void update_camera(Camera* camera, double time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the camera settings to the view transformation.
|
||||||
|
*/
|
||||||
|
void set_view(const Camera* camera);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the horizontal and vertical rotation of the view angle.
|
||||||
|
*/
|
||||||
|
void rotate_camera(Camera* camera, double horizontal, double vertical);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the speed of forward and backward motion.
|
||||||
|
*/
|
||||||
|
void set_camera_speed(Camera* camera, double speed);
|
||||||
|
|
||||||
|
void camera_set_vertical_speed(Camera* camera, double speed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the speed of left and right side steps.
|
||||||
|
*/
|
||||||
|
void set_camera_side_speed(Camera* camera, double speed);
|
||||||
|
|
||||||
|
#endif /* CAMERA_H */
|
11
include/game.h
Normal file
11
include/game.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
#include "app.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
49
include/utils.h
Normal file
49
include/utils.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GLSL-like three dimensional vector
|
||||||
|
*/
|
||||||
|
typedef struct vec3f
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} vec3f;
|
||||||
|
|
||||||
|
typedef struct vec3i
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
} vec3i;
|
||||||
|
|
||||||
|
typedef struct vec4f
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
} vec4f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color with RGB components
|
||||||
|
*/
|
||||||
|
typedef struct Color
|
||||||
|
{
|
||||||
|
float red;
|
||||||
|
float green;
|
||||||
|
float blue;
|
||||||
|
} Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates radian from degree.
|
||||||
|
*/
|
||||||
|
double degree_to_radian(double degree);
|
||||||
|
|
||||||
|
bool is_oob(int i, int min, int max);
|
||||||
|
|
||||||
|
void mult_matrix(float *matrix, vec4f vector, vec4f *ret);
|
||||||
|
|
||||||
|
#endif /* UTILS_H */
|
314
src/app.c
Normal file
314
src/app.c
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
#include "../include/app.h"
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
void init_app(App *app, uint w, uint h)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = SDL_Init(SDL_INIT_EVERYTHING);
|
||||||
|
if (err != 0) {
|
||||||
|
printf("Failed to initialize SDL. Error: %s\n",
|
||||||
|
SDL_GetError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
app->window = SDL_CreateWindow(
|
||||||
|
"test",
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
w, h, SDL_WINDOW_OPENGL);
|
||||||
|
|
||||||
|
if (app->window == NULL) {
|
||||||
|
printf("Failed to create window.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
app->context = SDL_GL_CreateContext(app->window);
|
||||||
|
if (app->context == NULL) {
|
||||||
|
printf("Failed to create OpenGL context.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
app->is_running = true;
|
||||||
|
|
||||||
|
//SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
init_camera(&app->camera);
|
||||||
|
init_opengl();
|
||||||
|
reshape(w, h);
|
||||||
|
|
||||||
|
init_camera(&(app->camera));
|
||||||
|
|
||||||
|
app->surface = IMG_Load("assets/block.jpg");
|
||||||
|
app->tid = 0;
|
||||||
|
|
||||||
|
if(app->surface==NULL) {
|
||||||
|
printf("error\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGenTextures(1, &app->tid);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, app->tid);
|
||||||
|
|
||||||
|
int Mode = GL_RGB;
|
||||||
|
|
||||||
|
if(app->surface->format->BytesPerPixel == 4) {
|
||||||
|
Mode = GL_RGBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, Mode, app->surface->w, app->surface->h, 0, Mode, GL_UNSIGNED_BYTE, app->surface->pixels);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, app->tid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_app(App* app)
|
||||||
|
{
|
||||||
|
app->camera.speed.z -= GRAVITY * (app->frame_time/1000);
|
||||||
|
|
||||||
|
if(app_check_collision(app))
|
||||||
|
camera_set_vertical_speed(&app->camera, 0.0);
|
||||||
|
update_camera(&(app->camera), app->frame_time/1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_opengl()
|
||||||
|
{
|
||||||
|
// https://gitlab.com/imre-piller/me-courses/ alapjan.
|
||||||
|
glShadeModel(GL_SMOOTH);
|
||||||
|
|
||||||
|
glEnable(GL_NORMALIZE);
|
||||||
|
glEnable(GL_AUTO_NORMAL);
|
||||||
|
|
||||||
|
glClearColor(0.1, 0.1, 0.1, 1.0);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glClearDepth(1.0);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reshape(GLsizei width, GLsizei height)
|
||||||
|
{
|
||||||
|
int x, y, w, h;
|
||||||
|
double ratio;
|
||||||
|
|
||||||
|
ratio = (double)width / height;
|
||||||
|
if (ratio > VIEWPORT_RATIO) {
|
||||||
|
w = (int)((double)height * VIEWPORT_RATIO);
|
||||||
|
h = height;
|
||||||
|
x = (width - w) / 2;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w = width;
|
||||||
|
h = (int)((double)width / VIEWPORT_RATIO);
|
||||||
|
x = 0;
|
||||||
|
y = (height - h) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
glViewport(x, y, w, h);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glFrustum(
|
||||||
|
-.08, .08,
|
||||||
|
-.06, .06,
|
||||||
|
.1, 1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_events(App* app)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
static bool is_mouse_down = false;
|
||||||
|
static int mouse_x = 0;
|
||||||
|
static int mouse_y = 0;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
switch (event.key.keysym.scancode) {
|
||||||
|
case SDL_SCANCODE_ESCAPE:
|
||||||
|
app->is_running = false;
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_W:
|
||||||
|
set_camera_speed(&(app->camera), SPEED);
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_S:
|
||||||
|
set_camera_speed(&(app->camera), -SPEED);
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_A:
|
||||||
|
set_camera_side_speed(&(app->camera), SPEED);
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_D:
|
||||||
|
set_camera_side_speed(&(app->camera), -SPEED);
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_SPACE:
|
||||||
|
if (app_check_collision(app))
|
||||||
|
app->camera.position.z+=0.3;
|
||||||
|
camera_set_vertical_speed(&app->camera, SPEED);
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_LSHIFT:
|
||||||
|
camera_set_vertical_speed(&app->camera, -SPEED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_KEYUP:
|
||||||
|
switch (event.key.keysym.scancode) {
|
||||||
|
case SDL_SCANCODE_W:
|
||||||
|
case SDL_SCANCODE_S:
|
||||||
|
set_camera_speed(&(app->camera), 0);
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_A:
|
||||||
|
case SDL_SCANCODE_D:
|
||||||
|
set_camera_side_speed(&(app->camera), 0);
|
||||||
|
break;
|
||||||
|
case SDL_SCANCODE_SPACE:
|
||||||
|
case SDL_SCANCODE_LSHIFT:
|
||||||
|
camera_set_vertical_speed(&app->camera, -0);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
is_mouse_down = true;
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
SDL_GetMouseState(&x, &y);
|
||||||
|
if (is_mouse_down) {
|
||||||
|
rotate_camera(&(app->camera), mouse_x - x, mouse_y - y);
|
||||||
|
}
|
||||||
|
mouse_x = x;
|
||||||
|
mouse_y = y;
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
is_mouse_down = false;
|
||||||
|
break;
|
||||||
|
case SDL_QUIT:
|
||||||
|
app->is_running = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_raycast(App *app)
|
||||||
|
{
|
||||||
|
vec4f v = {0, 0, -1, 1};
|
||||||
|
vec4f retv;
|
||||||
|
float projection[16];
|
||||||
|
glGetFloatv(GL_PROJECTION_MATRIX, projection);
|
||||||
|
mult_matrix(projection, v, &retv);
|
||||||
|
retv.z = -1.0;
|
||||||
|
retv.w = 0.0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_cube(App *app, float x, float y, float z)
|
||||||
|
{
|
||||||
|
/*x*=2;
|
||||||
|
y*=2;
|
||||||
|
z*=2;
|
||||||
|
*/
|
||||||
|
glBegin( GL_QUADS );
|
||||||
|
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
glTexCoord2f(0, 0); glVertex3f(x+1.0, y, z-1.0 );
|
||||||
|
glTexCoord2f(0, 1); glVertex3f(x, y, z-1.0);
|
||||||
|
glTexCoord2f(1, 1); glVertex3f(x, y, z);
|
||||||
|
glTexCoord2f(1, 0); glVertex3f(x+1.0, y, z);
|
||||||
|
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
glTexCoord2f(0, 0); glVertex3f(x+1.0, y-1.0, z-1.0);
|
||||||
|
glTexCoord2f(0, 1); glVertex3f(x, y-1.0, z-1.0);
|
||||||
|
glTexCoord2f(1, 1); glVertex3f(x, y-1.0, z);
|
||||||
|
glTexCoord2f(1, 0); glVertex3f(x+1.0, y-1.0, z);
|
||||||
|
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
glTexCoord2f(0, 0); glVertex3f(x+1.0, y, z);
|
||||||
|
glTexCoord2f(0, 1); glVertex3f(x, y, z);
|
||||||
|
glTexCoord2f(1, 1); glVertex3f(x, y-1.0, z);
|
||||||
|
glTexCoord2f(1, 0); glVertex3f(x+1.0, y-1.0, z);
|
||||||
|
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
glTexCoord2f(0, 0); glVertex3f(x, y, z-1.0); // Top-Right of back face
|
||||||
|
glTexCoord2f(0, 1); glVertex3f(x+1.0, y, z-1.0); // Top-Left of back face
|
||||||
|
glTexCoord2f(1, 1); glVertex3f(x+1.0, y-1.0, z-1.0); // Bottom-Left of back face
|
||||||
|
glTexCoord2f(1, 0); glVertex3f(x, y-1.0, z-1.0); // Bottom-Right of back face
|
||||||
|
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
glTexCoord2f(0, 0); glVertex3f(x, y, z); // Top-Right of left face
|
||||||
|
glTexCoord2f(0, 1); glVertex3f(x, y, z-1.0); // Top-Left of left face
|
||||||
|
glTexCoord2f(1, 1); glVertex3f(x, y-1.0, z-1.0); // Bottom-Left of left face
|
||||||
|
glTexCoord2f(1, 0); glVertex3f(x, y-1.0, z); // Bottom-Right of left face
|
||||||
|
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
glTexCoord2f(0, 0); glVertex3f(x+1.0, y, z); // Top-Right of left face
|
||||||
|
glTexCoord2f(0, 1); glVertex3f(x+1.0, y, z-1.0); // Top-Left of left face
|
||||||
|
glTexCoord2f(1, 1); glVertex3f(x+1.0, y-1.0, z-1.0); // Bottom-Left of left face
|
||||||
|
glTexCoord2f(1, 0); glVertex3f(x+1.0, y-1.0, z); // Bottom-Right of left face
|
||||||
|
glEnd();
|
||||||
|
glFlush();
|
||||||
|
}
|
||||||
|
|
||||||
|
float calc_frame_time(struct timespec *start, struct timespec *end)
|
||||||
|
{
|
||||||
|
float elapsed_time = (end->tv_sec - start->tv_sec)*1000;
|
||||||
|
|
||||||
|
elapsed_time += (float)(end->tv_nsec - start->tv_nsec)/1000000;
|
||||||
|
|
||||||
|
return elapsed_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
int app_get_current_chunk_index(App *app)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < app->chunk_count; i++) {
|
||||||
|
for (int x = 0; x < CHUNK_MAX_X; x++) {
|
||||||
|
for (int y = 0; y < CHUNK_MAX_Y; y++) {
|
||||||
|
for (int z = 0; z < CHUNK_MAX_Z; z++) {
|
||||||
|
if (app->camera.position.x < app->chunks[i].start_pos.x + CHUNK_MAX_X &&
|
||||||
|
app->camera.position.x > app->chunks[i].start_pos.x &&
|
||||||
|
app->camera.position.y < app->chunks[i].start_pos.y + CHUNK_MAX_Y &&
|
||||||
|
app->camera.position.y > app->chunks[i].start_pos.y) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_block(Block b)
|
||||||
|
{
|
||||||
|
if(b.type != BLOCKTYPE_AIR)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool app_check_collision(App *app)
|
||||||
|
{
|
||||||
|
int i = app_get_current_chunk_index(app);
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int x = 0; x < CHUNK_MAX_X; x++) {
|
||||||
|
for (int y = 0; y < CHUNK_MAX_Y; y++) {
|
||||||
|
for (int z = 0; z < CHUNK_MAX_Z; z++) {
|
||||||
|
if (!is_block(app->chunks[i].blocks[x][y][z]))
|
||||||
|
continue;
|
||||||
|
if (app->camera.position.z <= z+2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
83
src/camera.c
Normal file
83
src/camera.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "../include/camera.h"
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void init_camera(Camera* camera)
|
||||||
|
{
|
||||||
|
camera->position.x = 5.0;
|
||||||
|
camera->position.y = 5.0;
|
||||||
|
camera->position.z = 60.0;
|
||||||
|
camera->rotation.x = 0.0;
|
||||||
|
camera->rotation.y = 0.0;
|
||||||
|
camera->rotation.z = 0.0;
|
||||||
|
camera->speed.x = 0.0;
|
||||||
|
camera->speed.y = 0.0;
|
||||||
|
camera->speed.z = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_camera(Camera* camera, double time)
|
||||||
|
{
|
||||||
|
double angle;
|
||||||
|
double side_angle;
|
||||||
|
|
||||||
|
angle = degree_to_radian(camera->rotation.z);
|
||||||
|
side_angle = degree_to_radian(camera->rotation.z + 90.0);
|
||||||
|
|
||||||
|
camera->position.x += cos(angle) * camera->speed.y * time;
|
||||||
|
camera->position.y += sin(angle) * camera->speed.y * time;
|
||||||
|
camera->position.z += camera->speed.z * time;
|
||||||
|
|
||||||
|
camera->position.x += cos(side_angle) * camera->speed.x * time;
|
||||||
|
camera->position.y += sin(side_angle) * camera->speed.x * time;
|
||||||
|
camera->position.z += camera->speed.z * time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_view(const Camera* camera)
|
||||||
|
{
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glRotatef(-(camera->rotation.x), 1.0, 0, 0);
|
||||||
|
glRotatef(-(camera->rotation.z - 90), 0, 0, 1.0);
|
||||||
|
glTranslatef(-camera->position.x, -camera->position.y, -camera->position.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotate_camera(Camera* camera, double horizontal, double vertical)
|
||||||
|
{
|
||||||
|
camera->rotation.z += horizontal;
|
||||||
|
camera->rotation.x += vertical;
|
||||||
|
|
||||||
|
if (camera->rotation.z < 0) {
|
||||||
|
camera->rotation.z += 360.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera->rotation.z > 360.0) {
|
||||||
|
camera->rotation.z -= 360.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera->rotation.x < 0.0) {
|
||||||
|
camera->rotation.x = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera->rotation.x > 180.0) {
|
||||||
|
camera->rotation.x = 180.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_camera_speed(Camera* camera, double speed)
|
||||||
|
{
|
||||||
|
camera->speed.y = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_set_vertical_speed(Camera* camera, double speed)
|
||||||
|
{
|
||||||
|
camera->speed.z = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_camera_side_speed(Camera* camera, double speed)
|
||||||
|
{
|
||||||
|
camera->speed.x = speed;
|
||||||
|
}
|
61
src/game.c
Normal file
61
src/game.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include "../include/game.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
bool chunk_is_block_neighboring_block(Chunk* chunk, vec3i pos)
|
||||||
|
{
|
||||||
|
if (is_oob(pos.x-1, 0, CHUNK_MAX_X) || is_oob(pos.x+1, 0, CHUNK_MAX_X))
|
||||||
|
return false;
|
||||||
|
if (is_oob(pos.y-1, 0, CHUNK_MAX_Y) || is_oob(pos.y+1, 0, CHUNK_MAX_Y))
|
||||||
|
return false;
|
||||||
|
if (is_oob(pos.z-1, 0, CHUNK_MAX_Z) || is_oob(pos.z+1, 0, CHUNK_MAX_Z))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (chunk->blocks[pos.x-1][pos.y][pos.z].type != BLOCKTYPE_AIR &&
|
||||||
|
chunk->blocks[pos.x+1][pos.y][pos.z].type != BLOCKTYPE_AIR &&
|
||||||
|
chunk->blocks[pos.x][pos.y-1][pos.z].type != BLOCKTYPE_AIR &&
|
||||||
|
chunk->blocks[pos.x][pos.y+1][pos.z].type != BLOCKTYPE_AIR &&
|
||||||
|
chunk->blocks[pos.x][pos.y][pos.z-1].type != BLOCKTYPE_AIR &&
|
||||||
|
chunk->blocks[pos.x][pos.y][pos.z+1].type != BLOCKTYPE_AIR)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void chunk_set_blocks_visibility(Chunk* chunk)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < CHUNK_MAX_X; x++) {
|
||||||
|
for (int y = 0; y < CHUNK_MAX_Y; y++) {
|
||||||
|
for (int z = 0; z < CHUNK_MAX_Z; z++) {
|
||||||
|
vec3i v = {x, y, z};
|
||||||
|
if (chunk_is_block_neighboring_block(chunk, v))
|
||||||
|
chunk->blocks[x][y][z].visible = false;
|
||||||
|
else
|
||||||
|
chunk->blocks[x][y][z].visible = true;
|
||||||
|
|
||||||
|
if (chunk->blocks[x][y][z].type == BLOCKTYPE_AIR)
|
||||||
|
chunk->blocks[x][y][z].visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void chunk_create_displayl(App *app, Chunk *chunk)
|
||||||
|
{
|
||||||
|
chunk->id = glGenLists(1);
|
||||||
|
|
||||||
|
glNewList(chunk->id, GL_COMPILE);
|
||||||
|
for (int x = 0; x < CHUNK_MAX_X; x++) {
|
||||||
|
for (int y = 0; y < CHUNK_MAX_Y; y++) {
|
||||||
|
for (int z = 0; z < CHUNK_MAX_Z; z++) {
|
||||||
|
if (chunk->blocks[x][y][z].visible)
|
||||||
|
draw_cube(app, chunk->start_pos.x + x, chunk->start_pos.y + y, chunk->start_pos.z + z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEndList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void chunk_render(Chunk* chunk)
|
||||||
|
{
|
||||||
|
glCallList(chunk->id);
|
||||||
|
}
|
80
src/main.c
Normal file
80
src/main.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include "../include/app.h"
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
App app;
|
||||||
|
init_app(&app, 1280, 720);
|
||||||
|
|
||||||
|
Chunk *chunks = malloc(100*sizeof(Chunk));
|
||||||
|
memset(chunks, 0, 100*sizeof(Chunk));
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
for (int j = 0; j < 10; j++) {
|
||||||
|
Chunk c;
|
||||||
|
c.start_pos.x = i*CHUNK_MAX_X;
|
||||||
|
c.start_pos.y = j*CHUNK_MAX_Y;
|
||||||
|
c.start_pos.z = 0;
|
||||||
|
for (int x = 0; x < CHUNK_MAX_X; x++) {
|
||||||
|
for (int y = 0; y < CHUNK_MAX_Y; y++) {
|
||||||
|
for (int z = 0; z < CHUNK_MAX_Z; z++) {
|
||||||
|
if (z < 40)
|
||||||
|
c.blocks[x][y][z].type = BLOCKTYPE_STONE;
|
||||||
|
else
|
||||||
|
c.blocks[x][y][z].type = BLOCKTYPE_AIR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chunk_set_blocks_visibility(&c);
|
||||||
|
chunk_create_displayl(&app, &c);
|
||||||
|
|
||||||
|
chunks[i+(j*10)] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.chunks = chunks;
|
||||||
|
app.chunk_count = 100;
|
||||||
|
|
||||||
|
while(app.is_running) {
|
||||||
|
struct timespec start;
|
||||||
|
struct timespec end;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
|
||||||
|
|
||||||
|
handle_events(&app);
|
||||||
|
update_app(&app);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
set_view(&app.camera);
|
||||||
|
|
||||||
|
|
||||||
|
printf("camera x: %f y: %f z: %f\n", app.camera.position.x, app.camera.position.y, app.camera.position.z);
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
chunk_render(&chunks[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f dir = {cos(degree_to_radian(app.camera.rotation.z)), sin(degree_to_radian(app.camera.rotation.z)), -cos(degree_to_radian(app.camera.rotation.x))};
|
||||||
|
vec3f pos = {app.camera.position.x, app.camera.position.y, app.camera.position.z };
|
||||||
|
|
||||||
|
glLineWidth(20);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glColor3f(1.0, 0.0, 0.0);
|
||||||
|
glVertex3f(pos.x, pos.y, pos.z);
|
||||||
|
glVertex3f(pos.x+5*dir.x, pos.y+5*dir.y, pos.z+5*dir.z);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
SDL_GL_SwapWindow(app.window);
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
|
||||||
|
|
||||||
|
printf("fps: %f\n", 1000/calc_frame_time(&start, &end));
|
||||||
|
printf("lkat pos x: %f y: %f z: %f\n", pos.x+5*dir.x, pos.y+5*dir.y, pos.z+5*dir.z);
|
||||||
|
printf("lkat x: %f y: %f z: %f\n", dir.x, dir.y, dir.z);
|
||||||
|
app.frame_time = calc_frame_time(&start, &end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
31
src/utils.c
Normal file
31
src/utils.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
double degree_to_radian(double degree)
|
||||||
|
{
|
||||||
|
return degree * M_PI / 180.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_oob(int i, int min, int max)
|
||||||
|
{
|
||||||
|
if (i < min || i >= max)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mult_matrix(float *matrix, vec4f vector, vec4f *ret)
|
||||||
|
{
|
||||||
|
float vec[] = {vector.x, vector.y, vector.z, vector.w};
|
||||||
|
float ret1[4];
|
||||||
|
for(int i = 0; i <= 12; i+=4) {
|
||||||
|
float line_sum = 0.0;
|
||||||
|
for(int j = 0; j < 4; j++){
|
||||||
|
matrix[i+j] *= vec[j];
|
||||||
|
line_sum += matrix[i+j];
|
||||||
|
}
|
||||||
|
ret1[i/4] = line_sum;
|
||||||
|
}
|
||||||
|
ret->x = ret1[0]; ret->y = ret1[1]; ret->z=ret1[2]; ret->w = ret1[3];
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user