示例#1
0
int32_t drn_open(drn_t * cache, const char * filename, int mode)
{
    int fd = OPEN(filename, OPEN_MODE);
    if (fd <=0)
    {
        return -1;
    }
    cache->fd = fd;
    cache->mmap_size = drn_fsize(fd);
    cache->mode = mode;
    if (mode == DRN_READ_NOLOAD)
    {
        uint64_t i;
        size_t bytes;
        drn_desc_t hashes_desc;
        drn_map_container_t * map_containers;

        cache->mmap_start = 0;
        cache->data = 0;
        cache->header = ALLOCATE(sizeof(drn_header_container_t));
        bytes = READ(fd, cache->header, sizeof(drn_header_container_t));
        assert(bytes == sizeof(drn_header_container_t));
        if (drn_get_version(cache) != DRN_WRITER_VERSION)
            return 1;
        cache->descriptors = ALLOCATE(cache->header->chunk_count * sizeof(drn_desc_t));
        LSEEK(fd, cache->header->index_offset, SEEK_SET);
        bytes = READ(fd, cache->descriptors, READ_COUNT_CAST ((size_t) cache->header->chunk_count) * sizeof(drn_desc_t));
        assert(bytes == cache->header->chunk_count * sizeof(drn_desc_t));

        hashes_desc =  drn_get_desc(cache, cache->header->maps_chunk_id);
        cache->map_count = hashes_desc.size / sizeof(drn_map_container_t);
        cache->maps = ALLOCATE(sizeof(drn_map_t) * (size_t) cache->map_count);
        map_containers = ALLOCATE(hashes_desc.size);
        drn_read_chunk(cache, cache->header->maps_chunk_id, map_containers);
        for (i = 0; i < cache->map_count; ++i)
        {
            drn_desc_t d;
            const drn_map_container_t * c = map_containers + i;
            drn_map_t * h = cache->maps + i;

            h->hash = ALLOCATE(drn_get_desc(cache, c->hash_chunk_id).size);
            drn_read_chunk(cache, c->hash_chunk_id, (void *) h->hash);
            h->name = ALLOCATE(drn_get_desc(cache, c->name_chunk_id).size);
            drn_read_chunk(cache, c->name_chunk_id, (void *) h->name);
            d = drn_get_desc(cache, c->descriptors_chunk_id);
            h->chunk_count = d.size / sizeof(drn_hash_desc_t);
            h->descriptors = ALLOCATE(d.size);
            drn_read_chunk(cache, c->descriptors_chunk_id, (void *) h->descriptors);
            h->value_strings = ALLOCATE(drn_get_desc(cache, c->value_strings_chunk_id).size);
            drn_read_chunk(cache, c->value_strings_chunk_id, (void *)h->value_strings);
        }
        FREE(map_containers);
    }
    else
    {
        uint64_t i;
        drn_desc_t maps_desc;
        drn_map_container_t * map_containers;

        if (mode == DRN_READ_MMAP)
        {
#ifdef _MSC_VER
			wchar_t * w_filename;
			size_t bytes;

			CLOSE(fd);
			w_filename = ALLOCATE((strlen(filename)+1) * sizeof(wchar_t));
			bytes = mbstowcs(w_filename, filename, strlen(filename)+1);
			//cache->w_fhandle = CreateFile(L"test.drn", GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
			cache->w_fhandle = CreateFile(w_filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
			FREE(w_filename);
			if ((int) cache->w_fhandle  == HFILE_ERROR)
			{
				DWORD err = GetLastError();
				printf("ERROR %Ld\n", err);
				return -1;
			}
			cache->w_mhandle = CreateFileMapping(cache->w_fhandle, NULL, PAGE_READONLY, 0, 0, NULL);
			if (cache->w_mhandle  == NULL)
			{
				DWORD err = GetLastError();
				return -1;
			}
			cache->mmap_start = MapViewOfFile(cache->w_mhandle, FILE_MAP_READ, 0, 0, (size_t) cache->mmap_size);
			if (cache->mmap_start  == NULL)
			{
				DWORD err = GetLastError();
				return -1;
			}
#else
            cache->mmap_start = mmap(0, cache->mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
			CLOSE(fd);
#endif
        }
        else if (mode == DRN_READ_LOAD)
        {
            size_t bytes;

            cache->mmap_start = ALLOCATE(cache->mmap_size);
            bytes = READ(fd, cache->mmap_start, READ_COUNT_CAST (size_t) cache->mmap_size);
            assert(bytes == cache->mmap_size);
			CLOSE(fd);
        }
        cache->data = (char *) cache->mmap_start + sizeof(drn_header_container_t);
        cache->header = (drn_header_container_t *) cache->mmap_start;
        if (drn_get_version(cache) != DRN_WRITER_VERSION)
            return 1;
        cache->descriptors = (drn_desc_t *) ((char *)cache->mmap_start + cache->header->index_offset);
        maps_desc =  drn_get_desc(cache, cache->header->maps_chunk_id);
        cache->map_count = maps_desc.size / sizeof(drn_map_container_t);
        map_containers = (drn_map_container_t *) drn_get_chunk(cache, cache->header->maps_chunk_id);
        cache->maps = ALLOCATE(sizeof(drn_map_t) * (size_t) cache->map_count);
        for (i = 0; i < cache->map_count; ++i)
        {
            drn_desc_t d;
            const drn_map_container_t * c = map_containers + i;
            drn_map_t * h = cache->maps + i;

            h->hash =  drn_get_chunk(cache, c->hash_chunk_id);
            h->name =  drn_get_chunk(cache, c->name_chunk_id);
            d = drn_get_desc(cache, c->descriptors_chunk_id);
            h->chunk_count = d.size / sizeof(drn_hash_desc_t);
            h->descriptors =  drn_get_chunk(cache, c->descriptors_chunk_id);
            h->value_strings =  drn_get_chunk(cache, c->value_strings_chunk_id);
        }
    }
    return 0;
}
size_t loadInMemory(std::vector<Chunk>& memory, bool* loadedLeaf, Leaf l, double distance, uint16_t nbSub_lvl2, size_t freeMemory){
	drn_t cache;
	
	/* check if we can load the leaf - enough size in the memory */
	uint32_t lengthVoxelArray = nbSub_lvl2*nbSub_lvl2*nbSub_lvl2;
	uint32_t leafBytesSize = lengthVoxelArray*VOXELDATA_BYTES_SIZE + l.nbVertices_lvl2*3*sizeof(double);
	//~ std::cout<<"//-> LeafBytesSize : "<<leafBytesSize<<std::endl;
	while(leafBytesSize > freeMemory && memory.size()>0){
		freeMemory += freeInMemory(memory, loadedLeaf);
	}
	
	/* load the voxel data */
	uint32_t test_cache = drn_open(&cache, "./voxels_data/voxel_intersec_1.data", DRN_READ_NOLOAD);
	if(test_cache <0){ throw std::runtime_error("unable to open data file"); }
	
	VoxelData* voxArray = NULL;
	voxArray = new VoxelData[lengthVoxelArray];
	test_cache = drn_read_chunk(&cache, 2*l.id + CONFIGCHUNK_OFFSET, voxArray);
	if(test_cache <0){ throw std::runtime_error("unable to read data file"); }
	
	test_cache = drn_close(&cache);
	if(test_cache <0){ throw std::runtime_error("unable to close data file"); }
	
	/* load the mesh */
	test_cache = drn_open(&cache, "./voxels_data/voxel_intersec_1.data", DRN_READ_MMAP);
	if(test_cache <0){ throw std::runtime_error("unable to open data file in MMAP mode"); }
	
	const void* pMesh = drn_get_chunk(&cache, 2*l.id + 1 + CONFIGCHUNK_OFFSET);
	if(NULL == pMesh){ throw std::runtime_error("unable to get a chunk pointer"); }
	
	GLuint meshVBO = 0;
	glGenBuffers(1, &meshVBO);
	glBindBuffer(GL_ARRAY_BUFFER, meshVBO);
		glBufferData(GL_ARRAY_BUFFER, l.nbVertices_lvl2*sizeof(Vertex), pMesh, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	
	test_cache = drn_close(&cache);
	if(test_cache <0){ throw std::runtime_error("unable to close data file"); }
	
	/* setting the mesh */
	GLuint meshVAO = 0;
	glGenVertexArrays(1, &meshVAO);
	glBindVertexArray(meshVAO);
		glEnableVertexAttribArray(POSITION_LOCATION);
		glEnableVertexAttribArray(NORMAL_LOCATION);
		glEnableVertexAttribArray(BENDING_LOCATION);
		glEnableVertexAttribArray(DRAIN_LOCATION);
		glEnableVertexAttribArray(GRADIENT_LOCATION);
		glEnableVertexAttribArray(SURFACE_LOCATION);
		glBindBuffer(GL_ARRAY_BUFFER, meshVBO);
			glVertexAttribPointer(POSITION_LOCATION, 3, GL_DOUBLE, GL_FALSE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(0));
			glVertexAttribPointer(NORMAL_LOCATION, 3, GL_DOUBLE, GL_FALSE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(3*sizeof(GLdouble)));
			glVertexAttribPointer(BENDING_LOCATION, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(6*sizeof(GLdouble)));
			glVertexAttribPointer(DRAIN_LOCATION, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(6*sizeof(GLdouble)+sizeof(GLfloat)));
			glVertexAttribPointer(GRADIENT_LOCATION, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(6*sizeof(GLdouble)+2*sizeof(GLfloat)));
			glVertexAttribPointer(SURFACE_LOCATION, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(6*sizeof(GLdouble)+3*sizeof(GLfloat)));
		glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
	
	//add the new chunk to the vector
	Chunk newChunk;
	newChunk.voxels = voxArray;
	newChunk.pos = l.pos;
	newChunk.idxLeaf = l.id;
	newChunk.d = distance;
	newChunk.vao = meshVAO;
	newChunk.vbo = meshVBO;
	newChunk.byteSize = leafBytesSize;
	memory.push_back(newChunk);
	
	//~ std::cout<<"//-> Leaf "<<l.id<<" loaded."<<std::endl;
	loadedLeaf[l.id] = true;
	freeMemory -= leafBytesSize;
	return freeMemory;
}