# Rewrite fog-of-war rendering.
Disable shadows when only 2 TMUs available. Clean up some other rendering code. This was SVN commit r8882.
This commit is contained in:
parent
1e02fe70a7
commit
fe21c5e023
@ -5,6 +5,7 @@ uniform vec3 cameraPos;
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D reflectionMap;
|
||||
uniform sampler2D refractionMap;
|
||||
uniform sampler2D losMap;
|
||||
uniform float shininess; // Blinn-Phong specular strength
|
||||
uniform float specularStrength; // Scaling for specular reflection (specular color is (this,this,this))
|
||||
uniform float waviness; // "Wildness" of the reflections and refractions; choose based on texture
|
||||
@ -17,7 +18,6 @@ uniform float reflectionTintStrength; // Strength of reflection tint (how much o
|
||||
varying vec3 worldPos;
|
||||
varying float w;
|
||||
varying float waterDepth;
|
||||
varying float losMod;
|
||||
|
||||
void main()
|
||||
{
|
||||
@ -28,7 +28,8 @@ void main()
|
||||
float t; // Temporary variable
|
||||
vec2 reflCoords, refrCoords;
|
||||
vec3 reflColor, refrColor, specular;
|
||||
|
||||
float losMod;
|
||||
|
||||
n = normalize(texture2D(normalMap, gl_TexCoord[0].st).xzy - vec3(0.5, 0.5, 0.5));
|
||||
l = -sunDir;
|
||||
v = normalize(cameraPos - worldPos);
|
||||
@ -55,7 +56,9 @@ void main()
|
||||
myMurkiness);
|
||||
|
||||
specular = pow(max(0.0, ndoth), shininess) * sunColor * specularStrength;
|
||||
|
||||
|
||||
losMod = texture2D(losMap, gl_TexCoord[3].st).a;
|
||||
|
||||
gl_FragColor.rgb = mix(refrColor + 0.3*specular, reflColor + specular, fresnel) * losMod;
|
||||
|
||||
// Make alpha vary based on both depth (so it blends with the shore) and view angle (make it
|
||||
|
@ -1,23 +1,22 @@
|
||||
uniform mat4 reflectionMatrix;
|
||||
uniform mat4 refractionMatrix;
|
||||
uniform mat4 losMatrix;
|
||||
uniform vec4 translation;
|
||||
|
||||
attribute float vertexDepth;
|
||||
attribute float losMultiplier;
|
||||
|
||||
varying vec3 worldPos;
|
||||
varying float w;
|
||||
varying float waterDepth;
|
||||
varying float losMod;
|
||||
|
||||
void main()
|
||||
{
|
||||
worldPos = gl_Vertex.xyz;
|
||||
waterDepth = vertexDepth;
|
||||
losMod = losMultiplier;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0 + translation;
|
||||
gl_TexCoord[1] = reflectionMatrix * gl_Vertex; // projective texturing
|
||||
gl_TexCoord[2] = reflectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[3] = losMatrix * gl_Vertex;
|
||||
w = gl_TexCoord[1].w;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "graphics/ColladaManager.h"
|
||||
#include "graphics/HFTracer.h"
|
||||
#include "graphics/LightEnv.h"
|
||||
#include "graphics/LOSTexture.h"
|
||||
#include "graphics/Model.h"
|
||||
#include "graphics/ObjectManager.h"
|
||||
#include "graphics/Patch.h"
|
||||
@ -198,6 +199,7 @@ public:
|
||||
CMeshManager MeshManager;
|
||||
CSkeletonAnimManager SkeletonAnimManager;
|
||||
CObjectManager ObjectManager;
|
||||
CLOSTexture LOSTexture;
|
||||
|
||||
/**
|
||||
* this camera controls the eye position when rendering
|
||||
@ -354,12 +356,10 @@ CCinemaManager* CGameView::GetCinema()
|
||||
return &m->TrackManager;
|
||||
};
|
||||
|
||||
/*
|
||||
void CGameView::AttachToUnit(CEntity* target)
|
||||
CLOSTexture& CGameView::GetLOSTexture()
|
||||
{
|
||||
m->UnitAttach = target;
|
||||
return m->LOSTexture;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void CGameViewImpl::ScriptingInit()
|
||||
|
@ -31,6 +31,7 @@ class CGame;
|
||||
class CObjectManager;
|
||||
class CCamera;
|
||||
class CCinemaManager;
|
||||
class CLOSTexture;
|
||||
class CVector3D;
|
||||
struct SViewPort;
|
||||
|
||||
@ -90,6 +91,7 @@ public:
|
||||
|
||||
CCamera *GetCamera();
|
||||
CCinemaManager* GetCinema();
|
||||
CLOSTexture& GetLOSTexture();
|
||||
|
||||
JSObject* GetScript();
|
||||
static void ScriptingInit();
|
||||
|
244
source/graphics/LOSTexture.cpp
Normal file
244
source/graphics/LOSTexture.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
/* Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "LOSTexture.h"
|
||||
|
||||
#include "graphics/Terrain.h"
|
||||
#include "lib/bits.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/World.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
|
||||
/*
|
||||
|
||||
The LOS bitmap is computed with one value per map vertex, based on
|
||||
CCmpRangeManager's visibility information.
|
||||
|
||||
The bitmap is then blurred using an NxN box filter (i.e. convolution
|
||||
with (1 1 1; 1 1 1; 1 1 1) etc). To implement the blur efficiently without
|
||||
using extra memory for a second copy of the bitmap, we generate the bitmap
|
||||
with (N-1)/2 pixels of padding on each side, then the blur shifts the
|
||||
image back into the corner.
|
||||
|
||||
The blurred bitmap is then uploaded into a GL texture for use by the renderer.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// Blur with a NxN box filter, where N = g_BlurSize must be an odd number.
|
||||
static const size_t g_BlurSize = 5;
|
||||
|
||||
CLOSTexture::CLOSTexture() :
|
||||
m_Dirty(true), m_Texture(0), m_MapSize(0), m_TextureSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
CLOSTexture::~CLOSTexture()
|
||||
{
|
||||
if (m_Texture)
|
||||
{
|
||||
glDeleteTextures(1, &m_Texture);
|
||||
m_Texture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CLOSTexture::MakeDirty()
|
||||
{
|
||||
m_Dirty = true;
|
||||
}
|
||||
|
||||
void CLOSTexture::BindTexture(int unit)
|
||||
{
|
||||
if (m_Dirty)
|
||||
{
|
||||
RecomputeTexture(unit);
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
}
|
||||
|
||||
CMatrix3D CLOSTexture::GetTextureMatrix()
|
||||
{
|
||||
debug_assert(m_MapSize);
|
||||
|
||||
// We want to map
|
||||
// world pos (0, y, 0) (i.e. first vertex)
|
||||
// onto texcoord (0.5/texsize, 0.5/texsize) (i.e. middle of first texel);
|
||||
// world pos ((mapsize-1)*cellsize, y, (mapsize-1)*cellsize) (i.e. last vertex)
|
||||
// onto texcoord ((mapsize-0.5) / texsize, (mapsize-0.5) / texsize) (i.e. middle of last texel)
|
||||
// so construct an appropriate matrix:
|
||||
|
||||
float s = (m_MapSize-1) / (float)(m_TextureSize * (m_MapSize-1) * CELL_SIZE);
|
||||
float t = 0.5f / m_TextureSize;
|
||||
CMatrix3D m;
|
||||
m.SetZero();
|
||||
m._11 = s;
|
||||
m._23 = s;
|
||||
m._14 = t;
|
||||
m._24 = t;
|
||||
m._44 = 1;
|
||||
return m;
|
||||
}
|
||||
|
||||
CMatrix3D CLOSTexture::GetMinimapTextureMatrix()
|
||||
{
|
||||
debug_assert(m_MapSize);
|
||||
|
||||
// We want to map UV (0,0)-(1,1) onto (0,0)-(mapsize/texsize, mapsize/texsize)
|
||||
|
||||
float s = m_MapSize / (float)m_TextureSize;
|
||||
CMatrix3D m;
|
||||
m.SetZero();
|
||||
m._11 = s;
|
||||
m._22 = s;
|
||||
m._44 = 1;
|
||||
return m;
|
||||
}
|
||||
|
||||
void CLOSTexture::ConstructTexture(int unit)
|
||||
{
|
||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
||||
m_MapSize = terrain->GetVerticesPerSide();
|
||||
m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize + g_BlurSize - 1);
|
||||
|
||||
glGenTextures(1, &m_Texture);
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
void CLOSTexture::RecomputeTexture(int unit)
|
||||
{
|
||||
if (!m_Texture)
|
||||
ConstructTexture(unit);
|
||||
|
||||
PROFILE("recompute LOS texture");
|
||||
|
||||
std::vector<u8> losData;
|
||||
losData.resize(GetBitmapSize(m_MapSize, m_MapSize));
|
||||
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
|
||||
if (cmpRangeManager.null())
|
||||
return;
|
||||
|
||||
ICmpRangeManager::CLosQuerier los (cmpRangeManager->GetLosQuerier(g_Game->GetPlayerID()));
|
||||
|
||||
GenerateBitmap(los, &losData[0], m_MapSize, m_MapSize);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize + g_BlurSize - 1, m_MapSize + g_BlurSize - 1, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
}
|
||||
|
||||
size_t CLOSTexture::GetBitmapSize(size_t w, size_t h)
|
||||
{
|
||||
return (w + g_BlurSize - 1) * (h + g_BlurSize - 1);
|
||||
}
|
||||
|
||||
void CLOSTexture::GenerateBitmap(ICmpRangeManager::CLosQuerier los, u8* losData, size_t w, size_t h)
|
||||
{
|
||||
const size_t rowSize = w + g_BlurSize-1; // size of losData rows
|
||||
|
||||
u8 *dataPtr = losData;
|
||||
|
||||
// Initialise the top padding
|
||||
for (size_t j = 0; j < g_BlurSize/2; ++j)
|
||||
for (size_t i = 0; i < rowSize; ++i)
|
||||
*dataPtr++ = 0;
|
||||
|
||||
for (size_t j = 0; j < h; ++j)
|
||||
{
|
||||
// Initialise the left padding
|
||||
for (size_t i = 0; i < g_BlurSize/2; ++i)
|
||||
*dataPtr++ = 0;
|
||||
|
||||
// Fill in the visibility data
|
||||
for (size_t i = 0; i < w; ++i)
|
||||
{
|
||||
if (los.IsVisible(i, j))
|
||||
*dataPtr++ = 255;
|
||||
else if (los.IsExplored(i, j))
|
||||
*dataPtr++ = 127;
|
||||
else
|
||||
*dataPtr++ = 0;
|
||||
}
|
||||
|
||||
// Initialise the right padding
|
||||
for (size_t i = 0; i < g_BlurSize/2; ++i)
|
||||
*dataPtr++ = 0;
|
||||
}
|
||||
|
||||
// Initialise the bottom padding
|
||||
for (size_t j = 0; j < g_BlurSize/2; ++j)
|
||||
for (size_t i = 0; i < rowSize; ++i)
|
||||
*dataPtr++ = 0;
|
||||
|
||||
// Horizontal blur:
|
||||
|
||||
for (size_t j = g_BlurSize/2; j < h + g_BlurSize/2; ++j)
|
||||
{
|
||||
u32 accum = 0; // sum of values in the sliding Nx1 window
|
||||
|
||||
// Initialise the filter window for the first output pixel
|
||||
// (Start i at the first of the non-padding pixels, since the
|
||||
// padding was set to 0)
|
||||
for (size_t i = g_BlurSize/2; i < g_BlurSize-1; ++i)
|
||||
accum += losData[i+j*rowSize];
|
||||
|
||||
// For each pixel, update the sliding window and store the average
|
||||
// of the window's sum
|
||||
for (size_t i = 0; i < w; ++i)
|
||||
{
|
||||
accum += losData[i+g_BlurSize-1+j*rowSize];
|
||||
|
||||
u8 old = losData[i+j*rowSize];
|
||||
|
||||
losData[i+j*rowSize] = accum / g_BlurSize;
|
||||
|
||||
accum -= old;
|
||||
}
|
||||
}
|
||||
|
||||
// Vertical blur:
|
||||
|
||||
for (size_t i = 0; i < w; ++i)
|
||||
{
|
||||
u32 accum = 0;
|
||||
|
||||
for (size_t j = g_BlurSize/2; j < g_BlurSize-1; ++j)
|
||||
accum += losData[i+j*rowSize];
|
||||
|
||||
for (size_t j = 0; j < h; ++j)
|
||||
{
|
||||
accum += losData[i+(j+g_BlurSize-1)*rowSize];
|
||||
|
||||
u8 old = losData[i+j*rowSize];
|
||||
|
||||
losData[i+j*rowSize] = accum / g_BlurSize;
|
||||
|
||||
accum -= old;
|
||||
}
|
||||
}
|
||||
}
|
78
source/graphics/LOSTexture.h
Normal file
78
source/graphics/LOSTexture.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "lib/ogl.h"
|
||||
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
|
||||
class CMatrix3D;
|
||||
|
||||
/**
|
||||
* Maintains the LOS (fog-of-war / shroud-of-darkness) texture, used for
|
||||
* rendering and for the minimap.
|
||||
*/
|
||||
class CLOSTexture
|
||||
{
|
||||
NONCOPYABLE(CLOSTexture);
|
||||
friend class TestLOSTexture;
|
||||
|
||||
public:
|
||||
CLOSTexture();
|
||||
~CLOSTexture();
|
||||
|
||||
/**
|
||||
* Marks the LOS texture as needing recomputation. Call this after each
|
||||
* simulation update, to ensure responsive updates.
|
||||
*/
|
||||
void MakeDirty();
|
||||
|
||||
/**
|
||||
* Recomputes the LOS texture if necessary, and binds it to the requested
|
||||
* texture unit.
|
||||
* Also switches the current active texture unit, and enables texturing on it.
|
||||
* The texture is in 8-bit ALPHA format.
|
||||
*/
|
||||
void BindTexture(int unit);
|
||||
|
||||
/**
|
||||
* Returns a matrix to map (x,y,z) world coordinates onto (u,v) LOS texture
|
||||
* coordinates.
|
||||
* This must only be called after BindTexture.
|
||||
*/
|
||||
CMatrix3D GetTextureMatrix();
|
||||
|
||||
/**
|
||||
* Returns a matrix to map (0,0)-(1,1) texture coordinates onto LOS texture
|
||||
* coordinates.
|
||||
* This must only be called after BindTexture.
|
||||
*/
|
||||
CMatrix3D GetMinimapTextureMatrix();
|
||||
|
||||
private:
|
||||
void ConstructTexture(int unit);
|
||||
void RecomputeTexture(int unit);
|
||||
|
||||
size_t GetBitmapSize(size_t w, size_t h);
|
||||
void GenerateBitmap(ICmpRangeManager::CLosQuerier los, u8* losData, size_t w, size_t h);
|
||||
|
||||
bool m_Dirty;
|
||||
|
||||
GLuint m_Texture;
|
||||
|
||||
ssize_t m_MapSize; // vertexes per side
|
||||
GLsizei m_TextureSize; // texels per side
|
||||
};
|
78
source/graphics/tests/test_LOSTexture.h
Normal file
78
source/graphics/tests/test_LOSTexture.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "lib/self_test.h"
|
||||
|
||||
#include "graphics/LOSTexture.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
class TestLOSTexture : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_basic()
|
||||
{
|
||||
CLOSTexture tex;
|
||||
|
||||
const ssize_t size = 8;
|
||||
u32 inputData[size*size] = {
|
||||
2, 2, 2, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 2
|
||||
};
|
||||
std::vector<u32> inputDataVec(inputData, inputData+size*size);
|
||||
|
||||
ICmpRangeManager::CLosQuerier los(1, inputDataVec, size);
|
||||
|
||||
std::vector<u8> losData;
|
||||
losData.resize(tex.GetBitmapSize(size, size));
|
||||
|
||||
tex.GenerateBitmap(los, &losData[0], size, size);
|
||||
|
||||
// for (size_t i = 0; i < losData.size(); ++i)
|
||||
// printf("%s %3d", i % (size_t)sqrt(losData.size()) ? "" : "\n", losData[i]);
|
||||
|
||||
TS_ASSERT_EQUALS(losData[0], 91);
|
||||
}
|
||||
|
||||
void test_perf_DISABLED()
|
||||
{
|
||||
CLOSTexture tex;
|
||||
|
||||
const ssize_t size = 257;
|
||||
std::vector<u32> inputDataVec;
|
||||
inputDataVec.resize(size*size);
|
||||
|
||||
ICmpRangeManager::CLosQuerier los(1, inputDataVec, size);
|
||||
|
||||
size_t reps = 128;
|
||||
double t = timer_Time();
|
||||
for (size_t i = 0; i < reps; ++i)
|
||||
{
|
||||
std::vector<u8> losData;
|
||||
losData.resize(tex.GetBitmapSize(size, size));
|
||||
|
||||
tex.GenerateBitmap(los, &losData[0], size, size);
|
||||
}
|
||||
double dt = timer_Time() - t;
|
||||
printf("\n# %f secs\n", dt/reps);
|
||||
}
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -22,6 +22,7 @@
|
||||
#include "MiniMap.h"
|
||||
|
||||
#include "graphics/GameView.h"
|
||||
#include "graphics/LOSTexture.h"
|
||||
#include "graphics/MiniPatch.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/TerrainTextureEntry.h"
|
||||
@ -39,7 +40,6 @@
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpMinimap.h"
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
|
||||
bool g_GameRestarted = false;
|
||||
|
||||
@ -51,9 +51,8 @@ static unsigned int ScaleColor(unsigned int color, float x)
|
||||
return (0xff000000 | r | g<<8 | b<<16);
|
||||
}
|
||||
|
||||
CMiniMap::CMiniMap()
|
||||
: m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0),
|
||||
m_LOSTexture(0), m_TerrainDirty(true)
|
||||
CMiniMap::CMiniMap() :
|
||||
m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true)
|
||||
{
|
||||
AddSetting(GUIST_CColor, "fov_wedge_color");
|
||||
AddSetting(GUIST_bool, "circular");
|
||||
@ -61,8 +60,6 @@ CMiniMap::CMiniMap()
|
||||
AddSetting(GUIST_CStr, "tooltip_style");
|
||||
m_Clicking = false;
|
||||
m_Hovering = false;
|
||||
|
||||
m_LOSScale = 2;
|
||||
}
|
||||
|
||||
CMiniMap::~CMiniMap()
|
||||
@ -279,9 +276,7 @@ void CMiniMap::Draw()
|
||||
m_Width = (u32)(m_CachedActualSize.right - m_CachedActualSize.left);
|
||||
m_Height = (u32)(m_CachedActualSize.bottom - m_CachedActualSize.top);
|
||||
m_MapSize = m_Terrain->GetVerticesPerSide();
|
||||
m_LOSMapSize = (m_MapSize + m_LOSScale - 1) / m_LOSScale; // divide and round upwards
|
||||
m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize);
|
||||
m_LOSTextureSize = (GLsizei)round_up_to_pow2((size_t)m_LOSMapSize);
|
||||
|
||||
if(!m_TerrainTexture || g_GameRestarted)
|
||||
CreateTextures();
|
||||
@ -298,16 +293,12 @@ void CMiniMap::Draw()
|
||||
|
||||
if(m_TerrainDirty)
|
||||
RebuildTerrainTexture();
|
||||
|
||||
RebuildLOSTexture();
|
||||
}
|
||||
|
||||
const float x = m_CachedActualSize.left, y = m_CachedActualSize.bottom;
|
||||
const float x2 = m_CachedActualSize.right, y2 = m_CachedActualSize.top;
|
||||
const float z = GetBufferedZ();
|
||||
const float texCoordMax = (float)(m_MapSize - 1) / (float)m_TextureSize;
|
||||
const float losTexCoordMax = (float)(m_LOSMapSize - 1) / (float)m_LOSTextureSize;
|
||||
|
||||
const float angle = GetAngle();
|
||||
|
||||
// Draw the main textured quad
|
||||
@ -371,20 +362,29 @@ void CMiniMap::Draw()
|
||||
*/
|
||||
|
||||
// Draw the LOS quad in black, using alpha values from the LOS texture
|
||||
g_Renderer.BindTexture(0, m_LOSTexture);
|
||||
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
|
||||
losTexture.BindTexture(0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor3f(0.0f, 0.0f, 0.0f);
|
||||
DrawTexture(losTexCoordMax, angle, x, y, x2, y2, z);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(&losTexture.GetMinimapTextureMatrix()._11);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
DrawTexture(1.0f, angle, x, y, x2, y2, z);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// Set up the matrix for drawing points and lines
|
||||
@ -463,22 +463,11 @@ void CMiniMap::CreateTextures()
|
||||
m_TerrainData = new u32[(m_MapSize - 1) * (m_MapSize - 1)];
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||
|
||||
// Create LOS texture
|
||||
glGenTextures(1, &m_LOSTexture);
|
||||
g_Renderer.BindTexture(0, m_LOSTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, m_LOSTextureSize, m_LOSTextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
|
||||
m_LOSData.resize(m_LOSMapSize * m_LOSMapSize);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||
|
||||
// Rebuild and upload both of them
|
||||
RebuildTerrainTexture();
|
||||
RebuildLOSTexture();
|
||||
}
|
||||
|
||||
|
||||
@ -539,44 +528,6 @@ void CMiniMap::RebuildTerrainTexture()
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize - 1, m_MapSize - 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_TerrainData);
|
||||
}
|
||||
|
||||
|
||||
void CMiniMap::RebuildLOSTexture()
|
||||
{
|
||||
PROFILE("rebuild minimap: los");
|
||||
|
||||
ssize_t w = m_MapSize;
|
||||
ssize_t h = m_MapSize;
|
||||
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
|
||||
if (cmpRangeManager.null() || cmpRangeManager->GetLosRevealAll(g_Game->GetPlayerID()))
|
||||
{
|
||||
memset(&m_LOSData[0], 0, m_LOSData.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
ICmpRangeManager::CLosQuerier los (cmpRangeManager->GetLosQuerier(g_Game->GetPlayerID()));
|
||||
|
||||
u8 *dataPtr = &m_LOSData[0];
|
||||
|
||||
for (ssize_t j = 0; j < h; j += m_LOSScale)
|
||||
{
|
||||
for (ssize_t i = 0; i < w; i += m_LOSScale)
|
||||
{
|
||||
if (los.IsVisible(i, j))
|
||||
*dataPtr++ = 0;
|
||||
else if (los.IsExplored(i, j))
|
||||
*dataPtr++ = 76;
|
||||
else
|
||||
*dataPtr++ = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Upload the texture
|
||||
g_Renderer.BindTexture(0, m_LOSTexture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_LOSMapSize, m_LOSMapSize, GL_ALPHA, GL_UNSIGNED_BYTE, &m_LOSData[0]);
|
||||
}
|
||||
|
||||
void CMiniMap::Destroy()
|
||||
{
|
||||
if(m_TerrainTexture)
|
||||
@ -585,11 +536,6 @@ void CMiniMap::Destroy()
|
||||
m_TerrainTexture = 0;
|
||||
}
|
||||
|
||||
if(m_LOSTexture)
|
||||
{
|
||||
glDeleteTextures(1, &m_LOSTexture);
|
||||
m_LOSTexture = 0;
|
||||
}
|
||||
|
||||
delete[] m_TerrainData; m_TerrainData = 0;
|
||||
delete[] m_TerrainData;
|
||||
m_TerrainData = 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -40,9 +40,6 @@ protected:
|
||||
// rebuild the terrain texture map
|
||||
void RebuildTerrainTexture();
|
||||
|
||||
// rebuild the LOS map
|
||||
void RebuildLOSTexture();
|
||||
|
||||
// destroy and free any memory and textures
|
||||
void Destroy();
|
||||
|
||||
@ -61,15 +58,9 @@ protected:
|
||||
|
||||
// minimap texture handles
|
||||
GLuint m_TerrainTexture;
|
||||
GLuint m_LOSTexture;
|
||||
|
||||
// number of vertexes per LOS-texture texel
|
||||
u8 m_LOSScale;
|
||||
ssize_t m_LOSMapSize;
|
||||
|
||||
// texture data
|
||||
u32* m_TerrainData;
|
||||
std::vector<u8> m_LOSData;
|
||||
|
||||
// whether we need to regenerate the terrain texture
|
||||
bool m_TerrainDirty;
|
||||
@ -81,7 +72,6 @@ protected:
|
||||
|
||||
// texture size
|
||||
GLsizei m_TextureSize;
|
||||
GLsizei m_LOSTextureSize;
|
||||
|
||||
void DrawTexture(float coordMax, float angle, float x, float y, float x2, float y2, float z);
|
||||
|
||||
|
@ -65,6 +65,7 @@ FUNC2(void, glDrawRangeElementsEXT, glDrawRangeElements, "1.2", (GLenum, GLuint,
|
||||
|
||||
// GL_ARB_multitexture / GL1.3:
|
||||
FUNC2(void, glMultiTexCoord2fARB, glMultiTexCoord2f, "1.3", (int, float, float))
|
||||
FUNC2(void, glMultiTexCoord3fARB, glMultiTexCoord3f, "1.3", (int, float, float, float))
|
||||
FUNC2(void, glActiveTextureARB, glActiveTexture, "1.3", (int))
|
||||
FUNC2(void, glClientActiveTextureARB, glClientActiveTexture, "1.3", (int))
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "Game.h"
|
||||
|
||||
#include "graphics/GameView.h"
|
||||
#include "graphics/LOSTexture.h"
|
||||
#include "graphics/UnitManager.h"
|
||||
#include "lib/timer.h"
|
||||
#include "network/NetClient.h"
|
||||
@ -234,7 +235,10 @@ bool CGame::Update(double deltaTime, bool doInterpolate)
|
||||
|
||||
PROFILE("update");
|
||||
if (m_TurnManager->Update(deltaTime, maxTurns))
|
||||
{
|
||||
g_GUI->SendEventToAll("SimulationUpdate");
|
||||
GetView()->GetLOSTexture().MakeDirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (doInterpolate)
|
||||
|
@ -137,7 +137,6 @@ void CPatchRData::BuildBlends()
|
||||
{
|
||||
m_BlendSplats.clear();
|
||||
m_BlendVertices.clear();
|
||||
m_BlendVertexIndices.clear();
|
||||
|
||||
CTerrain* terrain = m_Patch->m_Parent;
|
||||
|
||||
@ -348,37 +347,29 @@ void CPatchRData::AddBlend(u16 i, u16 j, u8 shape)
|
||||
CalculateUV(dst.m_UVs, gx, gz);
|
||||
dst.m_AlphaUVs[0] = vtx[0].m_AlphaUVs[0];
|
||||
dst.m_AlphaUVs[1] = vtx[0].m_AlphaUVs[1];
|
||||
dst.m_LOSColor = vtx0.m_LOSColor;
|
||||
dst.m_Position = vtx0.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back((j * vsize) + i);
|
||||
|
||||
const SBaseVertex& vtx1 = m_Vertices[(j * vsize) + i + 1];
|
||||
CalculateUV(dst.m_UVs, gx + 1, gz);
|
||||
dst.m_AlphaUVs[0] = vtx[1].m_AlphaUVs[0];
|
||||
dst.m_AlphaUVs[1] = vtx[1].m_AlphaUVs[1];
|
||||
dst.m_LOSColor = vtx1.m_LOSColor;
|
||||
dst.m_Position = vtx1.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back((j * vsize) + i + 1);
|
||||
|
||||
const SBaseVertex& vtx2 = m_Vertices[((j + 1) * vsize) + i + 1];
|
||||
CalculateUV(dst.m_UVs, gx + 1, gz + 1);
|
||||
dst.m_AlphaUVs[0] = vtx[2].m_AlphaUVs[0];
|
||||
dst.m_AlphaUVs[1] = vtx[2].m_AlphaUVs[1];
|
||||
dst.m_LOSColor = vtx2.m_LOSColor;
|
||||
dst.m_Position = vtx2.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back(((j + 1) * vsize) + i + 1);
|
||||
|
||||
const SBaseVertex& vtx3 = m_Vertices[((j + 1) * vsize) + i];
|
||||
CalculateUV(dst.m_UVs, gx, gz + 1);
|
||||
dst.m_AlphaUVs[0] = vtx[3].m_AlphaUVs[0];
|
||||
dst.m_AlphaUVs[1] = vtx[3].m_AlphaUVs[1];
|
||||
dst.m_LOSColor = vtx3.m_LOSColor;
|
||||
dst.m_Position = vtx3.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back(((j + 1) * vsize) + i);
|
||||
}
|
||||
|
||||
void CPatchRData::BuildIndices()
|
||||
@ -391,7 +382,6 @@ void CPatchRData::BuildIndices()
|
||||
|
||||
// release existing indices and bins
|
||||
m_Indices.clear();
|
||||
m_ShadowMapIndices.clear();
|
||||
m_Splats.clear();
|
||||
|
||||
// build grid of textures on this patch and boundaries of adjacent patches
|
||||
@ -430,16 +420,6 @@ void CPatchRData::BuildIndices()
|
||||
}
|
||||
splat.m_IndexCount=m_Indices.size()-splat.m_IndexStart;
|
||||
}
|
||||
|
||||
// build indices for the shadow map pass
|
||||
for (ssize_t j=0;j<PATCH_SIZE;j++) {
|
||||
for (ssize_t i=0;i<PATCH_SIZE;i++) {
|
||||
m_ShadowMapIndices.push_back(u16(((j+0)*vsize+(i+0))+base));
|
||||
m_ShadowMapIndices.push_back(u16(((j+0)*vsize+(i+1))+base));
|
||||
m_ShadowMapIndices.push_back(u16(((j+1)*vsize+(i+1))+base));
|
||||
m_ShadowMapIndices.push_back(u16(((j+1)*vsize+(i+0))+base));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -474,7 +454,6 @@ void CPatchRData::BuildVertices()
|
||||
|
||||
// calculate vertex data
|
||||
terrain->CalcPosition(ix,iz,vertices[v].m_Position);
|
||||
vertices[v].m_LOSColor = SColor4ub(0, 0, 0, 0); // will be set to the proper value in Update()
|
||||
CalculateUV(vertices[v].m_UVs, ix, iz);
|
||||
|
||||
// Calculate diffuse lighting for this vertex
|
||||
@ -514,81 +493,19 @@ void CPatchRData::Update()
|
||||
|
||||
m_UpdateFlags=0;
|
||||
}
|
||||
|
||||
// Update vertex colors, which are affected by LOS
|
||||
|
||||
ssize_t px=m_Patch->m_X;
|
||||
ssize_t pz=m_Patch->m_Z;
|
||||
|
||||
CTerrain* terrain=m_Patch->m_Parent;
|
||||
ssize_t vsize=PATCH_SIZE+1;
|
||||
SColor4ub baseColour = terrain->GetBaseColour();
|
||||
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
|
||||
if (cmpRangeManager.null())
|
||||
{
|
||||
for (ssize_t j = 0; j < vsize; ++j)
|
||||
{
|
||||
for (ssize_t i = 0; i < vsize; ++i)
|
||||
{
|
||||
ssize_t v = (j*vsize)+i;
|
||||
m_Vertices[v].m_LOSColor = baseColour;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ICmpRangeManager::CLosQuerier los (cmpRangeManager->GetLosQuerier(g_Game->GetPlayerID()));
|
||||
|
||||
// this is very similar to BuildVertices(), but just for color
|
||||
for (ssize_t j = 0; j < vsize; j++)
|
||||
{
|
||||
for (ssize_t i = 0; i < vsize; i++)
|
||||
{
|
||||
ssize_t ix = px * PATCH_SIZE + i;
|
||||
ssize_t iz = pz * PATCH_SIZE + j;
|
||||
ssize_t v = (j * vsize) + i;
|
||||
|
||||
SColor4ub losMod;
|
||||
if (los.IsVisible(ix, iz))
|
||||
losMod = baseColour;
|
||||
else if (los.IsExplored(ix, iz))
|
||||
losMod = SColor4ub(178, 178, 178, 255);
|
||||
else
|
||||
losMod = SColor4ub(0, 0, 0, 255);
|
||||
|
||||
m_Vertices[v].m_LOSColor = losMod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// upload base vertices into their vertex buffer
|
||||
m_VBBase->m_Owner->UpdateChunkVertices(m_VBBase,m_Vertices);
|
||||
|
||||
// update blend colors by copying them from vertex colors
|
||||
for(size_t i=0; i<m_BlendVertices.size(); i++)
|
||||
{
|
||||
m_BlendVertices[i].m_LOSColor = m_Vertices[m_BlendVertexIndices[i]].m_LOSColor;
|
||||
}
|
||||
|
||||
// upload blend vertices into their vertex buffer too
|
||||
if(m_BlendVertices.size())
|
||||
{
|
||||
m_VBBlends->m_Owner->UpdateChunkVertices(m_VBBlends,&m_BlendVertices[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void CPatchRData::RenderBase(bool losColor)
|
||||
void CPatchRData::RenderBase()
|
||||
{
|
||||
debug_assert(m_UpdateFlags==0);
|
||||
|
||||
SBaseVertex *base=(SBaseVertex *)m_VBBase->m_Owner->Bind();
|
||||
|
||||
// setup data pointers
|
||||
GLsizei stride=sizeof(SBaseVertex);
|
||||
glVertexPointer(3,GL_FLOAT,stride,&base->m_Position[0]);
|
||||
glColorPointer(4,GL_UNSIGNED_BYTE,stride,losColor ? &base->m_LOSColor : &base->m_DiffuseColor);
|
||||
glTexCoordPointer(2,GL_FLOAT,stride,&base->m_UVs[0]);
|
||||
GLsizei stride = sizeof(SBaseVertex);
|
||||
glVertexPointer(3, GL_FLOAT, stride, &base->m_Position[0]);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &base->m_DiffuseColor);
|
||||
glTexCoordPointer(2, GL_FLOAT, stride, &base->m_UVs[0]);
|
||||
|
||||
// render each splat
|
||||
for (size_t i=0;i<m_Splats.size();i++) {
|
||||
@ -612,23 +529,44 @@ void CPatchRData::RenderBase(bool losColor)
|
||||
CVertexBuffer::Unbind();
|
||||
}
|
||||
|
||||
void CPatchRData::RenderStreams(int streamflags, bool losColor)
|
||||
void CPatchRData::RenderStreams(int streamflags)
|
||||
{
|
||||
debug_assert(m_UpdateFlags==0);
|
||||
|
||||
SBaseVertex* base=(SBaseVertex *)m_VBBase->m_Owner->Bind();
|
||||
|
||||
// setup data pointers
|
||||
GLsizei stride=sizeof(SBaseVertex);
|
||||
GLsizei stride = sizeof(SBaseVertex);
|
||||
glVertexPointer(3, GL_FLOAT, stride, &base->m_Position);
|
||||
if (streamflags & STREAM_UV0) {
|
||||
if (streamflags & STREAM_UV0)
|
||||
{
|
||||
glTexCoordPointer(2, GL_FLOAT, stride, &base->m_UVs);
|
||||
} else if (streamflags & STREAM_POSTOUV0) {
|
||||
}
|
||||
else if (streamflags & STREAM_POSTOUV0)
|
||||
{
|
||||
glTexCoordPointer(3, GL_FLOAT, stride, &base->m_Position);
|
||||
}
|
||||
if (streamflags & STREAM_POSTOUV1)
|
||||
{
|
||||
pglClientActiveTextureARB(GL_TEXTURE1);
|
||||
glTexCoordPointer(3, GL_FLOAT, stride, &base->m_Position);
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
}
|
||||
if (streamflags & STREAM_POSTOUV2)
|
||||
{
|
||||
pglClientActiveTextureARB(GL_TEXTURE2);
|
||||
glTexCoordPointer(3, GL_FLOAT, stride, &base->m_Position);
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
}
|
||||
if (streamflags & STREAM_POSTOUV3)
|
||||
{
|
||||
pglClientActiveTextureARB(GL_TEXTURE3);
|
||||
glTexCoordPointer(3, GL_FLOAT, stride, &base->m_Position);
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
}
|
||||
if (streamflags & STREAM_COLOR)
|
||||
{
|
||||
glColorPointer(4,GL_UNSIGNED_BYTE,stride,losColor ? &base->m_LOSColor : &base->m_DiffuseColor);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &base->m_DiffuseColor);
|
||||
}
|
||||
|
||||
// render all base splats at once
|
||||
@ -660,7 +598,6 @@ void CPatchRData::RenderBlends()
|
||||
// invalid - see http://gcc.gnu.org/ml/gcc/2003-11/msg00281.html - but it
|
||||
// doesn't seem to be worth changing this code since it works anyway.))
|
||||
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SBlendVertex,m_Position));
|
||||
glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SBlendVertex,m_LOSColor));
|
||||
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SBlendVertex,m_UVs[0]));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2009 Wildfire Games.
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -37,10 +37,10 @@ public:
|
||||
~CPatchRData();
|
||||
|
||||
void Update();
|
||||
void RenderBase(bool losColor);
|
||||
void RenderBase();
|
||||
void RenderBlends();
|
||||
void RenderOutline();
|
||||
void RenderStreams(int streamflags, bool losColor);
|
||||
void RenderStreams(int streamflags);
|
||||
void RenderPriorities();
|
||||
|
||||
private:
|
||||
@ -62,15 +62,11 @@ private:
|
||||
SColor4ub m_DiffuseColor;
|
||||
// vertex uvs for base texture
|
||||
float m_UVs[2];
|
||||
// color modulation from LOS
|
||||
SColor4ub m_LOSColor;
|
||||
};
|
||||
|
||||
struct SBlendVertex {
|
||||
// vertex position
|
||||
CVector3D m_Position;
|
||||
// color modulation from LOS
|
||||
SColor4ub m_LOSColor;
|
||||
// vertex uvs for base texture
|
||||
float m_UVs[2];
|
||||
// vertex uvs for alpha texture
|
||||
@ -108,19 +104,12 @@ private:
|
||||
// indices into base vertices for the base splats
|
||||
std::vector<unsigned short> m_Indices;
|
||||
|
||||
// indices into base vertices for the shadow map pass
|
||||
std::vector<unsigned short> m_ShadowMapIndices;
|
||||
|
||||
// list of base splats to apply to this patch
|
||||
std::vector<SSplat> m_Splats;
|
||||
|
||||
// vertices to use for blending transition texture passes
|
||||
std::vector<SBlendVertex> m_BlendVertices;
|
||||
|
||||
// remembers the index in the m_Vertices array of each blend vertex, so that we can
|
||||
// properly update its color for fog of war and shroud of darkness
|
||||
std::vector<size_t> m_BlendVertexIndices;
|
||||
|
||||
// splats used in blend pass
|
||||
std::vector<SSplat> m_BlendSplats;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -434,11 +434,12 @@ CRenderer::~CRenderer()
|
||||
void CRenderer::EnumCaps()
|
||||
{
|
||||
// assume support for nothing
|
||||
m_Caps.m_VBO=false;
|
||||
m_Caps.m_TextureBorderClamp=false;
|
||||
m_Caps.m_GenerateMipmaps=false;
|
||||
m_Caps.m_VertexShader=false;
|
||||
m_Caps.m_FragmentShader=false;
|
||||
m_Caps.m_VBO = false;
|
||||
m_Caps.m_TextureBorderClamp = false;
|
||||
m_Caps.m_GenerateMipmaps = false;
|
||||
m_Caps.m_VertexShader = false;
|
||||
m_Caps.m_FragmentShader = false;
|
||||
m_Caps.m_Shadows = false;
|
||||
m_Caps.m_DepthTextureShadows = false;
|
||||
m_Caps.m_FramebufferObject = false;
|
||||
|
||||
@ -448,12 +449,15 @@ void CRenderer::EnumCaps()
|
||||
m_Caps.m_VBO=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ogl_HaveExtension("GL_ARB_texture_border_clamp")) {
|
||||
m_Caps.m_TextureBorderClamp=true;
|
||||
}
|
||||
|
||||
if (ogl_HaveExtension("GL_SGIS_generate_mipmap")) {
|
||||
m_Caps.m_GenerateMipmaps=true;
|
||||
}
|
||||
|
||||
if (0 == ogl_HaveExtensions(0, "GL_ARB_shader_objects", "GL_ARB_shading_language_100", NULL))
|
||||
{
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_shader"))
|
||||
@ -462,6 +466,15 @@ void CRenderer::EnumCaps()
|
||||
m_Caps.m_FragmentShader=true;
|
||||
}
|
||||
|
||||
if (ogl_max_tex_units >= 3)
|
||||
{
|
||||
// To render shadows plus fog-of-war in a single lighting pass (see
|
||||
// TerrainRenderer.cpp) we need >= 3 TMUs. Only really ancient hardware
|
||||
// doesn't support that, so instead of implementing a compatible fallback
|
||||
// we'll just disable shadows entirely unless there's enough TMUs.
|
||||
m_Caps.m_Shadows = true;
|
||||
}
|
||||
|
||||
if (0 == ogl_HaveExtensions(0, "GL_ARB_shadow", "GL_ARB_depth_texture", NULL)) {
|
||||
// According to Delphi3d.net, all relevant graphics chips that support depth textures
|
||||
// (i.e. Geforce3+, Radeon9500+, even i915) also have >= 4 TMUs, so this restriction
|
||||
@ -470,6 +483,7 @@ void CRenderer::EnumCaps()
|
||||
if (ogl_max_tex_units >= 4)
|
||||
m_Caps.m_DepthTextureShadows = true;
|
||||
}
|
||||
|
||||
if (!m_Options.m_NoFramebufferObject)
|
||||
{
|
||||
if (ogl_HaveExtension("GL_EXT_framebuffer_object"))
|
||||
@ -764,7 +778,7 @@ void CRenderer::BeginFrame()
|
||||
// choose model renderers for this frame
|
||||
int vertexType;
|
||||
|
||||
if (m_Options.m_Shadows && m->shadow->GetUseDepthTexture())
|
||||
if (m_Caps.m_Shadows && m_Options.m_Shadows && m->shadow->GetUseDepthTexture())
|
||||
{
|
||||
vertexType = OnlyDiffuse;
|
||||
m->Model.ModNormal = m->Model.ModPlainLit;
|
||||
@ -884,7 +898,7 @@ void CRenderer::RenderPatches()
|
||||
}
|
||||
|
||||
// render all the patches, including blend pass
|
||||
m->terrainRenderer->RenderTerrain(m_Options.m_Shadows ? m->shadow : 0);
|
||||
m->terrainRenderer->RenderTerrain((m_Caps.m_Shadows && m_Options.m_Shadows) ? m->shadow : 0);
|
||||
|
||||
if (m_TerrainRenderMode==WIREFRAME) {
|
||||
// switch wireframe off again
|
||||
@ -1224,7 +1238,7 @@ void CRenderer::RenderSubmissions()
|
||||
m->overlayRenderer.PrepareForRendering();
|
||||
PROFILE_END("prepare overlays");
|
||||
|
||||
if (m_Options.m_Shadows)
|
||||
if (m_Caps.m_Shadows && m_Options.m_Shadows)
|
||||
{
|
||||
RenderShadowMap();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2009 Wildfire Games.
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -47,15 +47,18 @@ class CTextureManager;
|
||||
enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES };
|
||||
|
||||
// stream flags
|
||||
#define STREAM_POS 0x01
|
||||
#define STREAM_NORMAL 0x02
|
||||
#define STREAM_COLOR 0x04
|
||||
#define STREAM_UV0 0x08
|
||||
#define STREAM_UV1 0x10
|
||||
#define STREAM_UV2 0x20
|
||||
#define STREAM_UV3 0x40
|
||||
#define STREAM_POSTOUV0 0x80
|
||||
#define STREAM_TEXGENTOUV1 0x100
|
||||
#define STREAM_POS (1 << 0)
|
||||
#define STREAM_NORMAL (1 << 1)
|
||||
#define STREAM_COLOR (1 << 2)
|
||||
#define STREAM_UV0 (1 << 3)
|
||||
#define STREAM_UV1 (1 << 4)
|
||||
#define STREAM_UV2 (1 << 5)
|
||||
#define STREAM_UV3 (1 << 6)
|
||||
#define STREAM_POSTOUV0 (1 << 7)
|
||||
#define STREAM_POSTOUV1 (1 << 8)
|
||||
#define STREAM_POSTOUV2 (1 << 9)
|
||||
#define STREAM_POSTOUV3 (1 << 10)
|
||||
#define STREAM_TEXGENTOUV1 (1 << 11)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SVertex3D: simple 3D vertex declaration
|
||||
@ -152,6 +155,7 @@ public:
|
||||
bool m_GenerateMipmaps;
|
||||
bool m_VertexShader;
|
||||
bool m_FragmentShader;
|
||||
bool m_Shadows;
|
||||
bool m_DepthTextureShadows;
|
||||
bool m_FramebufferObject;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include "graphics/Camera.h"
|
||||
#include "graphics/LightEnv.h"
|
||||
#include "graphics/LOSTexture.h"
|
||||
#include "graphics/Patch.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/GameView.h"
|
||||
@ -37,9 +38,6 @@
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/World.h"
|
||||
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
|
||||
#include "renderer/PatchRData.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/ShadowMap.h"
|
||||
@ -159,7 +157,6 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
|
||||
// switch on required client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// render everything fullbright
|
||||
@ -167,11 +164,9 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
pglActiveTextureARB(GL_TEXTURE0);
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
||||
|
||||
// Set alpha to 1.0
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
@ -183,7 +178,7 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
for(size_t i = 0; i < m->visiblePatches.size(); ++i)
|
||||
{
|
||||
CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData();
|
||||
patchdata->RenderBase(true); // with LOS color
|
||||
patchdata->RenderBase();
|
||||
}
|
||||
|
||||
// render blends
|
||||
@ -225,6 +220,9 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
// Now apply lighting
|
||||
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
|
||||
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
glEnableClientState(GL_COLOR_ARRAY); // diffuse lighting colours
|
||||
|
||||
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
|
||||
// GL_TEXTURE_ENV_COLOR requires four floats, so we shouldn't use the RGBColor directly
|
||||
@ -234,6 +232,10 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
lightEnv.m_TerrainAmbientColor.Z,
|
||||
1.f
|
||||
};
|
||||
|
||||
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
|
||||
|
||||
int streamflags = STREAM_POS|STREAM_COLOR|STREAM_POSTOUV0;
|
||||
|
||||
if (!shadow)
|
||||
{
|
||||
@ -244,7 +246,7 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
// so assume that's still valid to use.
|
||||
// (TODO: That's a bit of an ugly hack.)
|
||||
|
||||
// Shadow rendering disabled: Ambient + Diffuse
|
||||
// Shadow rendering disabled: (Ambient + Diffuse) * LOS
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
@ -256,7 +258,25 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, terrainAmbientColor);
|
||||
|
||||
|
||||
losTexture.BindTexture(1);
|
||||
pglClientActiveTextureARB(GL_TEXTURE1);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
streamflags |= STREAM_POSTOUV1;
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(&losTexture.GetTextureMatrix()._11);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -271,7 +291,7 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
|
||||
if (shadow->GetUseDepthTexture())
|
||||
{
|
||||
// Ambient + ShTranslucency * Diffuse * (1 - Shadow) + Diffuse * Shadow
|
||||
// (Ambient + ShTranslucency * Diffuse * (1 - Shadow) + Diffuse * Shadow) * LOS
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR);
|
||||
@ -313,11 +333,29 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, terrainAmbientColor);
|
||||
|
||||
|
||||
losTexture.BindTexture(3);
|
||||
pglClientActiveTextureARB(GL_TEXTURE3);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
streamflags |= STREAM_POSTOUV3;
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(&losTexture.GetTextureMatrix()._11);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ambient + Diffuse * Shadow
|
||||
// (Ambient + Diffuse * Shadow) * LOS
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
@ -341,6 +379,24 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, terrainAmbientColor);
|
||||
|
||||
losTexture.BindTexture(2);
|
||||
pglClientActiveTextureARB(GL_TEXTURE2);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
streamflags |= STREAM_POSTOUV2;
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(&losTexture.GetTextureMatrix()._11);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,25 +406,52 @@ void TerrainRenderer::RenderTerrain(ShadowMap* shadow)
|
||||
for (size_t i = 0; i < m->visiblePatches.size(); ++i)
|
||||
{
|
||||
CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData();
|
||||
patchdata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_POSTOUV0, false);
|
||||
patchdata->RenderStreams(streamflags);
|
||||
}
|
||||
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
// restore OpenGL state
|
||||
if (shadow)
|
||||
g_Renderer.BindTexture(1, 0);
|
||||
if (!shadow)
|
||||
{
|
||||
pglClientActiveTextureARB(GL_TEXTURE1);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shadow->GetUseDepthTexture())
|
||||
g_Renderer.BindTexture(2,0);
|
||||
{
|
||||
g_Renderer.BindTexture(2, 0);
|
||||
g_Renderer.BindTexture(3, 0);
|
||||
|
||||
pglClientActiveTextureARB(GL_TEXTURE3);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Renderer.BindTexture(2, 0);
|
||||
|
||||
pglClientActiveTextureARB(GL_TEXTURE2);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
}
|
||||
g_Renderer.BindTexture(1,0);
|
||||
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
pglActiveTextureARB(GL_TEXTURE0);
|
||||
glDepthMask(1);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_BLEND);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
@ -386,7 +469,7 @@ void TerrainRenderer::RenderPatches()
|
||||
for(size_t i = 0; i < m->visiblePatches.size(); ++i)
|
||||
{
|
||||
CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData();
|
||||
patchdata->RenderStreams(STREAM_POS, true);
|
||||
patchdata->RenderStreams(STREAM_POS);
|
||||
}
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
@ -435,9 +518,7 @@ void TerrainRenderer::RenderWater()
|
||||
}
|
||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
||||
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
|
||||
debug_assert(!cmpRangeManager.null());
|
||||
ICmpRangeManager::CLosQuerier los (cmpRangeManager->GetLosQuerier(g_Game->GetPlayerID()));
|
||||
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
@ -479,6 +560,23 @@ void TerrainRenderer::RenderWater()
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
// Multiply by LOS texture
|
||||
losTexture.BindTexture(1);
|
||||
pglClientActiveTextureARB(GL_TEXTURE1);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glLoadMatrixf(&losTexture.GetTextureMatrix()._11);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
}
|
||||
|
||||
// Set the proper LOD bias
|
||||
@ -488,7 +586,6 @@ void TerrainRenderer::RenderWater()
|
||||
CVector3D camPos = camera.m_Orientation.GetTranslation();
|
||||
|
||||
GLint vertexDepth = 0; // water depth attribute, if using fancy water
|
||||
GLint losMultiplier = 0; // LOS multiplier, if using fancy water
|
||||
|
||||
if(fancy)
|
||||
{
|
||||
@ -500,6 +597,8 @@ void TerrainRenderer::RenderWater()
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glBindTexture( GL_TEXTURE_2D, WaterMgr->m_RefractionTexture );
|
||||
|
||||
losTexture.BindTexture(3);
|
||||
|
||||
// Bind water shader and set arguments
|
||||
ogl_program_use( m->fancyWaterShader );
|
||||
|
||||
@ -518,9 +617,11 @@ void TerrainRenderer::RenderWater()
|
||||
GLint translation = ogl_program_get_uniform_location( m->fancyWaterShader, "translation" );
|
||||
GLint reflectionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMatrix" );
|
||||
GLint refractionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMatrix" );
|
||||
GLint losMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "losMatrix" );
|
||||
GLint normalMap = ogl_program_get_uniform_location( m->fancyWaterShader, "normalMap" );
|
||||
GLint reflectionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMap" );
|
||||
GLint refractionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMap" );
|
||||
GLint losMap = ogl_program_get_uniform_location( m->fancyWaterShader, "losMap" );
|
||||
|
||||
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
|
||||
pglUniform3fvARB( ambient, 1, &lightEnv.m_TerrainAmbientColor.X );
|
||||
@ -537,13 +638,14 @@ void TerrainRenderer::RenderWater()
|
||||
pglUniform4fARB( translation, tx, ty, 0, 0 );
|
||||
pglUniformMatrix4fvARB( reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11 );
|
||||
pglUniformMatrix4fvARB( refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11 );
|
||||
pglUniformMatrix4fvARB( losMatrix, 1, false, &losTexture.GetTextureMatrix()._11 );
|
||||
pglUniform1iARB( normalMap, 0 ); // texture unit 0
|
||||
pglUniform1iARB( reflectionMap, 1 ); // texture unit 1
|
||||
pglUniform1iARB( refractionMap, 2 ); // texture unit 2
|
||||
pglUniform1iARB( losMap, 3 ); // texture unit 3
|
||||
pglUniform3fvARB( cameraPos, 1, &camPos.X );
|
||||
|
||||
vertexDepth = ogl_program_get_attrib_location( m->fancyWaterShader, "vertexDepth" );
|
||||
losMultiplier = ogl_program_get_attrib_location( m->fancyWaterShader, "losMultiplier" );
|
||||
}
|
||||
|
||||
float repeatPeriod = (fancy ? WaterMgr->m_RepeatPeriod : 16.0f);
|
||||
@ -589,18 +691,9 @@ void TerrainRenderer::RenderWater()
|
||||
|
||||
float terrainHeight = terrain->GetVertexGroundLevel(ix, iz);
|
||||
|
||||
float losMod;
|
||||
if (los.IsVisible(ix, iz))
|
||||
losMod = 1.0f;
|
||||
else if (los.IsExplored(ix, iz))
|
||||
losMod = 0.7f;
|
||||
else
|
||||
losMod = 0.0f;
|
||||
|
||||
if (fancy)
|
||||
{
|
||||
pglVertexAttrib1fARB(vertexDepth, WaterMgr->m_WaterHeight - terrainHeight);
|
||||
pglVertexAttrib1fARB(losMultiplier, losMod);
|
||||
pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod);
|
||||
glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ);
|
||||
}
|
||||
@ -616,11 +709,12 @@ void TerrainRenderer::RenderWater()
|
||||
// Invert and set boundaries
|
||||
FresnelScalar = 1.f - (FresnelScalar * 0.6);
|
||||
|
||||
glColor4f(WaterMgr->m_WaterColor.r*losMod,
|
||||
WaterMgr->m_WaterColor.g*losMod,
|
||||
WaterMgr->m_WaterColor.b*losMod,
|
||||
glColor4f(WaterMgr->m_WaterColor.r,
|
||||
WaterMgr->m_WaterColor.g,
|
||||
WaterMgr->m_WaterColor.b,
|
||||
alpha * FresnelScalar);
|
||||
pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod);
|
||||
pglMultiTexCoord3fARB(GL_TEXTURE1, vertX, WaterMgr->m_WaterHeight, vertZ);
|
||||
glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ);
|
||||
}
|
||||
|
||||
@ -630,25 +724,30 @@ void TerrainRenderer::RenderWater()
|
||||
}
|
||||
glEnd();
|
||||
|
||||
if(fancy)
|
||||
if (fancy)
|
||||
{
|
||||
// Unbind the refraction/reflection textures and the shader
|
||||
// Unbind the LOS/refraction/reflection textures and the shader
|
||||
|
||||
pglActiveTextureARB( GL_TEXTURE1_ARB );
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
g_Renderer.BindTexture(3, 0);
|
||||
g_Renderer.BindTexture(2, 0);
|
||||
g_Renderer.BindTexture(1, 0);
|
||||
|
||||
pglActiveTextureARB( GL_TEXTURE2_ARB );
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
|
||||
pglActiveTextureARB( GL_TEXTURE0_ARB );
|
||||
pglActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
ogl_program_use( 0 );
|
||||
ogl_program_use(0);
|
||||
}
|
||||
|
||||
if(!fancy)
|
||||
if (!fancy)
|
||||
{
|
||||
g_Renderer.BindTexture(1, 0);
|
||||
pglClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glLoadIdentity();
|
||||
|
||||
pglActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
pglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
// Clean up the texture matrix and blend mode
|
||||
glLoadIdentity();
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
@ -882,6 +882,8 @@ public:
|
||||
*/
|
||||
inline bool LosIsOffWorld(ssize_t i, ssize_t j)
|
||||
{
|
||||
const ssize_t edgeSize = 3; // number of vertexes around the edge that will be off-world
|
||||
|
||||
if (m_LosCircular)
|
||||
{
|
||||
// With a circular map, vertex is off-world if hypot(i - size/2, j - size/2) >= size/2:
|
||||
@ -889,13 +891,19 @@ public:
|
||||
ssize_t dist2 = (i - m_TerrainVerticesPerSide/2)*(i - m_TerrainVerticesPerSide/2)
|
||||
+ (j - m_TerrainVerticesPerSide/2)*(j - m_TerrainVerticesPerSide/2);
|
||||
|
||||
if (dist2 >= (m_TerrainVerticesPerSide/2)*(m_TerrainVerticesPerSide/2))
|
||||
return true;
|
||||
ssize_t r = m_TerrainVerticesPerSide/2 - edgeSize + 1;
|
||||
// subtract a bit from the radius to ensure nice
|
||||
// SoD blurring around the edges of the map
|
||||
|
||||
return (dist2 >= r*r);
|
||||
}
|
||||
else
|
||||
{
|
||||
// With a square map, the outermost edge of the map should be off-world,
|
||||
// so the SoD texture blends out nicely
|
||||
|
||||
// With a square map, nothing is off-world
|
||||
|
||||
return false;
|
||||
return (i < edgeSize || j < edgeSize || i >= m_TerrainVerticesPerSide-edgeSize || j >= m_TerrainVerticesPerSide-edgeSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,9 +169,10 @@ public:
|
||||
{
|
||||
private:
|
||||
friend class CCmpRangeManager;
|
||||
friend class TestLOSTexture;
|
||||
|
||||
CLosQuerier(int player, const std::vector<u32>& data, ssize_t verticesPerSide) :
|
||||
m_Data(data), m_VerticesPerSide(verticesPerSide)
|
||||
m_Data(&data[0]), m_VerticesPerSide(verticesPerSide)
|
||||
{
|
||||
if (player > 0 && player <= 16)
|
||||
m_PlayerMask = LOS_MASK << (2*(player-1));
|
||||
@ -192,7 +193,7 @@ public:
|
||||
debug_assert(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide);
|
||||
#endif
|
||||
// Check high bit of each bit-pair
|
||||
if ((m_Data.at(j*m_VerticesPerSide + i) & m_PlayerMask) & 0xAAAAAAAAu)
|
||||
if ((m_Data[j*m_VerticesPerSide + i] & m_PlayerMask) & 0xAAAAAAAAu)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@ -208,7 +209,7 @@ public:
|
||||
debug_assert(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide);
|
||||
#endif
|
||||
// Check low bit of each bit-pair
|
||||
if ((m_Data.at(j*m_VerticesPerSide + i) & m_PlayerMask) & 0x55555555u)
|
||||
if ((m_Data[j*m_VerticesPerSide + i] & m_PlayerMask) & 0x55555555u)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@ -216,7 +217,7 @@ public:
|
||||
|
||||
private:
|
||||
u32 m_PlayerMask;
|
||||
const std::vector<u32>& m_Data;
|
||||
const u32* m_Data;
|
||||
ssize_t m_VerticesPerSide;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user