vertices;
#define ADD(i, j) \
m_Terrain->CalcPosition(i, j, position); \
vertices.emplace_back(position.X); \
vertices.emplace_back(position.Y); \
vertices.emplace_back(position.Z);
CVector3D position;
ADD(i, j);
ADD(i+1, j);
ADD(i+1, j+1);
ADD(i, j+1);
#undef ADD
CShaderTechniquePtr overlayTech =
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
overlayTech->BeginPass();
CShaderProgramPtr overlayShader = overlayTech->GetShader();
overlayShader->Bind();
overlayShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
overlayShader->Uniform(str_color, color);
overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
overlayShader->AssertPointersBound();
glDrawArrays(GL_QUADS, 0, vertices.size() / 3);
overlayShader->Unbind();
overlayTech->EndPass();
if (line_width != 1)
glLineWidth(1.0f);
#endif
}
//////////////////////////////////////////////////////////////////////////
TerrainTextureOverlay::TerrainTextureOverlay(float texelsPerTile, int priority) :
- ITerrainOverlay(priority), m_TexelsPerTile(texelsPerTile), m_Texture(0), m_TextureW(0), m_TextureH(0)
+ ITerrainOverlay(priority), m_TexelsPerTile(texelsPerTile)
{
- glGenTextures(1, &m_Texture);
}
-TerrainTextureOverlay::~TerrainTextureOverlay()
-{
- glDeleteTextures(1, &m_Texture);
-}
+TerrainTextureOverlay::~TerrainTextureOverlay() = default;
void TerrainTextureOverlay::RenderAfterWater(int cullGroup)
{
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
ssize_t w = (ssize_t)(terrain->GetTilesPerSide() * m_TexelsPerTile);
ssize_t h = (ssize_t)(terrain->GetTilesPerSide() * m_TexelsPerTile);
+ const uint32_t requiredWidth = round_up_to_pow2(w);
+ const uint32_t requiredHeight = round_up_to_pow2(h);
+
glActiveTextureARB(GL_TEXTURE0);
// Recreate the texture with new size if necessary
- if (round_up_to_pow2(w) != m_TextureW || round_up_to_pow2(h) != m_TextureH)
+ if (!m_Texture || m_Texture->GetWidth() != requiredWidth || m_Texture->GetHeight() != requiredHeight)
{
- m_TextureW = round_up_to_pow2(w);
- m_TextureH = round_up_to_pow2(h);
-
- glBindTexture(GL_TEXTURE_2D, m_Texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureW, m_TextureH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ m_Texture = Renderer::Backend::GL::CTexture::Create2D(
+ Renderer::Backend::Format::R8G8B8A8, requiredWidth, requiredHeight,
+ Renderer::Backend::Sampler::MakeDefaultSampler(
+ Renderer::Backend::Sampler::Filter::NEAREST,
+ Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_2D, m_Texture->GetHandle());
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Texture->GetWidth(), m_Texture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
u8* data = (u8*)calloc(w * h, 4);
BuildTextureRGBA(data, w, h);
- glBindTexture(GL_TEXTURE_2D, m_Texture);
+ glBindTexture(GL_TEXTURE_2D, m_Texture->GetHandle());
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data);
free(data);
CMatrix3D matrix;
matrix.SetZero();
- matrix._11 = m_TexelsPerTile / (m_TextureW * TERRAIN_TILE_SIZE);
- matrix._23 = m_TexelsPerTile / (m_TextureH * TERRAIN_TILE_SIZE);
+ matrix._11 = m_TexelsPerTile / (m_Texture->GetWidth() * TERRAIN_TILE_SIZE);
+ matrix._23 = m_TexelsPerTile / (m_Texture->GetHeight() * TERRAIN_TILE_SIZE);
matrix._44 = 1;
- g_Renderer.GetTerrainRenderer().RenderTerrainOverlayTexture(cullGroup, matrix, m_Texture);
+ g_Renderer.GetTerrainRenderer().RenderTerrainOverlayTexture(cullGroup, matrix, m_Texture->GetHandle());
}
SColor4ub TerrainTextureOverlay::GetColor(size_t idx, u8 alpha) const
{
static u8 colors[][3] = {
{ 255, 0, 0 },
{ 0, 255, 0 },
{ 0, 0, 255 },
{ 255, 255, 0 },
{ 255, 0, 255 },
{ 0, 255, 255 },
{ 255, 255, 255 },
{ 127, 0, 0 },
{ 0, 127, 0 },
{ 0, 0, 127 },
{ 127, 127, 0 },
{ 127, 0, 127 },
{ 0, 127, 127 },
{ 127, 127, 127},
{ 255, 127, 0 },
{ 127, 255, 0 },
{ 255, 0, 127 },
{ 127, 0, 255},
{ 0, 255, 127 },
{ 0, 127, 255},
{ 255, 127, 127},
{ 127, 255, 127},
{ 127, 127, 255},
{ 127, 255, 255 },
{ 255, 127, 255 },
{ 255, 255, 127 },
};
size_t c = idx % ARRAY_SIZE(colors);
return SColor4ub(colors[c][0], colors[c][1], colors[c][2], alpha);
}
Index: ps/trunk/source/renderer/TerrainOverlay.h
===================================================================
--- ps/trunk/source/renderer/TerrainOverlay.h (revision 26116)
+++ ps/trunk/source/renderer/TerrainOverlay.h (revision 26117)
@@ -1,204 +1,203 @@
-/* Copyright (C) 2012 Wildfire Games.
+/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
/*
* System for representing tile-based information on top of the
* terrain.
*/
#ifndef INCLUDED_TERRAINOVERLAY
#define INCLUDED_TERRAINOVERLAY
-#include "lib/ogl.h"
+#include "renderer/backend/gl/Texture.h"
struct CColor;
struct SColor4ub;
class CTerrain;
class CSimContext;
/**
* Common interface for terrain-tile-based and texture-based debug overlays.
*
* An overlay object will be rendered for as long as it is allocated
* (it is automatically registered/deregistered by constructor/destructor).
*/
class ITerrainOverlay
{
NONCOPYABLE(ITerrainOverlay);
public:
virtual ~ITerrainOverlay();
virtual void RenderBeforeWater() { }
virtual void RenderAfterWater(int UNUSED(cullGroup)) { }
/**
* Draw all ITerrainOverlay objects that exist
* and that should be drawn before water.
*/
static void RenderOverlaysBeforeWater();
/**
* Draw all ITerrainOverlay objects that exist
* and that should be drawn after water.
*/
static void RenderOverlaysAfterWater(int cullGroup);
protected:
ITerrainOverlay(int priority);
};
/**
* Base class for (relatively) simple drawing of
* data onto terrain tiles, intended for debugging purposes and for the Atlas
* editor (hence not trying to be very efficient).
*
* To start drawing a terrain overlay, first create a subclass of TerrainOverlay.
* Override the method GetTileExtents if you want to change the range over which
* it is drawn.
* Override ProcessTile to do your processing for each tile, which should call
* RenderTile and RenderTileOutline as appropriate.
*/
class TerrainOverlay : public ITerrainOverlay
{
protected:
/**
* Construct the object and register it with the global
* list of terrain overlays.
*
* The priority parameter controls the order in which overlays are drawn,
* if several exist - they are processed in order of increasing priority,
* so later ones draw on top of earlier ones.
* Most should use the default of 100. Numbers from 200 are used
* by Atlas.
*
* @param priority controls the order of drawing
*/
TerrainOverlay(const CSimContext& simContext, int priority = 100);
/**
* Override to perform processing at the start of the overlay rendering,
* before the ProcessTile calls
*/
virtual void StartRender();
/**
* Override to perform processing at the end of the overlay rendering,
* after the ProcessTile calls
*/
virtual void EndRender();
/**
* Override to limit the range over which ProcessTile will
* be called. Defaults to the size of the map.
*
* @param min_i_inclusive [output] smallest i coordinate, in tile-space units
* (1 unit per tile, +i is world-space +x and game-space East)
* @param min_j_inclusive [output] smallest j coordinate
* (+j is world-space +z and game-space North)
* @param max_i_inclusive [output] largest i coordinate
* @param max_j_inclusive [output] largest j coordinate
*/
virtual void GetTileExtents(ssize_t& min_i_inclusive, ssize_t& min_j_inclusive,
ssize_t& max_i_inclusive, ssize_t& max_j_inclusive);
/**
* Override to perform processing of each tile. Typically calls
* RenderTile and/or RenderTileOutline.
*
* @param i i coordinate of tile being processed
* @param j j coordinate of tile being processed
*/
virtual void ProcessTile(ssize_t i, ssize_t j) = 0;
/**
* Draw a filled quad on top of the current tile.
*
* @param color color to draw. May be transparent (alpha < 1)
* @param draw_hidden true if hidden tiles (i.e. those behind other tiles)
* should be drawn
*/
void RenderTile(const CColor& color, bool draw_hidden);
/**
* Draw a filled quad on top of the given tile.
*/
void RenderTile(const CColor& color, bool draw_hidden, ssize_t i, ssize_t j);
/**
* Draw an outlined quad on top of the current tile.
*
* @param color color to draw. May be transparent (alpha < 1)
* @param line_width width of lines in pixels. 1 is a sensible value
* @param draw_hidden true if hidden tiles (i.e. those behind other tiles)
* should be drawn
*/
void RenderTileOutline(const CColor& color, int line_width, bool draw_hidden);
/**
* Draw an outlined quad on top of the given tile.
*/
void RenderTileOutline(const CColor& color, int line_width, bool draw_hidden, ssize_t i, ssize_t j);
private:
// Process all tiles
virtual void RenderBeforeWater();
// Temporary storage of tile coordinates, so ProcessTile doesn't need to
// pass it to RenderTile/etc (and doesn't have a chance to get it wrong)
ssize_t m_i, m_j;
CTerrain* m_Terrain;
};
/**
* Base class for texture-based terrain overlays, with an arbitrary number of
* texels per terrain tile, intended for debugging purposes.
* Subclasses must implement BuildTextureRGBA which will be called each frame.
*/
class TerrainTextureOverlay : public ITerrainOverlay
{
public:
TerrainTextureOverlay(float texelsPerTile, int priority = 100);
virtual ~TerrainTextureOverlay();
protected:
/**
* Called each frame to generate the texture to render on the terrain.
* @p data is w*h*4 bytes, where w and h are the terrain size multiplied
* by texelsPerTile. @p data defaults to fully transparent, and should
* be filled with data in RGBA order.
*/
virtual void BuildTextureRGBA(u8* data, size_t w, size_t h) = 0;
/**
* Returns an arbitrary color, for subclasses that want to distinguish
* different integers visually.
*/
SColor4ub GetColor(size_t idx, u8 alpha) const;
private:
void RenderAfterWater(int cullGroup);
float m_TexelsPerTile;
- GLuint m_Texture;
- GLsizei m_TextureW, m_TextureH;
+ std::unique_ptr m_Texture;
};
#endif // INCLUDED_TERRAINOVERLAY
Index: ps/trunk/source/renderer/backend/Format.h
===================================================================
--- ps/trunk/source/renderer/backend/Format.h (revision 26116)
+++ ps/trunk/source/renderer/backend/Format.h (revision 26117)
@@ -1,38 +1,41 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#ifndef INCLUDED_RENDERER_BACKEND_FORMAT
#define INCLUDED_RENDERER_BACKEND_FORMAT
namespace Renderer
{
namespace Backend
{
enum class Format
{
UNDEFINED,
R8G8B8A8,
A8,
+ D16,
+ D24,
+ D32
};
} // namespace Backend
} // namespace Renderer
#endif // INCLUDED_RENDERER_BACKEND_FORMAT