Exemplo n.º 1
0
void draw_object_ex(IDirect3DDevice9 *device, object *obj, BOOL trans){
	unsigned int mesh;
	if(!device) return;
	if(!obj) return;

	if(obj->update){
		vertex *dest;
		generate_normals(obj);
		IDirect3DVertexBuffer9_Lock(obj->vertexbuffer, 0, 0, (BYTE**)&dest, 0 );
		memcpy(dest,obj->vertices,sizeof(vertex)*obj->vertex_count);
		IDirect3DVertexBuffer9_Unlock(obj->vertexbuffer);
		obj->update = FALSE;
	}

	IDirect3DDevice9_SetTransform( device, D3DTS_WORLD, (D3DMATRIX*)&obj->mat );
	IDirect3DDevice9_SetStreamSource(device, 0, obj->vertexbuffer, 0, sizeof(vertex));
	IDirect3DDevice9_SetFVF(device, OBJECT_VERTEX_TYPE);

	for(mesh=0;mesh<obj->submesh_count;mesh++){
		if(obj->submeshes[mesh].mat){
			if(obj->submeshes[mesh].mat->additive==trans){
				set_material(device,obj->submeshes[mesh].mat);
				IDirect3DDevice9_SetIndices(device,obj->submeshes[mesh].indexbuffer);
				IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0,0,obj->vertex_count, 0,obj->submeshes[mesh].triangle_count);
			}
		}else{
			if(!trans){
				IDirect3DDevice9_SetIndices(device,obj->submeshes[mesh].indexbuffer);
				IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0,0,obj->vertex_count, 0,obj->submeshes[mesh].triangle_count);
			}
		}
	}
}
Exemplo n.º 2
0
/**
 * Initialize the project, doing any necessary opengl initialization.
 * @param camera An already-initialized camera.
 * @param scene The scene to render.
 * @return true on success, false on error.
 */
bool OpenglProject::initialize( Camera* camera, Scene* scene )
{
    // copy scene
    this->scene = *scene;

    // TODO opengl initialization code and precomputation of mesh/heightmap
    
    // Set configuration bitflags
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_NORMALIZE);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_CULL_FACE);

    glCullFace(GL_BACK);

    // Debug: Render in wireframe mode
    // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

    GLfloat light_ambient[] = { 0.5, 0.25, 0.55, 1.0 };
    GLfloat light_diffuse[] = { 0.95, 0.4, 0.5, 1.0 };
    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light_position[] = { 20.0, 5.0, 15.0, 0.0 };
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(
        camera->get_fov_degrees(),
        camera->get_aspect_ratio(),
        camera->get_near_clip(),
        camera->get_far_clip());
    
    glMatrixMode( GL_MODELVIEW );

    this->scene.mesh.normals = new Vector3[this->scene.mesh.num_vertices];
    generate_normals(this->scene.mesh);

    wave_resolution = 128;
    create_wave();

    return true;
}
Exemplo n.º 3
0
/**
 * Perform an update step. This happens on a regular interval.
 * @param dt The time difference from the previous frame to the current.
 */
void OpenglProject::update( real_t dt )
{
    // update our heightmap
    scene.heightmap->update( dt );

    // TODO any update code, e.g. commputing heightmap mesh positions and normals
    
    size_t res = wave_resolution;
    MeshData& wave = scene.wave;
    Vector3 *verts = wave.vertices;
    for (size_t i = 0; i < res; i++) {
        for (size_t j = 0; j < res; j++) {
            size_t idx = (i * res) + j;
            Vector3& v = verts[idx];
            v.y = scene.heightmap->compute_height(Vector2(v.x, v.z));
        }
    }

    generate_normals(wave);
}
Exemplo n.º 4
0
model obj(std::string const& name, model::attrib_flag_t import_attribs) {
    std::vector<tinyobj::shape_t> shapes;
    std::vector<tinyobj::material_t> materials;

    std::string err = tinyobj::LoadObj(shapes, materials, name.c_str());

    if (!err.empty()) {
        if (err[0] == 'W' && err[1] == 'A' && err[2] == 'R') {
            std::cerr << "tinyobjloader: " << err << std::endl;
        }
        else {
            throw std::logic_error("tinyobjloader: " + err);
        }
    }

    model::attrib_flag_t attributes{model::POSITION | import_attribs};


    std::vector<float> vertex_data;
    std::vector<unsigned> triangles;

    GLuint vertex_offset = 0;

    for (auto& shape : shapes) {
        tinyobj::mesh_t& curr_mesh = shape.mesh;
        // prevent MSVC warning due to Win BOOL implementation
        bool has_normals = (import_attribs & model::NORMAL) != 0;
        if(has_normals) {
            // generate normals if necessary
            if (curr_mesh.normals.empty()) {
                generate_normals(curr_mesh);
            }
        }

        bool has_uvs = (import_attribs & model::TEXCOORD) != 0;
        if(has_uvs) {
            if (curr_mesh.texcoords.empty()) {
                has_uvs = false;
                attributes ^= model::TEXCOORD;
                std::cerr << "Shape has no texcoords" << std::endl;
            }
        }

        bool has_tangents = import_attribs & model::TANGENT;
        std::vector<glm::vec3> tangents;
        if (has_tangents) {
            if (!has_uvs) {
                has_tangents = false;
                attributes ^= model::TANGENT;
                std::cerr << "Shape has no texcoords" << std::endl;
            }
            else {
                tangents = generate_tangents(curr_mesh);
            }
        }

        // push back vertex attributes
        for (unsigned i = 0; i < curr_mesh.positions.size() / 3; ++i) {
            vertex_data.push_back(curr_mesh.positions[i * 3]);
            vertex_data.push_back(curr_mesh.positions[i * 3 + 1]);
            vertex_data.push_back(curr_mesh.positions[i * 3 + 2]);

            if (has_normals) {
                vertex_data.push_back(curr_mesh.normals[i * 3]);
                vertex_data.push_back(curr_mesh.normals[i * 3 + 1]);
                vertex_data.push_back(curr_mesh.normals[i * 3 + 2]);
            }

            if (has_uvs) {
                vertex_data.push_back(curr_mesh.texcoords[i * 2]);
                vertex_data.push_back(curr_mesh.texcoords[i * 2 + 1]);
            }
            if (has_tangents) {
                vertex_data.push_back(tangents[i].x);
                vertex_data.push_back(tangents[i].y);
                vertex_data.push_back(tangents[i].z);
            }
        }

        // add triangles
        for (unsigned i = 0; i < curr_mesh.indices.size(); ++i) {
            triangles.push_back(vertex_offset + curr_mesh.indices[i]);
        }

        vertex_offset += GLuint(curr_mesh.positions.size() / 3);
    }

    return model{vertex_data, attributes, triangles};
}
Exemplo n.º 5
0
void a2estatic::load_from_memory(unsigned int object_count_, unsigned int vertex_count_,
								 float3* vertices_, float2* tex_coords_,
								 unsigned int* index_count_, uint3** indices_) {
	filename = "<memory>";
	a2estatic::vertex_count = vertex_count_;
	a2estatic::vertices = vertices_;
	
	a2estatic::tex_coord_count = vertex_count_;
	a2estatic::tex_coords = tex_coords_;
	
	a2estatic::index_count = index_count_;
	a2estatic::indices = indices_;
	a2estatic::tex_indices = indices_;
	normals = new float3[vertex_count];
	binormals = new float3[vertex_count];
	tangents = new float3[vertex_count];
	
	a2estatic::object_count = object_count_;
	min_index = new unsigned int[object_count];
	max_index = new unsigned int[object_count];
	memset(min_index, 0xFF, sizeof(unsigned int)*object_count);
	memset(max_index, 0, sizeof(unsigned int)*object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		if(index_count[i] == 0) {
			min_index[i] = 0;
			max_index[i] = 0;
		}
		for(unsigned int j = 0; j < index_count[i]; j++) {			
			// also get the max/highest and min/lowest index number
			if(tex_indices[i][j].x > max_index[i]) max_index[i] = tex_indices[i][j].x;
			if(tex_indices[i][j].y > max_index[i]) max_index[i] = tex_indices[i][j].y;
			if(tex_indices[i][j].z > max_index[i]) max_index[i] = tex_indices[i][j].z;
			if(tex_indices[i][j].x < min_index[i]) min_index[i] = tex_indices[i][j].x;
			if(tex_indices[i][j].y < min_index[i]) min_index[i] = tex_indices[i][j].y;
			if(tex_indices[i][j].z < min_index[i]) min_index[i] = tex_indices[i][j].z;
		}
	}
	
	delete_sub_bboxes();
	sub_bboxes.resize(object_count);
	
	object_names.clear();
	object_names.resize(object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		object_names[i] = "object #" + to_string(i);
	}
	
	// set this stuff for normal generating
	model_indices = indices;
	model_index_count = index_count;
	
	generate_normals();
	
	// set the actual model data after everything is computed correctly and its final state
	model_indices = indices;
	model_index_count = index_count;
	
	model_vertices = new float3*[object_count];
	model_vertex_count = new unsigned int[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		model_vertices[i] = &vertices[min_index[i]];
		model_vertex_count[i] = (min_index[i] != 0xFFFFFFFF ? max_index[i] - min_index[i] + 1 : 0);
	}
	
	build_bounding_box();
	
	// vertices vbo
	glGenBuffers(1, &vbo_vertices_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
	
	// tex_coords vbo
	glGenBuffers(1, &vbo_tex_coords_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 2 * sizeof(float), tex_coords, GL_STATIC_DRAW);
	
	// normals/binormals/tangents vbo
	glGenBuffers(1, &vbo_normals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_normals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), normals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_binormals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_binormals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), binormals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_tangents_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tangents_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), tangents, GL_STATIC_DRAW);
	
	// indices vbos
	vbo_indices_ids = new GLuint[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		glGenBuffers(1, &vbo_indices_ids[i]);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices_ids[i]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count[i] * 3 * sizeof(unsigned int), indices[i], GL_STATIC_DRAW);
	}
	
	// reset buffer
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	
	// general model setup
	model_setup();
}
Exemplo n.º 6
0
/*! loads a .a2m model file
 *  @param filename the name of the .a2m model file
 *  @param vbo flag that specifies if vertex buffer objects should be used
 */
void a2estatic::load_model(const string& filename_) {
	file_io file(filename_, file_io::OPEN_TYPE::READ_BINARY);
	if(!file.is_open()) {
		return;
	}
	filename = filename_;

	// get type and name
	char* file_type = new char[9];
	file.get_block(file_type, 8);
	file_type[8] = 0;

	if(strcmp(file_type, "A2EMODEL") != 0) {
		log_error("non supported file type for %s: %s!", filename, file_type);
		delete [] file_type;
		file.close();
		return;
	}
	delete [] file_type;
	
	// get model version
	unsigned int version = file.get_uint();
	if(version != A2M_VERSION) {
		log_error("wrong model file version %u - should be %u!", version, A2M_VERSION);
		file.close();
		return;
	}

	// get model type and abort if it's not 0x00 or 0x02
	auto mtype = file.get_char();
	if(mtype != 0x00 && mtype != 0x02) {
		log_error("non supported model type: %u!", (unsigned int)(mtype & 0xFF));
		file.close();
		return;
	}

	if(mtype == 0x02) collision_model = true;

	vertex_count = file.get_uint();
	tex_coord_count = file.get_uint();
	vertices = new float3[vertex_count];
	normals = new float3[vertex_count];
	binormals = new float3[vertex_count];
	tangents = new float3[vertex_count];
	tex_coords = new float2[tex_coord_count];

	for(unsigned int i = 0; i < vertex_count; i++) {
		vertices[i].x = file.get_float();
		vertices[i].y = file.get_float();
		vertices[i].z = file.get_float();
	}
	for(unsigned int i = 0; i < tex_coord_count; i++) {
		tex_coords[i].x = file.get_float();
		tex_coords[i].y = 1.0f - file.get_float();
	}

	object_count = file.get_uint();
	delete_sub_bboxes();
	sub_bboxes.resize(object_count);

	object_names.clear();
	object_names.resize(object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		file.get_terminated_block(object_names[i], 0xFF);
	}

	indices = new uint3*[object_count];
	tex_indices = new uint3*[object_count];
	index_count = new unsigned int[object_count];
	min_index = new unsigned int[object_count];
	max_index = new unsigned int[object_count];
	memset(min_index, 0xFF, sizeof(unsigned int)*object_count);
	memset(max_index, 0, sizeof(unsigned int)*object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		index_count[i] = file.get_uint();
		indices[i] = new uint3[index_count[i]];
		tex_indices[i] = new uint3[index_count[i]];
		for(unsigned int j = 0; j < index_count[i]; j++) {
			indices[i][j].x = file.get_uint();
			indices[i][j].y = file.get_uint();
			indices[i][j].z = file.get_uint();
		}
		for(unsigned int j = 0; j < index_count[i]; j++) {
			tex_indices[i][j].x = file.get_uint();
			tex_indices[i][j].y = file.get_uint();
			tex_indices[i][j].z = file.get_uint();
		}
	}

	if(collision_model) {
		col_vertex_count = file.get_uint();
		col_vertices = new float3[col_vertex_count];
		for(unsigned int i = 0; i < col_vertex_count; i++) {
			col_vertices[i].x = file.get_float();
			col_vertices[i].y = file.get_float();
			col_vertices[i].z = file.get_float();
		}

		col_index_count = file.get_uint();
		col_indices = new uint3[col_index_count];
		for(unsigned int i = 0; i < col_index_count; i++) {
			col_indices[i].x = file.get_uint();
			col_indices[i].y = file.get_uint();
			col_indices[i].z = file.get_uint();
		}
	}

	file.close();
	
	// set this stuff for normal generating
	model_indices = indices;
	model_index_count = index_count;

	generate_normals();
	reorganize_model_data();
	
	// set the actual model data after everything is computed correctly and its final state
	model_indices = indices;
	model_index_count = index_count;
	
	model_vertices = new float3*[object_count];
	model_tex_coords = new float2*[object_count];
	model_vertex_count = new unsigned int[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		model_vertices[i] = &vertices[min_index[i]];
		model_tex_coords[i] = &tex_coords[min_index[i]];
		model_vertex_count[i] = max_index[i] - min_index[i] + 1;
	}

	build_bounding_box();
	
	// vertices vbo
	glGenBuffers(1, &vbo_vertices_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
	
	// tex_coords vbo
	glGenBuffers(1, &vbo_tex_coords_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 2 * sizeof(float), tex_coords, GL_STATIC_DRAW);
	
	// normals/binormals/tangents vbo
	glGenBuffers(1, &vbo_normals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_normals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), normals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_binormals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_binormals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), binormals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_tangents_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tangents_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), tangents, GL_STATIC_DRAW);
	
	// indices vbos
	vbo_indices_ids = new GLuint[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		glGenBuffers(1, &vbo_indices_ids[i]);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices_ids[i]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count[i] * 3 * sizeof(unsigned int), indices[i], GL_STATIC_DRAW);
	}
	
	// reset buffer
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	
	// general model setup
	model_setup();
}