예제 #1
0
GraphicStore::GraphicStore(CL_GraphicContext &gc) : shader_bumpmap(gc)
{
#ifdef _DEBUG
	//struct aiLogStream stream;
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
	//aiAttachLogStream(&stream);
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
	//aiAttachLogStream(&stream);
#endif

	store = aiCreatePropertyStore();
	aiSetImportPropertyFloat(store, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,89.53f);

}
예제 #2
0
GraphicStore::GraphicStore(GraphicContext &gc) : shader_color(gc)
{
#ifdef _DEBUG
	//struct aiLogStream stream;
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
	//aiAttachLogStream(&stream);
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
	//aiAttachLogStream(&stream);
#endif

#if defined(I_LOVE_ASSIMP_AND_PRECOMPILED_IT)
	store = aiCreatePropertyStore();
	aiSetImportPropertyFloat(store, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,89.53f);
#endif

}
예제 #3
0
// The start of the Application
int App::start(const std::vector<CL_String> &args)
{
	quit = false;
    CL_GL1WindowDescription desc;

	desc.set_title("ClanLib Object 3D Example");
	desc.set_size(CL_Size(640, 480), true);
	desc.set_multisampling(4);
	desc.set_depth_size(16);

	CL_DisplayWindow window(desc);

#ifdef _DEBUG
	//struct aiLogStream stream;
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
	//aiAttachLogStream(&stream);
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
	//aiAttachLogStream(&stream);
#endif

	// Connect the Window close event
	CL_Slot slot_quit = window.sig_window_close().connect(this, &App::on_window_close);

	// Connect a keyboard handler to on_key_up()
	CL_Slot slot_input_up = (window.get_ic().get_keyboard()).sig_key_up().connect(this, &App::on_input_up);

	// Get the graphic context
	CL_GraphicContext gc = window.get_gc();

#ifdef USE_OPENGL_1
    CL_GraphicContext_GL1 gc_gl1 = gc;
#endif

	// Prepare the display
	gc.set_map_mode(cl_user_projection);

	CL_PolygonRasterizer polygon_rasterizer;
	polygon_rasterizer.set_culled(true);
	polygon_rasterizer.set_face_cull_mode(cl_cull_back);
	polygon_rasterizer.set_front_face(cl_face_side_clockwise);
	gc.set_polygon_rasterizer(polygon_rasterizer);

	CL_BufferControl buffer_control;
	buffer_control.enable_depth_test(true);
	buffer_control.set_depth_compare_function(cl_comparefunc_lequal);
	buffer_control.enable_depth_write(true);
	gc.set_buffer_control(buffer_control);

#ifdef USE_OPENGL_1
	// Set the lights
	CL_LightModel_GL1 light_model;
	light_model.enable_lighting(true);
	light_model.set_flat_shading(false);
	light_model.set_scene_ambient_light(CL_Colorf(0.2f, 0.2f, 0.2f, 1.0f));
	gc_gl1.set_light_model(light_model);

	CL_LightSource_GL1 light_distant;
	light_distant.set_spot_cutoff(180.0f);
	light_distant.set_diffuse_intensity(CL_Colorf(1.0f, 1.0f, 1.0f, 1.0f));
	light_distant.set_position(CL_Vec4f(0.0f, -2.0f, 30.0f, 0.0f).normalize3());
	gc_gl1.set_light(0, light_distant);

	cl1Enable(GL_NORMALIZE);
#endif

#ifdef USE_OPENGL_2
    Shader shader(gc);
#endif

	// Create the objects

	aiSetImportPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,89.53f);

	const struct aiScene* scene_teapot = aiImportFile("../Clan3D/Resources/teapot.dae",aiProcessPreset_TargetRealtime_MaxQuality);
	if (!scene_teapot)
		throw CL_Exception("Cannot load the teapot model");

	const struct aiScene* scene_clanlib = aiImportFile("../Clan3D/Resources/clanlib.dae",aiProcessPreset_TargetRealtime_MaxQuality);
	if (!scene_clanlib)
		throw CL_Exception("Cannot load the clanlib model");

	const struct aiScene* scene_tuxball = aiImportFile("../Clan3D/Resources/tux_ball.dae",aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_FlipUVs);
	if (!scene_tuxball)
		throw CL_Exception("Cannot load the tux ball model");

	// Load the texture
	CL_Texture tux(gc, "../Clan3D/Resources/tux.png");

	float angle = 0.0f;
	// Run until someone presses escape
	while (!quit)
	{

		CL_Mat4f perp = CL_Mat4f::perspective(45.0f, ((float) gc.get_width()) / ((float) gc.get_height()), 0.1f, 1000.0f);
		gc.set_projection(perp);

		gc.clear(CL_Colorf::black);
		gc.clear_depth(1.0f);

		angle += 1.0f;
		if (angle >= 360.0f)
			angle -= 360.0f;


#ifdef USE_OPENGL_2
        shader.Set(gc);
        shader.Use(gc);
#else
        gc.set_program_object(cl_program_color_only);
#endif

		CL_PrimitivesArray prim_array(gc);

		gc.set_modelview(CL_Mat4f::identity());
		gc.mult_scale(1.0f,1.0f, -1.0f);	// So +'ve Z goes into the screen
		gc.mult_translate(0.0f, 0.0f, 2.0f);
		gc.mult_rotate(CL_Angle(angle, cl_degrees), 0.0f, 1.0f, 0.0f, false);

		gc.push_modelview();
		recursive_render(gc, scene_teapot, scene_teapot->mRootNode, false);
		gc.pop_modelview();

		gc.push_modelview();
		gc.mult_scale(0.5f, 0.5f, 0.5f);
		gc.mult_translate(0.0f, -0.5f, 0.0f);
		recursive_render(gc, scene_clanlib, scene_clanlib->mRootNode, false);
		gc.pop_modelview();

#ifdef USE_OPENGL_2
        shader.Set(gc, 0);
        shader.Use(gc);
#else
        gc.set_program_object(cl_program_single_texture);
#endif

		gc.set_texture(0, tux);
 		gc.set_modelview(CL_Mat4f::identity());
		gc.mult_scale(1.0f,1.0f, -1.0f);	// So +'ve Z goes into the screen
		gc.mult_translate(0.7f, 0.5f, 2.0f);
		gc.mult_scale(0.05f, 0.05f, 0.05f);
		gc.mult_rotate(CL_Angle(angle * 4.0f, cl_degrees), 0.0f, 1.0f, 0.0f, false);
		recursive_render(gc, scene_tuxball, scene_tuxball->mRootNode, true);
		gc.reset_texture(0);

		gc.reset_program_object();
		
		// Flip the display, showing on the screen what we have drawed
		// since last call to flip()
		window.flip(1);

		// This call processes user input and other events
		CL_KeepAlive::process();
	}

	aiReleaseImport(scene_tuxball);
	aiReleaseImport(scene_clanlib);
	aiReleaseImport(scene_teapot);
	aiDetachAllLogStreams();

	return 0;
}
예제 #4
0
bool opMeshBaker::LoadAndBake(const char* input_filename, const char* output_filename) {

  aiSetImportPropertyFloat("AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE", 80.0f);
  aiSetImportPropertyInteger("AI_CONFIG_PP_RVC_FLAGS", aiComponent_NORMALS); // throw away normals (generate them)

  /* generate a mesh from the input file:
    Calculate tangents and bitangents
    Triangulate
    Weld vertices together
    Sort by primitive type
    Generate smooth normals
    Fix infacing normals
    Generate UV coords
    optimize the mesh
  */
  const aiScene* scene = aiImportFile(input_filename, 
    aiProcess_CalcTangentSpace | 
    aiProcess_Triangulate      |
    aiProcess_JoinIdenticalVertices  |
    aiProcess_SortByPType |
    aiProcess_GenSmoothNormals |
    aiProcess_FixInfacingNormals |
    aiProcess_GenUVCoords |
    aiProcess_ConvertToLeftHanded |
    aiProcess_OptimizeMeshes);

  if(scene == NULL) {
    palPrintf("Could not open understand input file: %s\n", input_filename);
    return false;
  }

  palPrintf("Baking %s to %s\n", input_filename, output_filename);

  // we only support 1:1 mapping between input file meshes and output file meshes
  palAssert(scene->mNumMeshes == 1);

  aiMesh* mesh = scene->mMeshes[0];

  // we expect faces
  palAssert(mesh->HasFaces() == true);
  
  // we expect vertex positions
  palAssert(mesh->HasPositions() == true);
  //printf("Has vertex positions.\n");
  // we expect normals
  palAssert(mesh->HasNormals() == true);
  //printf("Has vertex normal.\n");
  // we only support triangular meshes
  palAssert(mesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE);

  palFile baked;
  int r;
  r = baked.OpenForWritingTruncate(output_filename);
  if (r != 0) {
    palPrintf("Could not open output file: %s\n", output_filename);
    return false;
  }

  palArray<opBakedMeshArrayHeader> mesh_arrays;
  mesh_arrays.SetAllocator(g_DefaultHeapAllocator);
  palArray<void*> mesh_arrays_data;
  mesh_arrays_data.SetAllocator(g_DefaultHeapAllocator);
  palArray<opBakedMeshAttributeHeader> mesh_attributes;
  mesh_attributes.SetAllocator(g_DefaultHeapAllocator);

  opBakedMeshArrayHeader mesh_array;

  // index array
  mesh_array.array_type = OP_BAKED_MESH_INDEX_ARRAY;

  // pack index data tightly
  uint32_t num_indices = mesh->mNumFaces * 3;
  void* index_array_data = NULL;
  if (num_indices < 0xffff) {
    mesh_array.index_type = kOpRenderDeviceFormatUintR16;
    mesh_array.length_in_bytes = num_indices * sizeof(uint16_t);
    uint16_t* indices = (uint16_t*)g_DefaultHeapAllocator->Allocate(mesh_array.length_in_bytes);
    palAssert(indices);
    index_array_data = indices;
    for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
      *indices = mesh->mFaces[i].mIndices[0];
      indices++;
      *indices = mesh->mFaces[i].mIndices[1];
      indices++;
      *indices = mesh->mFaces[i].mIndices[2];
      indices++;
    }
  } else {
    mesh_array.index_type = kOpRenderDeviceFormatUintR32;
    mesh_array.length_in_bytes = num_indices * sizeof(uint32_t);
    uint32_t* indices = (uint32_t*)g_DefaultHeapAllocator->Allocate(mesh_array.length_in_bytes);
    palAssert(indices);
    index_array_data = indices;
    for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
      *indices = mesh->mFaces[i].mIndices[0];
      indices++;
      *indices = mesh->mFaces[i].mIndices[1];
      indices++;
      *indices = mesh->mFaces[i].mIndices[2];
      indices++;
    }
  }
  printf("Indexed triangle mesh: %d triangles (%d bytes in index data)\n", num_indices/3, mesh_array.length_in_bytes);

  mesh_arrays_data.push_back(index_array_data);
  mesh_arrays.push_back(mesh_array);

  // pack into single interleaved array
  {
    uint32_t offset = 0;

    opBakedMeshAttributeHeader mesh_component;
    
    // position
    mesh_component.attribute_type = OP_BAKED_MESH_ATTRIBUTE_VERTICES;
    mesh_component.element_type = kOpRenderDeviceFormatFloat32x3;
    mesh_component.offset_in_bytes = 0;
    mesh_component.array_index = 1;

    mesh_attributes.push_back(mesh_component);

    offset += 3 * sizeof(float);

    // normals
    mesh_component.attribute_type = OP_BAKED_MESH_ATTRIBUTE_NORMALS;
    mesh_component.element_type = kOpRenderDeviceFormatFloat32x3;
    mesh_component.offset_in_bytes = offset;
    mesh_component.array_index = 1;

    mesh_attributes.push_back(mesh_component);

    offset += 3 * sizeof(float);

    if (mesh->HasTangentsAndBitangents()) {
      // tangents
      mesh_component.attribute_type = OP_BAKED_MESH_ATTRIBUTE_TANGENTS;
      mesh_component.element_type = kOpRenderDeviceFormatFloat32x3;
      mesh_component.offset_in_bytes = offset;
      mesh_component.array_index = 1;

      mesh_attributes.push_back(mesh_component);

      offset += 3 * sizeof(float);

      // bitangents
      mesh_component.attribute_type = OP_BAKED_MESH_ATTRIBUTE_BITANGENTS;
      mesh_component.element_type = kOpRenderDeviceFormatFloat32x3;
      mesh_component.offset_in_bytes = offset;
      mesh_component.array_index = 1;

      mesh_attributes.push_back(mesh_component);

      offset += 3 * sizeof(float);

      printf("Has vertex tangents and bitangents.\n");
    }
    
    // texture coordinates 0..3
    for (unsigned int i = 0; i < mesh->GetNumUVChannels(); i++) {
      mesh_component.attribute_type = (opBakedMeshAttributeType)(OP_BAKED_MESH_ATTRIBUTE_TEXCOORDS0 + i);
      mesh_component.element_type = TextureElementType(mesh->mNumUVComponents[i]);
      mesh_component.offset_in_bytes = offset;
      mesh_component.array_index = 1;
      printf("Has UV channel %d (%d)\n", i, mesh->mNumUVComponents[i]);
      mesh_attributes.push_back(mesh_component);
      offset += mesh->mNumUVComponents[i] * sizeof(float);
    }

    // fill in the stride between vertices
    for (int i = 0; i < mesh_attributes.GetSize(); i++) {
      mesh_attributes[i].stride_in_bytes = offset;
    }

    mesh_array.array_type = OP_BAKED_MESH_VERTEX_ARRAY;
    mesh_array.length_in_bytes = mesh->mNumVertices * offset;

    printf("%d vertices (%d bytes in vertex data)\n", mesh->mNumVertices, mesh_array.length_in_bytes);

    void* vertex_array_data = g_DefaultHeapAllocator->Allocate(mesh_array.length_in_bytes);
    float* vertex_array_data_f = (float*)vertex_array_data;
    for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
      // positions
      *vertex_array_data_f = mesh->mVertices[i].x;
      vertex_array_data_f++;
      *vertex_array_data_f = mesh->mVertices[i].y;
      vertex_array_data_f++;
      *vertex_array_data_f = mesh->mVertices[i].z;
      vertex_array_data_f++;
      // normals
      *vertex_array_data_f = mesh->mNormals[i].x;
      vertex_array_data_f++;
      *vertex_array_data_f = mesh->mNormals[i].y;
      vertex_array_data_f++;
      *vertex_array_data_f = mesh->mNormals[i].z;
      vertex_array_data_f++;

      if (mesh->HasTangentsAndBitangents()) {
        // tangents
        *vertex_array_data_f = mesh->mTangents[i].x;
        vertex_array_data_f++;
        *vertex_array_data_f = mesh->mTangents[i].y;
        vertex_array_data_f++;
        *vertex_array_data_f = mesh->mTangents[i].z;
        vertex_array_data_f++;
        // bitangents
        *vertex_array_data_f = mesh->mBitangents[i].x;
        vertex_array_data_f++;
        *vertex_array_data_f = mesh->mBitangents[i].y;
        vertex_array_data_f++;
        *vertex_array_data_f = mesh->mBitangents[i].z;
        vertex_array_data_f++;
      }
      
      // texture channels
      for (unsigned int tc = 0; tc < mesh->GetNumUVChannels(); tc++) {
        // texture coordinates
        for (unsigned int st = 0; st < mesh->mNumUVComponents[tc]; st++) {
          //printf("tex[%d] = %f\n", st, mesh->mTextureCoords[tc][i][st]);
          *vertex_array_data_f = mesh->mTextureCoords[tc][i][st];
          vertex_array_data_f++;
        }
      }
    }

    // push data back into arrays
    mesh_arrays_data.push_back(vertex_array_data);
    mesh_arrays.push_back(mesh_array);
  }

  // write data to disk
  opBakedMeshHeader header;
  header.magic = OP_BAKED_MESH_FILE_MAGIC;
  header.attribute_count = mesh_attributes.GetSize();
  header.attribute_offset = sizeof(header);
  header.array_count = mesh_arrays.GetSize();
  header.array_offset = sizeof(header) + sizeof(opBakedMeshAttributeHeader) * mesh_attributes.GetSize();
  baked.Write(&header, sizeof(header));
  for (int i = 0; i < mesh_attributes.GetSize();i++) {
    opBakedMeshAttributeHeader& component_attribute = mesh_attributes[i];
    baked.Write(&component_attribute, sizeof(component_attribute));
  }

  uint32_t array_offset = sizeof(header);
  array_offset += sizeof(opBakedMeshAttributeHeader) * mesh_attributes.GetSize();
  array_offset += sizeof(opBakedMeshArrayHeader) * mesh_arrays.GetSize();

  for (int i = 0; i < mesh_arrays.GetSize(); i++) {
    opBakedMeshArrayHeader& array_header = mesh_arrays[i];
    array_header.offset_in_bytes = array_offset;
    baked.Write(&array_header, sizeof(array_header));
    array_offset += array_header.length_in_bytes;
  }

  for (int i = 0; i < mesh_arrays.GetSize(); i++) {
    baked.Write(mesh_arrays_data[i], mesh_arrays[i].length_in_bytes);
    g_DefaultHeapAllocator->Deallocate(mesh_arrays_data[i]);
  }

  baked.Close();

  aiReleaseImport(scene);

  return true;
}
예제 #5
0
// The start of the Application
int App::start(const std::vector<CL_String> &args)
{
	quit = false;

	CL_OpenGLWindowDescription desc;
	desc.set_title("ClanLib Shadow Example");
	desc.set_size(CL_Size(640, 640), true);
	desc.set_multisampling(4);
	desc.set_depth_size(16);

	CL_DisplayWindow window(desc);

#ifdef _DEBUG
	//struct aiLogStream stream;
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
	//aiAttachLogStream(&stream);
	//stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
	//aiAttachLogStream(&stream);
#endif
	aiSetImportPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,89.53f);

	// Connect the Window close event
	CL_Slot slot_quit = window.sig_window_close().connect(this, &App::on_window_close);

	// Connect a keyboard handler to on_key_up()
	CL_Slot slot_input_up = (window.get_ic().get_keyboard()).sig_key_up().connect(this, &App::on_input_up);

	// Get the graphic context
	CL_GraphicContext gc = window.get_gc();

	GraphicStore graphic_store(gc);
	scene.gs = &graphic_store;

	// Prepare the display
	gc.set_map_mode(cl_user_projection);

	CL_PolygonRasterizer polygon_rasterizer;
	polygon_rasterizer.set_culled(true);
	polygon_rasterizer.set_face_cull_mode(cl_cull_back);
	polygon_rasterizer.set_front_face(cl_face_side_clockwise);
	gc.set_polygon_rasterizer(polygon_rasterizer);

	create_scene(gc);

	CL_FrameBuffer framebuffer(gc);

	CL_Texture new_depth_texture(gc, CL_Size(1024, 1024), cl_depth_component);
	new_depth_texture.set_wrap_mode(cl_wrap_clamp_to_edge, cl_wrap_clamp_to_edge, cl_wrap_clamp_to_edge);
	framebuffer.attach_depth_buffer(new_depth_texture);

	scene.gs->texture_shadow = new_depth_texture;

	camera_angle = 0.0f;

	CL_Font font(gc, "tahoma", 24);

	FramerateCounter framerate_counter;

	unsigned int time_last = CL_System::get_time();
	// Run until someone presses escape
	while (!quit)
	{
		framerate_counter.frame_shown();

		unsigned int time_now = CL_System::get_time();
		time_delta = time_now - time_last;
		time_last = time_now;

		rotate_teapot();
		control_camera();
		update_light(gc);

		calculate_matricies(gc);

		render_from_lightsource(gc, framebuffer);
		render_from_camera(gc, framebuffer);

		gc.set_modelview(CL_Mat4f::identity());
		gc.set_map_mode(cl_map_2d_upper_left);

		CL_String fps(cl_format("%1 fps", framerate_counter.get_framerate()));
		font.draw_text(gc, 16-2, gc.get_height()-16-2, fps, CL_Colorf(0.0f, 0.0f, 0.0f, 1.0f));
		font.draw_text(gc, 16, gc.get_height()-16-2, fps, CL_Colorf(1.0f, 1.0f, 1.0f, 1.0f));

		// Use flip(1) to lock the fps
		window.flip(0);

		// This call processes user input and other events
		CL_KeepAlive::process();
	}
	aiDetachAllLogStreams();
	return 0;
}