/** * * @author OLiver */ void Minimap::CreateMapTexture(const void *param) { map.DeleteTexture(); if(!param) return; /// Buffer für die Daten erzeugen unsigned char *buffer = new unsigned char[map_width * 2 * map_height * 4]; for(MapCoord y = 0;y<map_height;++y) { for(MapCoord x = 0;x<map_width;++x) { // Die 2. Terraindreiecke durchgehen for(unsigned t = 0;t<2;++t) { unsigned color = CalcPixelColor(param,x,y,t); unsigned pos = y*map_width*4*2+(x*4*2+t*4+(y&1)*4)%(map_width*4*2); buffer[pos+2] = GetRed(color); buffer[pos+1] = GetGreen(color); buffer[pos] = GetBlue(color); buffer[pos+3] = GetAlpha(color); } } } map.setFilter(GL_LINEAR); map.create(map_width*2, map_height, buffer, map_width*2, map_height, libsiedler2::FORMAT_RGBA, LOADER.GetPaletteN("pal5")); delete [] buffer; }
/** * Additional stuff we need to do before drawing (in this case: update the map) */ void IngameMinimap::BeforeDrawing() { // Ab welcher Knotenanzahl (Teil der Gesamtknotenanzahl) die Textur komplett neu erstellt werden soll static const unsigned MAX_NODES_UPDATE_DENOMINATOR = 2; // (2 = 1/2, 3 = 1/3 usw.) if(!nodesToUpdate.empty()) { // Komplette Textur neu erzeugen, weil es zu viele Knoten sind? if(nodesToUpdate.size() >= map_width * map_height / MAX_NODES_UPDATE_DENOMINATOR) { // Ja, alles neu erzeugen UpdateAll(); for(MapPoint p(0, 0); p.y < map_height; p.y++) for(p.x = 0; p.x < map_width; p.x++) nodes_updated[GetMMIdx(p)] = false; } else { // Entsprechende Pixel updaten for(std::vector<MapPoint>::iterator it = nodesToUpdate.begin(); it != nodesToUpdate.end(); ++it) { for(unsigned t = 0; t < 2; ++t) { unsigned color = CalcPixelColor(*it, t); map.tex_setPixel((it->x * 2 + t + (it->y & 1)) % (map_width * 2), it->y, GetRed(color), GetGreen(color), GetBlue(color), GetAlpha(color)); } nodes_updated[GetMMIdx(*it)] = false; } } this->nodesToUpdate.clear(); } }
/** * Alle Punkte Updaten, bei denen das DrawnObject * gleich dem übergebenen drawn_object ist * * @author OLiver */ void IngameMinimap::UpdateAll(const DrawnObject drawn_object) { // Gesamte Karte neu berechnen for(MapCoord y = 0;y<map_height;++y) { for(MapCoord x = 0;x<map_width;++x) { for(unsigned t = 0;t<2;++t) { if(dos[y*map_width+x] == drawn_object || // das gewünschte Objekt (drawn_object == DO_PLAYER && // bei DO_PLAYER auf evtl. nicht gezeichnete Häuser und Straßen ((dos[y*map_width+x] == DO_BUILDING && !houses) || // achten, da dort auch nur das Player- (dos[y*map_width+x] == DO_ROAD && !roads)))) // Territorium zu sehen ist! { unsigned color = CalcPixelColor(&gwv,x,y,t); map.tex_setPixel((x*2+t+(y&1))%(map_width*2),y,GetRed(color),GetGreen(color), GetBlue(color),GetAlpha(color)); } } } } }
/** * Zusätzliche Dinge, die die einzelnen Maps vor dem Zeichenvorgang zu tun haben * in dem Falle: Karte aktualisieren * * @author OLiver */ void IngameMinimap::BeforeDrawing() { // Ab welcher Knotenanzahl (Teil der Gesamtknotenanzahl) die Textur komplett neu erstellt werden soll static const unsigned MAX_NODES_UPDATE_DENOMINATOR = 2; // (2 = 1/2, 3 = 1/3 usw.) // Überhaupt Änderungen nötig? if(nodes_updated_list.size()) { // Komplette Textur neu erzeugen, weil es zu viele Knoten sind? if(nodes_updated_list.size() >= map_width*map_height/MAX_NODES_UPDATE_DENOMINATOR) { // Ja, alles neu erzeugen UpdateAll(); // Alles Aktualisierungen wieder zurücksetzen for(MapCoord y = 0;y<map_height;++y) { for(MapCoord x = 0;x<map_width;++x) nodes_updated[y*map_width+x] = false; } } else { // Entsprechende Pixel updaten for(list<Node>::iterator it = nodes_updated_list.begin();it.valid();++it) { for(unsigned t = 0;t<2;++t) { unsigned color = CalcPixelColor(&gwv,it->x,it->y,t); map.tex_setPixel((it->x*2+t+(it->y&1))%(map_width*2),it->y,GetRed(color),GetGreen(color), GetBlue(color),GetAlpha(color)); } // Jetzt muss er nicht mehr geändert werden nodes_updated[it->y*map_width+it->x] = false; } } this->nodes_updated_list.clear(); } }
/** * Update all nodes with the given drawn object */ void IngameMinimap::UpdateAll(const DrawnObject drawn_object) { // Gesamte Karte neu berechnen for(MapCoord y = 0; y < map_height; ++y) { for(MapCoord x = 0; x < map_width; ++x) { MapPoint pt(x, y); for(unsigned t = 0; t < 2; ++t) { if(dos[GetMMIdx(pt)] == drawn_object || (drawn_object == DO_PLAYER && // for DO_PLAYER check for not drawn buildings or roads as there is only the player territory visible ((dos[GetMMIdx(pt)] == DO_BUILDING && !houses) || (dos[GetMMIdx(pt)] == DO_ROAD && !roads)))) { unsigned color = CalcPixelColor(pt, t); map.tex_setPixel((x * 2 + t + (y & 1)) % (map_width * 2), y, GetRed(color), GetGreen(color), GetBlue(color), GetAlpha(color)); } } } } }