// PaintEffectDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PaintEffect.h"
#include "PaintEffectDlg.h"
#include "BMPLoader.h"
#include "PaintEffectImpl.h"
#include "GLSetup.h"
#include "GLTexture.h"
#include "GLVertexBuffer.h"
#include "gdiplus.h"
#include "GdiplusImaging.h"
#include "Gdipluspixelformats.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPaintEffectDlg dialog
CPaintEffectDlg::CPaintEffectDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPaintEffectDlg::IDD, pParent)
, m_bPaintingEffect(FALSE)
, m_bOpenGLDisplay(FALSE)
{
//{{AFX_DATA_INIT(CPaintEffectDlg)
m_nIntensity = 0;
m_nRadius = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pbyEffectAppliedData = 0;
m_pbyImageInputData = 0;
m_pImageTexture = 0;
}
CPaintEffectDlg::~CPaintEffectDlg()
{
// Release all resources on exit.
Gdiplus::GdiplusShutdown( m_gdiplusToken );
if( m_pVertexBuffer )
{
delete m_pVertexBuffer;
m_pVertexBuffer = 0;
}
if( m_pImageTexture )
{
delete m_pImageTexture;
m_pImageTexture = 0;
}
if( m_pbyEffectAppliedData )
{
delete[] m_pbyEffectAppliedData;
m_pbyEffectAppliedData = 0;
}
if( m_pbyImageInputData )
{
delete[] m_pbyImageInputData;
m_pbyImageInputData = 0;
}
if( m_pGLSetup )
{
delete m_pGLSetup;
m_pGLSetup = 0;
}
}
void CPaintEffectDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPaintEffectDlg)
DDX_Text(pDX, IDC_EDIT_INTENSITY, m_nIntensity);
DDV_MinMaxInt(pDX, m_nIntensity, 0, 1000);
DDX_Text(pDX, IDC_EDIT_RADIUS, m_nRadius);
DDV_MinMaxInt(pDX, m_nRadius, 0, 100);
//}}AFX_DATA_MAP
DDX_Check(pDX, IDC_CHECK_PAINTING_EFFECT, m_bPaintingEffect);
DDX_Check(pDX, IDC_CHECK_OPENGL_DISPLAY, m_bOpenGLDisplay);
DDX_Control(pDX, IDC_SLIDER_RADIUS, m_SliderRadius);
DDX_Control(pDX, IDC_SLIDER_INTENSITY, m_SliderIntensity);
}
BEGIN_MESSAGE_MAP(CPaintEffectDlg, CDialog)
//{{AFX_MSG_MAP(CPaintEffectDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_LOAD_BITMAP, OnButtonLoadBitmap)
//}}AFX_MSG_MAP
ON_EN_CHANGE(IDC_EDIT_RADIUS, CPaintEffectDlg::OnEnChangeEditRadius)
ON_EN_CHANGE(IDC_EDIT_INTENSITY, CPaintEffectDlg::OnEnChangeEditIntensity)
ON_WM_SIZE()
ON_BN_CLICKED(IDC_BUTTON_SAVE, CPaintEffectDlg::OnBnClickedButtonSave)
ON_BN_CLICKED(IDC_BUTTON_ABOUT, CPaintEffectDlg::OnBnClickedButtonAbout)
ON_BN_CLICKED(IDC_CHECK_PAINTING_EFFECT, CPaintEffectDlg::OnBnClickedCheckPaintingEffect)
ON_BN_CLICKED(IDC_CHECK_OPENGL_DISPLAY, CPaintEffectDlg::OnBnClickedCheckOpenglDisplay)
ON_WM_HSCROLL()
// ON_WM_ERASEBKGND()
// ON_WM_SETFOCUS()
// ON_WM_ACTIVATE()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPaintEffectDlg message handlers
BOOL CPaintEffectDlg::OnInitDialog()
{
// Initialization of GDI+ library.
// GDI+ is used for loading images of different file format.
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// OpenGL is initialised to enable OpenGL display.
// Texture image is not prepared here.
// If OpenGL display is enabled, then texture will be loaded and drawn.
m_pGLSetup = new GLSetup();
if( !m_pGLSetup->InitGL( GetDlgItem( IDC_STATIC_IMAGE )->m_hWnd ))
{
AfxMessageBox( L"OpenGL initialisation failed." );
GetDlgItem( IDC_CHECK_OPENGL_DISPLAY )->EnableWindow( false );
}
// Vertex buffer created for displaying Quad image with Texture mapping.
m_pVertexBuffer = new GLVertexBuffer();
m_pVertexBuffer->CreateQuadVertexBuffer();
// Update UI with default values.
m_nRadius = 4;
m_nIntensity = 20;
m_bPaintingEffect = true;
// OpenGL is disabled because some machine maynot support big sized textures.
m_bOpenGLDisplay = false;
UpdateData( false );
// Initial dialog displayed with controls in proper position.
// 690 and 440 is required to display default image properly.
RECT rect;
GetClientRect( &rect );
m_nOldDlgWidth = rect.right;
// For Center display.
RECT DesktopRegon;
GetDesktopWindow()->GetClientRect( &DesktopRegon );
// SetWindowPos is called for proper display of initial bitmap.
int nLeft = DesktopRegon.right / 2 - 690 / 2;
int nTop = DesktopRegon.bottom / 2 - 440 / 2;
SetWindowPos( 0, nLeft, nTop, 690, 440, SWP_SHOWWINDOW );
// Load initial image from Resource.
BMPLoader imageloader;
if( imageloader.LoadBMP( IDB_BITMAP_AUTUMN, m_nImageWidth, m_nImageHeight, m_pbyImageInputData ))
{
int nBytesInARow = ceil( m_nImageWidth * 3 / 4.0 ) * 4.0;
// Allocate image for effect applied data.
m_pbyEffectAppliedData = new BYTE[ nBytesInARow * m_nImageHeight ];
// Applying effect on startup.
ProcessEffect();
}
m_SliderRadius.SetRange( 0, 10 );
m_SliderRadius.SetPos( m_nRadius );
m_SliderIntensity.SetRange( 0, 50 );
m_SliderIntensity.SetPos( m_nIntensity / 5 );
return TRUE; // return TRUE unless you set the focus to a control
}
void CPaintEffectDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
// if( ( nID & 0xFFF0 ) == SC_MINIMIZE )
{
TRACE( "Minim Identified" );
GetDlgItem( IDC_SLIDER_INTENSITY )->InvalidateRect( 0 );
}
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CPaintEffectDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
TRACE( L"Iconic\n" );
GetDlgItem( IDC_STATIC_IMAGE )->InvalidateRect( 0 );
}
else
{
TRACE( L"Paint\n" );
CDialog::OnPaint();
if( m_bOpenGLDisplay )
{
// Drawing with OpenGL.
// Output image from texture is mapped to screen.
DrawWithOpenGL();
}
else
{
// Drawing with GDI.
// Output image from Bitmap object is mapped to screen.
DrawWithGDI();
}
GetDlgItem( IDC_STATIC_STATUS )->SetWindowText(L"");
// After drawing to dc, dc is set as drawn.
GetDlgItem( IDC_STATIC_IMAGE )->ValidateRect( 0 );
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CPaintEffectDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CPaintEffectDlg::OnButtonLoadBitmap()
{
// Create a file open Dialog for opening .bmp file.
CFileDialog* pFileOpenDlg = new CFileDialog( TRUE,L"image", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
L"Input Image (*.bmp;*.jpg;*.png;*.tga)|*.bmp;*.jpg;*.png;*.tga||");
if( IDOK == pFileOpenDlg->DoModal())
{
CString csFileName = pFileOpenDlg->GetPathName();
int nWidth = 0;
int nHeight = 0;
BYTE* pbyData = 0;
BMPLoader BMPLoaderObj;
if( !BMPLoaderObj.LoadBMP( csFileName.GetBuffer( 0 ), nWidth, nHeight, pbyData ))
{
AfxMessageBox( L"BMP Loading failed" );
return;
}
if( 0 == pbyData )
{
AfxMessageBox( L"Memory Allocation failed." );
return;
}
if( m_pbyImageInputData )
{
delete[] m_pbyImageInputData;
m_pbyImageInputData = 0;
}
if( m_pbyEffectAppliedData )
{
delete[] m_pbyEffectAppliedData;
m_pbyEffectAppliedData = 0;
}
// Change data to new data.
m_pbyImageInputData = pbyData;
m_nImageWidth = nWidth;
m_nImageHeight = nHeight;
// Prepare buffer to hold ouput data.
int nBytesInARow = ceil( m_nImageWidth * 3 / 4.0 ) * 4.0;
m_pbyEffectAppliedData = new BYTE[nBytesInARow * m_nImageHeight];
ProcessEffect();
Invalidate( false );
}
delete pFileOpenDlg;
}
/*
This function is called when a parameter changing, or loading a new image.
*/
void CPaintEffectDlg::ProcessEffect()
{
if( m_pbyImageInputData && m_pbyEffectAppliedData )
{
if( m_bPaintingEffect )
{
// A static window is used to inform the user, processing of oil paint effect
// is going on.. Processing Effect...
GetDlgItem( IDC_STATIC_STATUS )->SetWindowText( L"Processing Effect..." );
PaintEffect EffectProcessor;
EffectProcessor.Process( m_pbyImageInputData, m_nRadius, m_nIntensity,
m_nImageWidth, m_nImageHeight, m_pbyEffectAppliedData );
// After processing the effect, Processing finished is set.
// This text will be removed on next on paint.
GetDlgItem( IDC_STATIC_STATUS )->SetWindowText( L"Processing Finished..." );
}
else
{
// On disable oil painting effect, source image is copied to output image.
int nBytesInARow = ceil( m_nImageWidth * 3 / 4.0 ) * 4.0;
memcpy( m_pbyEffectAppliedData, m_pbyImageInputData, nBytesInARow * m_nImageHeight );
}
// Changed data is copied to Bitmap or OpenGL texture.
BITMAPINFO stBitmapInfo;
stBitmapInfo.bmiHeader.biClrImportant = 0;
stBitmapInfo.bmiHeader.biClrUsed = 0;
stBitmapInfo.bmiHeader.biCompression = 0;
stBitmapInfo.bmiHeader.biPlanes = 1;
stBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
stBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
stBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
stBitmapInfo.bmiHeader.biBitCount = 3 * 8;
stBitmapInfo.bmiHeader.biSizeImage = m_nImageWidth * m_nImageHeight;
stBitmapInfo.bmiHeader.biHeight = m_nImageHeight;
stBitmapInfo.bmiHeader.biWidth = m_nImageWidth;
stBitmapInfo.bmiColors[0].rgbBlue = 0x0;
stBitmapInfo.bmiColors[0].rgbGreen = 0x0;
stBitmapInfo.bmiColors[0].rgbRed = 0x0;
stBitmapInfo.bmiColors[0].rgbReserved = 0x0;
HDC hdc = ::GetDC(NULL);
HBITMAP hbmDest = ::CreateCompatibleBitmap(hdc, m_nImageWidth, m_nImageHeight);
if (hbmDest)
{
if (SetDIBits(hdc, hbmDest, 0, m_nImageHeight, m_pbyEffectAppliedData, &stBitmapInfo, DIB_RGB_COLORS))
{
m_BitmapObject.DeleteObject();
m_BitmapObject.Attach( hbmDest );
}
}
// If OpenGL is enabled, copying processed data to opengl texture.
if( m_bOpenGLDisplay && m_pImageTexture )
{
delete m_pImageTexture;
m_pImageTexture = new GLTexture();
m_pImageTexture->Create( m_nImageWidth, m_nImageHeight, m_pbyEffectAppliedData );
}
}
}
/*
OnSize() handles repositioning of all controls on resizing the dialog.
The size of parameters and button are kept same on all redrawing.
The size of image drawing static window is changed on resize of main dialog.
*/
void CPaintEffectDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// Finding left position of Image display static window.
RECT rcOldRegon;
if(GetDlgItem( IDC_STATIC_IMAGE ))
{
GetDlgItem( IDC_STATIC_IMAGE )->GetClientRect( &rcOldRegon );
}
else
{
return;
}
RECT rcScreenRect = rcOldRegon;
if( GetDlgItem( IDC_STATIC_IMAGE ))
{
GetDlgItem( IDC_STATIC_IMAGE )->ClientToScreen( &rcScreenRect );
}
POINT LeftTopPos;
RECT rcWindowRelativePos = rcScreenRect;
ScreenToClient( &rcWindowRelativePos );
int nParameterWindowWidth = 0;
RECT parameterWindowRgn;
if( GetDlgItem( IDC_STATIC_PARAM ))
{
GetDlgItem( IDC_STATIC_PARAM )->GetClientRect( ¶meterWindowRgn );
}
nParameterWindowWidth = parameterWindowRgn.right;
// Find new position of Image area.
RECT rcNewImagePos = rcWindowRelativePos; // Left and top will be same
rcNewImagePos.bottom = cy - rcWindowRelativePos.top; // Keep same space in top and bottom.
rcNewImagePos.right = cx - nParameterWindowWidth - 20;
int nImageWidth = rcNewImagePos.right - rcNewImagePos.left + 1;
int nImageHeight = rcNewImagePos.bottom - rcNewImagePos.top + 1;
// Change size of Image Area.
if( GetDlgItem( IDC_STATIC_IMAGE ))
{
GetDlgItem( IDC_STATIC_IMAGE )->SetWindowPos( 0, rcNewImagePos.left, rcNewImagePos.top,
nImageWidth, nImageHeight, SWP_NOREDRAW );
}
// Change position of parameters window.
int nParamWindowMoveX = cx - m_nOldDlgWidth;
m_nOldDlgWidth = cx;
// All windows other than image display window is moved in X direction.
MoveWindowInXDirection( IDC_EDIT_RADIUS, nParamWindowMoveX );
MoveWindowInXDirection( IDC_STATIC_RADIUS, nParamWindowMoveX );
MoveWindowInXDirection( IDC_EDIT_INTENSITY, nParamWindowMoveX );
MoveWindowInXDirection( IDC_STATIC_INTENSITY, nParamWindowMoveX );
MoveWindowInXDirection( IDC_STATIC_PARAM, nParamWindowMoveX );
MoveWindowInXDirection( IDC_STATIC_PARAM_2, nParamWindowMoveX );
MoveWindowInXDirection( IDC_BUTTON_LOAD_BITMAP, nParamWindowMoveX );
MoveWindowInXDirection( IDC_BUTTON_SAVE, nParamWindowMoveX );
MoveWindowInXDirection( IDC_BUTTON_ABOUT, nParamWindowMoveX );
MoveWindowInXDirection( IDC_CHECK_PAINTING_EFFECT, nParamWindowMoveX );
MoveWindowInXDirection( IDC_STATIC_STATUS, nParamWindowMoveX );
MoveWindowInXDirection( IDC_CHECK_OPENGL_DISPLAY, nParamWindowMoveX );
MoveWindowInXDirection( IDC_SLIDER_RADIUS, nParamWindowMoveX );
MoveWindowInXDirection( IDC_SLIDER_INTENSITY, nParamWindowMoveX );
// Change opengl view port.
glViewport( 0, 0, nImageWidth, nImageHeight );
// Request redraw of the window.
Invalidate( true );
}
/*
This function is responsible to move a window with in X direction.
nDistance_i indicates the number of pixels to move in X direction.
*/
void CPaintEffectDlg::MoveWindowInXDirection( const int nControlID_i, const int nDistance_i )
{
RECT oldRect;
// Get current region.
if( GetDlgItem( nControlID_i ) )
{
GetDlgItem( nControlID_i )->GetWindowRect( &oldRect );
}
ScreenToClient( &oldRect );
// Add offset to current region.
oldRect.left += nDistance_i;
oldRect.right += nDistance_i;
// Change position of window with new region.
if( GetDlgItem( nControlID_i ) )
{
GetDlgItem( nControlID_i )->SetWindowPos( 0, oldRect.left, oldRect.top,
oldRect.right - oldRect.left,
oldRect.bottom - oldRect.top, SWP_NOREDRAW );
}
}
// To save the processed image.
void CPaintEffectDlg::OnBnClickedButtonSave()
{
// Construct file name. Radius and Intensity parameters are added in the deafult file name.
CString csFileName;
csFileName.Format( L"OilPaintEffect_radius%d_Intensity%d.bmp",m_nRadius, m_nIntensity );
CFileDialog SaveDlg( false, L"*.bmp", csFileName );
if( IDOK == SaveDlg.DoModal())
{
CString csFileName = SaveDlg.GetPathName();
BMPLoader SaveBmp;
SaveBmp.SaveBMP( csFileName, m_nImageWidth, m_nImageHeight, m_pbyEffectAppliedData );
}
}
// About button handler.
void CPaintEffectDlg::OnBnClickedButtonAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
// Handling Radius parameter change.
void CPaintEffectDlg::OnEnChangeEditRadius()
{
// Handle changes in GUI.
HandleGUIChanges();
}
// Handling Intensity parameter change.
void CPaintEffectDlg::OnEnChangeEditIntensity()
{
// Handle changes in GUI.
HandleGUIChanges();
}
// Handling Painting Effect enable or disable.
void CPaintEffectDlg::OnBnClickedCheckPaintingEffect()
{
// Handle changes in GUI.
HandleGUIChanges();
}
/*
Function called on changing any gui parameter by user.
Here retrieves new parameter from GUI and proecsses effect,
and request repainting the image.
*/
void CPaintEffectDlg::HandleGUIChanges()
{
// Get data from UI.
UpdateData( true );
ProcessEffect();
Invalidate( false );
}
/*
Function draws bitmap object to screen.
*/
void CPaintEffectDlg::DrawWithGDI()
{
// Use GDI method to draw the bitmap to screen.
// CDC* pDC = GetDlgItem( IDC_STATIC_IMAGE )->GetDC();
CPaintDC dc(GetDlgItem( IDC_STATIC_IMAGE ));
CDC* pDC = &dc;
if (m_BitmapObject.GetSafeHandle())
{
CDC dcMem;
if (dcMem.CreateCompatibleDC(pDC))
{
CBitmap* pOldBM = dcMem.SelectObject(&m_BitmapObject);
BITMAP BM;
m_BitmapObject.GetBitmap(&BM);
RECT ClientRegion;
GetDlgItem( IDC_STATIC_IMAGE )->GetClientRect( &ClientRegion );
// StretchBlt is used to resize the actual image to region of static window.
pDC->StretchBlt( 0, 0, ClientRegion.right, ClientRegion.bottom,
&dcMem, 0, 0, m_nImageWidth, m_nImageHeight, SRCCOPY );
dcMem.SelectObject(pOldBM);
}
GetDlgItem( IDC_STATIC_IMAGE )->ReleaseDC( pDC );
}
else
{
TRACE( "FAILED" );
}
}
void CPaintEffectDlg::DrawWithOpenGL()
{
// Use OpenGL method to draw the bitmap to screen.
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// OPenGL drawing, Enable the texture,
// draw vertex buffer and swap the buffer to screen..
if( m_pVertexBuffer && m_pGLSetup && m_pImageTexture )
{
m_pImageTexture->Enable();
m_pVertexBuffer->DrawVertexBuffer( GL_QUADS );
m_pGLSetup->Draw();
}
}
/*
This function handles openGL disply enable and disable.
On enabling openGL display, new texture is created in image size.
On disabling previous openGL texture is deleted.
*/
void CPaintEffectDlg::OnBnClickedCheckOpenglDisplay()
{
m_bOpenGLDisplay = !m_bOpenGLDisplay;
if( m_bOpenGLDisplay )
{
if( m_pImageTexture )
{
delete m_pImageTexture;
m_pImageTexture = 0;
}
// Create OpenGL resources.
m_pImageTexture = new GLTexture();
m_pImageTexture->Create( m_nImageWidth, m_nImageHeight,
m_pbyEffectAppliedData );
}
else
{
if( m_pImageTexture )
{
// Delete opengl resources.
delete m_pImageTexture;
m_pImageTexture = 0;
}
}
// Request repainting...
Invalidate( false );
}
void CPaintEffectDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( nSBCode == SB_THUMBPOSITION )
{
if( pScrollBar->m_hWnd == GetDlgItem( IDC_SLIDER_INTENSITY )->m_hWnd )
{
m_nIntensity = nPos * 5;
UpdateData( false );
HandleGUIChanges();
m_SliderIntensity.SetPos( nPos );
}
else
{
m_nRadius = nPos;
UpdateData( false );
HandleGUIChanges();
m_SliderRadius.SetPos( nPos );
}
}
else
{
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
}