polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

rogue.c (5084B)


      1 
      2 #include "rogue.h"
      3 #include "render.h"
      4 #include "gpu.h"
      5 #include "grid.h"
      6 #include "mat4.h"
      7 #include "lens.h"
      8 #include "stb_image.h"
      9 #include "file.h"
     10 
     11 enum shader_structs {
     12 	COMMON_VARS
     13 };
     14 
     15 #define CV_LENS(field, typ) { #field, offsetof(struct common_vars, field), DATA_ID_##typ }
     16 static struct lens common_lenses[] = {
     17 	CV_LENS(depth_mvp, MAT4),
     18 	CV_LENS(mvp, MAT4),
     19 	CV_LENS(model_view, MAT4),
     20 	//CV_LENS(normal_matrix, MAT4),
     21 	//CV_LENS(camera_position, VEC3P),
     22 	//CV_LENS(light_dir, VEC3),
     23 };
     24 #undef CV_LENS
     25 
     26 static struct structure_binding uniform_bindings[] = {
     27 	[COMMON_VARS] = { common_lenses, ARRAY_SIZE(common_lenses) },
     28 };
     29 
     30 static void init_ortho(struct rogue_game *game)
     31 {
     32 	float left = 0.0;
     33 	float right = 1.0;
     34 	float bottom = 0.0;
     35 	float top = 1.0;
     36 	float near = -1.0;
     37 	float far = 2.0;
     38 
     39 	mat4_ortho(left, right, bottom, top, near, far, game->ortho);
     40 }
     41 
     42 static int compile_shaders(struct gpu *gpu)
     43 {
     44 	struct shader fragment, vertex;
     45 
     46 	if (!make_shader(GL_FRAGMENT_SHADER, SHADER("rogue/main.f.glsl"), &fragment))
     47 		return 0;
     48 
     49 	if (!make_shader(GL_VERTEX_SHADER, SHADER("rogue/grid.v.glsl"), &vertex))
     50 		return 0;
     51 
     52 	return make_program("grid", &vertex, &fragment,
     53 			&gpu->programs[GRID_PROGRAM],
     54 			uniform_bindings,
     55 			ARRAY_SIZE(uniform_bindings));
     56 }
     57 
     58 static int init_grid(struct grid *grid)
     59 {
     60 	make_grid_geom(&grid->geom, 32.0, 32.0, 1.0);
     61 	return 1;
     62 }
     63 
     64 static void render_grid(struct grid *grid, struct gpu *gpu,
     65 		struct common_vars *cvars)
     66 {
     67 	struct gpu_program *program;
     68 
     69 	void *structures[] = {
     70 		[COMMON_VARS] = cvars
     71 	};
     72 
     73 	program = &gpu->programs[GRID_PROGRAM];
     74 
     75 	glUseProgram(program->handle);            check_gl();
     76 	bind_uniforms(program, structures, 1);    check_gl();
     77 	bind_geometry(&grid->geom, program);      check_gl();
     78 
     79 	glActiveTexture(GL_TEXTURE0);
     80 	render_geometry(&grid->geom, program);    check_gl();
     81 }
     82 
     83 u32 make_items_texture()
     84 {
     85 	unsigned char *img_data, *data;
     86 	size_t data_len;
     87 	u32 tid;
     88 	int width, height, n_channels;
     89 
     90 	glGenTextures(1, &tid);
     91 	glBindTexture(GL_TEXTURE_2D, tid);
     92 	check_gl();
     93 
     94 	data = file_contents(TEXTURE("roguelikeitems.png"), &data_len);
     95 	assert(data);
     96         img_data = stbi_load_from_memory(data, data_len, &width, &height,
     97 			&n_channels, 0);
     98 
     99         if (img_data) {
    100 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width,
    101 			height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data);
    102 		check_gl();
    103 		stbi_image_free(img_data);
    104 		free(data);
    105 	}
    106 
    107 	return tid;
    108 }
    109 
    110 int init_rogue_game(struct engine *engine, struct rogue_game *game)
    111 {
    112 	int cell_size = 1.0;
    113 
    114 	init_ortho(game);
    115 
    116 	game->grid.items_tilemap = make_items_texture();
    117 
    118 	engine->gpu.num_programs = NUM_ROGUE_PROGRAMS;
    119 	if (!compile_shaders(&engine->gpu))
    120 		return 0;
    121 	return init_grid(&game->grid);
    122 }
    123 
    124 static void render(struct engine *engine, struct rogue_game *game, struct render_config *config) {
    125 	float gtmp[3];
    126 
    127 	struct geometry *geom;
    128 	struct gpu_program *program = NULL;
    129 	struct common_vars *cvars = &game->common_vars;
    130 
    131 	glEnable(GL_DEPTH_TEST);
    132 
    133 	glClearColor( 40.0/255.0, 44.0/255.0, 52.0/255.0, 1.0 ); //clear background screen to black
    134 	/* glClearColor( 0.5294f * adjust, 0.8078f * adjust, 0.9216f * adjust, 1.0f ); //clear background screen to black */
    135 	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    136 
    137 	check_gl();
    138 
    139 	static float id[MAT4_ELEMS] = { 0 };
    140 	static float view[MAT4_ELEMS] = { 0 };
    141 	static float normal_matrix[MAT4_ELEMS] = { 0 };
    142 
    143 	mat4_id(id);
    144 	mat4_id(cvars->model_view);
    145 	mat4 *projection = config->projection;
    146 
    147 	/*
    148 	struct node *camera_node = get_node(&config->camera);
    149 	assert(camera_node);
    150 
    151 	const mat4 *camera = camera_node->mat;
    152 
    153 	mat4_inverse((float*)camera, view);
    154 	mat4_multiply(projection, view, cvars->mvp);
    155 
    156 	cvars->camera_position = (float*)&camera[M_X];
    157 	*/
    158 
    159 	mat4_copy(projection, cvars->mvp);
    160 
    161 	float aspect = (float)engine->width / (float)engine->height;
    162 
    163 	float h = 0.03124; // 32.0 / 1024.0
    164 	float w = h / aspect;
    165 
    166 	mat4_translate(cvars->mvp, V3(-0.5, -0.5, 0.0), cvars->mvp);
    167 	mat4_scale(cvars->mvp, V3(w, h, 1.0), cvars->mvp);
    168 
    169         //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    170 
    171 	render_grid(&game->grid, &engine->gpu, cvars);
    172 
    173 	if (config->is_depth_pass) {
    174 		glDisable(GL_CULL_FACE);
    175 		//mat4_multiply(bias_matrix, view_proj, config->depth_vp);
    176 	}
    177 	else {
    178 		glCullFace(GL_BACK);
    179 	}
    180 
    181 	if (!config->is_depth_pass) {
    182 		//mat4_inverse((float*)camera, view);
    183 		mat4_remove_translations(view);
    184 		mat4_multiply(projection, view, cvars->mvp);
    185 
    186 		//render_skybox(&game->skybox, view_proj);
    187 	}
    188 
    189 	//if (config->draw_ui)
    190 	//	render_ui(&game->ui, view);
    191 }
    192 
    193 void rogue_frame(struct engine *engine, struct rogue_game *game)
    194 {
    195 	static float depth_vp[MAT4_ELEMS];
    196 	mat4_id(depth_vp);
    197 
    198 	/*
    199 	struct render_config fbo_render_config = {
    200 		.draw_ui = 0,
    201 		.is_depth_pass = 1,
    202 		.camera = game->sun_camera_id,
    203 		.projection = game->proj_ortho,
    204 		.depth_vp = depth_vp
    205 	};
    206 	*/
    207 
    208 	struct render_config default_config = {
    209 		.draw_ui = 1,
    210 		.is_depth_pass = 0,
    211 		.camera = game->camera_node_id,
    212 		.projection = game->ortho,
    213 		.depth_vp = depth_vp
    214 	};
    215 
    216 	//render(engine, game, &fbo_render_config);
    217 	render(engine, game, &default_config);
    218 }
    219