Permalink
Browse files

ROAM: render a map border (WIP & FFP atm)

  • Loading branch information...
1 parent 61bea7a commit 912eda90600aba04fe71628361766987ffd37821 jK committed Mar 23, 2013
@@ -20,6 +20,7 @@ class IMeshDrawer
virtual void Update() = 0;
virtual void DrawMesh(const DrawPass::e& drawPass) = 0;
+ virtual void DrawBorderMesh(const DrawPass::e& drawPass) = 0;
};
#endif // _MESH_DRAWER_H_
@@ -25,6 +25,7 @@ class CLegacyMeshDrawer : public IMeshDrawer
void Update() {}
void DrawMesh(const DrawPass::e& drawPass);
+ void DrawBorderMesh(const DrawPass::e& drawPass) {}
void DrawShadowMesh();
private:
View
@@ -16,6 +16,7 @@
#include "Game/Camera.h"
#include "Map/ReadMap.h"
#include "Map/SMF/SMFGroundDrawer.h"
+#include "Rendering/GL/VertexArray.h"
#include "Sim/Misc/GlobalConstants.h"
#include "System/Log/ILog.h"
#include "System/TimeProfiler.h"
@@ -357,7 +358,7 @@ void Patch::RecursTessellate(TriTreeNode* const tri, const int2 left, const int2
const int sizeY = std::max(left.y - right.y, right.y - left.y);
const int size = std::max(sizeX, sizeY);
- // Take both distance and variance and patch size into consideration
+ // Take distance, variance and patch size into consideration
TriVariance = (myVariance * PATCH_SIZE * size) * camDistLODFactor;
} else {
TriVariance = 10.0f; // >1 -> When variance isn't saved issue further tessellation
@@ -380,11 +381,11 @@ void Patch::RecursTessellate(TriTreeNode* const tri, const int2 left, const int2
}
}
+
// ---------------------------------------------------------------------
// Render the tree.
//
-
void Patch::RecursRender(TriTreeNode* const tri, const int2 left, const int2 right, const int2 apex)
{
if ( tri->IsLeaf()) {
@@ -402,6 +403,13 @@ void Patch::RecursRender(TriTreeNode* const tri, const int2 left, const int2 rig
}
+void Patch::GenerateIndices()
+{
+ indices.clear();
+ RecursRender(&m_BaseLeft, int2(0, PATCH_SIZE), int2(PATCH_SIZE, 0), int2(0, 0) );
+ RecursRender(&m_BaseRight, int2(PATCH_SIZE, 0), int2(0, PATCH_SIZE), int2(PATCH_SIZE, PATCH_SIZE));
+}
+
// ---------------------------------------------------------------------
// Computes Variance over the entire tree. Does not examine node relationships.
@@ -427,7 +435,7 @@ float Patch::RecursComputeVariance(const int leftX, const int leftY, const float
// Variance of this triangle is the actual height at it's hypotenuse midpoint minus the interpolated height.
// Use values passed on the stack instead of re-accessing the Height Field.
float myVariance = math::fabs(centerZ - ((leftZ + rightZ) / 2));
-
+
if (leftZ*rightZ<0 || leftZ*centerZ<0 || rightZ*centerZ<0)
myVariance = std::max(myVariance * 1.5f, 20.0f); //shore lines get more variance for higher accuracy
@@ -511,6 +519,7 @@ void Patch::Tessellate(const float3& campos, int groundDetail)
1);
}
+
// ---------------------------------------------------------------------
// Render the mesh.
//
@@ -551,11 +560,84 @@ void Patch::Draw()
}
-void Patch::GenerateIndices()
+void Patch::DrawBorder()
{
- indices.clear();
- RecursRender(&m_BaseLeft, int2(0, PATCH_SIZE), int2(PATCH_SIZE, 0), int2(0, 0) );
- RecursRender(&m_BaseRight, int2(PATCH_SIZE, 0), int2(0, PATCH_SIZE), int2(PATCH_SIZE, PATCH_SIZE));
+ CVertexArray* va = GetVertexArray();
+ GenerateBorderIndices(va);
+ va->DrawArrayC(GL_TRIANGLES);
+}
+
+
+void Patch::RecursBorderRender(CVertexArray* va, TriTreeNode* const& tri, const int2& left, const int2& right, const int2& apex, int i, bool left_)
+{
+ if ( tri->IsLeaf() ) {
+ const float3& v1 = *(float3*)&vertices[(apex.x + apex.y * (PATCH_SIZE + 1))*3];
+ const float3& v2 = *(float3*)&vertices[(left.x + left.y * (PATCH_SIZE + 1))*3];
+ const float3& v3 = *(float3*)&vertices[(right.x + right.y * (PATCH_SIZE + 1))*3];
+
+ const unsigned char white[] = {255,255,255,255};
+ const unsigned char trans[] = {255,255,255,0};
+
+ if (i % 2 == 0) {
+ va->AddVertexC(float3(v2.x, v2.y, v2.z), white);
+ va->AddVertexC(float3(v2.x, -400.0f, v2.z), trans);
+ va->AddVertexC(float3(v3.x, v3.y, v3.z), white);
+
+ va->AddVertexC(float3(v3.x, v3.y, v3.z), white);
+ va->AddVertexC(float3(v2.x, -400.0f, v2.z), trans);
+ va->AddVertexC(float3(v3.x, -400.0f, v3.z), trans);
+ } else {
+ if (left_) {
+ va->AddVertexC(float3(v1.x, v1.y, v1.z), white);
+ va->AddVertexC(float3(v1.x, -400.0f, v1.z), trans);
+ va->AddVertexC(float3(v2.x, v2.y, v2.z), white);
+
+ va->AddVertexC(float3(v2.x, v2.y, v2.z), white);
+ va->AddVertexC(float3(v1.x, -400.0f, v1.z), trans);
+ va->AddVertexC(float3(v2.x, -400.0f, v2.z), trans);
+ } else {
+ va->AddVertexC(float3(v3.x, v3.y, v3.z), white);
+ va->AddVertexC(float3(v3.x, -400.0f, v3.z), trans);
+ va->AddVertexC(float3(v1.x, v1.y, v1.z), white);
+
+ va->AddVertexC(float3(v1.x, v1.y, v1.z), white);
+ va->AddVertexC(float3(v3.x, -400.0f, v3.z), trans);
+ va->AddVertexC(float3(v1.x, -400.0f, v1.z), trans);
+ }
+ }
+
+ } else {
+ const int2 center(
+ (left.x + right.x) >> 1, // Compute X coordinate of center of Hypotenuse
+ (left.y + right.y) >> 1 // Compute Y coord...
+ );
+
+ if (i % 2 == 0) {
+ RecursBorderRender(va, tri->LeftChild, apex, left, center, i + 1, !left_);
+ RecursBorderRender(va, tri->RightChild, right, apex, center, i + 1, left_);
+ } else {
+ if (left_) {
+ RecursBorderRender(va, tri->LeftChild, apex, left, center, i + 1, left_);
+ } else {
+ RecursBorderRender(va, tri->RightChild, right, apex, center, i + 1, !left_);
+ }
+ }
+ }
+}
+
+void Patch::GenerateBorderIndices(CVertexArray* va)
+{
+ va->Initialize();
+
+ const bool isLeftBorder = !m_BaseLeft.LeftNeighbor;
+ const bool isBottomBorder = !m_BaseRight.RightNeighbor;
+ const bool isRightBorder = !m_BaseLeft.RightNeighbor;
+ const bool isTopBorder = !m_BaseRight.LeftNeighbor;
+
+ if (isLeftBorder) RecursBorderRender(va, &m_BaseLeft, int2(0, PATCH_SIZE), int2(PATCH_SIZE, 0), int2(0, 0), 1, true);
+ if (isBottomBorder) RecursBorderRender(va, &m_BaseRight, int2(PATCH_SIZE, 0), int2(0, PATCH_SIZE), int2(PATCH_SIZE, PATCH_SIZE), 1, false);
+ if (isRightBorder) RecursBorderRender(va, &m_BaseLeft, int2(0, PATCH_SIZE), int2(PATCH_SIZE, 0), int2(0, 0), 1, false);
+ if (isTopBorder) RecursBorderRender(va, &m_BaseRight, int2(PATCH_SIZE, 0), int2(0, PATCH_SIZE), int2(PATCH_SIZE, PATCH_SIZE), 1, true);
}
View
@@ -113,7 +113,7 @@ class Patch
friend class CPatchInViewChecker;
void Reset();
-
+
TriTreeNode* GetBaseLeft() { return &m_BaseLeft; }
TriTreeNode* GetBaseRight() { return &m_BaseRight; }
char IsDirty() const { return m_isDirty; }
@@ -128,7 +128,7 @@ class Patch
void GenerateIndices();
void Upload();
void Draw();
-
+ void DrawBorder();
void SetSquareTexture() const;
public:
@@ -147,6 +147,8 @@ class Patch
void RecursRender(TriTreeNode* const tri, const int2 left, const int2 right, const int2 apex);
float RecursComputeVariance(const int leftX, const int leftY, const float leftZ, const int rightX, const int rightY, const float rightZ, const int apexX, const int apexY, const float apexZ, const int node);
+ void RecursBorderRender(CVertexArray* va, TriTreeNode* const& tri, const int2& left, const int2& right, const int2& apex, int i, bool left_);
+ void GenerateBorderIndices(CVertexArray* va);
protected:
static RenderMode renderMode;
@@ -247,6 +247,25 @@ void CRoamMeshDrawer::DrawMesh(const DrawPass::e& drawPass)
}
}
+void CRoamMeshDrawer::DrawBorderMesh(const DrawPass::e& drawPass)
+{
+ const bool inShadowPass = (drawPass == DrawPass::Shadow);
+ CCamera* cam = (inShadowPass)? camera: cam2;
+
+ for (int Y = 0; Y < numPatchesY; ++Y) {
+ for (int X = 0; X < numPatchesX; ++X) {
+ if (X % (numPatchesX - 1) == 0 || Y % (numPatchesY - 1) == 0) {
+ Patch& p = m_Patches[Y * numPatchesX + X];
+ if (p.IsVisible()) {
+ if (!inShadowPass)
+ p.SetSquareTexture();
+
+ p.DrawBorder();
+ }
+ }
+ }
+ }
+}
#ifdef DRAW_DEBUG_IN_MINIMAP
void CRoamMeshDrawer::DrawInMiniMap()
@@ -49,6 +49,7 @@ class CRoamMeshDrawer : public IMeshDrawer, public CEventClient
void Update();
void DrawMesh(const DrawPass::e& drawPass);
+ void DrawBorderMesh(const DrawPass::e& drawPass);
private:
void Reset();
@@ -245,6 +245,8 @@ void CSMFGroundDrawer::Draw(const DrawPass::e& drawPass)
smfRenderState->Disable(this, drawPass);
glDisable(GL_CULL_FACE);
+ DrawBorder(drawPass);
+
if (drawPass == DrawPass::Normal) {
if (mapInfo->water.hasWaterPlane) {
DrawWaterPlane(false);
@@ -256,6 +258,67 @@ void CSMFGroundDrawer::Draw(const DrawPass::e& drawPass)
}
+void CSMFGroundDrawer::DrawBorder(const DrawPass::e drawPass)
+{
+ glDisable(GL_BLEND);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ glEnable(GL_TEXTURE_2D); // needed for the non-shader case
+
+ smfRenderState = smfRenderStateFFP;
+ //smfRenderState->Enable(this, drawPass);
+
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ glActiveTexture(GL_TEXTURE2);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, smfMap->GetDetailTexture());
+
+ glMultiTexCoord4f(GL_TEXTURE2_ARB, 1.0f, 1.0f, 1.0f, 1.0f);
+ SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), -0.5f / gs->pwr2mapx, -0.5f / gs->pwr2mapy);
+
+ static const GLfloat planeX[] = {0.005f, 0.0f, 0.005f, 0.5f};
+ static const GLfloat planeZ[] = {0.0f, 0.005f, 0.0f, 0.5f};
+
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGenfv(GL_S, GL_EYE_PLANE, planeX);
+ glEnable(GL_TEXTURE_GEN_S);
+
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGenfv(GL_T, GL_EYE_PLANE, planeZ);
+ glEnable(GL_TEXTURE_GEN_T);
+
+ glActiveTexture(GL_TEXTURE3);
+ glDisable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE1);
+ glDisable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE0);
+ glEnable(GL_TEXTURE_2D); // needed for the non-shader case
+
+ glEnable(GL_BLEND);
+
+ if (wireframe) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+ /*if (mapInfo->map.voidWater && (drawPass != DrawPass::WaterReflection)) {
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.9f);
+ }*/
+
+ meshDrawer->DrawBorderMesh(drawPass);
+
+ /*if (mapInfo->map.voidWater && (drawPass != DrawPass::WaterReflection)) {
+ glDisable(GL_ALPHA_TEST);
+ }*/
+ if (wireframe) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+
+ smfRenderState->Disable(this, drawPass);
+ glDisable(GL_CULL_FACE);
+}
+
+
void CSMFGroundDrawer::DrawShadowPass()
{
if (mapInfo->map.voidWater && readmap->currMaxHeight < 0.0f) {
@@ -55,9 +55,7 @@ class CSMFGroundDrawer : public CBaseGroundDrawer
bool LoadMapShaders();
void CreateWaterPlanes(bool camOufOfMap);
inline void DrawWaterPlane(bool drawWaterReflection);
-
- void SetupTextureUnits(bool drawReflection);
- void ResetTextureUnits(bool drawReflection);
+ inline void DrawBorder(const DrawPass::e drawPass);
protected:
CSMFReadMap* smfMap;

0 comments on commit 912eda9

Please sign in to comment.