430 lines
13 KiB
C++
430 lines
13 KiB
C++
// TopRendererWnd.cpp: implementation of the CTopRendererWnd class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "TopRendererWnd.h"
|
|
#include "Heightmap.h"
|
|
#include "VegetationMap.h"
|
|
#include "DisplaySettings.h"
|
|
#include "EditTool.h"
|
|
#include "ViewManager.h"
|
|
#include "Objects\ObjectManager.h"
|
|
|
|
#include "TerrainTexGen.h"
|
|
//#include "Image.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
// Size of the surface texture
|
|
#define SURFACE_TEXTURE_WIDTH 512
|
|
|
|
#define MARKER_SIZE 6.0f
|
|
#define MARKER_DIR_SIZE 10.0f
|
|
#define SELECTION_RADIUS 30.0f
|
|
|
|
#define GL_RGBA 0x1908
|
|
#define GL_BGRA 0x80E1
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
IMPLEMENT_DYNCREATE(CTopRendererWnd,C2DViewport)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
BEGIN_MESSAGE_MAP(CTopRendererWnd, C2DViewport)
|
|
//{{AFX_MSG_MAP(CTopRendererWnd)
|
|
//}}AFX_MSG_MAP
|
|
ON_WM_DESTROY()
|
|
END_MESSAGE_MAP()
|
|
|
|
// Used to give each static object type a different color
|
|
static uint sVegetationColors[16] =
|
|
{
|
|
0xFFFF0000,
|
|
0xFF00FF00,
|
|
0xFF0000FF,
|
|
0xFFFFFFFF,
|
|
0xFFFF00FF,
|
|
0xFFFFFF00,
|
|
0xFF00FFFF,
|
|
0xFF7F00FF,
|
|
0xFF7FFF7F,
|
|
0xFFFF7F00,
|
|
0xFF00FF7F,
|
|
0xFF7F7F7F,
|
|
0xFFFF0000,
|
|
0xFF00FF00,
|
|
0xFF0000FF,
|
|
0xFFFFFFFF,
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CTopRendererWnd::CTopRendererWnd()
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Set the window type member of the base class to the correct type and
|
|
// create the initial surface texture
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CLogFile::WriteLine("Top render window created");
|
|
|
|
m_bShowHeightmap = false;
|
|
m_bShowStatObjects = false;
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Surface texture
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CLogFile::WriteLine("Creating initial surface texture for top render window...");
|
|
|
|
m_textureSize.cx = SURFACE_TEXTURE_WIDTH;
|
|
m_textureSize.cy = SURFACE_TEXTURE_WIDTH;
|
|
|
|
m_heightmapSize = CSize(1,1);
|
|
|
|
m_terrainTextureId = 0;
|
|
|
|
m_vegetationTextureId = 0;
|
|
|
|
// Create a new surface texture image
|
|
ResetSurfaceTexture();
|
|
|
|
m_bContentsUpdated = false;
|
|
|
|
m_gridAlpha = 0.3f;
|
|
m_colorGridText = RGB(255,255,255);
|
|
m_colorAxisText = RGB(255,255,255);
|
|
m_colorBackground = RGB(128,128,128);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CTopRendererWnd::~CTopRendererWnd()
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Destroy the attached render and free the surface texture
|
|
////////////////////////////////////////////////////////////////////////
|
|
CLogFile::WriteLine("Top render window destroied");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::SetType( EViewportType type )
|
|
{
|
|
C2DViewport::SetType( ET_ViewportXY );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::ResetContent()
|
|
{
|
|
C2DViewport::ResetContent();
|
|
ResetSurfaceTexture();
|
|
|
|
// Reset texture ids.
|
|
m_terrainTextureId = 0;
|
|
m_vegetationTextureId = 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::UpdateContent( int flags )
|
|
{
|
|
C2DViewport::UpdateContent(flags);
|
|
if (!GetIEditor()->GetDocument())
|
|
return;
|
|
|
|
CHeightmap *heightmap = GetIEditor()->GetHeightmap();
|
|
if (!heightmap)
|
|
return;
|
|
|
|
if (!m_hWnd)
|
|
return;
|
|
|
|
if (!IsWindowVisible())
|
|
return;
|
|
|
|
m_heightmapSize.cx = heightmap->GetWidth() * heightmap->GetUnitSize();
|
|
m_heightmapSize.cy = heightmap->GetHeight() * heightmap->GetUnitSize();
|
|
|
|
UpdateSurfaceTexture( flags );
|
|
m_bContentsUpdated = true;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::UpdateSurfaceTexture( int flags )
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Generate a new surface texture
|
|
////////////////////////////////////////////////////////////////////////
|
|
if (flags & eUpdateHeightmap)
|
|
{
|
|
CLogFile::FormatLine("Updating top view surface data (%i x %i)...", m_textureSize.cx, m_textureSize.cy);
|
|
|
|
if (!m_bShowHeightmap)
|
|
{
|
|
m_textureSize.cx = SURFACE_TEXTURE_WIDTH;
|
|
m_textureSize.cy = SURFACE_TEXTURE_WIDTH;
|
|
|
|
m_terrainTexture.Allocate( m_textureSize.cx,m_textureSize.cy );
|
|
|
|
// Fill in the surface data into the array. Apply lighting and water, use
|
|
// the settings from the document
|
|
//bReturn = cSurfaceTexture.GenerateSurface( (unsigned long*)m_terrainTexture.GetData(),m_textureSize.cx,m_textureSize.cy,GEN_USE_LIGHTING|GEN_SHOW_WATER|GEN_ABGR );
|
|
//texGen.GenerateSurfaceTexture( ETTG_LIGHTING|ETTG_SHOW_WATER|ETTG_ABGR,m_terrainTexture );
|
|
CTerrainTexGen texGen;
|
|
texGen.GenerateSurfaceTexture( ETTG_LIGHTING|ETTG_SHOW_WATER|ETTG_FAST_LLIGHTING|ETTG_ABGR,m_terrainTexture );
|
|
}
|
|
else
|
|
{
|
|
m_textureSize.cx = 512;
|
|
m_textureSize.cy = 512;
|
|
m_terrainTexture.Allocate( m_textureSize.cx,m_textureSize.cy );
|
|
|
|
// Show heightmap data.
|
|
//GLOBAL_GET_DOC->m_cHeightmap.GetDataEx(pHeightmap, (m_rcView.right - m_rcView.left), false, false);
|
|
GetIEditor()->GetHeightmap()->GetPreviewBitmap( (DWORD*)m_terrainTexture.GetData(),m_textureSize.cx,false,false );
|
|
}
|
|
}
|
|
|
|
if (flags == eUpdateStatObj)
|
|
{
|
|
// If The only update flag is Update of static objects, display them.
|
|
m_bShowStatObjects = true;
|
|
}
|
|
|
|
if (flags & eUpdateStatObj)
|
|
{
|
|
if (m_bShowStatObjects)
|
|
{
|
|
DrawStaticObjects();
|
|
}
|
|
}
|
|
//if (::IsWindow(m_hWnd))
|
|
//RedrawWindow();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::DrawStaticObjects()
|
|
{
|
|
if (!m_bShowStatObjects)
|
|
return;
|
|
|
|
CVegetationMap *vegetationMap = GetIEditor()->GetVegetationMap();
|
|
int srcW = vegetationMap->GetNumSectors();
|
|
int srcH = vegetationMap->GetNumSectors();
|
|
|
|
CRect rc = CRect(0,0,srcW,srcH);
|
|
BBox updateRegion = GetIEditor()->GetViewManager()->GetUpdateRegion();
|
|
if (updateRegion.min.x > -10000)
|
|
{
|
|
// Update region valid.
|
|
CRect urc;
|
|
CPoint p1 = CPoint( vegetationMap->WorldToSector(updateRegion.min.y),vegetationMap->WorldToSector(updateRegion.min.x) );
|
|
CPoint p2 = CPoint( vegetationMap->WorldToSector(updateRegion.max.y),vegetationMap->WorldToSector(updateRegion.max.x) );
|
|
urc = CRect( p1.x-1,p1.y-1,p2.x+1,p2.y+1 );
|
|
rc &= urc;
|
|
}
|
|
|
|
int trgW = rc.right - rc.left;
|
|
int trgH = rc.bottom - rc.top;
|
|
|
|
if (trgW <= 0 || trgH <= 0)
|
|
return;
|
|
|
|
m_vegetationTexturePos = CPoint( rc.left,rc.top );
|
|
m_vegetationTextureSize = CSize( srcW,srcH );
|
|
m_vegetationTexture.Allocate( trgW,trgH );
|
|
|
|
uint *trg = m_vegetationTexture.GetData();
|
|
vegetationMap->DrawToTexture( trg,trgW,trgH,rc.left,rc.top );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::ResetSurfaceTexture()
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Create a surface texture that consists entirely of water
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
unsigned int i, j;
|
|
DWORD *pSurfaceTextureData = NULL;
|
|
DWORD *pPixData = NULL, *pPixDataEnd = NULL;
|
|
CBitmap bmpLoad;
|
|
BOOL bReturn;
|
|
|
|
CLogFile::WriteLine("Resetting surface texture for top render window...");
|
|
|
|
// Load the water texture out of the ressource
|
|
bReturn = bmpLoad.Attach(::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_WATER)));
|
|
ASSERT(bReturn);
|
|
|
|
// Allocate new memory to hold the bitmap data
|
|
CImage waterImage;
|
|
waterImage.Allocate( 128,128 );
|
|
|
|
// Retrieve the bits from the bitmap
|
|
bmpLoad.GetBitmapBits( 128*128*sizeof(DWORD), waterImage.GetData() );
|
|
|
|
// Allocate memory for the surface texture
|
|
m_terrainTexture.Allocate( m_textureSize.cx,m_textureSize.cy );
|
|
|
|
// Fill the surface texture with the water texture, tile as needed
|
|
for (j=0; j<m_textureSize.cy; j++)
|
|
for (i=0; i<m_textureSize.cx; i++)
|
|
{
|
|
m_terrainTexture.ValueAt(i,j) = waterImage.ValueAt( i&127,j&127 );
|
|
}
|
|
|
|
if (::IsWindow(m_hWnd))
|
|
{
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::Draw( DisplayContext &dc )
|
|
{
|
|
FUNCTION_PROFILER( GetIEditor()->GetSystem(),PROFILE_EDITOR );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Perform the rendering for this window
|
|
////////////////////////////////////////////////////////////////////////
|
|
if (!m_bContentsUpdated)
|
|
UpdateContent( 0xFFFFFFFF );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Render the 2D map
|
|
////////////////////////////////////////////////////////////////////////
|
|
if (!m_terrainTextureId)
|
|
{
|
|
//GL_BGRA_EXT
|
|
if (m_terrainTexture.IsValid())
|
|
{
|
|
m_terrainTextureId = m_renderer->DownLoadToVideoMemory( (unsigned char*)m_terrainTexture.GetData(),m_textureSize.cx,m_textureSize.cy,eTF_8888,eTF_8888,0,0,0 );
|
|
//m_terrainTexture.Release();
|
|
}
|
|
}
|
|
|
|
if (m_terrainTextureId && m_terrainTexture.IsValid())
|
|
{
|
|
m_renderer->UpdateTextureInVideoMemory( m_terrainTextureId,(unsigned char*)m_terrainTexture.GetData(),0,0,m_textureSize.cx,m_textureSize.cy,eTF_8888 );
|
|
//m_renderer->RemoveTexture( m_terrainTextureId );
|
|
//m_terrainTextureId = m_renderer->DownLoadToVideoMemory( (unsigned char*)m_terrainTexture.GetData(),m_textureSize.cx,m_textureSize.cy,eTF_8888,eTF_8888,0,0,0 );
|
|
m_terrainTexture.Release();
|
|
}
|
|
|
|
|
|
if (m_bShowStatObjects)
|
|
{
|
|
if (m_vegetationTexture.IsValid())
|
|
{
|
|
int w = m_vegetationTexture.GetWidth();
|
|
int h = m_vegetationTexture.GetHeight();
|
|
uint *tex = m_vegetationTexture.GetData();
|
|
if (!m_vegetationTextureId)
|
|
{
|
|
m_vegetationTextureId = m_renderer->DownLoadToVideoMemory( (unsigned char*)tex,w,h,eTF_8888,eTF_8888,0,0,FILTER_NONE );
|
|
}
|
|
else
|
|
{
|
|
int px = m_vegetationTexturePos.x;
|
|
int py = m_vegetationTexturePos.y;
|
|
m_renderer->UpdateTextureInVideoMemory( m_vegetationTextureId,(unsigned char*)tex,px,py,w,h,eTF_8888 );
|
|
}
|
|
m_vegetationTexture.Release();
|
|
}
|
|
}
|
|
|
|
|
|
// Reset states
|
|
m_renderer->ResetToDefault();
|
|
// Disable depth test
|
|
//m_renderer->EnableDepthTest(false);
|
|
//m_renderer->EnableDepthWrites(false);
|
|
dc.SetState(GS_NODEPTHTEST);
|
|
|
|
//m_renderer->EnableBlend(false);
|
|
// Draw the map into the view
|
|
|
|
//m_renderer->Draw2dImage(iX, iY+iHeight, iWidth, -iHeight, m_terrainTextureId);
|
|
Matrix44 tm = GetScreenTM();
|
|
Matrix44 rot;
|
|
rot.SetIdentity();
|
|
rot.BuildFromVectors( Vec3(0,1,0),Vec3(1,0,0),Vec3(0,0,1),Vec3(0,0,0) );
|
|
|
|
dc.PushMatrix( rot*tm );
|
|
//m_renderer->DrawImage( 0,0,m_heightmapSize.cx,m_heightmapSize.cy, m_terrainTextureId,0,1,1,0,1,1,1,1 );
|
|
m_renderer->DrawImage( 0,0,m_heightmapSize.cx,m_heightmapSize.cy, m_terrainTextureId, 0,1, 1,0, 1,1,1,1 );
|
|
dc.PopMatrix();
|
|
|
|
//m_renderer->EnableDepthTest(true);
|
|
//m_renderer->EnableDepthWrites(true);
|
|
|
|
//m_renderer->EnableBlend(true);
|
|
dc.SetState(GS_NODEPTHTEST | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA);
|
|
|
|
/*
|
|
// Draw the static objects into the view
|
|
if (m_bShowStatObjects && m_vegetationTextureId)
|
|
{
|
|
m_renderer->SetBlendMode();
|
|
m_renderer->EnableBlend(true);
|
|
|
|
GetMapRect( m_textureSize,rcMap );
|
|
|
|
iWidth = (m_vegetationTextureSize.cx * m_fZoomFactor) * ((float)m_textureSize.cx/m_vegetationTextureSize.cx);
|
|
iHeight = (m_vegetationTextureSize.cy * m_fZoomFactor) * ((float)m_textureSize.cy/m_vegetationTextureSize.cy);
|
|
|
|
// Convert the window coordinates into coordinates for the renderer
|
|
iX = ((float)rcMap.left / rcWnd.right * 800.0f);
|
|
iY = ((float)rcMap.top / rcWnd.bottom * 600.0f);
|
|
iWidth = ((float)iWidth / rcWnd.right * 800.0f);
|
|
iHeight = ((float)iHeight / rcWnd.bottom * 600.0f);
|
|
m_renderer->Draw2dImage(iX, iY+iHeight, iWidth, -iHeight, m_vegetationTextureId);
|
|
m_renderer->EnableBlend(false);
|
|
}
|
|
*/
|
|
|
|
C2DViewport::Draw( dc );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::OnTitleMenu( CMenu &menu )
|
|
{
|
|
bool labels = GetIEditor()->GetDisplaySettings()->IsDisplayLabels();
|
|
menu.AppendMenu( MF_STRING|(labels)?MF_CHECKED:MF_UNCHECKED,1,"Labels" );
|
|
menu.AppendMenu( MF_STRING|(m_bShowHeightmap)?MF_CHECKED:MF_UNCHECKED,2,"Show Heightmap" );
|
|
menu.AppendMenu( MF_STRING|(m_bShowStatObjects)?MF_CHECKED:MF_UNCHECKED,3,"Show Static Objects" );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTopRendererWnd::OnTitleMenuCommand( int id )
|
|
{
|
|
switch (id)
|
|
{
|
|
case 1:
|
|
GetIEditor()->GetDisplaySettings()->DisplayLabels( !GetIEditor()->GetDisplaySettings()->IsDisplayLabels() );
|
|
break;
|
|
case 2:
|
|
m_bShowHeightmap = !m_bShowHeightmap;
|
|
UpdateContent( 0xFFFFFFFF );
|
|
break;
|
|
case 3:
|
|
m_bShowStatObjects = !m_bShowStatObjects;
|
|
if (m_bShowStatObjects)
|
|
UpdateContent( eUpdateStatObj );
|
|
break;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Vec3d CTopRendererWnd::ViewToWorld( CPoint vp,bool *collideWithTerrain,bool onlyTerrain )
|
|
{
|
|
Vec3d wp = C2DViewport::ViewToWorld( vp,collideWithTerrain,onlyTerrain );
|
|
wp.z = GetIEditor()->GetTerrainElevation( wp.x,wp.y );
|
|
return wp;
|
|
} |