void Renderer::draw() { //int dw = al_get_display_width(dpy_); //int dh = al_get_display_height(dpy_); ALLEGRO_TRANSFORM trans; al_identity_transform(&trans); al_compose_transform(&trans, &camera_transform_); al_rotate_transform_3d(&trans, 1.0, 0.0, 0.0, rx_look); setupProjection(&trans); al_identity_transform(&trans); al_use_transform(&trans); getWorldPos(camera_pos_); al_copy_transform(&cur3d_transform_, al_get_current_transform()); glEnable(GL_DEPTH_TEST); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); glEnable(GL_ALPHA_TEST); if(!setShader(SHADER_DEFAULT)) { NBT_Debug("failed to set default shader"); } glBindVertexArray(vao_); resManager_->setAtlasUniforms(); for(auto &it: chunkData_) { ChunkData *cd = it.second; ALLEGRO_TRANSFORM ctrans; al_identity_transform(&ctrans); al_translate_transform_3d(&ctrans, cd->x()*15.0, 0.0, cd->z()*15.0); al_use_transform(&ctrans); cd->draw(&ctrans); } glBindVertexArray(0); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); //drawSelection(); resManager_->unsetAtlasUniforms(); }
ChunkData *ChunkData::Create(Chunk *chunk, ResourceManager *resourceManager) { const uint32_t DATA_VTX_COUNT = MAX_VERTS / MAX_SLICES; CustomVertex *data = (CustomVertex*)malloc(sizeof(CustomVertex) * DATA_VTX_COUNT); if(!data) return nullptr; memset(data, 0, DATA_VTX_COUNT * sizeof(CustomVertex)); uint32_t total_size = 0; // TODO: maybe allow putting more than one section per slice if we end up with more than 16 sections. // currently minecraft only uses 16 sections per chunk. //assert(num_sections <= MAX_SLICES); int32_t x_off = chunk->x() * 16; int32_t z_off = chunk->z() * 16; ChunkData *cdata = new ChunkData(chunk->x(), chunk->z()); CustomVertex *dptr = data; // reset dptr, reuse data memory. for(uint32_t i = 0; i < chunk->sectionCount(); i++) { ChunkSection *section = chunk->getSection(i); if(!section) continue; //NBT_Debug("new section[%i]: %p", i, section); int32_t y = section->y() * 16; //int32_t y = section_y * 16; #ifdef VIEWER_USE_MORE_VBOS dptr = data; total_size = 0; #endif for(int dy = 0; dy < 16; dy++) { for(int dz = 0; dz < 16; dz++) { for(int dx = 0; dx < 16; dx++) { BlockAddress baddr; if(!chunk->getBlockAddress(x_off + dx, y + dy, z_off + dz, &baddr)) { NBT_Debug("failed to find block %i, %i, %i", x_off + dx, y + dy, z_off + dz); assert(nullptr); continue; } //NBT_Debug("block %i,%i,%i: %s", x_off+dx, y+dy, z_off+dz, baddr.toString().c_str()); BlockInfo bi; chunk->getBlockInfo(baddr, &bi); //NBT_Debug("blockInfo: %i:%i:%s", bi.id, bi.data, bi.state_name); Resource::ID rid = resourceManager->getModelVariant(bi); if(rid == Resource::INVALID_ID) { //NBT_Debug("failed to get model %i:%i:%s", bi.id, bi.data, bi.state_name); continue; } //if(bi.id != BLOCK_AIR && bi.id != BLOCK_BARRIER) // NBT_Debug("block:%i:%i %s", bi.id, bi.data, bi.state_name); ResourceModelVariant *var = resourceManager->getModelVariantResource(rid); uint32_t vertex_count = var->getVertexCount(); CustomVertex *verticies = var->getVertexData(); for(uint32_t i = 0; i < vertex_count; i++) { CustomVertex &v = verticies[i], &cv = dptr[i]; float xoff = cdata->x() + dx, yoff = y + dy, zoff = cdata->z() + dz; cv.pos = { v.pos.f1 + xoff, v.pos.f2 + yoff, v.pos.f3 + zoff }; //cv.txcoord = { (v.txcoord.f1 * tx_xfact + tx_x), 1-(v.txcoord.f2 * tx_yfact + tx_y) }; cv.txcoord = { v.txcoord.f1 , 1-v.txcoord.f2 }; // { 0.25 + 0.25 * v.txcoord.f1, 0.25 + 0.25 * v.txcoord.f2 }; //NBT_Debug("tex: %f, %f", cv.txcoord.f1, cv.txcoord.f2); cv.tx_page = v.tx_page; cv.color = v.color; } dptr += vertex_count; total_size += vertex_count; } } } #ifdef VIEWER_USE_MORE_VBOS if(total_size > 0) if(!cdata->fillSlice(section->y(), data, total_size)) NBT_Warn("failed to fill slice %i???", y); #endif } #ifndef VIEWER_USE_MORE_VBOS if(total_size) if(!cdata->fillSlice(0, data, total_size)) NBT_Warn("failed to fill chunk data"); #endif free(data); return cdata; }