729 lines
20 KiB
C++
729 lines
20 KiB
C++
// DrawWnd.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "DrawWnd.h"
|
|
#include "Heightmap.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#pragma warning (disable : 4800)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDrawWnd
|
|
|
|
CDrawWnd::CDrawWnd()
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Load the brushes for drawing and create a DC for them
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CBitmap bmpLoad;
|
|
|
|
// Load the ressource
|
|
VERIFY(m_bmpBrushes.LoadBitmap(IDB_BRUSH));
|
|
|
|
// Make pink (255, 0, 255) pixels transparent
|
|
MakeAlpha(m_bmpBrushes);
|
|
|
|
// Create the DC
|
|
m_dcBrushes.CreateCompatibleDC(NULL);
|
|
m_dcBrushes.SelectObject(&m_bmpBrushes);
|
|
|
|
// Allocate new memory to hold the water bitmap data
|
|
m_pWaterTexData = new DWORD[128 * 128];
|
|
ASSERT(m_pWaterTexData);
|
|
|
|
// Load the water texture out of the ressource
|
|
VERIFY(bmpLoad.Attach(::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_WATER))));
|
|
|
|
// Retrieve the bits from the bitmap
|
|
VERIFY(bmpLoad.GetBitmapBits(128 * 128 * sizeof(DWORD), m_pWaterTexData));
|
|
|
|
int HX = GetIEditor()->GetHeightmap()->GetWidth();
|
|
// Init other members
|
|
m_iCurBrush = 2;
|
|
m_fZoomFactor = 512.0f / HX;
|
|
m_cScrollOffset = CPoint(0, 0);
|
|
m_fOpacity = 16;
|
|
m_pCoordWnd = NULL;
|
|
m_bShowWater = true;
|
|
m_bShowMapObj = true;
|
|
m_fSetToHeight = -1.0f;
|
|
m_bUseNoiseBrush = false;
|
|
m_ptMarker = CPoint(0, 0);
|
|
|
|
m_heightmap = GetIEditor()->GetHeightmap();
|
|
}
|
|
|
|
CDrawWnd::~CDrawWnd()
|
|
{
|
|
if (m_pWaterTexData)
|
|
{
|
|
delete [] m_pWaterTexData;
|
|
m_pWaterTexData = NULL;
|
|
}
|
|
|
|
if (m_pCoordWnd)
|
|
m_pCoordWnd->Detach();
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CDrawWnd, CWnd)
|
|
//{{AFX_MSG_MAP(CDrawWnd)
|
|
ON_WM_PAINT()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_MOUSEWHEEL()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_MBUTTONDOWN()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDrawWnd message handlers
|
|
|
|
void CDrawWnd::OnPaint()
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Paint the window with the heightmap
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CPaintDC dc(this); // device context for painting
|
|
CRect rect;
|
|
CDC dcHeightmap;
|
|
CBitmap bmpHeightmap;
|
|
|
|
CHeightmap *pHeightmap = GetIEditor()->GetHeightmap();
|
|
DWORD *pImageData = NULL;
|
|
float fScaleX, fScaleY;
|
|
int i, j;
|
|
float fWaterLevel = pHeightmap->GetWaterLevel();
|
|
long iYPreCalc;
|
|
CPoint cTransfPt;
|
|
CPoint ptTransfMarker = m_ptMarker;
|
|
|
|
|
|
// Get the rect of the client window
|
|
GetClientRect(&rect);
|
|
|
|
// Allocate memory for the bitmap data
|
|
pImageData = new DWORD[rect.right * rect.bottom];
|
|
ASSERT(pImageData);
|
|
|
|
// Calculate the scaling
|
|
fScaleX = 1.0f / m_fZoomFactor;
|
|
fScaleY = 1.0f / m_fZoomFactor;
|
|
|
|
int maxHX = pHeightmap->GetWidth();
|
|
int maxHY = pHeightmap->GetHeight();
|
|
|
|
// Copy the heightmap into the bitmap data
|
|
for (j=0; j<rect.bottom; j++)
|
|
{
|
|
// Precalculate for speed reasons
|
|
iYPreCalc = ftoi((j - m_cScrollOffset.y) * fScaleY);
|
|
if (iYPreCalc >= maxHY)
|
|
continue;
|
|
|
|
for (i=0; i<rect.right; i++)
|
|
{
|
|
int iXPreCalc = ftoi((i- m_cScrollOffset.x)* fScaleX);
|
|
if (iYPreCalc >= maxHX)
|
|
continue;
|
|
|
|
// Get the grayscale value from the heightmap array
|
|
float h = pHeightmap->GetXY(iXPreCalc,iYPreCalc);
|
|
|
|
// Only draw the water if the flag has been set
|
|
if (h < fWaterLevel && m_bShowWater)
|
|
{
|
|
// Water, fetch a tiled texel from the water texture
|
|
pImageData[i + j * rect.right] = m_pWaterTexData[i % 128 + ((j % 128) << 7)];
|
|
}
|
|
else
|
|
{
|
|
int iColor = ftoi(h);
|
|
if (iColor > 255)
|
|
iColor = 255;
|
|
// Create a ABGR color and store it in the bitmap array
|
|
pImageData[i + j * rect.right] = (iColor << 16) | (iColor << 8) | iColor;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create DC and bitmap for the heightmap
|
|
VERIFY(dcHeightmap.CreateCompatibleDC(&dc));
|
|
VERIFY(bmpHeightmap.CreateBitmap(rect.right, rect.bottom, 1, 32, pImageData));
|
|
dcHeightmap.SelectObject(&bmpHeightmap);
|
|
|
|
// Free the temporary image data
|
|
if (pImageData)
|
|
{
|
|
delete [] pImageData;
|
|
pImageData = NULL;
|
|
}
|
|
|
|
/*
|
|
if (m_bShowMapObj)
|
|
{
|
|
// Draw the map objects over the preview
|
|
for (i=0; i<(long) GLOBAL_GET_DOC->m_sMapObjects.GetSize(); i++)
|
|
{
|
|
// Convert the position to map coordinates
|
|
cTransfPt.x = (long) (GLOBAL_GET_DOC->m_sMapObjects[i].fX / 2.0f);
|
|
cTransfPt.y = (long) (GLOBAL_GET_DOC->m_sMapObjects[i].fY / 2.0f);
|
|
|
|
// Convert it to window coordinates
|
|
HMCoordToWndCoord(&cTransfPt);
|
|
|
|
// Calculate the rectangle that is used to draw the position of the map object
|
|
::SetRect(&rcObject, cTransfPt.x - 1, cTransfPt.y - 1,
|
|
cTransfPt.x + 1, cTransfPt.y + 1);
|
|
|
|
// Get the color of the object
|
|
switch (GLOBAL_GET_DOC->m_sMapObjects[i].eType)
|
|
{
|
|
case MOEntity:
|
|
// Entities are red
|
|
dwMapObjColor = 0x000000FF;
|
|
break;
|
|
|
|
case MOTagPoint:
|
|
// Tag points are white
|
|
dwMapObjColor = 0x00FFFFFF;
|
|
break;
|
|
|
|
case MOBuilding:
|
|
// Buldings are yellow
|
|
dwMapObjColor = 0x0000FFFF;
|
|
break;
|
|
|
|
default:
|
|
// Use white as default color
|
|
dwMapObjColor = 0x00FFFFFF;
|
|
break;
|
|
}
|
|
|
|
// Draw the rectangle
|
|
dcHeightmap.FillRect(&rcObject, &CBrush(dwMapObjColor));
|
|
}
|
|
}
|
|
*/
|
|
|
|
// Draw the current position marker
|
|
HMCoordToWndCoord(&ptTransfMarker);
|
|
dcHeightmap.Ellipse(ptTransfMarker.x - 3, ptTransfMarker.y - 3,
|
|
ptTransfMarker.x + 3, ptTransfMarker.y + 3);
|
|
|
|
// Blit the heightmap to the window
|
|
dc.BitBlt(0, 0, rect.right, rect.bottom, &dcHeightmap, 0, 0, SRCCOPY);
|
|
|
|
// Do not call CWnd::OnPaint() for painting messages
|
|
}
|
|
|
|
bool CDrawWnd::Create(CWnd *pwndParent)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Use this function instead of the base class versions to create the
|
|
// window
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
RECT rcDefault;
|
|
|
|
// Create the window with a custom window class
|
|
return CreateEx(NULL, AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
|
|
AfxGetApp()->LoadCursor(IDC_HAND_INTERNAL), NULL, NULL), "DrawWindow",
|
|
WS_CHILD | WS_VISIBLE, rcDefault, pwndParent, NULL);
|
|
}
|
|
|
|
void CDrawWnd::MakeAlpha(CBitmap &ioBM)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Make pink pixels transparent
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
struct RGBAQUAD
|
|
{
|
|
BYTE rgbatBlue;
|
|
BYTE rgbatGreen;
|
|
BYTE rgbatRed;
|
|
BYTE rgbatAlpha;
|
|
};
|
|
|
|
RGBAQUAD *pixels;
|
|
|
|
// Figure out how many pixels there are in the bitmap
|
|
BITMAP bmInfo;
|
|
|
|
VERIFY(ioBM.GetBitmap (&bmInfo));
|
|
|
|
// Add support for additional bit depths if you choose
|
|
VERIFY(bmInfo.bmBitsPixel == 32);
|
|
VERIFY(bmInfo.bmWidthBytes == (bmInfo.bmWidth * 4));
|
|
|
|
if (bmInfo.bmBitsPixel != 32)
|
|
{
|
|
CLogFile::WriteLine("Drawing Error: Dektop is set to 16 bit, need 32 bit");
|
|
AfxMessageBox("Please set your desktop color depth to 32 bits !");
|
|
}
|
|
|
|
const UINT numPixels (bmInfo.bmHeight * bmInfo.bmWidth);
|
|
|
|
// Allocate space to receive the pixel data
|
|
pixels = new RGBAQUAD[bmInfo.bmHeight * bmInfo.bmWidth];
|
|
|
|
// Retrieve the pixels
|
|
VERIFY(ioBM.GetBitmapBits(bmInfo.bmHeight * bmInfo.bmWidth * sizeof(RGBAQUAD), pixels) != 0);
|
|
|
|
// Loop trough all pixels
|
|
for (UINT i = 0; i < numPixels; ++i)
|
|
{
|
|
if (pixels[i].rgbatBlue == 255
|
|
&& pixels[i].rgbatGreen == 0
|
|
&& pixels[i].rgbatRed == 255)
|
|
{
|
|
pixels[i].rgbatGreen = 0;
|
|
pixels[i].rgbatRed = 0;
|
|
pixels[i].rgbatBlue = 0;
|
|
|
|
// Skip pixels that have the background color
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Write the bitmap data back
|
|
VERIFY(ioBM.SetBitmapBits(bmInfo.bmHeight * bmInfo.bmWidth * sizeof(RGBAQUAD), pixels) != 0);
|
|
|
|
// Free the pixels
|
|
delete [] pixels;
|
|
pixels = 0;
|
|
}
|
|
|
|
BOOL CDrawWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Mousewheel is used to control zooming
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// Scroll in / out relative to the mouse wheel direction
|
|
SetZoomFactor(GetZoomFactor() + (zDelta / 120.0f) * 0.15f);
|
|
|
|
// Redraw the window
|
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool CDrawWnd::SetScrollOffset(long iX, long iY)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Set the scrolling offset. If the passed values are invalid, the
|
|
// nearest valid values will be set and false is returned
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
bool bRangeValid = true;
|
|
RECT rcWndPos;
|
|
long iScaledWidth = (long) (m_heightmap->GetWidth() * GetZoomFactor());
|
|
|
|
// Obtain the size of the window
|
|
GetClientRect(&rcWndPos);
|
|
|
|
// Don't allow to scroll beyond the lower right corner
|
|
if (abs(iX) > iScaledWidth - rcWndPos.right)
|
|
{
|
|
iX = -(iScaledWidth - rcWndPos.right);
|
|
bRangeValid = false;
|
|
}
|
|
|
|
if (abs(iY) > iScaledWidth - rcWndPos.bottom)
|
|
{
|
|
iY = -(iScaledWidth - rcWndPos.bottom);
|
|
bRangeValid = false;
|
|
}
|
|
|
|
// Don't allow to scroll beyond the upper left corner
|
|
if (iX > 0)
|
|
{
|
|
iX = 0;
|
|
bRangeValid = false;
|
|
}
|
|
|
|
if (iY > 0)
|
|
{
|
|
iY = 0;
|
|
bRangeValid = false;
|
|
}
|
|
|
|
// Save the (eventually corrected) scroll offset
|
|
m_cScrollOffset = CPoint(iX, iY);
|
|
|
|
// Redraw the window
|
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
|
|
|
return bRangeValid;
|
|
}
|
|
|
|
bool CDrawWnd::SetZoomFactor(float fZoomFactor)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Adjust the zoom factor of the view. If the passed values are invalid,
|
|
// the nearest valid values will be set and false is returned
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
RECT rcWndPos;
|
|
bool bRangeValid = true;
|
|
float fNewSizeTemp = 0;
|
|
float fEnlargementFactor;
|
|
|
|
// Zero can produce artifacts and errors
|
|
if (fZoomFactor == 0.0f)
|
|
{
|
|
fZoomFactor = m_fZoomFactor;
|
|
bRangeValid = false;
|
|
}
|
|
|
|
// Is the new zoom factor smaller than the last one ?
|
|
if (fZoomFactor < m_fZoomFactor)
|
|
{
|
|
// We might run into the problem that the map is smaller than the
|
|
// the window when displayed with the specified zoom factor
|
|
|
|
// Obtain the dimensions of the window
|
|
GetClientRect(&rcWndPos);
|
|
|
|
if (m_heightmap->GetWidth() * fZoomFactor < rcWndPos.right)
|
|
{
|
|
// Calculate the new size
|
|
fZoomFactor = (float) rcWndPos.right / m_heightmap->GetWidth();
|
|
|
|
bRangeValid = false;
|
|
}
|
|
|
|
if (m_heightmap->GetWidth() * fZoomFactor < rcWndPos.bottom)
|
|
{
|
|
// Calculate the new size
|
|
fNewSizeTemp = (float) rcWndPos.bottom / m_heightmap->GetWidth();
|
|
|
|
// Only set the new zoom if it is larger than the previous
|
|
fZoomFactor = (fZoomFactor > fNewSizeTemp) ? fZoomFactor : fNewSizeTemp;
|
|
|
|
bRangeValid = false;
|
|
}
|
|
}
|
|
|
|
// Calculate how much larger the new zoom is compared to the old one
|
|
fEnlargementFactor = fZoomFactor / m_fZoomFactor;
|
|
|
|
// Save the new zoom factor
|
|
m_fZoomFactor = fZoomFactor;
|
|
|
|
// Let SetScrollOffset() find a valid scroll offset
|
|
// TODO: Scroll centering is broken
|
|
SetScrollOffset((long) (GetScrollOffset().x * fEnlargementFactor),
|
|
(long) (GetScrollOffset().y * fEnlargementFactor));
|
|
|
|
return bRangeValid;
|
|
}
|
|
|
|
void CDrawWnd::OnMButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// New marker position
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
m_ptMarker = point;
|
|
WndCoordToHMCoord(&m_ptMarker);
|
|
|
|
RedrawWindow();
|
|
|
|
CWnd::OnMButtonDown(nFlags, point);
|
|
}
|
|
|
|
afx_msg void CDrawWnd::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// User pressed the left mouse button
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
RECT rcClient;
|
|
|
|
GetClientRect(&rcClient);
|
|
|
|
// Save the mouse down position
|
|
m_cMouseDownPos = point;
|
|
|
|
// Capture mouse input for this window, we need it for the scrolling
|
|
SetCapture();
|
|
|
|
// Call the mouse move function to immediatly draw a spot
|
|
OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
afx_msg void CDrawWnd::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// User pressed the right mouse button
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
RECT rcClient;
|
|
|
|
GetClientRect(&rcClient);
|
|
|
|
// Save the mouse down position
|
|
m_cMouseDownPos = point;
|
|
|
|
// Capture mouse input for this window, we need it for the scrolling
|
|
SetCapture();
|
|
|
|
// Call the mouse move function to immediatly draw a spot
|
|
OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CDrawWnd::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
RECT rcWin;
|
|
char szCoordText[256];
|
|
|
|
if (nFlags & MK_LBUTTON || nFlags & MK_MBUTTON)
|
|
{
|
|
// CTRL or SHIFT indicate scrolling and zooming
|
|
if (nFlags & MK_CONTROL || nFlags & MK_MBUTTON)
|
|
{
|
|
// You can only scroll while the left mouse button is down and you hold down CTRL
|
|
|
|
// Set the new scrolled coordinates
|
|
SetScrollOffset(GetScrollOffset() + (point - m_cMouseDownPos));
|
|
}
|
|
else if (nFlags & MK_SHIFT)
|
|
{
|
|
// You can only zoom while the left mouse button is down and you hold down SHIFT
|
|
|
|
// Get the dimensions of the window
|
|
GetClientRect(&rcWin);
|
|
|
|
// Zoom
|
|
SetZoomFactor(GetZoomFactor() + ((point.y - m_cMouseDownPos.y) / (float) rcWin.bottom));
|
|
}
|
|
else
|
|
{
|
|
// None of the modificator keys pressed, draw
|
|
|
|
// Get the heightmap coordinates of the clicked point
|
|
WndCoordToHMCoord(&point);
|
|
|
|
// Draw a spot
|
|
m_heightmap->DrawSpot(point.y, point.x,
|
|
(uint8) (10.0f + m_iCurBrush * 25.0f), m_fOpacity,
|
|
m_fSetToHeight, m_bUseNoiseBrush);
|
|
}
|
|
|
|
// Redraw the window
|
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
|
}
|
|
else if (nFlags & MK_RBUTTON)
|
|
{
|
|
// Get the heightmap coordinates of the clicked point
|
|
WndCoordToHMCoord(&point);
|
|
|
|
// Draw a spot
|
|
m_heightmap->DrawSpot(point.y, point.x,
|
|
(uint8) (10.0f + m_iCurBrush * 25.0f), -m_fOpacity,
|
|
m_fSetToHeight);
|
|
|
|
// Redraw the window
|
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
|
}
|
|
|
|
// Save the new mouse down position
|
|
m_cMouseDownPos = point;
|
|
|
|
// Display the current coordinates in the coordinate window
|
|
if (m_pCoordWnd)
|
|
{
|
|
// Convert to meters
|
|
WndCoordToHMCoord(&point);
|
|
point.x *= 2;
|
|
point.y *= 2;
|
|
|
|
// Create and set the string
|
|
sprintf(szCoordText, "X: %i Y: %i", point.x, point.y);
|
|
m_pCoordWnd->SetWindowText(szCoordText);
|
|
}
|
|
|
|
CWnd::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
afx_msg void CDrawWnd::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// User released the left mouse button
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// Release the restriction of the cursor
|
|
ReleaseCapture();
|
|
|
|
CWnd::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
void CDrawWnd::WndCoordToHMCoord(CPoint *pWndPt)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Transform a point from window space into map space
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
long lTemp;
|
|
|
|
ASSERT(pWndPt);
|
|
|
|
// Add the offset
|
|
pWndPt->x += abs(GetScrollOffset().x);
|
|
pWndPt->y += abs(GetScrollOffset().y);
|
|
|
|
// Swap the axis
|
|
lTemp = pWndPt->x;
|
|
pWndPt->x = pWndPt->y;
|
|
pWndPt->y = lTemp;
|
|
|
|
// Scale with the zoom factor
|
|
pWndPt->x = (long) (pWndPt->x / GetZoomFactor());
|
|
pWndPt->y = (long) (pWndPt->y / GetZoomFactor());
|
|
|
|
// Scale from map texture coordinates to heightmap coordinates
|
|
pWndPt->x = (long) (pWndPt->x / (float) m_heightmap->GetWidth() * m_heightmap->GetWidth());
|
|
pWndPt->y = (long) (pWndPt->y / (float) m_heightmap->GetHeight() * m_heightmap->GetHeight());
|
|
}
|
|
|
|
void CDrawWnd::HMCoordToWndCoord(CPoint *pWndPt)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Transform a point from map space into window space
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
RECT rcWndPos;
|
|
long lTemp;
|
|
|
|
// Obtain the window dimensions
|
|
GetClientRect(&rcWndPos);
|
|
|
|
// Swap the axis
|
|
lTemp = pWndPt->x;
|
|
pWndPt->x = pWndPt->y;
|
|
pWndPt->y = lTemp;
|
|
|
|
pWndPt->x = (long) (pWndPt->x / (float) m_heightmap->GetWidth() * (m_heightmap->GetWidth() * GetZoomFactor()));
|
|
pWndPt->y = (long) (pWndPt->y / (float) m_heightmap->GetHeight() * (m_heightmap->GetWidth() * GetZoomFactor()));
|
|
|
|
// Add the offset
|
|
pWndPt->x += GetScrollOffset().x;
|
|
pWndPt->y += GetScrollOffset().y;
|
|
}
|
|
|
|
/*
|
|
void CDrawWnd::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Use the current brush / rubber to draw on the heightmap
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CPoint TransformedPoint;
|
|
UINT iScaledBrushWidth, iScaledBrushHeight;
|
|
BLENDFUNCTION bfBrushBlend;
|
|
typedef BOOL (CALLBACK * ALPHABLEND) (HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION);
|
|
ALPHABLEND pfnAlphaBlend = NULL;
|
|
BOOL bSuccess;
|
|
HINSTANCE hLib;
|
|
RECT rcInvalid;
|
|
|
|
// Only draw when the left mouse button is pressed
|
|
if (!nFlags & MK_LBUTTON)
|
|
return;
|
|
|
|
// Transform mouse coordinates into heightmap coordinates
|
|
TransformedPoint.x = (LONG) ((point.x / 350.0f) * GLOBAL_GET_DOC->m_cHeightmap.GetWidth());
|
|
TransformedPoint.y = (LONG) ((point.y / 350.0f) * GLOBAL_GET_DOC->m_cHeightmap.GetHeight());
|
|
|
|
// Calculate the scaled brush size
|
|
iScaledBrushWidth = (UINT) ((350.0f / GLOBAL_GET_DOC->m_cHeightmap.GetWidth()) * 32);
|
|
iScaledBrushHeight = (UINT) ((350.0f / GLOBAL_GET_DOC->m_cHeightmap.GetHeight()) * 32);
|
|
|
|
// Scale the brush (TODO: Make this not hardcoded but selectable)
|
|
iScaledBrushWidth *= 4;
|
|
iScaledBrushHeight *= 4;
|
|
|
|
// Center brush
|
|
TransformedPoint.x -= iScaledBrushWidth / 2;
|
|
TransformedPoint.y -= iScaledBrushHeight / 2;
|
|
|
|
// Random offset
|
|
TransformedPoint.x -= 2 - ((LONG) (rand() / (float) RAND_MAX * 4));
|
|
TransformedPoint.y -= 2 - ((LONG) (rand() / (float) RAND_MAX * 4));
|
|
|
|
// Are we in rubber mode ?
|
|
if (m_bRubberMode)
|
|
{
|
|
// Just erase a rectangular area
|
|
GLOBAL_GET_DOC->m_dcHeightmap.BitBlt(TransformedPoint.x, TransformedPoint.y, iScaledBrushWidth,
|
|
iScaledBrushHeight, &GLOBAL_GET_DOC->m_dcHeightmap, 0, 0, BLACKNESS);
|
|
|
|
// Update the painted part of the window
|
|
SetRect(&rcInvalid, point.x - iScaledBrushWidth / 2,
|
|
point.y - iScaledBrushHeight / 2, point.x + iScaledBrushWidth / 2,
|
|
point.y + iScaledBrushHeight / 2);
|
|
InvalidateRect(&rcInvalid);
|
|
}
|
|
else
|
|
{
|
|
// Load the imaging library
|
|
hLib = LoadLibrary("msimg32.dll");
|
|
assert(hLib);
|
|
|
|
// Query the function pointer for AlphaBlend
|
|
pfnAlphaBlend = (ALPHABLEND) GetProcAddress(hLib, "AlphaBlend");
|
|
|
|
if (!pfnAlphaBlend)
|
|
{
|
|
CLogFile::WriteLine("Drawing Error: Can't find entry point for AlphaBlend() or can't load msimg32.dll at all");
|
|
AfxMessageBox("Can't find entry point for AlphaBlend() or can't load msimg32.dll at all. " \
|
|
"Upgrade to Win98 / WinME / Win2K / WinXP or install the needed DLL manually");
|
|
assert(pfnAlphaBlend);
|
|
return;
|
|
}
|
|
|
|
// Setup the blend function
|
|
bfBrushBlend.BlendOp = AC_SRC_OVER;
|
|
bfBrushBlend.BlendFlags = 0;
|
|
bfBrushBlend.SourceConstantAlpha = 32;
|
|
bfBrushBlend.AlphaFormat = AC_SRC_NO_PREMULT_ALPHA;
|
|
|
|
// Paint the brush
|
|
bSuccess = (* pfnAlphaBlend) (GLOBAL_GET_DOC->m_dcHeightmap.m_hDC, TransformedPoint.x,
|
|
TransformedPoint.y, iScaledBrushWidth, iScaledBrushHeight, m_dcBrushes.m_hDC,
|
|
m_iCurBrush * 32, 0, 32, 32, bfBrushBlend);
|
|
assert(bSuccess);
|
|
|
|
// Update the painted part of the window
|
|
SetRect(&rcInvalid, point.x - iScaledBrushWidth / 2,
|
|
point.y - iScaledBrushHeight / 2, point.x + iScaledBrushWidth / 2,
|
|
point.y + iScaledBrushHeight / 2);
|
|
InvalidateRect(&rcInvalid);
|
|
|
|
// We dont need the imaging library anymore
|
|
FreeLibrary(hLib);
|
|
}
|
|
|
|
// We modified the document
|
|
GLOBAL_GET_DOC->SetModifiedFlag();
|
|
|
|
// Need to generate all layers from scratch
|
|
GLOBAL_GET_DOC->InvalidateLayers();
|
|
|
|
CWnd::OnMouseMove(nFlags, point);
|
|
}
|
|
*/
|