Exemple #1
0
void mat4_look_at(mat4 matrix, vec3 from, vec3 to, vec3 up) {
    mat4_zero(matrix);

    vec3 f = sub(to, from);
    f = normalize(f);

    vec3 s = cross(f, up);

    s = normalize(s);
    vec3 u = cross(s, f);

    matrix[0]  = (float)  s.x;
    matrix[1]  = (float)  u.x;
    matrix[2]  = (float) -f.x;

    matrix[4]  = (float)  s.y;
    matrix[5]  = (float)  u.y;
    matrix[6]  = (float) -f.y;

    matrix[8]  = (float)  s.z;
    matrix[9]  = (float)  u.z;
    matrix[10] = (float) -f.z;

    matrix[15] = 1.0f;

    mat4_translate(matrix, (float) -from.x, (float) -from.y, (float) -from.z);
}
Exemple #2
0
void mat4_id(mat4 dest) {
    mat4_zero(dest);
    dest[0]  = 1.0f;
    dest[5]  = 1.0f;
    dest[10] = 1.0f;
    dest[15] = 1.0f;
}
static void mat4_identity(struct mat4 *m)
{
	mat4_zero(m);
	m->v[0][0] = 1;
	m->v[1][1] = 1;
	m->v[2][2] = 1;
	m->v[3][3] = 1;
}
Exemple #4
0
void mat4_mult(mat4 dest, mat4 left, mat4 right) {
    mat4_zero(dest);
    int base;
    for (int i = 0; i < 16; i++) {
        base = i % 4;
        for (int j = 0; j < 4; j++) {
            dest[i] += left[i - base + j] * right[base + j * 4];
        }
    }
}
Exemple #5
0
void mat4_perspective(mat4 matrix, float fov, float near, float far) {
   float f = (float) (1.0 / tan(fov * deg_to_rad / 2.0));
    float frustum = near - far;

    mat4_zero(matrix);

    matrix[0]  = f / get_aspect_ratio();
    matrix[5]  = f;
    matrix[10] = (far + near) / frustum;
    matrix[11] = -1.0f;
    matrix[14] = (2.0f * far * near) / frustum;
}
static void redraw(struct glwin *win)
{
	struct glwin_thread_state thread_state;
	glwin_get_thread_state(&thread_state);
	glwin_make_current(win, g_ctx);

	lua_State *L = g_L;

	static bool gl_init_attempted = false;
	static bool gl_init_result = false;

	if (!gl_init_attempted) {
		gl_init_result = glb_glcore_init(3, 3);
	}
	if (!gl_init_result) {
		printf("Failed to initialize OpenGL bindings\n");
		exit(-1);
		return;
	}

	glViewport(0, 0, win->width, win->height);
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);

	lua_getglobal(L, "b2l_data"); //1
	if (!lua_istable(L, -1)) {
		lua_pop(L, 1);
		goto end;
	}
	lua_getfield(L, -1, "objects"); //2
	lua_getglobal(L, "current_object"); //3
	if (!lua_isstring(L, -1)) {
		lua_pop(L, 3);
		goto end;
	}
	const char *current_object = lua_tostring(L, -1);
	lua_getfield(L, -2, current_object); //4
	if (lua_isnil(L, -1)) {
		lua_pop(L, 4);
		goto end;
	}

	lua_getfield(L, -1, "type"); //5
	if(strcmp(lua_tostring(L, -1), "MESH")) {
		lua_pop(L, 5);
		goto end;
	}
	lua_getfield(L, -2, "data"); //6
	lua_getfield(L, -6, "meshes"); //7
	lua_getfield(L, -1, lua_tostring(L, -2)); //8

	if (lua_isnil(L, -1)) {
		lua_pop(L, 8);
		goto end;
	}

	if (!g_gl_state.initialized)
		init_gl_state();

	if (g_gl_state.recompile_shaders)
		g_gl_state.program_valid = recompile_shaders();

	if (!g_gl_state.initialized || !g_gl_state.program_valid) {
		lua_pop(L, 8);
		goto end;
	}

	g_gl_state.recompile_shaders = false;

	glUseProgram(g_gl_state.program);
	glBindVertexArray(g_gl_state.vao);

	if (g_gl_state.blob_updated)  {
		glBufferData(GL_ARRAY_BUFFER, g_gl_state.blob_size, g_gl_state.blob ,GL_STATIC_DRAW);
		g_gl_state.blob_updated = false;
	}

	lua_getfield(L, -1, "vertex_normal_array_offset"); //9
	int vertex_normal_array_offset = lua_tointeger(L, -1);
	lua_getfield(L, -2, "uv_array_offset"); //10
	int uv_array_offset = lua_tointeger(L, -1);

	lua_getfield(L, -3, "uv_layers"); //11
	lua_len(L, -1); //12
	int num_uv_layers = lua_tointeger(L, -1);

	int tangent_array_offset;
	if (num_uv_layers > 0) {
		lua_getfield(L, -5, "tangent_array_offset");
		tangent_array_offset = lua_tointeger(L, -1);
		lua_pop(L, 1);
	}

	lua_getfield(L, -5, "vertex_co_array_offset"); //13
	int vertex_co_array_offset = lua_tointeger(L, -1);

	lua_getfield(L, -6, "weights_per_vertex"); //14
	int weights_per_vertex = lua_tointeger(L, -1);

	int weights_array_offset;
	if (weights_per_vertex > 0) {
		lua_getfield(L, -7, "weights_array_offset");
		weights_array_offset = lua_tointeger(L, -1);
		lua_pop(L, 1);
	} else {
		weights_array_offset = -1;
	}

	lua_getfield(L, -11, "vertex_groups"); //15
	int num_vertex_groups;
	if (lua_isnil(L, -1)) {
		num_vertex_groups = 0;
	} else {
		lua_len(L, -1);
		num_vertex_groups = lua_tointeger(L, -1);
		lua_pop(L, 1);
	}

	glBindVertexBuffer(NORMAL, g_gl_state.vbo, vertex_normal_array_offset, sizeof(float) * 3);
	if (num_uv_layers > 0) {
		glBindVertexBuffer(UV, g_gl_state.vbo, uv_array_offset, sizeof(float) * 2 * num_uv_layers);
		glBindVertexBuffer(TANGENT, g_gl_state.vbo, tangent_array_offset, sizeof(float) * 4);
	}
	glBindVertexBuffer(POS, g_gl_state.vbo, vertex_co_array_offset, sizeof(float) * 3);
	if (weights_per_vertex > 0)
		glBindVertexBuffer(WEIGHTS, g_gl_state.vbo, weights_array_offset, weights_per_vertex * 4);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_gl_state.vbo);
	if (g_gl_state.normal_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.normal_index);
		glVertexAttribFormat(g_gl_state.normal_index, 3, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.normal_index, NORMAL);
	}

	if (g_gl_state.uv_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.uv_index);
		glVertexAttribFormat(g_gl_state.uv_index, 2, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.uv_index, UV);
	}

	if (g_gl_state.pos_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.pos_index);
		glVertexAttribFormat(g_gl_state.pos_index, 3, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.pos_index, POS);
	}
	int i = 0;
	for (i = 0; i < 6; i++) {
		if (g_gl_state.weights_index[i] >= 0 && weights_per_vertex > 0) {
			glEnableVertexAttribArray(g_gl_state.weights_index[i]);
			glVertexAttribIFormat(g_gl_state.weights_index[i], 2, GL_SHORT, 4 * i);
			glVertexAttribBinding(g_gl_state.weights_index[i], WEIGHTS);
		}
	}
	if (num_uv_layers > 0 && g_gl_state.tangent_index >= 0) {
		glEnableVertexAttribArray(g_gl_state.tangent_index);
		glVertexAttribFormat(g_gl_state.tangent_index, 4, GL_FLOAT, GL_FALSE, 0);
		glVertexAttribBinding(g_gl_state.tangent_index, TANGENT);
	}

	struct mat4 view;
	struct mat4 model;
	struct quaternion next;
	quaternion_mul(&q_delta, &q_cur, &next);
	quaternion_to_mat4(&next, &view);
	view.v[3][3] = 1;
	mat4_identity(&model);
	model.v[3][0] = g_offset[0] + g_offset_next[0];
	model.v[3][1] = g_offset[1] + g_offset_next[1];
	model.v[3][2] = g_offset[2] + g_offset_next[2];
	glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "model"), 1, GL_FALSE, (GLfloat *)&model);
	struct mat4 ident;
	mat4_identity(&ident);
	glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "view"), 1, GL_FALSE, (GLfloat *)&view);

	float zoom = exp(g_log_zoom);
	float zr = 100;
	struct mat4 proj;
	mat4_zero(&proj);
	proj.v[0][0] = 1.0/zoom;
	proj.v[1][1] = 1.0*win->width/(zoom*win->height);
	proj.v[2][2] = 1.0/zr;
	proj.v[3][3] = 1.0;
	glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "proj"), 1, GL_FALSE, (GLfloat *)&proj);

	if (weights_per_vertex > 0) {
		static int render_count = 0;
		render_count++;
		double frame;
		int frame_start;
		int frame_end;
		lua_getglobal(L, "frame_start"); //16
		frame_start = lua_tointeger(L, -1);
		lua_getglobal(L, "frame_end"); //17
		frame_end = lua_tointeger(L, -1);
		lua_getglobal(L, "frame_delta"); //18
		frame = frame_start + lua_tonumber(L, -1);
		int frame_i = floorf(frame);
		double frame_fract = frame - frame_i;

		lua_getfield(L, -18, "scenes"); //19
		lua_getglobal(L, "current_scene"); //20
		lua_getfield(L, -2, lua_tostring(L, -1)); //21
		if (!lua_istable(L, -1)) {
			lua_pop(L, 20);
			goto end;
		}
		lua_getfield(L, -1, "objects");
		lua_getfield(L, -1, current_object);
		lua_getfield(L, -1, "vertex_group_transform_array_offset");
		int offset = lua_tointeger(L, -1);
		lua_pop(L, 9);
		int stride = sizeof(float) * 4 * 4 * num_vertex_groups;
		int i;
		for (i = 0; i < num_vertex_groups; i++) {
			struct mat4 res;
			struct mat4 M1;
			struct mat4 M2;
			struct mat4 *base = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + frame_i * stride);
			struct mat4 *next = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + (frame_i + 1) * stride);

			if (frame_i == (frame_end-1)) {
				next = (struct mat4 *)(g_gl_state.blob + offset + i * sizeof(float) * 4 * 4 + (frame_start) * stride);
			} else if (frame_fract == 0) {
				next = base;
			}


#if USE_SLERP
			struct mat4 temp;
			mat4_zero(&temp);
			temp.v[3][3] = 1;
			M1 = *base;
			M2 = *next;
			spherical_lerp(M1.v[0], M2.v[0], frame_fract, temp.v[0]);
			spherical_lerp(M1.v[1], M2.v[1], frame_fract, temp.v[1]);
			spherical_lerp(M1.v[2], M2.v[2], frame_fract, temp.v[2]);
			mat4_transpose(&temp, &res);
			float v1[3];
			float v2[3];
			v1[0] = M1.v[0][3];
			v1[1] = M1.v[1][3];
			v1[2] = M1.v[2][3];
			v2[0] = M2.v[0][3];
			v2[1] = M2.v[1][3];
			v2[2] = M2.v[2][3];
			lerp(v1, v2, frame_fract, res.v[3]);
#else
			mat4_zero(&res);
			res.v[3][3] = 1;
			mat4_transpose(base, &M1);
			mat4_transpose(next, &M2);
			lerp(M1.v[0], M2.v[0], frame_fract, res.v[0]);
			lerp(M1.v[1], M2.v[1], frame_fract, res.v[1]);
			lerp(M1.v[2], M2.v[2], frame_fract, res.v[2]);
			lerp(M1.v[3], M2.v[3], frame_fract, res.v[3]);
#endif

			glUniformMatrix4fv(g_gl_state.groups_index + i,
					1, /*num_vertex_groups, */
					GL_FALSE,
					(GLfloat *)&res);
		}
	}

	lua_getglobal(L, "controls"); //16
	int controls = lua_gettop(L);
	lua_getglobal(L, "materials"); //17
	int materials = lua_gettop(L);

	lua_getfield(L, -10, "index_array_offset"); //18
	int index_array_offset = lua_tointeger(L, -1);

	lua_getfield(L, -11, "submeshes"); //19
	lua_len(L, -1); //20
	int num_submeshes = lua_tointeger(L, -1);

	for (i = 0; i < num_submeshes; i++) {
		lua_rawgeti(L, -2, i + 1);
		lua_getfield(L, -1, "material_name");

		const char *material_name = lua_tostring(L, -1);

		lua_getfield(L, -2, "triangle_no");
		int triangle_no = lua_tointeger(L, -1);
		lua_getfield(L, -3, "triangle_count");
		int triangle_count = lua_tointeger(L, -1);
		lua_getfield(L, materials, material_name);
		lua_getfield(L, -1, "params");
		lua_pushnil(L);  /* first key */
		while (lua_next(L, -2)) {
			int variable = lua_gettop(L);
			const char *variable_name = lua_tostring(L, variable - 1);
			int uniform_loc = glGetUniformLocation(g_gl_state.program, variable_name);
			if (uniform_loc == -1) {
				lua_pop(L, 1);
				continue;
			}
			lua_getfield(L, variable, "value");
			int value = variable + 1;
			lua_getfield(L, variable, "datatype");
			const char *datatype = strdup(lua_tostring(L, -1));
			lua_pop(L, 1);
			if (!strcmp(datatype, "bool")) {
				int bool_value = lua_toboolean(L, value);
				glUniform1i(uniform_loc, bool_value);
			} else if (!strcmp(datatype, "vec3")) {
				lua_rawgeti(L, value, 1);
				lua_rawgeti(L, value, 2);
				lua_rawgeti(L, value, 3);
				float val[3];
				val[0] = (float)lua_tonumber(L, -3);
				val[1] = (float)lua_tonumber(L, -2);
				val[2] = (float)lua_tonumber(L, -1);
				glUniform3fv(uniform_loc, 1, val);
				lua_pop(L, 3);
			} else if (!strcmp(datatype, "float")) {
				float fval = lua_tonumber(L, value);
				glUniform1f(uniform_loc, fval);
			} else if (!strcmp(datatype, "sampler2D")) {
				lua_getfield(L, controls, variable_name);
				int control = lua_gettop(L);
				lua_getfield(L, control, "needs_upload");
				int needs_upload = lua_toboolean(L, -1);
				lua_pop(L, 1);
				if (needs_upload) {
					int texunit;
					GdkPixbuf *pbuf;
					lua_getfield(L, control, "texunit");
					texunit = lua_tointeger(L, -1) - 1;
					lua_pop(L, 1);

					lua_getfield(L, control, "pbuf");
					lua_getfield(L, -1, "_native");
					pbuf = (GdkPixbuf *)lua_touserdata(L, -1);
					lua_pop(L, 2);
					glActiveTexture(GL_TEXTURE0 + texunit);
					glBindTexture(GL_TEXTURE_2D, g_texture_names[texunit]);
					int width = gdk_pixbuf_get_width(pbuf);
					int height = gdk_pixbuf_get_height(pbuf);
					int n_chan = gdk_pixbuf_get_n_channels(pbuf);
					glPixelStorei(GL_UNPACK_ROW_LENGTH, gdk_pixbuf_get_rowstride(pbuf)/ n_chan);
					glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
					glTexImage2D(GL_TEXTURE_2D,
						0, /* level */
						n_chan > 3 ? GL_RGBA : GL_RGB,
						width,
						height,
						0, /* border */
						n_chan > 3 ? GL_RGBA : GL_RGB,
						GL_UNSIGNED_BYTE,
						gdk_pixbuf_get_pixels(pbuf));
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
					glGenerateMipmap(GL_TEXTURE_2D);
					glUniform1i(uniform_loc, texunit);

					lua_pushboolean(L, 0);
					lua_setfield(L, control, "needs_upload");
				}
				lua_pop(L, 1);
			}
			free((void *)datatype);
			lua_pop(L, 2);
		} //while (lua_next(L, -2) != 0)
		glDrawElements(GL_TRIANGLES,
				3 * triangle_count,
				GL_UNSIGNED_SHORT,
				(void *)((int64_t)index_array_offset) + 3 * 2 * triangle_no);
		lua_pop(L, 6);
	}
	lua_pop(L, 20);
end:
	{
		GLenum err = glGetError();
		if (err)
			printf("render_scene GL error = %d\n", err);
	}
	glwin_swap_buffers(g_win);
	glwin_set_thread_state(&thread_state);
	g_need_redraw = false;
	return;
}
Exemple #7
0
void mat4_identity(struct mat4 *m)
{
	mat4_zero(m);

	m->xx = m->yy = m->zz = m->ww = 1.0f;
}