Пример #1
0
void CShaderObject::BindStateMatrix(const char* paramName, unsigned int matrix)
{
    // Check and validate bind status //
	if(!m_bIsBound)
		return;

    // Get and validate bind point //
	int bind_point = glGetUniformLocation(m_shaderObject, paramName);
	if(bind_point < 0)
		return;

	mat4 MV, P, F;
	mat4_load_identity(MV);
	mat4_load_identity(P);

	if(matrix & MATRIX_MODELVIEW)
		glGetFloatv(GL_MODELVIEW_MATRIX, MV);
	if(matrix & MATRIX_PROJECTION)
		glGetFloatv(GL_PROJECTION_MATRIX, P);

	mat4_mul_mat4(P, MV, F);

	if(matrix & MATRIX_TRANSPOSE)
		mat4_transpose(F);

	glUniformMatrix4fv(bind_point, 1, false, F);
}
Пример #2
0
mat4 transform_get_view_matrix(transform2D* trans)
{
    mat4 mat = create_mat4();
    mat4_rotate(&mat, trans->angle, 0);
    mat4_transpose(&mat);
    mat.data[12] = (-trans->x * mat.data[0]) - (trans->y * mat.data[4]);
    mat.data[13] = (-trans->y * mat.data[0]) + (trans->y * mat.data[4]);

    // TODO: Take scale into account

    return mat;
}
mat3 *GFX_get_normal_matrix( void )
{
	mat4 mat;
	
	mat4_copy_mat4( &mat, GFX_get_modelview_matrix() );

	mat4_invert_full( &mat );

	mat4_transpose( &mat );
	
	mat3_copy_mat4( &gfx.normal_matrix, &mat );

	return &gfx.normal_matrix;
}
Пример #4
0
void render_debug(geometry *in, mat4_t model, mat4_t view, mat4_t projection)
{
    glUseProgram(in->debug_geometry.program);

    float mvp[16];
    mat4_multiply(projection, view, mvp);
    mat4_multiply(mvp, model , mvp);

    float normal_matrix[16];
    mat4_multiply(view, model , normal_matrix);

    mat4_inverse(normal_matrix, normal_matrix);
    mat4_transpose(normal_matrix, normal_matrix);

    glUniformMatrix4fv(in->debug_geometry.uniform.mvp_matrix, 1, GL_FALSE, mvp);

    glDrawArrays(GL_LINES, 0, in->vertex_count * 2);
}
Пример #5
0
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;
}
Пример #6
0
animation* ani_load_file(char* filename) {
  
  int state = STATE_LOAD_EMPTY;
  
  animation* a =  animation_new();
  skeleton* base = skeleton_new();
  frame* f = NULL;
  
  SDL_RWops* file = SDL_RWFromFile(filename, "r");
  
  if(file == NULL) {
    error("Could not load file %s", filename);
  }
  
  char line[1024];
  while(SDL_RWreadline(file, line, 1024)) {
    
    if (state == STATE_LOAD_EMPTY) {
      
      int version;
      if (sscanf(line, "version %i", &version) > 0) {
        if (version != 1) {
          error("Can't load ani file '%s'. Don't know how to load version %i\n", filename, version);
        }
      }
      
      if (strstr(line, "nodes")) {
        state = STATE_LOAD_NODES;
      }
      
      if (strstr(line, "skeleton")) {
        state = STATE_LOAD_SKELETON;
      }
    }
    
    else if (state == STATE_LOAD_NODES) {
      char name[1024];
      int id, parent;
      if (sscanf(line, "%i \"%[^\"]\" %i", &id, name, &parent) == 3) {
        skeleton_joint_add(base, name, parent);
      }
      
      if (strstr(line, "end")) {
        state = STATE_LOAD_EMPTY;
      }
    }
    
    else if (state == STATE_LOAD_SKELETON) {
    
      float time;
      if (sscanf(line, "time %f", &time) == 1) {
        f = animation_add_frame(a, base->rest_pose);
      }
    
      int id;
      float x, y, z, rx, ry, rz;
      if (sscanf(line, "%i %f %f %f %f %f %f", &id, &x, &y, &z, &rx, &ry, &rz) > 0) {
        
        f->joint_positions[id] = vec3_new(x, z, y);
        
        mat4 rotation = mat4_rotation_euler(rx, ry, rz);
        mat4 handedflip = mat4_new(1,0,0,0,
                                   0,0,1,0,
                                   0,1,0,0,
                                   0,0,0,1);
      
        rotation = mat4_mul_mat4(handedflip, rotation);
        rotation = mat4_mul_mat4(rotation, handedflip);
        rotation = mat4_transpose(rotation);
        
        f->joint_rotations[id] = mat4_to_quat(rotation);
        
      }
      
      if (strstr(line, "end")) {
        state = STATE_LOAD_EMPTY;
      }
      
    }
  }
  
  SDL_RWclose(file);
  
  skeleton_delete(base);
  
  return a;
}
Пример #7
0
static int _llfunc_mat4_transpose(lua_State *L) {
	mat4 *m = (mat4*)userdata_get_or_die(L, 1);
	mat4_transpose(m);
	return 0;
}
Пример #8
0
/*
How do you find the adjoint of a 4x4 matrix?

Find the cofactor (determinant of the signed minor) of each entry, keeping in mind the sign array
(starting with + in the upper left corner):
[+ - + -]
[- + - +]
[+ - + -]
[- + - +]

//
//	11  12  13  14
//  21  22  23  24
//  31  32  33  34
//  41  42  43  44
//

// c = adjoint(a)
*/
void mat4_adjoint(mat4 &c, const mat4 &a)
{
	mat3 m3;
	mat4 m4;

	// Create matrix of minors
	// Apply +- pattern to create matrix of cofactors
	// 11
	m3.m11 = a.m22; m3.m12 = a.m23; m3.m13 = a.m24;
	m3.m21 = a.m32; m3.m22 = a.m33; m3.m23 = a.m34;
	m3.m31 = a.m42; m3.m32 = a.m43; m3.m33 = a.m44;
	m4.m11 = mat3_determinant(m3);

	// 12
	m3.m11 = a.m21; m3.m12 = a.m23; m3.m13 = a.m24;
	m3.m21 = a.m31; m3.m22 = a.m33; m3.m23 = a.m34;
	m3.m31 = a.m41; m3.m32 = a.m43; m3.m33 = a.m44;
	m4.m12 = -mat3_determinant(m3);

	// 13
	m3.m11 = a.m21; m3.m12 = a.m22; m3.m13 = a.m24;
	m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m34;
	m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m44;
	m4.m13 = mat3_determinant(m3);

	// 14
	m3.m11 = a.m21; m3.m12 = a.m22; m3.m13 = a.m23;
	m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m33;
	m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m43;
	m4.m14 = -mat3_determinant(m3);

	// 21
	m3.m11 = a.m12; m3.m12 = a.m13; m3.m13 = a.m14;
	m3.m21 = a.m32; m3.m22 = a.m33; m3.m23 = a.m34;
	m3.m31 = a.m42; m3.m32 = a.m43; m3.m33 = a.m44;
	m4.m21 = -mat3_determinant(m3);

	// 22
	m3.m11 = a.m11; m3.m12 = a.m13; m3.m13 = a.m14;
	m3.m21 = a.m31; m3.m22 = a.m33; m3.m23 = a.m34;
	m3.m31 = a.m41; m3.m32 = a.m43; m3.m33 = a.m44;
	m4.m22 = mat3_determinant(m3);

	// 23
	m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m14;
	m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m34;
	m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m44;
	m4.m23 = -mat3_determinant(m3);

	// 24
	m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m13;
	m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m33;
	m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m43;
	m4.m24 = mat3_determinant(m3);


	// 31
	m3.m11 = a.m12; m3.m12 = a.m13; m3.m13 = a.m14;
	m3.m21 = a.m22; m3.m22 = a.m23; m3.m23 = a.m24;
	m3.m31 = a.m42; m3.m32 = a.m43; m3.m33 = a.m44;
	m4.m31 = mat3_determinant(m3);

	// 32
	m3.m11 = a.m11; m3.m12 = a.m13; m3.m13 = a.m14;
	m3.m21 = a.m21; m3.m22 = a.m23; m3.m23 = a.m24;
	m3.m31 = a.m41; m3.m32 = a.m43; m3.m33 = a.m44;
	m4.m32 = -mat3_determinant(m3);

	// 33
	m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m14;
	m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m24;
	m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m44;
	m4.m33 = mat3_determinant(m3);

	// 34
	m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m13;
	m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m23;
	m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m43;
	m4.m34 = -mat3_determinant(m3);


	// 41
	m3.m11 = a.m12; m3.m12 = a.m13; m3.m13 = a.m14;
	m3.m21 = a.m22; m3.m22 = a.m23; m3.m23 = a.m24;
	m3.m31 = a.m32; m3.m32 = a.m33; m3.m33 = a.m34;
	m4.m41 = -mat3_determinant(m3);

	// 42
	m3.m11 = a.m11; m3.m12 = a.m13; m3.m13 = a.m14;
	m3.m21 = a.m21; m3.m22 = a.m23; m3.m23 = a.m24;
	m3.m31 = a.m31; m3.m32 = a.m33; m3.m33 = a.m34;
	m4.m42 = mat3_determinant(m3);

	// 43
	m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m14;
	m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m24;
	m3.m31 = a.m31; m3.m32 = a.m32; m3.m33 = a.m34;
	m4.m43 = -mat3_determinant(m3);

	// 44
	m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m13;
	m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m23;
	m3.m31 = a.m31; m3.m32 = a.m32; m3.m33 = a.m33;
	m4.m44 = mat3_determinant(m3);


	// create adjoint by transposing
	mat4_transpose(c, m4);
}
Пример #9
0
void hostviewport_render(
	struct arena*  vp, struct style* aa,
	struct arena* win, struct style* st)
{
	int j;
	struct datapair* mod;

	float cammvp[4*4];
	float w,h,x0,y0,x1,y1;

	w = win->fbwidth;
	h = win->fbheight;
	x0 = w * st->vc[0];	//0
	y0 = h * st->vc[1];	//0
	x1 = w * st->vq[0];	//0.5
	y1 = h * st->vq[1];	//1

	//
	vp->width = vp->fbwidth = x1;
	vp->height = vp->fbheight = y1;
	glViewport(x0, y0, x1, y1);

	//
	struct relation* rel;
	struct arena* ctxnode;
	rel = vp->orel0;
	while(1){
		if(0 == rel)break;
		if(_win_ == rel->dsttype){
			ctxnode = (void*)(rel->dstchip);
			if(ctxnode)goto found;
			break;
		}
		rel = samesrcnextdst(rel);
	}
	return;

found:
	fixmatrix(cammvp, vp);
	mat4_transpose((void*)cammvp);


	//solid
	mod = ctxnode->gl_solid;
	for(j=0;j<64;j++)
	{
		if(0 == mod[j].src.vbuf)continue;
		display_eachpass(&mod[j].dst, &mod[j].src, vp, cammvp);
	}


	//opaque
	glDepthMask(GL_FALSE);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	mod = ctxnode->gl_opaque;
	for(j=0;j<64;j++)
	{
		if(0 == mod[j].src.vbuf)continue;
		display_eachpass(&mod[j].dst, &mod[j].src, vp, cammvp);
	}

	glDisable(GL_BLEND);
	glDepthMask(GL_TRUE);
}
Пример #10
0
static bool ray_surface_intersect(Ray ray, const Surface *surf, Hit *hit)
{
	float ts[2] = {-HUGE_VAL, -HUGE_VAL}, t;
	Vec3 tnormals[2] = {{0,0,0},{0,0,0}}, tnormal;
	Ray tray;
	Mat4 normal_matrix;
	Shape *shape = surf->shape;
	int hits;

	mat4_copy(normal_matrix, surf->world_to_model);
	mat4_transpose(normal_matrix);

	tray.origin = mat4_transform3_homo(surf->world_to_model, ray.origin);
	tray.direction = mat4_transform3_hetero(surf->world_to_model, ray.direction);
	tray.near = ray.near;
	tray.far = ray.far;

	switch(shape->type)
	{
	case SHAPE_PLANE:
		hits = ray_plane_intersect(tray, shape->u.plane, ts, tnormals);
		break;
	case SHAPE_DISK:
		hits = ray_disk_intersect(tray, shape->u.disk, ts, tnormals);
		break;
	case SHAPE_SPHERE:
		hits = ray_sphere_intersect(tray, shape->u.sphere, ts, tnormals);
		break;
	case SHAPE_CYLINDER:
		hits = ray_cylinder_intersect(tray, shape->u.cylinder, ts, tnormals);
		break;
	case SHAPE_CONE:
		hits = ray_cone_intersect(tray, shape->u.cone, ts, tnormals);
		break;
	case SHAPE_MESH:
		hits = ray_mesh_intersect(tray, shape->u.mesh, ts, tnormals);
		break;
	default:
		printf("Unknown shape\n");
		return false;
		break;
	}

	/* We're looking for the smallest hit that is between the near and far
	 * planes of the ray. */
	if (hits == 0)
		return false;
	if (hits == 1)
	{
		if (ts[0] < ray.near || ts[0] > ray.far)
			return false;

		t = ts[0];
		tnormal = tnormals[0];
	} else if (hits == 2)
	{
		bool t0_ok = ts[0] >= ray.near && ts[0] <= ray.far;
		bool t1_ok = ts[1] >= ray.near && ts[1] <= ray.far;

		     if (!t0_ok && !t1_ok)
		{
			return false;
		}
		else if (t0_ok && !t1_ok)
		{
			t = ts[0];
			tnormal = tnormals[0];
		}
		else if (!t0_ok && t1_ok)
		{
			t = ts[1];
			tnormal = tnormals[1];
		}
		else
		{
			if (ts[0] < ts[1])
			{
				t = ts[0];
				tnormal = tnormals[0];
			} else
			{
				t = ts[1];
				tnormal = tnormals[1];
			}
		}
	} else
	{
		printf("General t finding code unimplemented\n");
		return false;
	}

	hit->t = t;
	hit->position = vec3_add(ray.origin, vec3_scale(t, ray.direction));
	hit->normal = vec3_normalize(mat4_transform3_hetero(normal_matrix, tnormal));
	return true;
}