void TerrainRenderer::UpdateVertexColor(const MapPoint pt, const GameWorldViewer& gwv) { switch(gwv.GetVisibility(pt)) { // Unsichtbar -> schwarz case VIS_INVISIBLE: GetVertex(pt).color = 0.0f; break; // Fog of War -> abgedunkelt case VIS_FOW: GetVertex(pt).color = float(gwv.GetNode(pt).shadow + 0x40) / float(0xFF) / 2; break; // Normal sichtbar case VIS_VISIBLE: GetVertex(pt).color = float(gwv.GetNode(pt).shadow + 0x40) / float(0xFF); break; } }
/// erzeugt Vertex void TerrainRenderer::UpdateVertexPos(const MapPoint pt, const GameWorldViewer& gwv) { int x = pt.x * TR_W; if(pt.y & 1) x += TR_W / 2; GetVertex(pt).pos.x = float(x); GetVertex(pt).pos.y = float(pt.y * TR_H - HEIGHT_FACTOR * gwv.GetNode(pt).altitude + HEIGHT_FACTOR * 0x0A ); }
void TerrainRenderer::UpdateTriangleTerrain(const MapPoint pt, const GameWorldViewer& gwv, const bool update) { const MapNode& node = gwv.GetNode(pt); unsigned int pos = GetTriangleIdx(pt); Triangle& texCoord = gl_texcoords[pos]; if(!TerrainData::IsAnimated(node.t1)) { texCoord[1].x = 0.225f; texCoord[1].y = 0.f; texCoord[2].x = 0.f; //-V807 texCoord[2].y = 0.45f; texCoord[0].x = 0.45f; texCoord[0].y = texCoord[2].y; }else { // We use the full texture as it already consists of 2 triangles // But we need to make sure to only use the correct part of it (texture sizes are powers of 2) // Note: Better would be to use the actual textures, but they are not loaded when this is called during game start Rect texRect = TerrainData::GetPosInTexture(node.t1); int w = texRect.right - texRect.left; int h = texRect.bottom - texRect.top; assert(w > 0 && h > 0); unsigned texW = helpers::roundToNextPowerOfTwo(w); unsigned texH = helpers::roundToNextPowerOfTwo(h); float texScaleW = 1.f / texW; float texScaleH = 1.f / texH; // Tip of the triangle is in the middle in x texCoord[1].x = (w + 1) / 2.f * texScaleW; texCoord[1].y = 0.f; // Bottom of the triangle is in the middle in y texCoord[2].x = 0.f; texCoord[2].y = (h + 1) / 2.f * texScaleH; texCoord[0].x = (w - 1) * texScaleW; texCoord[0].y = texCoord[2].y; } Triangle& texCoord2 = gl_texcoords[pos+1]; if(!TerrainData::IsAnimated(node.t2)) { texCoord2[1].x = 0.235f; texCoord2[1].y = 0.45f; texCoord2[2].x = 0.47f; //-V807 texCoord2[2].y = 0.0f; texCoord2[0].x = 0.0f; texCoord2[0].y = texCoord2[2].y; }else { Rect texRect = TerrainData::GetPosInTexture(node.t1); int w = texRect.right - texRect.left; int h = texRect.bottom - texRect.top; assert(w > 0 && h > 0); unsigned texW = helpers::roundToNextPowerOfTwo(w); unsigned texH = helpers::roundToNextPowerOfTwo(h); float texScaleW = 1.f / texW; float texScaleH = 1.f / texH; // Bottom tip of the triangle is in the middle in x texCoord2[1].x = (w + 1) / 2.f * texScaleW; texCoord2[1].y = (h - 1) * texScaleH; // Top of the triangle is in the middle in y texCoord2[2].x = (w - 1) * texScaleW; texCoord2[2].y = (h + 1) / 2.f * texScaleH; texCoord2[0].x = 0.f; texCoord2[0].y = texCoord2[2].y; } /// Bei Vertexbuffern das die Daten aktualisieren if(update && vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, (pos - 1) * sizeof(Triangle), 2 * sizeof(Triangle), &gl_texcoords[pos - 1]); } }
/** * erzeugt die OpenGL-Vertices. * * @author OLiver * @author FloSoft */ void TerrainRenderer::GenerateOpenGL(const GameWorldViewer& gwv) { width = gwv.GetWidth(); height = gwv.GetHeight(); LandscapeType lt = gwv.GetLandscapeType(); GenerateVertices(gwv); // We have 2 triangles per map point unsigned int triangleCount = width * height * 2; // Ränder zählen borders.resize(width * height); for(MapCoord y = 0; y < height; ++y) { for(MapCoord x = 0; x < width; ++x) { MapPoint pt(x, y); TerrainType t1 = gwv.GetNode(pt).t1; //-V807 TerrainType t2 = gwv.GetNode(pt).t2; unsigned int pos = GetVertexIdx(pt); if( (borders[pos].left_right[0] = TerrainData::GetEdgeType(lt, t2, t1)) ) borders[pos].left_right_offset[0] = triangleCount++; if( (borders[pos].left_right[1] = TerrainData::GetEdgeType(lt, t1, t2)) ) borders[pos].left_right_offset[1] = triangleCount++; t1 = gwv.GetNodeAround(pt, 3).t1; if( (borders[pos].right_left[0] = TerrainData::GetEdgeType(lt, t1, t2)) ) borders[pos].right_left_offset[0] = triangleCount++; if( (borders[pos].right_left[1] = TerrainData::GetEdgeType(lt, t2, t1)) ) borders[pos].right_left_offset[1] = triangleCount++; t1 = gwv.GetNode(pt).t1; t2 = gwv.GetNodeAround(pt, 5).t2; if( (borders[pos].top_down[0] = TerrainData::GetEdgeType(lt, t2, t1)) ) borders[pos].top_down_offset[0] = triangleCount++; if( (borders[pos].top_down[1] = TerrainData::GetEdgeType(lt, t1, t2)) ) borders[pos].top_down_offset[1] = triangleCount++; } } gl_vertices.resize(triangleCount); gl_texcoords.resize(triangleCount); gl_colors.resize(triangleCount); // Normales Terrain erzeugen for(MapCoord y = 0; y < height; ++y) { for(MapCoord x = 0; x < width; ++x) { MapPoint pt(x, y); UpdateTrianglePos(pt, gwv, false); UpdateTriangleColor(pt, gwv, false); UpdateTriangleTerrain(pt, gwv, false); } } // Ränder erzeugen for(MapCoord y = 0; y < height; ++y) { for(MapCoord x = 0; x < width; ++x) { MapPoint pt(x, y); UpdateBorderTrianglePos(pt, gwv, false); UpdateBorderTriangleColor(pt, gwv, false); UpdateBorderTriangleTerrain(pt, gwv, false); } } if(SETTINGS.video.vbo) { // Generiere und Binde den Vertex Buffer glGenBuffersARB(1, (GLuint*)&vbo_vertices); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices); glBufferDataARB(GL_ARRAY_BUFFER_ARB, gl_vertices.size() * sizeof(Triangle), &gl_vertices.front(), GL_STATIC_DRAW_ARB); glVertexPointer(2, GL_FLOAT, 0, NULL); // Generiere und Binde den Textur Koordinaten Buffer glGenBuffersARB(1, (GLuint*)&vbo_texcoords); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_texcoords); glBufferDataARB(GL_ARRAY_BUFFER_ARB, gl_texcoords.size() * sizeof(Triangle), &gl_texcoords.front(), GL_STATIC_DRAW_ARB ); glTexCoordPointer(2, GL_FLOAT, 0, NULL); // Generiere und Binde den Color Buffer glGenBuffersARB(1, (GLuint*)&vbo_colors); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_colors); glBufferDataARB(GL_ARRAY_BUFFER_ARB, gl_colors.size() * sizeof(ColorTriangle), &gl_colors.front(), GL_STATIC_DRAW_ARB ); glColorPointer(3, GL_FLOAT, 0, NULL); vboBuffersUsed = true; } 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()); } }
void TerrainRenderer::UpdateVertexTerrain(const MapPoint pt, const GameWorldViewer& gwv) { const MapNode& node = gwv.GetNode(pt); GetVertex(pt).terrain[0] = node.t1; GetVertex(pt).terrain[1] = node.t2; }