void CatapultStone::Draw(const GameWorldView& gwv, const int xoffset, const int yoffset) { // Stein überhaupt zeichnen (wenn Quelle und Ziel nicht sichtbar sind, dann nicht!) if(gwv.GetGameWorldViewer()->GetVisibility(dest_building) != VIS_VISIBLE && gwv.GetGameWorldViewer()->GetVisibility(dest_map) != VIS_VISIBLE) return; int world_width = gwg->GetWidth() * TR_W; int world_height = gwg->GetHeight() * TR_H; if(explode) { // Stein explodierend am Ziel zeichnen LOADER.GetMapImageN(3102 + GAMECLIENT.Interpolate(4, event))-> Draw((dest_x - xoffset + world_width) % world_width, (dest_y - yoffset + world_height) % world_height); } else { // Linear interpolieren zwischen Ausgangs- und Zielpunkt int x = GAMECLIENT.Interpolate(start_x, dest_x, event); int y = GAMECLIENT.Interpolate(start_y, dest_y, event); int whole = int(std::sqrt(double((dest_x - start_x) * (dest_x - start_x) + (dest_y - start_y) * (dest_y - start_y)))); int s = GAMECLIENT.Interpolate(whole , event); double dx = double(s) / double(whole) - 0.5; // Y-Verschiebung ausrechnen, damit die Nullpunkte beim Start- und Endpunkt liegen double y_diff = 0.5 * 0.5; // Verschiebung ausrechnen von Y int diff = int((dx * dx - y_diff) * 200); // Schatten auf linearer Linie zeichnen LOADER.GetMapImageN(3101)->Draw((x - xoffset + world_width) % world_width, (y - yoffset + world_height) % world_height, 0, 0, 0, 0, 0, 0, COLOR_SHADOW); // Stein auf Parabel zeichnen LOADER.GetMapImageN(3100)->Draw((x - xoffset + world_width) % world_width, (y - yoffset + world_height + diff) % world_height); } }
void TerrainRenderer::PrepareWaysPoint(PreparedRoads& sorted_roads, const GameWorldView& gwv, MapPoint t, const PointI& offset) { PointI startPos = PointI(GetTerrain(t)) - gwv.GetOffset() + offset; GameWorldViewer& gwViewer = gwv.GetGameWorldViewer(); Visibility visibility = gwViewer.GetVisibility(t); int totalWidth = gwViewer.GetWidth() * TR_W; int totalHeight = gwViewer.GetHeight() * TR_H; // Wegtypen für die drei Richtungen for(unsigned dir = 0; dir < 3; ++dir) { unsigned char type = gwViewer.GetVisibleRoad(t, dir, visibility); if (!type) continue; MapPoint ta = gwViewer.GetNeighbour(t, 3 + dir); PointI endPos = PointI(GetTerrain(ta)) - gwv.GetOffset() + offset; PointI diff = startPos - endPos; // Gehen wir über einen Kartenrand (horizontale Richung?) if(std::abs(diff.x) >= totalWidth / 2) { if(std::abs(endPos.x - totalWidth - startPos.x) < std::abs(diff.x)) endPos.x -= totalWidth; else endPos.x += totalWidth; } // Und dasselbe für vertikale Richtung if(std::abs(diff.y) >= totalHeight / 2) { if(std::abs(endPos.y - totalHeight - startPos.y) < std::abs(diff.y)) endPos.y -= totalHeight; else endPos.y += totalHeight; } --type; // Wegtypen "konvertieren" switch(type) { case RoadSegment::RT_DONKEY: case RoadSegment::RT_NORMAL: { TerrainType t1 = gwViewer.GetTerrainAround(t, dir + 2); TerrainType t2 = gwViewer.GetTerrainAround(t, dir + 3); // Prüfen, ob Bergwege gezeichnet werden müssen, indem man guckt, ob der Weg einen // Berg "streift" oder auch eine Bergwiese if(TerrainData::IsMountain(t1) || TerrainData::IsMountain(t2)) type = 3; break; } case RoadSegment::RT_BOAT: type = 2; break; } sorted_roads[type].push_back( PreparedRoad(type, startPos, endPos, GetColor(t), GetColor(ta), dir) ); } }
/** * zeichnet den Kartenausschnitt. * * @author OLiver * @author FloSoft */ void TerrainRenderer::Draw(const GameWorldView& gwv, unsigned int* water) { assert(!gl_vertices.empty()); assert(!borders.empty()); /* if ((gwv.GetXOffset() == gwv.terrain_last_xoffset) && (gwv.GetYOffset() == gwv.terrain_last_yoffset) && (gwv.terrain_list != 0) && (GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0) == gwv.terrain_last_global_animation)) { glCallList(gwv.terrain_list); *water = gwv.terrain_last_water; return; } gwv.terrain_last_xoffset = gwv.GetXOffset(); gwv.terrain_last_yoffset = gwv.GetYOffset(); gwv.terrain_last_global_animation = GAMECLIENT.GetGlobalAnimation(4, 5, 4, 0); if (gwv.terrain_list == 0) gwv.terrain_list = glGenLists(1); glNewList(gwv.terrain_list, GL_COMPILE_AND_EXECUTE);*/ // nach Texture in Listen sortieren boost::array< std::vector<MapTile>, TT_COUNT> sorted_textures; boost::array< std::vector<BorderTile>, 5> sorted_borders; PreparedRoads sorted_roads; Point<int> lastOffset(0, 0); // Beim zeichnen immer nur beginnen, wo man auch was sieht for(int y = gwv.GetFirstPt().y; y < gwv.GetLastPt().y; ++y) { unsigned char lastTerrain = 255; unsigned char lastBorder = 255; for(int x = gwv.GetFirstPt().x; x < gwv.GetLastPt().x; ++x) { Point<int> posOffset; MapPoint tP = ConvertCoords(Point<int>(x, y), &posOffset); TerrainType t = gwv.GetGameWorldViewer().GetNode(tP).t1; if(posOffset != lastOffset) lastTerrain = 255; if(t == lastTerrain && tP != MapPoint(0, 0)) ++sorted_textures[t].back().count; else { MapTile tmp(GetTriangleIdx(tP), posOffset); sorted_textures[t].push_back(tmp); lastTerrain = t; } t = gwv.GetGameWorldViewer().GetNode(tP).t2; if(t == lastTerrain) ++sorted_textures[t].back().count; else { MapTile tmp(GetTriangleIdx(tP) + 1, posOffset); sorted_textures[t].push_back(tmp); } lastTerrain = t; const Borders& curBorders = borders[GetVertexIdx(tP)]; boost::array<unsigned char, 6> tiles = {{ curBorders.left_right[0], curBorders.left_right[1], curBorders.right_left[0], curBorders.right_left[1], curBorders.top_down[0], curBorders.top_down[1] }}; // Offsets into gl_* arrays boost::array<unsigned, 6> offsets = {{ curBorders.left_right_offset[0], curBorders.left_right_offset[1], curBorders.right_left_offset[0], curBorders.right_left_offset[1], curBorders.top_down_offset[0], curBorders.top_down_offset[1] }}; for(unsigned char i = 0; i < 6; ++i) { if(!tiles[i]) continue; if(tiles[i] == lastBorder) { BorderTile& curTile = sorted_borders[lastBorder - 1].back(); // Check that we did not wrap around the map and the expected offset matches if(curTile.tileOffset + curTile.count == offsets[i]) { ++curTile.count; continue; } } lastBorder = tiles[i]; BorderTile tmp(offsets[i], posOffset); sorted_borders[lastBorder - 1].push_back(tmp); } PrepareWaysPoint(sorted_roads, gwv, tP, posOffset); lastOffset = posOffset; } } if (water) { unsigned water_count = 0; for(unsigned char t = 0; t < TT_COUNT; ++t){ if(!TerrainData::IsWater(TerrainType(t))) continue; for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it) { water_count += it->count; } } PointI diff = gwv.GetLastPt() - gwv.GetFirstPt(); if( diff.x && diff.y ) *water = 50 * water_count / ( diff.x * diff.y ); else *water = 0; } lastOffset = PointI(0, 0); if(vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices); glVertexPointer(2, GL_FLOAT, 0, NULL); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords); glTexCoordPointer(2, GL_FLOAT, 0, NULL); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors); glColorPointer(3, GL_FLOAT, 0, NULL); } else { glVertexPointer(2, GL_FLOAT, 0, &gl_vertices.front()); glTexCoordPointer(2, GL_FLOAT, 0, &gl_texcoords.front()); glColorPointer(3, GL_FLOAT, 0, &gl_colors.front()); } // Arrays aktivieren glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // Modulate2x glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); // Verschieben gem#ß x und y offset glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f); // Alphablending aus glDisable(GL_BLEND); for(unsigned char t = 0; t < TT_COUNT; ++t) { if(sorted_textures[t].empty()) continue; unsigned animationFrame; TerrainType tt = TerrainType(t); if(TerrainData::IsLava(tt)) animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 4, 0); else if(TerrainData::IsWater(tt)) animationFrame = GAMECLIENT.GetGlobalAnimation(TerrainData::GetFrameCount(tt), 5, 2, 0); else animationFrame = 0; VIDEODRIVER.BindTexture(LOADER.GetTerrainTexture(tt, animationFrame).GetTexture()); for(std::vector<MapTile>::iterator it = sorted_textures[t].begin(); it != sorted_textures[t].end(); ++it) { if(it->posOffset != lastOffset) { PointI trans = it->posOffset - lastOffset; glTranslatef( float(trans.x), float(trans.y), 0.0f); lastOffset = it->posOffset; } assert(it->tileOffset + it->count <= width * height * 2u); glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values } } glEnable(GL_BLEND); glLoadIdentity(); glTranslatef( float(-gwv.GetXOffset()), float(-gwv.GetYOffset()), 0.0f); lastOffset = PointI(0, 0); for(unsigned short i = 0; i < 5; ++i) { if(sorted_borders[i].empty()) continue; VIDEODRIVER.BindTexture(GetImage(borders, i)->GetTexture()); for(std::vector<BorderTile>::iterator it = sorted_borders[i].begin(); it != sorted_borders[i].end(); ++it) { if(it->posOffset != lastOffset) { PointI trans = it->posOffset - lastOffset; glTranslatef( float(trans.x), float(trans.y), 0.0f); lastOffset = it->posOffset; } assert(it->tileOffset + it->count <= gl_vertices.size()); glDrawArrays(GL_TRIANGLES, it->tileOffset * 3, it->count * 3); // Arguments are in Elements. 1 triangle has 3 values } } glLoadIdentity(); DrawWays(sorted_roads); // Wieder zurück ins normale modulate glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); }