Fixed a bug with rendering and added rpath in linux build

dev
Shariq Shah 7 years ago
parent c651847d43
commit e47b494d80
  1. 6
      README.md
  2. 3
      build/genie.lua
  3. 1
      src/common/log.h
  4. 276
      src/common/parser.c
  5. 232
      src/game/platform.c
  6. 2
      src/game/sound.c
  7. 94
      src/libsymmetry/console.c
  8. 4
      src/libsymmetry/console.h
  9. 106
      src/libsymmetry/editor.c
  10. 312
      src/libsymmetry/game.c
  11. 2
      src/libsymmetry/light.h
  12. 1
      src/libsymmetry/model.h
  13. 1
      src/libsymmetry/player.c
  14. 3
      src/libsymmetry/player.h
  15. 501
      src/libsymmetry/renderer.c
  16. 1
      src/libsymmetry/renderer.h
  17. 2
      src/libsymmetry/scene.h
  18. 0
      tools/genie

@ -155,6 +155,11 @@
- ## TODO
- String data-type that is based on array implementation
- Remove all malloc calls/free and move them into custom memory allocator/deallocator functions that only tag/track usage for now
- Rethink/remove the game executable and game library split.
- Remove all previous build system files and implement cross-compilation to windows in current build system or move to a build system that supports it as a first-class citizen
- Refactor all global application state into 'Application_Context' struct. A single global instance of which is available everywhere
- Fix mouse button press/release behaviour by investigating how sdl handles mouse release or by explicitly caching mouse state by using event callbacks recieved when a mousebutton release event is reported by sdl
- Improve bounding sphere calculation
- Screen mouse coordinates to world-coordinates for aiming
@ -164,7 +169,6 @@
- Console command history
- Console command help
- Space partitioning and scene handling
- NPR and cross-hatching
- Move Gui_State and Editor_State into game_state and modify usage as needed
- Remove model and replace all usages with static mesh
- Get editor camera speed and other settings from config file

@ -68,6 +68,7 @@ solution "Symmetry"
configuration "linux"
includedirs {"../include/linux/sdl2/", "../include/common/soloud/", "../include/linux/"}
libdirs {"../lib/linux/sdl2/", "../lib/linux/soloud/", "../lib/linux/ode/"}
linkoptions {"'-Wl,-rpath,$$ORIGIN'"}
links {"SDL2", "m", "ode", "pthread"}
configuration {"windows", "vs2017"}
@ -142,4 +143,4 @@ solution "Symmetry"
local output = os.outputof("cd ../blender_addon && zip -r io_symmetry_exp.zip io_symmetry_exp/__init__.py io_symmetry_exp/exporter.py && mv io_symmetry_exp.zip ../build");
printf("Output of blender addon build : \n%s\n", output)
end
}
}

@ -2,6 +2,7 @@
#define LOG_H
#include <stdio.h>
#include <stdarg.h>
typedef void (*Log_Message_CB)(const char* message, va_list args);
typedef void (*Log_Warning_CB)(const char* warning_message, va_list args);

@ -17,14 +17,14 @@ bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_fun
{
if(!file)
{
log_error("parser:load", "Invalid file handle for file %s", filename);
return false;
log_error("parser:load", "Invalid file handle for file %s", filename);
return false;
}
if(!assign_func)
{
log_error("parser:load", "No assign function provided to load file %s", filename);
return false;
log_error("parser:load", "No assign function provided to load file %s", filename);
return false;
}
/* Read line by line, ignore comments */
@ -39,28 +39,28 @@ bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_fun
while(fgets(line_buffer, MAX_LINE_LEN - 1, file))
{
current_line++;
memset(key_str, '\0', HASH_MAX_KEY_LEN);
memset(value_str, '\0', HASH_MAX_KEY_LEN);
if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0)
{
if(return_on_emptyline)
return true;
else
continue;
}
current_line++;
memset(key_str, '\0', HASH_MAX_KEY_LEN);
memset(value_str, '\0', HASH_MAX_KEY_LEN);
if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0)
{
if(return_on_emptyline)
return true;
else
continue;
}
if(line_buffer[0] == '#')
continue;
if(line_buffer[0] == '#')
continue;
if(sscanf(line_buffer, format_str, key_str, value_str) != 2)
{
log_warning("Malformed value in config file %s, line %d", filename, current_line);
continue;
}
if(sscanf(line_buffer, format_str, key_str, value_str) != 2)
{
log_warning("Malformed value in config file %s, line %d", filename, current_line);
continue;
}
assign_func(key_str, value_str, filename, current_line);
assign_func(key_str, value_str, filename, current_line);
}
return true;
}
@ -76,8 +76,8 @@ struct Parser* parser_load_objects(FILE* file, const char* filename)
if(!file)
{
log_error("parser:load_objects", "Invalid file handle for file %s", filename);
return false;
log_error("parser:load_objects", "Invalid file handle for file %s", filename);
return false;
}
struct Parser* parser = malloc(sizeof(*parser));
@ -96,102 +96,102 @@ struct Parser* parser_load_objects(FILE* file, const char* filename)
while(fgets(line_buffer, MAX_LINE_LEN - 1, file))
{
current_line++;
memset(type_str, '\0', HASH_MAX_KEY_LEN);
current_line++;
memset(type_str, '\0', HASH_MAX_KEY_LEN);
if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0)
{
continue;
}
if(line_buffer[0] == '#')
continue;
/* Object type */
if(sscanf(line_buffer, "%s", type_str) != 1)
{
log_warning("Malformed line in config file %s, line %d", filename, current_line);
continue;
}
// Check if type string is valid
size_t type_str_len = strnlen(type_str, HASH_MAX_KEY_LEN);
if(type_str_len < 3 || strncmp(type_str, "{", HASH_MAX_KEY_LEN) == 0 || strncmp(type_str, "}", HASH_MAX_KEY_LEN) == 0)
{
log_warning("Invalid object type '%s' on line %d", type_str, current_line);
continue;
}
long obj_beginning = -1;
long obj_ending = -1;
int obj_begin_expexted_at = current_line;
bool found_next_before_current_ended = false;
if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0)
{
continue;
}
/* Opening brace and closing brace */
char c = ' ';
size_t line_len = strnlen(line_buffer, MAX_LINE_LEN);
size_t seek_amount = line_len - type_str_len;
fseek(file, -seek_amount, SEEK_CUR);
while(!feof(file))
{
c = fgetc(file);
if(c == '\n')
{
current_line++;
continue;
}
if(line_buffer[0] == '#')
continue;
if(c == '{')
{
obj_beginning = ftell(file);
c = ' ';
while(!feof(file))
/* Object type */
if(sscanf(line_buffer, "%s", type_str) != 1)
{
log_warning("Malformed line in config file %s, line %d", filename, current_line);
continue;
}
// Check if type string is valid
size_t type_str_len = strnlen(type_str, HASH_MAX_KEY_LEN);
if(type_str_len < 3 || strncmp(type_str, "{", HASH_MAX_KEY_LEN) == 0 || strncmp(type_str, "}", HASH_MAX_KEY_LEN) == 0)
{
c = fgetc(file);
if(c == '\n')
{
current_line++;
log_warning("Invalid object type '%s' on line %d", type_str, current_line);
continue;
}
}
long obj_beginning = -1;
long obj_ending = -1;
int obj_begin_expexted_at = current_line;
bool found_next_before_current_ended = false;
/* Opening brace and closing brace */
char c = ' ';
size_t line_len = strnlen(line_buffer, MAX_LINE_LEN);
size_t seek_amount = line_len - type_str_len;
fseek(file, -seek_amount, SEEK_CUR);
while(!feof(file))
{
c = fgetc(file);
if(c == '\n')
{
current_line++;
continue;
}
if(c == '{')
{
obj_beginning = ftell(file);
c = ' ';
while(!feof(file))
{
c = fgetc(file);
if(c == '\n')
{
current_line++;
continue;
}
/* check if we found opening brace of next object,
if this is true then it means that this object is missing
it's closing brace and we should stop */
if(c == '{')
{
found_next_before_current_ended = true;
break;
}
if(c == '}')
{
/* check if we found opening brace of next object,
if this is true then it means that this object is missing
it's closing brace and we should stop */
if(c == '{')
{
found_next_before_current_ended = true;
break;
}
if(c == '}')
{
obj_ending = ftell(file) - 1;
break;
}
break;
}
}
if(obj_ending != -1) break;
}
}
if(obj_beginning == -1)
{
log_error("parser:load_object", "Syntax error while loading %s, expected '{' at line %d", filename, obj_begin_expexted_at);
return false;
}
if(obj_ending == -1)
{
if(found_next_before_current_ended)
log_error("parser:load_object", "Syntax error while loading %s, expected '}' before line %d but found '{'", filename, current_line);
else
log_error("parser:load_object", "Syntax error while loading %s, expected '}' at line %d", filename, current_line);
return false;
}
if(obj_ending != -1) break;
}
}
if(obj_beginning == -1)
{
log_error("parser:load_object", "Syntax error while loading %s, expected '{' at line %d", filename, obj_begin_expexted_at);
return false;
}
if(obj_ending == -1)
{
if(found_next_before_current_ended)
log_error("parser:load_object", "Syntax error while loading %s, expected '}' before line %d but found '{'", filename, current_line);
else
log_error("parser:load_object", "Syntax error while loading %s, expected '}' at line %d", filename, current_line);
return false;
}
memset(obj_str, '\0', 1024);
memset(line_buffer, '\0', MAX_LINE_LEN);
fseek(file, obj_beginning, SEEK_SET);
fread(obj_str, obj_ending - obj_beginning, 1, file);
memset(obj_str, '\0', 1024);
memset(line_buffer, '\0', MAX_LINE_LEN);
fseek(file, obj_beginning, SEEK_SET);
fread(obj_str, obj_ending - obj_beginning, 1, file);
fseek(file, obj_ending + 1, SEEK_SET); // Position cursor after closing brace '}'
// Read into intermediate parser object and add it to the objects list
@ -280,16 +280,16 @@ struct Parser* parser_new(void)
parser = malloc(sizeof(*parser));
if(!parser)
{
log_error("parser:new", "Out of memory");
return NULL;
log_error("parser:new", "Out of memory");
return NULL;
}
parser->objects = array_new(struct Parser_Object);
if(!parser->objects)
{
log_error("parser:new", "Could not create objects array for parser");
free(parser);
return NULL;
log_error("parser:new", "Could not create objects array for parser");
free(parser);
return NULL;
}
return parser;
@ -301,8 +301,8 @@ struct Parser_Object* parser_object_new(struct Parser* parser, int type)
struct Parser_Object* object = array_grow(parser->objects, struct Parser_Object);
if(!object)
{
log_error("parser:object_new", "Failed to add new parser object");
return NULL;
log_error("parser:object_new", "Failed to add new parser object");
return NULL;
}
object->type = type;
object->data = hashmap_new();
@ -317,25 +317,25 @@ bool parser_write_objects(struct Parser* parser, FILE* file, const char* filenam
int counter = 0;
for(int i = 0; i < array_len(parser->objects); i++)
{
struct Parser_Object* object = &parser->objects[i];
if(object->type == PO_UNKNOWN)
{
log_warning("Unknown object type, cannot write to %s", filename);
continue;
}
fprintf(file, "%s\n{\n", parser_object_type_to_str(object->type));
char* key = NULL;
struct Variant* value = NULL;
HASHMAP_FOREACH(object->data, key, value)
{
memset(value_str, '\0', MAX_VALUE_LEN);
struct Parser_Object* object = &parser->objects[i];
if(object->type == PO_UNKNOWN)
{
log_warning("Unknown object type, cannot write to %s", filename);
continue;
}
fprintf(file, "%s\n{\n", parser_object_type_to_str(object->type));
char* key = NULL;
struct Variant* value = NULL;
HASHMAP_FOREACH(object->data, key, value)
{
memset(value_str, '\0', MAX_VALUE_LEN);
variant_to_str(value, &value_str[0], MAX_VALUE_LEN);
fprintf(file, "\t%s : %s\n", key, value_str);
}
fprintf(file, "}\n\n");
counter++;
fprintf(file, "\t%s : %s\n", key, value_str);
}
fprintf(file, "}\n\n");
counter++;
}
log_message("%d objects written to %s", counter, filename);

@ -36,15 +36,15 @@ struct Window* window_create(const char* title, int width, int height, int msaa,
struct Window* new_window = NULL;
if(!new_window)
{
new_window = malloc(sizeof(*new_window));
if(!new_window)
{
log_error("window_create", "Out of memory");
return NULL;
}
new_window->sdl_window = NULL;
new_window->gl_context = NULL;
new_window->is_fullscreen = 0;
new_window = malloc(sizeof(*new_window));
if(!new_window)
{
log_error("window_create", "Out of memory");
return NULL;
}
new_window->sdl_window = NULL;
new_window->gl_context = NULL;
new_window->is_fullscreen = 0;
}
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
@ -54,8 +54,8 @@ struct Window* window_create(const char* title, int width, int height, int msaa,
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
if(msaa)
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, msaa);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_levels);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, msaa);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_levels);
}
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
@ -67,36 +67,36 @@ struct Window* window_create(const char* title, int width, int height, int msaa,
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
#endif
SDL_Window* sdl_window = SDL_CreateWindow(title,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
width, height,
SDL_WINDOW_OPENGL |
SDL_WINDOW_RESIZABLE |
SDL_WINDOW_INPUT_FOCUS |
SDL_WINDOW_MOUSE_FOCUS);
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
width, height,
SDL_WINDOW_OPENGL |
SDL_WINDOW_RESIZABLE |
SDL_WINDOW_INPUT_FOCUS |
SDL_WINDOW_MOUSE_FOCUS);
if(!sdl_window)
{
log_error("window_create:SDL_CreateWindow", "Could not create window : %s", SDL_GetError());
free(new_window);
new_window = NULL;
return new_window;
log_error("window_create:SDL_CreateWindow", "Could not create window : %s", SDL_GetError());
free(new_window);
new_window = NULL;
return new_window;
}
new_window->sdl_window = sdl_window;
SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window);
if(!gl_context)
{
log_error("window_create:SDL_GL_CreateContext", "Failed to create GL context : %s", SDL_GetError());
log_error("window_create:SDL_GL_CreateContext", "Failed to create GL context : %s", SDL_GetError());
window_destroy(new_window);
free(new_window);
new_window = NULL;
return new_window;
free(new_window);
new_window = NULL;
return new_window;
}
new_window->gl_context = gl_context;
SDL_Window* current_window = SDL_GL_GetCurrentWindow();
SDL_GLContext current_context = SDL_GL_GetCurrentContext();
SDL_GL_MakeCurrent((SDL_Window*)new_window->sdl_window, new_window->gl_context);
SDL_GL_SetSwapInterval(1); /* 0: Vsync disabled, 1: Vsync enabled*/
SDL_GL_SetSwapInterval(0); /* 0: Vsync disabled, 1: Vsync enabled*/
if(current_window && current_context) SDL_GL_MakeCurrent(current_window, current_context);
int major = 0, minor = 0;
@ -112,18 +112,18 @@ int window_fullscreen_set(struct Window* window, int fullscreen)
int rc = SDL_SetWindowFullscreen(window->sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
if(rc == 0)
{
window->is_fullscreen = fullscreen ? 1 : 0;
success = 1;
log_message("Window set to %s mode", fullscreen ? "fullscreen" : "windowed");
int w, h;
window_get_size(window, &w, &h);
log_message("Window size : %dx%d", w, h);
window_get_drawable_size(window, &w, &h);
log_message("Drawable size : %dx%d", w, h);
window->is_fullscreen = fullscreen ? 1 : 0;
success = 1;
log_message("Window set to %s mode", fullscreen ? "fullscreen" : "windowed");
int w, h;
window_get_size(window, &w, &h);
log_message("Window size : %dx%d", w, h);
window_get_drawable_size(window, &w, &h);
log_message("Drawable size : %dx%d", w, h);
}
else
{
log_error("platform:window_fullscreen", "window_fullscreen_set failed, %s", SDL_GetError());
log_error("platform:window_fullscreen", "window_fullscreen_set failed, %s", SDL_GetError());
}
return success;
}
@ -180,27 +180,27 @@ bool platform_init(void)
if(SDL_Init(SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0)
{
success = false;
if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Init failed", SDL_GetError(), NULL) != 0)
log_to_stdout("platform_init", "SDL Init failed : %s", SDL_GetError());
if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Init failed", SDL_GetError(), NULL) != 0)
log_to_stdout("platform_init", "SDL Init failed : %s", SDL_GetError());
}
else
{
platform_state = malloc(sizeof(*platform_state));
if(!platform_state)
{
if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Allocation Failure", "Memory allocation failed, out of memory!", NULL) != 0)
log_to_stdout("platform_init", "Could not create platform state, out of memory");
platform_state = malloc(sizeof(*platform_state));
if(!platform_state)
{
if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Allocation Failure", "Memory allocation failed, out of memory!", NULL) != 0)
log_to_stdout("platform_init", "Could not create platform state, out of memory");
success = false;
}
else
{
platform_state->on_keyboard_func = NULL;
platform_state->on_mousebutton_func = NULL;
platform_state->on_mousemotion_func = NULL;
platform_state->on_mousewheel_func = NULL;
platform_state->on_textinput_func = NULL;
platform_state->on_windowresize_func = NULL;
}
}
else
{
platform_state->on_keyboard_func = NULL;
platform_state->on_mousebutton_func = NULL;
platform_state->on_mousemotion_func = NULL;
platform_state->on_mousewheel_func = NULL;
platform_state->on_textinput_func = NULL;
platform_state->on_windowresize_func = NULL;
}
}
return success;
}
@ -245,64 +245,64 @@ void platform_poll_events(bool* out_quit)
static SDL_Event event;
while(SDL_PollEvent(&event) != 0)
{
switch(event.type)
{
case SDL_QUIT:
*out_quit = 1;
break;
case SDL_KEYDOWN: case SDL_KEYUP:
{
int scancode = event.key.keysym.scancode;
int key = event.key.keysym.sym;
int state = event.key.state;
int repeat = event.key.repeat;
int mod_ctrl = (event.key.keysym.mod & KMOD_CTRL) ? 1 : 0;
int mod_shift = (event.key.keysym.mod & KMOD_SHIFT) ? 1 : 0;
int mod_alt = (event.key.keysym.mod & KMOD_ALT) ? 1 : 0;
platform_state->on_keyboard_func(key, scancode, state, repeat, mod_ctrl, mod_shift, mod_alt);
//log_message("Key name : %s", SDL_GetKeyName(key));
break;
}
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP:
{
int button = event.button.button;
int state = event.button.state;
int num_clicks = event.button.clicks;
int x = event.button.x;
int y = event.button.y;
platform_state->on_mousebutton_func(button, state, x, y, num_clicks);
break;
}
case SDL_MOUSEMOTION:
{
int xrel = event.motion.xrel;
int yrel = event.motion.yrel;
int x = event.motion.x;
int y = event.motion.y;
platform_state->on_mousemotion_func(x, y, xrel, yrel);
break;
}
case SDL_MOUSEWHEEL:
{
int x = event.wheel.x;
int y = event.wheel.y;
platform_state->on_mousewheel_func(x, y);
break;
}
case SDL_TEXTINPUT:
{
platform_state->on_textinput_func(event.text.text);
break;
}
case SDL_WINDOWEVENT:
{
if(event.window.event == SDL_WINDOWEVENT_RESIZED)
{
platform_state->on_windowresize_func(event.window.data1, event.window.data2);
}
}
break;
}
switch(event.type)
{
case SDL_QUIT:
*out_quit = 1;
break;
case SDL_KEYDOWN: case SDL_KEYUP:
{
int scancode = event.key.keysym.scancode;
int key = event.key.keysym.sym;
int state = event.key.state;
int repeat = event.key.repeat;
int mod_ctrl = (event.key.keysym.mod & KMOD_CTRL) ? 1 : 0;
int mod_shift = (event.key.keysym.mod & KMOD_SHIFT) ? 1 : 0;
int mod_alt = (event.key.keysym.mod & KMOD_ALT) ? 1 : 0;
platform_state->on_keyboard_func(key, scancode, state, repeat, mod_ctrl, mod_shift, mod_alt);
//log_message("Key name : %s", SDL_GetKeyName(key));
break;
}
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP:
{
int button = event.button.button;
int state = event.button.state;
int num_clicks = event.button.clicks;
int x = event.button.x;
int y = event.button.y;
platform_state->on_mousebutton_func(button, state, x, y, num_clicks);
break;
}
case SDL_MOUSEMOTION:
{
int xrel = event.motion.xrel;
int yrel = event.motion.yrel;
int x = event.motion.x;
int y = event.motion.y;
platform_state->on_mousemotion_func(x, y, xrel, yrel);
break;
}
case SDL_MOUSEWHEEL:
{
int x = event.wheel.x;
int y = event.wheel.y;
platform_state->on_mousewheel_func(x, y);
break;
}
case SDL_TEXTINPUT:
{
platform_state->on_textinput_func(event.text.text);
break;
}
case SDL_WINDOWEVENT:
{
if(event.window.event == SDL_WINDOWEVENT_RESIZED)
{
platform_state->on_windowresize_func(event.window.data1, event.window.data2);
}
}
break;
}
}
}
@ -392,8 +392,8 @@ char* platform_install_directory_get(void)
char* path = NULL;
if(returned_path)
{
path = str_new(returned_path);
SDL_free(returned_path);
path = str_new(returned_path);
SDL_free(returned_path);
}
return path;
}
@ -409,8 +409,8 @@ char* platform_clipboard_text_get(void)
char* text = NULL;
if(returned_text)
{
text = str_new(returned_text);
SDL_free(returned_text);
text = str_new(returned_text);
SDL_free(returned_text);
}
return text;
}
@ -448,8 +448,8 @@ char* platform_user_directory_get(const char* organization, const char* applicat
char* temp_path = SDL_GetPrefPath(organization, application);
if(temp_path)
{
user_directory = str_new(temp_path);
SDL_free(temp_path);
user_directory = str_new(temp_path);
SDL_free(temp_path);
}
else
{

@ -207,7 +207,7 @@ struct Sound_Source_Buffer* sound_source_create(const char* filename, int type)
}
long size = 0L;
char* memory = io_file_read(DIRT_INSTALL, filename, "rb", &size);
unsigned char* memory = io_file_read(DIRT_INSTALL, filename, "rb", &size);
source = malloc(sizeof(*source));
if(!source)

@ -55,39 +55,39 @@ void console_update(struct Console* console, struct Gui_State* gui_state, float
if(nk_begin_titled(context, "Console", "Console", nk_recti(0, 0, win_width, half_height), NK_WINDOW_SCROLL_AUTO_HIDE))
{
nk_layout_row_dynamic(context, nk_window_get_height(context) - console->text_region_height * 2, 1);
if(nk_group_begin(context, "Log", NK_WINDOW_BORDER))
{
for(int i = 0; i <= console->current_message_index; i++)
{
nk_layout_row_dynamic(context, console->line_height, 1);
nk_labelf_colored(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, console_message_color[console->console_messages[i].type], console->console_messages[i].message);
}
if(console->scroll_to_bottom == true) // scroll console message area to the bottom if required
{
*context->current->layout->offset_y = (nk_uint)context->current->layout->at_y;
console->scroll_to_bottom = false;
}
nk_layout_row_dynamic(context, nk_window_get_height(context) - console->text_region_height * 2, 1);
if(nk_group_begin(context, "Log", NK_WINDOW_BORDER))
{
for(int i = 0; i <= console->current_message_index; i++)
{
nk_layout_row_dynamic(context, console->line_height, 1);
nk_labelf_colored(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, console_message_color[console->console_messages[i].type], console->console_messages[i].message);
}
if(console->scroll_to_bottom == true) // scroll console message area to the bottom if required
{
*context->current->layout->offset_y = (nk_uint)context->current->layout->at_y;
console->scroll_to_bottom = false;
}
nk_group_end(context);
}
//Edit-string/Textfield for command
nk_layout_row_dynamic(context, console->text_region_height, 1);
int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER;
nk_edit_focus(context, edit_flags);
int edit_state = nk_edit_string_zero_terminated(context, edit_flags, console->console_command_text, MAX_CONSOLE_MESSAGE_LEN, console_filter);
if(edit_state & NK_EDIT_COMMITED)
{
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0;
nk_group_end(context);
}
//Edit-string/Textfield for command
nk_layout_row_dynamic(context, console->text_region_height, 1);
int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER;
nk_edit_focus(context, edit_flags);
int edit_state = nk_edit_string_zero_terminated(context, edit_flags, console->console_command_text, MAX_CONSOLE_MESSAGE_LEN, console_filter);
if(edit_state & NK_EDIT_COMMITED)
{
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0;
snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "> %s", console->console_command_text);
console->console_messages[console->current_message_index].type = CMT_COMMAND;
memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN);
console->scroll_to_bottom = true;
}
snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "> %s", console->console_command_text);
console->console_messages[console->current_message_index].type = CMT_COMMAND;
memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN);
console->scroll_to_bottom = true;
}
}
nk_end(context);
}
@ -108,28 +108,28 @@ int console_filter(const struct nk_text_edit *box, nk_rune unicode)
void console_on_log_message(struct Console* console, const char* message, va_list args)
{
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0;
vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, message, args);
console->console_messages[console->current_message_index].type = CMT_MESSAGE;
console->scroll_to_bottom = true;
/* if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) */
/* console->current_message_index = 0; */
/* vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, message, args); */
/* console->console_messages[console->current_message_index].type = CMT_MESSAGE; */
/* console->scroll_to_bottom = true; */
}
void console_on_log_warning(struct Console* console, const char* warning_message, va_list args)
{
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0;
vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, warning_message, args);
console->console_messages[console->current_message_index].type = CMT_WARNING;
console->scroll_to_bottom = true;
/* if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) */
/* console->current_message_index = 0; */
/* vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, warning_message, args); */
/* console->console_messages[console->current_message_index].type = CMT_WARNING; */
/* console->scroll_to_bottom = true; */
}
void console_on_log_error(struct Console* console, const char* context, const char* error, va_list args)
{
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0;
int loc = snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "(%s)", context);
vsnprintf(console->console_messages[console->current_message_index].message + loc, MAX_CONSOLE_MESSAGE_LEN, error, args);
console->console_messages[console->current_message_index].type = CMT_ERROR;
console->scroll_to_bottom = true;
/* if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) */
/* console->current_message_index = 0; */
/* int loc = snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "(%s)", context); */
/* vsnprintf(console->console_messages[console->current_message_index].message + loc, MAX_CONSOLE_MESSAGE_LEN - loc, error, args); */
/* console->console_messages[console->current_message_index].type = CMT_ERROR; */
/* console->scroll_to_bottom = true; */
}

@ -7,6 +7,8 @@
#define MAX_CONSOLE_MESSAGE_LEN 256
#define MAX_CONSOLE_MESSAGES 1024
struct Gui_State;
enum Console_Message_Type
{
CMT_NONE = 0,
@ -43,4 +45,4 @@ void console_on_log_warning(struct Console* console, const char* warning_message
void console_on_log_error(struct Console* console, const char* context, const char* error, va_list args);
#endif
#endif

@ -567,77 +567,77 @@ void editor_camera_update(float dt)
if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED))
{
const float scale = 0.1f;
int cursor_lr, cursor_ud;
input_mouse_delta_get(&cursor_lr, &cursor_ud);
if(input_mouse_mode_get() != MM_RELATIVE)
{
input_mouse_mode_set(MM_RELATIVE);
cursor_lr = cursor_ud = 0;
}
const float scale = 0.1f;
int cursor_lr, cursor_ud;
input_mouse_delta_get(&cursor_lr, &cursor_ud);
if(input_mouse_mode_get() != MM_RELATIVE)
{
input_mouse_mode_set(MM_RELATIVE);
cursor_lr = cursor_ud = 0;
}
turn_up_down = -cursor_ud * turn_speed * dt * scale;
turn_left_right = cursor_lr * turn_speed * dt * scale;
//log_message("ud : %d, lr : %d", cursor_ud, cursor_lr);
turn_up_down = -cursor_ud * turn_speed * dt * scale;
turn_left_right = cursor_lr * turn_speed * dt * scale;
//log_message("ud : %d, lr : %d", cursor_ud, cursor_lr);
}
else
{
input_mouse_mode_set(MM_NORMAL);
turn_up_down *= dt;
turn_left_right *= dt;
//Picking
//If we're not looking around then allow picking
if(input_mousebutton_state_get(MSB_LEFT, KS_RELEASED))
{
log_message("editor picking");
int mouse_x = 0, mouse_y = 0;
platform->mouse_position_get(&mouse_x, &mouse_y);
struct Ray ray = camera_screen_coord_to_ray(editor_camera, mouse_x, mouse_y);
//log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z);
struct Scene* scene = game_state_get()->scene;
struct Raycast_Result ray_result;
scene_ray_intersect(scene, &ray, &ray_result);
if(ray_result.num_entities_intersected > 0)
{
//For now, just select the first entity that is intersected
struct Entity* intersected_entity = ray_result.entities_intersected[0];
if(editor_state.selected_entity && editor_state.selected_entity != intersected_entity)
{
editor_state.selected_entity->editor_selected = false;
editor_state.selected_entity = NULL;
}
intersected_entity->editor_selected = true;
editor_state.selected_entity = intersected_entity;
}
}
input_mouse_mode_set(MM_NORMAL);
turn_up_down *= dt;
turn_left_right *= dt;
//Picking
//If we're not looking around then allow picking
/* if(input_mousebutton_state_get(MSB_LEFT, KS_RELEASED)) */
/* { */
/* log_message("editor picking"); */
/* int mouse_x = 0, mouse_y = 0; */
/* platform->mouse_position_get(&mouse_x, &mouse_y); */
/* struct Ray ray = camera_screen_coord_to_ray(editor_camera, mouse_x, mouse_y); */
/* //log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); */
/* struct Scene* scene = game_state_get()->scene; */
/* struct Raycast_Result ray_result; */
/* scene_ray_intersect(scene, &ray, &ray_result); */
/* if(ray_result.num_entities_intersected > 0) */
/* { */
/* //For now, just select the first entity that is intersected */
/* struct Entity* intersected_entity = ray_result.entities_intersected[0]; */
/* if(editor_state.selected_entity && editor_state.selected_entity != intersected_entity) */
/* { */
/* editor_state.selected_entity->editor_selected = false; */
/* editor_state.selected_entity = NULL; */
/* } */
/* intersected_entity->editor_selected = true; */
/* editor_state.selected_entity = intersected_entity; */
/* } */
/* } */
}
total_up_down_rot += turn_up_down;
if(total_up_down_rot >= max_up_down)
{
total_up_down_rot = max_up_down;
turn_up_down = 0.f;
total_up_down_rot = max_up_down;
turn_up_down = 0.f;
}
else if(total_up_down_rot <= -max_up_down)
{
total_up_down_rot = -max_up_down;
turn_up_down = 0.f;
total_up_down_rot = -max_up_down;
turn_up_down = 0.f;
}
if(turn_left_right != 0.f)
{
transform_rotate(editor_camera, &rot_axis_left_right, -turn_left_right, TS_WORLD);
transform_rotate(editor_camera, &rot_axis_left_right, -turn_left_right, TS_WORLD);
}
if(turn_up_down != 0.f)
{
//transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL);
transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL);
//transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL);
transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL);
}
/* Movement */
@ -652,8 +652,8 @@ void editor_camera_update(float dt)
vec3_scale(&offset, &offset, dt);
if(offset.x != 0 || offset.y != 0 || offset.z != 0)
{
transform_translate(editor_camera, &offset, TS_LOCAL);
//log_message("Position : %s", tostr_vec3(&transform->position));
transform_translate(editor_camera, &offset, TS_LOCAL);
//log_message("Position : %s", tostr_vec3(&transform->position));
}
}

@ -70,49 +70,49 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api)
game_state = malloc(sizeof(*game_state));
if(!game_state)
{
log_error("game:init", "Out of memory, failed to allocate game_state");
return 0;
log_error("game:init", "Out of memory, failed to allocate game_state");
return 0;
}
else
{
game_state->window = window;
game_state->is_initialized = false;
game_state->game_mode = GAME_MODE_GAME;
game_state->renderer = calloc(1, sizeof(*game_state->renderer));
game_state->scene = calloc(1, sizeof(*game_state->scene));
game_state->console = calloc(1, sizeof(*game_state->console));
log_file_handle_set(platform->log.file_handle_get());
log_message_callback_set(game_on_log_message);
log_warning_callback_set(game_on_log_warning);
log_error_callback_set(game_on_log_error);
if(!gl_load_extentions())
{
log_error("game:init", "Failed to load GL extentions");
return false;
}
else
{
log_message("Loaded GL extentions");
}
input_init();
shader_init();
texture_init();
framebuffer_init();
gui_init();
console_init(game_state->console);
geom_init();
platform->physics.init();
platform->physics.gravity_set(0.f, -9.8f, 0.f);
platform->physics.body_set_moved_callback(entity_rigidbody_on_move);
platform->physics.body_set_collision_callback(entity_rigidbody_on_collision);
editor_init();
renderer_init(game_state->renderer);
scene_init(game_state->scene);
game_state->window = window;
game_state->is_initialized = false;
game_state->game_mode = GAME_MODE_GAME;
game_state->renderer = calloc(1, sizeof(*game_state->renderer));
game_state->scene = calloc(1, sizeof(*game_state->scene));
game_state->console = calloc(1, sizeof(*game_state->console));
log_file_handle_set(platform->log.file_handle_get());
log_message_callback_set(game_on_log_message);
log_warning_callback_set(game_on_log_warning);
log_error_callback_set(game_on_log_error);
if(!gl_load_extentions())
{
log_error("game:init", "Failed to load GL extentions");
return false;
}
else
{
log_message("Loaded GL extentions");
}
input_init();
shader_init();
texture_init();
framebuffer_init();
gui_init();
console_init(game_state->console);
geom_init();
platform->physics.init();
platform->physics.gravity_set(0.f, -9.8f, 0.f);
platform->physics.body_set_moved_callback(entity_rigidbody_on_move);
platform->physics.body_set_collision_callback(entity_rigidbody_on_collision);
editor_init();
renderer_init(game_state->renderer);
scene_init(game_state->scene);
}
/* Debug scene setup */
@ -297,18 +297,18 @@ void game_scene_setup(void)
vec3 suz_pos = {0.f};
for(int i = 0; i < num_suz; i++)
{
memset(&suz_name, '\0', MAX_ENTITY_NAME_LEN);
snprintf(&suz_name[0], MAX_ENTITY_NAME_LEN, "Suzanne_%d", i);
struct Static_Mesh* suzanne = scene_static_mesh_create(game_state->scene, suz_name, NULL, "sphere.symbres", MAT_BLINN);
suzanne->model.material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file("white.tga", TU_DIFFUSE);
suzanne->model.material_params[MMP_DIFFUSE].val_float = 0.5f;
suzanne->model.material_params[MMP_SPECULAR].val_float = 1.f;
suzanne->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f;
vec3_fill(&suzanne->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 0.f, 1.f);
suz_pos.x = i + 10.f;
suz_pos.y = 5.f;
suz_pos.z = i + 5.f;
transform_set_position(suzanne, &suz_pos);
memset(&suz_name, '\0', MAX_ENTITY_NAME_LEN);
snprintf(&suz_name[0], MAX_ENTITY_NAME_LEN, "Suzanne_%d", i);
struct Static_Mesh* suzanne = scene_static_mesh_create(game_state->scene, suz_name, NULL, "sphere.symbres", MAT_BLINN);
suzanne->model.material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file("white.tga", TU_DIFFUSE);
suzanne->model.material_params[MMP_DIFFUSE].val_float = 0.5f;
suzanne->model.material_params[MMP_SPECULAR].val_float = 1.f;
suzanne->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f;
vec3_fill(&suzanne->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 0.f, 1.f);
suz_pos.x = i + 10.f;
suz_pos.y = 5.f;
suz_pos.z = i + 5.f;
transform_set_position(suzanne, &suz_pos);
}
@ -326,27 +326,27 @@ void game_debug(float dt)
{
if(input_is_key_pressed(KEY_SPACE))
{
struct Entity* model = scene_find(game_state->scene, "Light_Ent");
vec3 x_axis = {0, 1, 0};
transform_rotate(model, &x_axis, 25.f * dt, TS_WORLD);
struct Entity* model = scene_find(game_state->scene, "Light_Ent");
vec3 x_axis = {0, 1, 0};
transform_rotate(model, &x_axis, 25.f * dt, TS_WORLD);
}
if(input_is_key_pressed(KEY_M))
{
struct Entity* model = scene_find(game_state->scene, "Model_Entity");
//vec3 y_axis = {0, 0, 1};
//transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_LOCAL);
vec3 amount = {0, 0, -5 * dt};
transform_translate(model, &amount, TS_LOCAL);
struct Entity* model = scene_find(game_state->scene, "Model_Entity");
//vec3 y_axis = {0, 0, 1};
//transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_LOCAL);
vec3 amount = {0, 0, -5 * dt};
transform_translate(model, &amount, TS_LOCAL);
}
if(input_is_key_pressed(KEY_N))
{
struct Entity* model = scene_find(game_state->scene, "Model_Entity");
/* vec3 y_axis = {0, 0, 1}; */
/* transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_WORLD); */
vec3 amount = {0, 0, 5 * dt};
transform_translate(model, &amount, TS_LOCAL);
struct Entity* model = scene_find(game_state->scene, "Model_Entity");
/* vec3 y_axis = {0, 0, 1}; */
/* transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_WORLD); */
vec3 amount = {0, 0, 5 * dt};
transform_translate(model, &amount, TS_LOCAL);
}
/*struct Entity* model = scene_find("Model_Entity");
@ -388,22 +388,22 @@ void game_debug(float dt)
//Raycast test
if(input_is_key_pressed(KEY_R))
{
/*Collision_Shape ray = platform->physics.cs_ray_create(20.f, true, true);
vec3 position = {0.f, 0.f, 0.f};
vec3 direction = {0.f, 0.f, 0.f};
transform_get_absolute_forward(player_entity, &direction);
transform_get_absolute_position(player_entity, &position);
struct Raycast_Hit hit;
if(platform->physics.cs_ray_cast(ray, &hit, position.x, position.y, position.z, direction.x, direction.y, direction.z))
{
struct Entity* entity_hit = entity_get(hit.entity_id);
log_message("Ray hit %s", entity_hit->name);
}
else
{
log_message("Ray didn't hit anything!");
}
platform->physics.cs_remove(ray);*/
/*Collision_Shape ray = platform->physics.cs_ray_create(20.f, true, true);
vec3 position = {0.f, 0.f, 0.f};
vec3 direction = {0.f, 0.f, 0.f};
transform_get_absolute_forward(player_entity, &direction);
transform_get_absolute_position(player_entity, &position);
struct Raycast_Hit hit;
if(platform->physics.cs_ray_cast(ray, &hit, position.x, position.y, position.z, direction.x, direction.y, direction.z))
{
struct Entity* entity_hit = entity_get(hit.entity_id);
log_message("Ray hit %s", entity_hit->name);
}
else
{
log_message("Ray didn't hit anything!");
}
platform->physics.cs_remove(ray);*/
}
// Immediate geometry test
@ -483,8 +483,8 @@ void game_debug(float dt)
for(int i = 0; i < 10; i++)
{
im_position.x += i * 2.f;
im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES);
im_position.x += i * 2.f;
im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES);
}
}
@ -495,18 +495,18 @@ bool game_run(void)
while(!should_window_close)
{
uint32 curr_time = platform->ticks_get();
float delta_time = (float)(curr_time - last_time) / 1000.f;
last_time = curr_time;
if(delta_time > MAX_FRAME_TIME) delta_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */
float delta_time = (float)(curr_time - last_time) / 1000.f;
last_time = curr_time;
if(delta_time > MAX_FRAME_TIME) delta_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */
gui_input_begin();
gui_input_begin();
platform->poll_events(&should_window_close);
gui_input_end();
gui_input_end();
game_update(delta_time, &should_window_close);
game_post_update(delta_time);
game_render();
platform->window.swap_buffers(game_state->window);
game_update(delta_time, &should_window_close);
game_post_update(delta_time);
game_render();
platform->window.swap_buffers(game_state->window);
}
return true;
}
@ -519,24 +519,24 @@ void game_update(float dt, bool* window_should_close)
if(input_map_state_get("Console_Toggle", KS_RELEASED)) console_toggle(game_state->console);
if(input_map_state_get("Editor_Toggle", KS_RELEASED))
{
//editor_toggle();
if(game_state->game_mode == GAME_MODE_EDITOR)
{
game_state->game_mode = GAME_MODE_GAME;
game_state->scene->active_camera_index = CAM_GAME;
}
else if(game_state->game_mode == GAME_MODE_GAME)
{
game_state->game_mode = GAME_MODE_EDITOR;
game_state->scene->active_camera_index = CAM_EDITOR;
}
//editor_toggle();
if(game_state->game_mode == GAME_MODE_EDITOR)
{
game_state->game_mode = GAME_MODE_GAME;
game_state->scene->active_camera_index = CAM_GAME;
}
else if(game_state->game_mode == GAME_MODE_GAME)
{
game_state->game_mode = GAME_MODE_EDITOR;
game_state->scene->active_camera_index = CAM_EDITOR;
}
}
if(input_map_state_get("Reload_Game_Lib", KS_RELEASED))
{
*window_should_close = true;
platform->reload_game_lib();
return;
*window_should_close = true;
platform->reload_game_lib();
return;
}
//game_debug(dt);
@ -545,11 +545,11 @@ void game_update(float dt, bool* window_should_close)
scene_update(game_state->scene, dt);
if(game_state->game_mode == GAME_MODE_GAME)
{
platform->physics.step(dt);
platform->physics.step(dt);
}
else if(game_state->game_mode == GAME_MODE_EDITOR)
{
editor_update(dt);
editor_update(dt);
}
}
@ -1001,27 +1001,27 @@ void game_debug_gui(float dt)
/* good old week day formula (double because precision) */
{int year_n = (sel_date.tm_mon < 2) ? year-1: year;
int y = year_n % 100;
int c = year_n / 100;
int y4 = (int)((float)y / 4);
int c4 = (int)((float)c / 4);
int m = (int)(2.6 * (double)(((sel_date.tm_mon + 10) % 12) + 1) - 0.2);
int week_day = (((1 + m + y + y4 + c4 - 2 * c) % 7) + 7) % 7;
/* weekdays */
nk_layout_row_dynamic(ctx, 35, 7);
for (i = 0; i < (int)LEN(week_days); ++i)
nk_label(ctx, week_days[i], NK_TEXT_CENTERED);
/* days */
if (week_day > 0) nk_spacing(ctx, week_day);
for (i = 1; i <= days; ++i) {
sprintf(buffer, "%d", i);
if (nk_button_label(ctx, buffer)) {
sel_date.tm_mday = i;
nk_combo_close(ctx);
}
}}
int y = year_n % 100;
int c = year_n / 100;
int y4 = (int)((float)y / 4);
int c4 = (int)((float)c / 4);
int m = (int)(2.6 * (double)(((sel_date.tm_mon + 10) % 12) + 1) - 0.2);
int week_day = (((1 + m + y + y4 + c4 - 2 * c) % 7) + 7) % 7;
/* weekdays */
nk_layout_row_dynamic(ctx, 35, 7);
for (i = 0; i < (int)LEN(week_days); ++i)
nk_label(ctx, week_days[i], NK_TEXT_CENTERED);
/* days */
if (week_day > 0) nk_spacing(ctx, week_day);
for (i = 1; i <= days; ++i) {
sprintf(buffer, "%d", i);
if (nk_button_label(ctx, buffer)) {
sel_date.tm_mday = i;
nk_combo_close(ctx);
}
}}
nk_combo_end(ctx);
}
}
@ -1628,7 +1628,7 @@ void game_debug_gui(float dt)
bounds = nk_widget_bounds(ctx);
nk_spacing(ctx, 1);
if ((nk_input_is_mouse_hovering_rect(in, bounds) ||
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_down(in, NK_BUTTON_LEFT))
{
a = row_layout[0] + in->mouse.delta.x;
@ -1651,7 +1651,7 @@ void game_debug_gui(float dt)
bounds = nk_widget_bounds(ctx);
nk_spacing(ctx, 1);
if ((nk_input_is_mouse_hovering_rect(in, bounds) ||
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_down(in, NK_BUTTON_LEFT))
{
b = (row_layout[2] + in->mouse.delta.x);
@ -1707,7 +1707,7 @@ void game_debug_gui(float dt)
bounds = nk_widget_bounds(ctx);
nk_spacing(ctx, 1);
if ((nk_input_is_mouse_hovering_rect(in, bounds) ||
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_down(in, NK_BUTTON_LEFT))
{
a = a + in->mouse.delta.y;
@ -1732,7 +1732,7 @@ void game_debug_gui(float dt)
nk_layout_row_dynamic(ctx, 8, 1);
bounds = nk_widget_bounds(ctx);
if ((nk_input_is_mouse_hovering_rect(in, bounds) ||
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_prev_hovering_rect(in, bounds)) &&
nk_input_is_mouse_down(in, NK_BUTTON_LEFT))
{
b = b + in->mouse.delta.y;
@ -1773,31 +1773,31 @@ void game_cleanup(void)
{
if(game_state)
{
if(game_state->is_initialized)
{
editor_cleanup();
scene_destroy(game_state->scene);
input_cleanup();
renderer_cleanup(game_state->renderer);
gui_cleanup();
console_destroy(game_state->console);
if(game_state->is_initialized)
{
editor_cleanup();
scene_destroy(game_state->scene);
input_cleanup();
renderer_cleanup(game_state->renderer);
gui_cleanup();
console_destroy(game_state->console);
geom_cleanup();
framebuffer_cleanup();
texture_cleanup();
shader_cleanup();
free(game_state->console);
free(game_state->scene);
free(game_state->renderer);
}
free(game_state);
game_state = NULL;
framebuffer_cleanup();
texture_cleanup();
shader_cleanup();
free(game_state->console);
free(game_state->scene);
free(game_state->renderer);
}
free(game_state);
game_state = NULL;
}
if(platform)
{
platform->physics.cleanup();
free(platform);
platform->physics.cleanup();
free(platform);
}
}
@ -1811,9 +1811,9 @@ void on_collision_test(struct Entity* this_ent, struct Entity* other_ent, Rigidb
float y = this_ent->transform.position.y;
if(y < 10.f)
{
//vec3 translation = {0.f, 50.f, 0.f};
//transform_translate(this_ent, &translation, TS_WORLD);
//platform->physics.body_force_add(body, 0.f, -100.f, 0.f);
//vec3 translation = {0.f, 50.f, 0.f};
//transform_translate(this_ent, &translation, TS_WORLD);
//platform->physics.body_force_add(body, 0.f, -100.f, 0.f);
}
//platform->physics.body_force_add(body, 0.f, 500.f, 0.f);
}

@ -3,6 +3,8 @@
#define MAX_SHADOWMAPS 4
struct Light;
void light_init(struct Light* light, int light_type);
void light_reset(struct Light* light);

@ -2,6 +2,7 @@
#define MODEL_H
struct Model;
struct Static_Mesh;
void model_init(struct Model* model, struct Static_Mesh* mesh, const char* geometry_name, int material_type);
void model_reset(struct Model* model, struct Static_Mesh* mesh);

@ -8,6 +8,7 @@
#include "bounding_volumes.h"
#include "../common/hashmap.h"
#include "../common/log.h"
#include "entity.h"
void player_init(struct Player* player, struct Scene* scene)
{

@ -2,9 +2,10 @@
#define PLAYER_H
struct Player;
struct Scene;
void player_init(struct Player* player, struct Scene* scene);
void player_destroy(struct Player* player);
void player_update(struct Player* player, struct Scene* scene, float dt);
#endif
#endif

@ -87,24 +87,24 @@ void renderer_init(struct Renderer* renderer)
struct Game_State* game_state = game_state_get();
platform->window.get_size(game_state->window, &width, &height);
renderer->def_albedo_tex = texture_create("def_albedo_texture",
TU_DIFFUSE,
width, height,
GL_RGB,
GL_RGB16F,
GL_FLOAT,
NULL);
TU_DIFFUSE,
width, height,
GL_RGB,
GL_RGB16F,
GL_FLOAT,
NULL);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
renderer->def_depth_tex = texture_create("def_depth_texture",
TU_SHADOWMAP4,
width, height,
GL_DEPTH_COMPONENT,
GL_DEPTH_COMPONENT32F,
GL_FLOAT,
NULL);
TU_SHADOWMAP4,
width, height,
GL_DEPTH_COMPONENT,
GL_DEPTH_COMPONENT32F,
GL_FLOAT,
NULL);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(renderer->def_depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -125,11 +125,11 @@ void renderer_init(struct Renderer* renderer)
renderer->sprite_batch = malloc(sizeof(*renderer->sprite_batch));
if(!renderer->sprite_batch)
{
log_error("renderer:init", "Failed to allocated sprite batch");
log_error("renderer:init", "Failed to allocated sprite batch");
}
else
{
sprite_batch_create(renderer->sprite_batch, "sprite_map.tga", "sprite.vert", "sprite.frag", GL_TRIANGLES);
sprite_batch_create(renderer->sprite_batch, "sprite_map.tga", "sprite.vert", "sprite.frag", GL_TRIANGLES);
}
im_init();
@ -137,7 +137,7 @@ void renderer_init(struct Renderer* renderer)
// Initialize materials
for(int i = 0; i < MAT_MAX; i++)
{
material_init(&renderer->materials[i], i);
material_init(&renderer->materials[i], i);
}
}
@ -146,180 +146,181 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene)
/* Render each camera output into it's framebuffer or to the default framebuffer */
for(int i = 0; i < MAX_CAMERAS; i++)
{
struct Camera* camera = &scene->cameras[i];
if(!camera->base.active) continue;
int fbo = camera->fbo == -1 ? renderer->def_fbo : camera->fbo;
framebuffer_bind(fbo);
{
glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo));
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearColor(camera->clear_color.x,
camera->clear_color.y,
camera->clear_color.z,
camera->clear_color.w);
glEnable(GL_CULL_FACE );
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static mat4 mvp;
for(int i = 0; i < MAT_MAX; i++)
{
/* for each material, get all the registered models and render them */
struct Material* material = &renderer->materials[i];
GL_CHECK(shader_bind(material->shader));
if(material->lit) /* Set light information */
{
char uniform_name[MAX_UNIFORM_NAME_LEN];
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
int light_count = -1;
for(int i = 0; i < MAX_LIGHTS; i++)
{
struct Light* light = &scene->lights[i]; /* TODO: Cull lights according to camera frustum */
if(!light->base.active && light->valid) continue;
light_count++;
vec3 light_pos = {0, 0, 0};
transform_get_absolute_position(&light->base, &light_pos);
if(light->type != LT_POINT)
{
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count);
vec3 light_dir = {0.f, 0.f, 0.f};
transform_get_absolute_lookat(&light->base, &light_dir);
vec3_norm(&light_dir, &light_dir);
shader_set_uniform_vec3(material->shader, uniform_name, &light_dir);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
struct Camera* camera = &scene->cameras[i];
if(!camera->base.active) continue;
if(light->type != LT_DIR)
int fbo = camera->fbo == -1 ? renderer->def_fbo : camera->fbo;
framebuffer_bind(fbo);
{
glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo));
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearColor(camera->clear_color.x,
camera->clear_color.y,
camera->clear_color.z,
camera->clear_color.w);
glEnable(GL_CULL_FACE );
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static mat4 mvp;
for(int i = 0; i < MAT_MAX; i++)
{
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count);
shader_set_uniform_vec3(material->shader, uniform_name, &light_pos);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->outer_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
/* for each material, get all the registered models and render them */
struct Material* material = &renderer->materials[i];
GL_CHECK(shader_bind(material->shader));
if(material->lit) /* Set light information */
{
char uniform_name[MAX_UNIFORM_NAME_LEN];
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
int light_count = -1;
for(int i = 0; i < MAX_LIGHTS; i++)
{
struct Light* light = &scene->lights[i]; /* TODO: Cull lights according to camera frustum */
if(!light->base.active || !light->valid) continue;
light_count++;
vec3 light_pos = {0, 0, 0};
transform_get_absolute_position(&light->base, &light_pos);
if(light->type != LT_POINT)
{
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count);
vec3 light_dir = {0.f, 0.f, 0.f};
transform_get_absolute_lookat(&light->base, &light_dir);
vec3_norm(&light_dir, &light_dir);
shader_set_uniform_vec3(material->shader, uniform_name, &light_dir);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
if(light->type != LT_DIR)
{
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count);
shader_set_uniform_vec3(material->shader, uniform_name, &light_pos);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->outer_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->inner_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->inner_angle);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->falloff);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->radius);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->falloff);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->radius);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count);
shader_set_uniform_vec3(material->shader, uniform_name, &light->color);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count);
shader_set_uniform_vec3(material->shader, uniform_name, &light->color);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].intensity", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->intensity);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].intensity", light_count);
shader_set_uniform_float(material->shader, uniform_name, light->intensity);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->type);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
light_count++; // this variable is going to be used for looping an array so increase its length by one
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count));
vec3 camera_pos = {0, 0, 0};
transform_get_absolute_position(&camera->base, &camera_pos);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos));
}
/* Set material pipeline uniforms */
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_START_DIST].type, material->pipeline_params[MPP_FOG_START_DIST].location, &renderer->settings.fog.start_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MAX_DIST].type, material->pipeline_params[MPP_FOG_MAX_DIST].location, &renderer->settings.fog.max_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_AMBIENT_LIGHT].type, material->pipeline_params[MPP_AMBIENT_LIGHT].location, &renderer->settings.ambient_light));
if(material->lit) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat));
snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", light_count);
shader_set_uniform_int(material->shader, uniform_name, light->type);
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
}
light_count++; // this variable is going to be sent as a uniform and be used for looping an array so increase its length by one
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count));
vec3 camera_pos = {0, 0, 0};
transform_get_absolute_position(&camera->base, &camera_pos);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos));
}
/* Set material pipeline uniforms */
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_START_DIST].type, material->pipeline_params[MPP_FOG_START_DIST].location, &renderer->settings.fog.start_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MAX_DIST].type, material->pipeline_params[MPP_FOG_MAX_DIST].location, &renderer->settings.fog.max_dist));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_AMBIENT_LIGHT].type, material->pipeline_params[MPP_AMBIENT_LIGHT].location, &renderer->settings.ambient_light));
if(material->lit) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat));
for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++)
{
if(!material->registered_static_meshes[j]) continue;
/* for each registered model, set up uniforms and render */
struct Static_Mesh* mesh = material->registered_static_meshes[j];
struct Geometry* geometry = geom_get(mesh->model.geometry_index);
/* Check if model is in frustum */
vec3 abs_pos, abs_scale;
transform_get_absolute_position(&mesh->base, &abs_pos);
transform_get_absolute_scale(&mesh->base, &abs_scale);
int intersection = bv_intersect_frustum_sphere(&camera->frustum[0], &geometry->bounding_sphere, &abs_pos, &abs_scale);
if(intersection == IT_OUTSIDE)
{
renderer->num_culled++;
continue;
}
else
{
renderer->num_indices += array_len(geometry->indices);
renderer->num_rendered++;
}
/* set material params for the model */
for(int k = 0; k < MMP_MAX; k++)
{
switch(mesh->model.material_params[k].type)
{
case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break;
case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break;
case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break;
case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break;
}
}
/* Set pipeline uniforms that are derived per model */
mat4_identity(&mvp);
mat4_mul(&mvp, &camera->view_proj_mat, &mesh->base.transform.trans_mat);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MVP].type, material->pipeline_params[MPP_MVP].location, &mvp));
if(material->lit)
{
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat));
mat4 inv_mat;
mat4_identity(&inv_mat);
mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat));
}
for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++)
{
if(!material->registered_static_meshes[j]) continue;
/* for each registered model, set up uniforms and render */
struct Static_Mesh* mesh = material->registered_static_meshes[j];
struct Geometry* geometry = geom_get(mesh->model.geometry_index);
/* Check if model is in frustum */
vec3 abs_pos, abs_scale;
transform_get_absolute_position(&mesh->base, &abs_pos);
transform_get_absolute_scale(&mesh->base, &abs_scale);
int intersection = bv_intersect_frustum_sphere(&camera->frustum[0], &geometry->bounding_sphere, &abs_pos, &abs_scale);
if(intersection == IT_OUTSIDE)
{
renderer->num_culled++;
continue;
}
else
{
renderer->num_indices += array_len(geometry->indices);
renderer->num_rendered++;
}
/* set material params for the model */
for(int k = 0; k < MMP_MAX; k++)
{
switch(mesh->model.material_params[k].type)
{
case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break;
case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break;
case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break;
case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break;
}
}
/* Set pipeline uniforms that are derived per model */
mat4_identity(&mvp);
mat4_mul(&mvp, &camera->view_proj_mat, &mesh->base.transform.trans_mat);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MVP].type, material->pipeline_params[MPP_MVP].location, &mvp));
if(material->lit)
{
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat));
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat));
mat4 inv_mat;
mat4_identity(&inv_mat);
mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat);
GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat));
}
/* Render the geometry */
//int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode);
//geom_render(model->geometry_index, draw_mode);
geom_render(mesh->model.geometry_index, GDM_TRIANGLES);
for(int k = 0; k < MMP_MAX; k++)
{
/* unbind textures, if any */
if(material->model_params[k].type == UT_TEX)
GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int));
}
/* Render the geometry */
//int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode);
//geom_render(model->geometry_index, draw_mode);
geom_render(mesh->model.geometry_index, GDM_TRIANGLES);
for(int k = 0; k < MMP_MAX; k++)
{
/* unbind textures, if any */
if(material->model_params[k].type == UT_TEX)
GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int));
}
}
shader_unbind();
}
editor_debugvar_slot_set_int(renderer->num_rendered_slot, renderer->num_rendered);
editor_debugvar_slot_set_int(renderer->num_culled_slot, renderer->num_culled);
editor_debugvar_slot_set_int(renderer->num_indices_slot, renderer->num_indices);
renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0;
}
shader_unbind();
}
editor_debugvar_slot_set_int(renderer->num_rendered_slot, renderer->num_rendered);
editor_debugvar_slot_set_int(renderer->num_culled_slot, renderer->num_culled);
editor_debugvar_slot_set_int(renderer->num_indices_slot, renderer->num_indices);
renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0;
}
framebuffer_unbind();
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
framebuffer_unbind();
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
}
/* Final Render */
@ -340,71 +341,71 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene)
struct Hashmap* cvars = platform->config.get();
if(hashmap_bool_get(cvars, "debug_draw_enabled"))
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
vec4 debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color");
shader_bind(renderer->debug_shader);
{
static mat4 mvp;
shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &debug_draw_color);
for(int i = 0; i < MAX_STATIC_MESHES; i++)
{
struct Static_Mesh* mesh = &scene->static_meshes[i];
if(!mesh->base.active) continue;
struct Model* model = &mesh->model;
struct Transform* transform = &mesh->base.transform;
int geometry = model->geometry_index;
mat4_identity(&mvp);
mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat);
shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp);
geom_render(geometry, hashmap_int_get(cvars, "debug_draw_mode"));
}
}
shader_unbind();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
vec4 debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color");
shader_bind(renderer->debug_shader);
{
static mat4 mvp;
shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &debug_draw_color);
for(int i = 0; i < MAX_STATIC_MESHES; i++)
{
struct Static_Mesh* mesh = &scene->static_meshes[i];
if(!mesh->base.active) continue;
struct Model* model = &mesh->model;
struct Transform* transform = &mesh->base.transform;
int geometry = model->geometry_index;
mat4_identity(&mvp);
mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat);
shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp);
geom_render(geometry, hashmap_int_get(cvars, "debug_draw_mode"));
}
}
shader_unbind();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
// Debug Physics render
if(hashmap_bool_get(cvars, "debug_draw_physics"))
{
static vec4 physics_draw_color = { 0.f, 0.f, 1.f, 1.f };
for(int i = 0; i < MAX_STATIC_MESHES; i++)
{
struct Static_Mesh* mesh = &scene->static_meshes[i];
if(!mesh->base.active || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue;
//Get collision mesh and it's props then render it
vec3 pos = {0.f};
quat rot = {0.f, 0.f, 0.f, 1.f };
if(mesh->collision.rigidbody)
{
platform->physics.body_position_get(mesh->collision.rigidbody, &pos.x, &pos.y, &pos.z);
platform->physics.body_rotation_get(mesh->collision.rigidbody, &rot.x, &rot.y, &rot.z, &rot.w);
}
else
{
platform->physics.cs_position_get(mesh->collision.collision_shape, &pos.x, &pos.y, &pos.z);
platform->physics.cs_rotation_get(mesh->collision.collision_shape, &rot.x, &rot.y, &rot.z, &rot.w);
}
int collision_shape_type = platform->physics.cs_type_get(mesh->collision.collision_shape);
switch(collision_shape_type)
{
case CST_SPHERE:
{
float radius = platform->physics.cs_sphere_radius_get(mesh->collision.collision_shape);
im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES);
}
break;
case CST_BOX:
{
float x = 0.f, y = 0.f, z = 0.f;
platform->physics.cs_box_params_get(mesh->collision.collision_shape, &x, &y, &z);
im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES);
};
break;
default: break;
}
}
static vec4 physics_draw_color = { 0.f, 0.f, 1.f, 1.f };
for(int i = 0; i < MAX_STATIC_MESHES; i++)
{
struct Static_Mesh* mesh = &scene->static_meshes[i];
if(!mesh->base.active || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue;
//Get collision mesh and it's props then render it
vec3 pos = {0.f};
quat rot = {0.f, 0.f, 0.f, 1.f };
if(mesh->collision.rigidbody)
{
platform->physics.body_position_get(mesh->collision.rigidbody, &pos.x, &pos.y, &pos.z);
platform->physics.body_rotation_get(mesh->collision.rigidbody, &rot.x, &rot.y, &rot.z, &rot.w);
}
else
{
platform->physics.cs_position_get(mesh->collision.collision_shape, &pos.x, &pos.y, &pos.z);
platform->physics.cs_rotation_get(mesh->collision.collision_shape, &rot.x, &rot.y, &rot.z, &rot.w);
}
int collision_shape_type = platform->physics.cs_type_get(mesh->collision.collision_shape);
switch(collision_shape_type)
{
case CST_SPHERE:
{
float radius = platform->physics.cs_sphere_radius_get(mesh->collision.collision_shape);
im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES);
}
break;
case CST_BOX:
{
float x = 0.f, y = 0.f, z = 0.f;
platform->physics.cs_box_params_get(mesh->collision.collision_shape, &x, &y, &z);
im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES);
};
break;
default: break;
}
}
}
//Immediate mode geometry render
@ -414,16 +415,16 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene)
/* Render 2D stuff */
shader_bind(renderer->sprite_batch->shader);
{
static mat4 ortho_mat;
mat4_identity(&ortho_mat);
int width, height;
struct Game_State* game_state = game_state_get();
platform->window.get_size(game_state->window, &width, &height);
static mat4 ortho_mat;
mat4_identity(&ortho_mat);
int width, height;
struct Game_State* game_state = game_state_get();
platform->window.get_size(game_state->window, &width, &height);
mat4_ortho(&ortho_mat, 0.f, (float)width, (float)height, 0.f, -10.f, 10.f);
shader_set_uniform_mat4(renderer->sprite_batch->shader, "mvp", &ortho_mat);
mat4_ortho(&ortho_mat, 0.f, (float)width, (float)height, 0.f, -10.f, 10.f);
shader_set_uniform_mat4(renderer->sprite_batch->shader, "mvp", &ortho_mat);
sprite_batch_render(renderer->sprite_batch);
sprite_batch_render(renderer->sprite_batch);
}
shader_unbind();
@ -435,7 +436,7 @@ void renderer_cleanup(struct Renderer* renderer)
{
for(int i = 0; i < MAT_MAX; i++)
{
material_reset(&renderer->materials[i]);
material_reset(&renderer->materials[i]);
}
im_cleanup();
sprite_batch_remove(renderer->sprite_batch);
@ -452,9 +453,9 @@ void on_framebuffer_size_change(int width, int height)
float aspect = (float)width / (float)height;
for(int i = 0; i < MAX_CAMERAS; i++)
{
struct Camera* viewer = &scene->cameras[i];
viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f;
camera_update_proj(viewer);
struct Camera* viewer = &scene->cameras[i];
viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f;
camera_update_proj(viewer);
}
framebuffer_resize_all(width, height);

@ -6,6 +6,7 @@
#include "material.h"
struct Sprite_Batch;
struct Scene;
enum Fog_Mode
{

@ -10,8 +10,8 @@
#define MAX_STATIC_MESHES 1024
#define MAX_SOUND_SOURCES 128
struct Ray;
struct Raycast_Result;
struct Scene
{

Loading…
Cancel
Save