mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-22 10:20:26 +01:00
493 lines
14 KiB
C++
493 lines
14 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
|
|
|
// DlgCreateSpecularTexture.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef new
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgCreateSpecularTexture dialog
|
|
|
|
static TIME timeLastTick=TIME(0);
|
|
|
|
static ANGLE3D a3dObjectRotation = ANGLE3D( 0, 0, 0);
|
|
static ANGLE3D a3dLightRotation = ANGLE3D( 0, 0, 0);
|
|
static ANGLE3D a3dObjectAngles = ANGLE3D( 0, 0, 0);
|
|
static ANGLE3D a3dLightAngles = ANGLE3D( 0, 0, 0);
|
|
|
|
static CPoint ptLMBDown;
|
|
static CPoint ptRMBDown;
|
|
|
|
static ANGLE3D GetRotForDelta(CPoint ptDelta, BOOL bInvertY)
|
|
{
|
|
FLOAT fdH = ptDelta.x/15.0f;
|
|
FLOAT fdP = ptDelta.y/15.0f;
|
|
if( bInvertY)
|
|
return ANGLE3D( fdH, -fdP, 0);
|
|
else
|
|
return ANGLE3D( fdH, fdP, 0);
|
|
}
|
|
|
|
#define DEFAULT_EXPONENT_POS 50
|
|
|
|
CDlgCreateSpecularTexture::CDlgCreateSpecularTexture(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CDlgCreateSpecularTexture::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CDlgCreateSpecularTexture)
|
|
m_strNumericalExponent = _T("");
|
|
m_bAutoRotate = FALSE;
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_bAutoRotate = TRUE;
|
|
m_colorSpecular.m_pwndParentDialog = this;
|
|
m_colorLight.m_pwndParentDialog = this;
|
|
m_colorAmbient.m_pwndParentDialog = this;
|
|
m_pPreviewDrawPort = NULL;
|
|
m_pPreviewViewPort = NULL;
|
|
m_pGraphDrawPort = NULL;
|
|
m_pGraphViewPort = NULL;
|
|
|
|
m_colorAmbient.SetColor( 0x030303FF);
|
|
|
|
m_bCustomWindowsCreated = FALSE;
|
|
|
|
m_plPlacement.pl_OrientationAngle = ANGLE3D( 30, 0, 0);
|
|
m_moModel.mo_Stretch = FLOAT3D( 1.0f, 1.0f, 1.0f);
|
|
|
|
// mark that timer is not yet started
|
|
m_iTimerID = -1;
|
|
}
|
|
|
|
|
|
void CDlgCreateSpecularTexture::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
|
|
if( !pDX->m_bSaveAndValidate)
|
|
{
|
|
INDEX iExponent = DEFAULT_EXPONENT_POS;
|
|
if( IsWindow( m_sliderSpecularExponent.m_hWnd))
|
|
{
|
|
iExponent = m_sliderSpecularExponent.GetPos();
|
|
}
|
|
CTString strNumericalExponent;
|
|
strNumericalExponent.PrintF( "Value: %.1f", GetFactorForPercentage(iExponent));
|
|
m_strNumericalExponent = strNumericalExponent;
|
|
}
|
|
|
|
//{{AFX_DATA_MAP(CDlgCreateSpecularTexture)
|
|
DDX_Control(pDX, IDC_SPECULAR_EXPONENT, m_sliderSpecularExponent);
|
|
DDX_Control(pDX, IDC_SPECULAR_COLOR, m_colorSpecular);
|
|
DDX_Control(pDX, IDC_SIZE_IN_PIXELS, m_comboSizeInPixels);
|
|
DDX_Control(pDX, IDC_LIGHT_COLOR, m_colorLight);
|
|
DDX_Control(pDX, IDC_AMBIENT_COLOR, m_colorAmbient);
|
|
DDX_Text(pDX, IDC_NUMERIC_EXPONENT_T, m_strNumericalExponent);
|
|
DDX_Check(pDX, IDC_AUTO_ROTATE, m_bAutoRotate);
|
|
//}}AFX_DATA_MAP
|
|
|
|
if( (pDX->m_bSaveAndValidate) && IsWindow( m_sliderSpecularExponent.m_hWnd) )
|
|
{
|
|
INDEX iSlider = m_sliderSpecularExponent.GetPos();
|
|
CreateTexture( CTString("temp\\SpecularTemp.tex"), GetFactorForPercentage( iSlider));
|
|
CTextureData *pTD = (CTextureData *) m_moModel.mo_toSpecular.GetData();
|
|
if( pTD != NULL) pTD->Reload();
|
|
Invalidate( FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgCreateSpecularTexture, CDialog)
|
|
//{{AFX_MSG_MAP(CDlgCreateSpecularTexture)
|
|
ON_WM_HSCROLL()
|
|
ON_WM_PAINT()
|
|
ON_WM_TIMER()
|
|
ON_WM_DESTROY()
|
|
ON_BN_CLICKED(IDC_AUTO_ROTATE, OnAutoRotate)
|
|
ON_CBN_SELCHANGE(IDC_SIZE_IN_PIXELS, OnSelchangeSizeInPixels)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void CDlgCreateSpecularTexture::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
UpdateData( TRUE);
|
|
UpdateData( FALSE);
|
|
}
|
|
|
|
#define EXP_MIN (0.1)
|
|
#define EXP_MAX (4000.0)
|
|
|
|
#define EXP_FACTOR EXP_MIN
|
|
#define EXP_BASE pow(EXP_MAX/EXP_MIN, 1.0/100)
|
|
|
|
FLOAT CDlgCreateSpecularTexture::GetFactorForPercentage( INDEX iSlider)
|
|
{
|
|
return FLOAT(EXP_FACTOR*pow(EXP_BASE, iSlider));
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::CreateTexture( CTFileName fnTexture, FLOAT fExp)
|
|
{
|
|
CImageInfo II;
|
|
CTFileStream fsFile;
|
|
CTextureData TD;
|
|
|
|
INDEX iSelectedSize = m_comboSizeInPixels.GetCurSel();
|
|
ASSERT( iSelectedSize != CB_ERR);
|
|
PIX pixSize = 1UL<<iSelectedSize;
|
|
PIX pixSizeI = pixSize;
|
|
PIX pixSizeJ = pixSize;
|
|
UBYTE *pubImage = (UBYTE *)AllocMemory(pixSize*pixSize*3);
|
|
II.Attach(pubImage, pixSize, pixSize, 24);
|
|
for (PIX pixI=0; pixI<pixSizeI; pixI++) {
|
|
for (PIX pixJ=0; pixJ<pixSizeJ; pixJ++) {
|
|
FLOAT fS = pixI*2.0f/pixSizeI-1;
|
|
FLOAT fT = pixJ*2.0f/pixSizeJ-1;
|
|
FLOAT fZ = Sqrt(1-2*fS*fS-2*fT*fT);
|
|
fZ = Clamp(fZ, 0.0f, 1.0f);
|
|
FLOAT fZN = FLOAT(pow(fZ, fExp));
|
|
ASSERT(fZN>=0 && fZN<=1);
|
|
UBYTE ub = UBYTE(fZN*255);
|
|
pubImage[(pixJ*pixSize+pixI)*3+0] = ub;
|
|
pubImage[(pixJ*pixSize+pixI)*3+1] = ub;
|
|
pubImage[(pixJ*pixSize+pixI)*3+2] = ub;
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
TD.Create_t( &II, pixSize, 1, FALSE);
|
|
fsFile.Create_t( fnTexture);
|
|
TD.Write_t( &fsFile);
|
|
fsFile.Close();
|
|
}
|
|
// if failed
|
|
catch (char *strError)
|
|
{
|
|
// report error
|
|
AfxMessageBox(CString(strError));
|
|
}
|
|
II.Detach();
|
|
FreeMemory(pubImage);
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::DrawPreview( CDrawPort *pdp, FLOAT fExp)
|
|
{
|
|
BOOL bErrorOcured = FALSE;
|
|
|
|
if( (m_moModel.GetData() == NULL) || (m_moModel.mo_toTexture.GetData() == NULL) ||
|
|
(m_moModel.mo_toSpecular.GetData() == NULL) )
|
|
// obtain components for rendering
|
|
try
|
|
{
|
|
DECLARE_CTFILENAME( fnBCGTexture, "Models\\Editor\\SpecularPreviewBCG.tex");
|
|
m_toBackground.SetData_t( fnBCGTexture);
|
|
|
|
DECLARE_CTFILENAME( fnTeapotModel, "Models\\Editor\\Teapot.mdl");
|
|
DECLARE_CTFILENAME( fnTeapotTexture, "Models\\Editor\\Teapot.tex");
|
|
m_moModel.SetData_t( fnTeapotModel);
|
|
m_moModel.mo_toTexture.SetData_t( fnTeapotTexture);
|
|
m_moModel.mo_toSpecular.SetData_t( CTString("temp\\SpecularTemp.tex"));
|
|
}
|
|
catch( char *strError)
|
|
{
|
|
(void) strError;
|
|
bErrorOcured = TRUE;
|
|
}
|
|
|
|
if( !bErrorOcured)
|
|
{
|
|
|
|
((CModelData*)m_moModel.GetData())->md_colSpecular = m_colorSpecular.GetColor();
|
|
PIXaabbox2D screenBox = PIXaabbox2D( PIX2D(0,0), PIX2D(pdp->GetWidth(), pdp->GetHeight()) );
|
|
//pdp->PutTexture( &m_moModel.mo_toSpecular, screenBox);
|
|
//return;
|
|
pdp->PutTexture( &m_toBackground, screenBox);
|
|
pdp->FillZBuffer( ZBUF_BACK);
|
|
|
|
CRenderModel rmRenderModel;
|
|
CPerspectiveProjection3D prPerspectiveProjection;
|
|
|
|
a3dObjectAngles += a3dObjectRotation;
|
|
a3dLightAngles += a3dLightRotation;
|
|
|
|
m_plPlacement.pl_OrientationAngle = a3dObjectAngles;
|
|
AnglesToDirectionVector( a3dLightAngles, rmRenderModel.rm_vLightDirection);
|
|
|
|
prPerspectiveProjection.FOVL() = AngleDeg(50.0f);
|
|
prPerspectiveProjection.ScreenBBoxL() = FLOATaabbox2D(
|
|
FLOAT2D(0.0f,0.0f),FLOAT2D((float)pdp->GetWidth(), (float)pdp->GetHeight()));
|
|
prPerspectiveProjection.AspectRatioL() = 1.0f;
|
|
prPerspectiveProjection.FrontClipDistanceL() = 0.05f;
|
|
|
|
prPerspectiveProjection.ViewerPlacementL().pl_PositionVector = FLOAT3D(0.0f,0.0f,0.0f);
|
|
prPerspectiveProjection.ViewerPlacementL().pl_OrientationAngle = ANGLE3D( 0, -20, 0);
|
|
prPerspectiveProjection.Prepare();
|
|
CAnyProjection3D apr;
|
|
apr = prPerspectiveProjection;
|
|
BeginModelRenderingView(apr, pdp);
|
|
|
|
_mrpModelRenderPrefs.SetRenderType( RT_TEXTURE|RT_SHADING_PHONG);
|
|
m_plPlacement.pl_PositionVector = FLOAT3D( 0.0f, -0.19f, -0.35f);
|
|
rmRenderModel.SetObjectPlacement(m_plPlacement);
|
|
rmRenderModel.rm_colLight = m_colorLight.GetColor();
|
|
rmRenderModel.rm_colAmbient = m_colorAmbient.GetColor();
|
|
m_moModel.SetupModelRendering(rmRenderModel);
|
|
m_moModel.RenderModel(rmRenderModel);
|
|
EndModelRenderingView();
|
|
}
|
|
|
|
|
|
/*
|
|
pdp->Fill(C_GREEN|CT_OPAQUE);
|
|
PIX pixSizeI = pdp->GetWidth();
|
|
PIX pixSizeJ = pdp->GetHeight();
|
|
for (PIX pixI=0; pixI<pixSizeI; pixI++) {
|
|
for (PIX pixJ=0; pixJ<pixSizeJ; pixJ++) {
|
|
FLOAT fX = pixI*2.0f/pixSizeI-1;
|
|
FLOAT fY = pixJ*2.0f/pixSizeJ-1;
|
|
FLOAT fZ;
|
|
FLOAT fZ2 = 1-fX*fX-fY*fY;
|
|
if (fZ2<0) {
|
|
fZ = 0;
|
|
} else {
|
|
fZ = Sqrt(fZ2);
|
|
}
|
|
FLOAT fZN = FLOAT(pow(fZ, fExp));
|
|
ASSERT(fZN>=0 && fZN<=1);
|
|
UBYTE ub = UBYTE(fZN*255);
|
|
pdp->Fill(pixI, pixJ, 1,1, RGBToColor(ub,ub,ub)|CT_OPAQUE);
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::DrawGraph( CDrawPort *pdp, FLOAT fExp)
|
|
{
|
|
pdp->Fill(C_WHITE|CT_OPAQUE);
|
|
PIX pixSizeI = pdp->GetWidth();
|
|
PIX pixSizeJ = pdp->GetHeight();
|
|
PIX pixLastI = 0;
|
|
PIX pixLastJ = 0;
|
|
for (PIX pixI=0; pixI<pixSizeI; pixI++) {
|
|
FLOAT fAlpha = 90.0f*pixI/pixSizeI;
|
|
FLOAT fCos = FLOAT(pow(Cos(fAlpha), fExp));
|
|
PIX pixJ = PIX(pixSizeJ*(1-fCos));
|
|
pdp->DrawLine(pixLastI, pixLastJ, pixI, pixJ, C_BLACK|CT_OPAQUE);
|
|
pixLastI = pixI;
|
|
pixLastJ = pixJ;
|
|
}
|
|
}
|
|
|
|
|
|
void CDlgCreateSpecularTexture::RenderGraph(void)
|
|
{
|
|
// ******** Render graph window
|
|
if (m_pGraphViewPort==NULL) {
|
|
_pGfx->CreateWindowCanvas( m_wndGraph.m_hWnd, &m_pGraphViewPort, &m_pGraphDrawPort);
|
|
}
|
|
if( (m_pGraphDrawPort != NULL) && (m_pGraphDrawPort->Lock()) )
|
|
{
|
|
INDEX iSlider = m_sliderSpecularExponent.GetPos();
|
|
DrawGraph( m_pGraphDrawPort, GetFactorForPercentage( iSlider));
|
|
m_pGraphDrawPort->Unlock();
|
|
}
|
|
if (m_pGraphViewPort!=NULL) m_pGraphViewPort->SwapBuffers();
|
|
if( m_pGraphViewPort != NULL)
|
|
{
|
|
_pGfx->DestroyWindowCanvas( m_pGraphViewPort);
|
|
m_pGraphViewPort = NULL;
|
|
}
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::RenderPreview(void)
|
|
{
|
|
// ******** Render preview window
|
|
if (m_pPreviewDrawPort==NULL) {
|
|
_pGfx->CreateWindowCanvas( m_wndPreview.m_hWnd, &m_pPreviewViewPort, &m_pPreviewDrawPort);
|
|
}
|
|
if( (m_pPreviewDrawPort != NULL) && (m_pPreviewDrawPort->Lock()) )
|
|
{
|
|
INDEX iSlider = m_sliderSpecularExponent.GetPos();
|
|
DrawPreview( m_pPreviewDrawPort, GetFactorForPercentage( iSlider));
|
|
m_pPreviewDrawPort->Unlock();
|
|
}
|
|
if (m_pPreviewViewPort!=NULL) m_pPreviewViewPort->SwapBuffers();
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::OnPaint()
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
if( m_iTimerID == -1)
|
|
{
|
|
m_iTimerID = (int) SetTimer( 1, 24, NULL);
|
|
}
|
|
|
|
if( !m_bCustomWindowsCreated)
|
|
{
|
|
// ---------------- Create window for graph
|
|
// obtain frames area window
|
|
CWnd *pwndGraph = GetDlgItem(IDC_GRAPH_FRAME);
|
|
ASSERT(pwndGraph != NULL);
|
|
CRect rectGraphWindow;
|
|
pwndGraph->GetWindowRect(&rectGraphWindow);
|
|
ScreenToClient(&rectGraphWindow);
|
|
m_wndGraph.Create( NULL, NULL, WS_BORDER|WS_VISIBLE, rectGraphWindow,
|
|
this, IDW_SPECULAR_GRAPH);
|
|
// ---------------- Create window for preview
|
|
CWnd *pWndPreview = GetDlgItem(IDC_PREVIEW_FRAME);
|
|
ASSERT(pWndPreview != NULL);
|
|
CRect rectPreview;
|
|
pWndPreview->GetWindowRect(&rectPreview);
|
|
ScreenToClient(&rectPreview);
|
|
// create window for for animation testing
|
|
m_wndPreview.Create( NULL, NULL, WS_BORDER|WS_VISIBLE, rectPreview,
|
|
this, IDW_SPECULAR_PREVIEW);
|
|
// mark that custom windows are created
|
|
m_bCustomWindowsCreated = TRUE;
|
|
}
|
|
|
|
RenderGraph();
|
|
RenderPreview();
|
|
}
|
|
|
|
BOOL CDlgCreateSpecularTexture::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
if(::IsWindow( m_comboSizeInPixels.m_hWnd))
|
|
{
|
|
m_comboSizeInPixels.SetCurSel( 6);
|
|
}
|
|
|
|
if( IsWindow( m_sliderSpecularExponent.m_hWnd))
|
|
{
|
|
m_sliderSpecularExponent.SetRange(0, 100, TRUE);
|
|
m_sliderSpecularExponent.SetPos(DEFAULT_EXPONENT_POS);
|
|
}
|
|
|
|
UpdateData( TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::OnTimer(UINT nIDEvent)
|
|
{
|
|
// on our timer discard preview window
|
|
if( nIDEvent == 1)
|
|
{
|
|
TIME timeCurrentTick = _pTimer->GetRealTimeTick();
|
|
if( timeCurrentTick > timeLastTick )
|
|
{
|
|
_pTimer->SetCurrentTick( timeCurrentTick);
|
|
timeLastTick = timeCurrentTick;
|
|
}
|
|
RenderPreview();
|
|
}
|
|
|
|
CDialog::OnTimer(nIDEvent);
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::OnDestroy()
|
|
{
|
|
if( m_pPreviewViewPort != NULL)
|
|
{
|
|
_pGfx->DestroyWindowCanvas( m_pPreviewViewPort);
|
|
m_pPreviewViewPort = NULL;
|
|
}
|
|
|
|
KillTimer( m_iTimerID);
|
|
_pTimer->SetCurrentTick( 0.0f);
|
|
CDialog::OnDestroy();
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::OnAutoRotate()
|
|
{
|
|
a3dObjectAngles = ANGLE3D( 0, 0, 0);
|
|
a3dLightAngles = ANGLE3D( 0, 0, 0);
|
|
if( m_bAutoRotate)
|
|
{
|
|
a3dObjectRotation = ANGLE3D( 0, 0, 0);
|
|
a3dLightRotation = ANGLE3D( 0, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
a3dObjectRotation = ANGLE3D( -2.5f, 0, 0);
|
|
a3dLightRotation = ANGLE3D( 0, 0, 0);
|
|
}
|
|
m_bAutoRotate = !m_bAutoRotate;
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::OnSelchangeSizeInPixels()
|
|
{
|
|
UpdateData( TRUE);
|
|
}
|
|
|
|
static BOOL bWeStartedMouseDown = FALSE;
|
|
|
|
BOOL CDlgCreateSpecularTexture::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
ULONG fwKeys = pMsg->wParam;
|
|
PIX xPos = LOWORD(pMsg->lParam);
|
|
PIX yPos = HIWORD(pMsg->lParam);
|
|
CPoint point = CPoint(xPos, yPos);
|
|
CPoint pointScreen;
|
|
GetCursorPos( &pointScreen);
|
|
|
|
CWnd *pWndPreview = GetDlgItem(IDC_PREVIEW_FRAME);
|
|
CRect rectPreview;
|
|
pWndPreview->GetClientRect( &rectPreview);
|
|
pWndPreview->ClientToScreen( &rectPreview);
|
|
|
|
|
|
if( rectPreview.PtInRect( pointScreen))
|
|
{
|
|
if( (pMsg->message == WM_MOUSEMOVE) && (bWeStartedMouseDown) )
|
|
{
|
|
if( fwKeys&MK_LBUTTON) a3dObjectRotation = GetRotForDelta( point-ptLMBDown, FALSE);
|
|
else if( fwKeys&MK_RBUTTON) a3dLightRotation = GetRotForDelta( point-ptRMBDown, FALSE);
|
|
}
|
|
else if( (pMsg->message == WM_LBUTTONDOWN) || ( pMsg->message == WM_RBUTTONDOWN) )
|
|
{
|
|
ptLMBDown = point;
|
|
ptRMBDown = point;
|
|
bWeStartedMouseDown = TRUE;
|
|
}
|
|
else if( (pMsg->message == WM_LBUTTONUP) && (bWeStartedMouseDown) )
|
|
{
|
|
a3dObjectRotation = GetRotForDelta( point-ptLMBDown, FALSE);
|
|
bWeStartedMouseDown = FALSE;
|
|
}
|
|
else if( (pMsg->message == WM_RBUTTONUP) && (bWeStartedMouseDown) )
|
|
{
|
|
a3dLightRotation = GetRotForDelta( point-ptRMBDown, FALSE);
|
|
bWeStartedMouseDown = FALSE;
|
|
}
|
|
}
|
|
|
|
return CDialog::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
void CDlgCreateSpecularTexture::OnOK()
|
|
{
|
|
CTFileName fnTemp = _fnmApplicationPath+CTString("temp\\SpecularTemp.tex");
|
|
CTFileName fnFinal = _EngineGUI.FileRequester( "Save texture as ...",
|
|
FILTER_TEX FILTER_ALL FILTER_END,
|
|
"Specular map textures directory",
|
|
"Textures\\");
|
|
if( fnFinal != "")
|
|
{
|
|
CopyFileA( fnTemp, _fnmApplicationPath+fnFinal, FALSE);
|
|
}
|
|
|
|
CDialog::OnOK();
|
|
}
|