Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
VectorCtl.cpp
Package: vector_control_source.zip [view]
Upload User: bjzhiyi
Upload Date: 2007-01-01
Package Size: 40k
Code Size: 11k
Category:
OpenGL program
Development Platform:
Visual C++
- #include "stdafx.h"
- #include "VectorCtl.h"
- #include <math.h>
- CVectorCtl::CVectorCtl () :
- m_bBmpCreated (FALSE),
- m_bImageChange (TRUE),
- m_bBackgroundBitmapUsed (FALSE),
- m_clrDiffuse (DEFAULT_DIFFUSE),
- m_clrAmbient (DEFAULT_AMBIENT),
- m_clrLight (DEFAULT_LIGHT),
- m_clrBackgroundStart (DEFAULT_START_BACKGROUND_COLOR),
- m_clrBackgroundEnd (DEFAULT_END_BACKGROUND_COLOR),
- m_dSpecularExponent (DEFAULT_SPEC_EXP),
- m_bHasFocus (FALSE),
- m_bSelected (FALSE),
- m_bFrontVector (FALSE),
- m_iLastMouseY (VAL_NOT_IN_USE),
- m_iLastMouseX (VAL_NOT_IN_USE),
- m_dSensitivity (20.0),
- m_procVectorChanging (NULL),
- m_procVectorChanged (NULL)
- {
- double DefaultVec[3] = DEFAULT_VEC;
- for (int i=0; i<3; i++) {
- m_dVec[i] = DefaultVec[i];
- pCtl[i] = NULL;
- }
- }
- CVectorCtl::~CVectorCtl ()
- {
- if (m_bBmpCreated)
- m_dcMem.SelectObject (m_pOldBitmap);
- ClearBackgroundBitmap ();
- }
- // Owner-drawn control service function:
- void CVectorCtl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
- {
- CDC *pDC = CDC::FromHandle (lpDrawItemStruct->hDC); // Get CDC to draw
- if (!m_bSelected && lpDrawItemStruct->itemState & ODS_SELECTED) {
- // Just got re-selected (user starts a new mouse dragging session)
- m_iLastMouseX = VAL_NOT_IN_USE;
- m_iLastMouseY = VAL_NOT_IN_USE;
- } else if (m_bSelected && // Last state was selected
- !(lpDrawItemStruct->itemState & ODS_SELECTED) && // New state is NOT selected
- (lpDrawItemStruct->itemState & ODS_FOCUS) && // New state is still in focus
- m_procVectorChanged) // User asked for a callback
- // User has left the track-ball and asked for a callback.
- m_procVectorChanged (m_dVec[0], m_dVec[1], m_dVec[2]); // Call it!
- m_bHasFocus = lpDrawItemStruct->itemState & ODS_FOCUS; // Update focus status
- m_bSelected = lpDrawItemStruct->itemState & ODS_SELECTED; // Update selection status
- if (!m_bBmpCreated) // 1st time
- InitBitmap (lpDrawItemStruct, pDC);
- if (m_bImageChange) { // Image has changes - recalc it!
- if (m_procVectorChanging) // User has specified a callback
- m_procVectorChanging (m_dVec[0], m_dVec[1], m_dVec[2]); // Call it!
- BuildImage (lpDrawItemStruct);
- m_bImageChange = FALSE;
- }
- pDC->BitBlt (0,0,m_iWidth, m_iHeight, &m_dcMem, 0, 0, SRCCOPY); // Update screen
- }
- // Mouse was dragged
- void CVectorCtl::OnMouseDrag (int ixMove, int iyMove)
- {
- RotateByXandY (double(-iyMove) / m_dSensitivity,
- double(ixMove) / m_dSensitivity);
- }
- // Recalc ball image
- void CVectorCtl::BuildImage (LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- int xf, yf;
- for (int x=0; x<m_iWidth; x++) // Scan all columns
- for (int y=0; y<m_iHeight; y++) { // Scan all rows
- xf = x-m_iXCenter; // Find distance from center
- yf = y-m_iYCenter;
- if (xf*xf + yf*yf <= m_iSqrRadius) { // Point on ball surface
- double vx = double(xf) / double(m_iRadius),
- vy = double(yf) / double(m_iRadius),
- vz = sqrt (1.0 - vx*vx - vy*vy); // Find ball's normal
- m_dcMem.SetPixelV (x,y, CalcLight (vx,vy,vz));
- }
- }
- }
- // Normalize a vector to unit size
- BOOL CVectorCtl::Normalize ()
- {
- double Norm = m_dVec[0] * m_dVec[0] + m_dVec[1] * m_dVec[1] + m_dVec[2] * m_dVec[2];
- if (Norm > EPS) {
- Norm = sqrt (Norm);
- m_dVec[0] /= Norm;
- m_dVec[1] /= Norm;
- m_dVec[2] /= Norm;
- return TRUE;
- } else { // Reset to defualt vector
- double DefaultVec[3] = DEFAULT_VEC;
- for (int i=0; i<3; i++)
- m_dVec[i] = DefaultVec[i];
- return FALSE;
- }
- }
- // Calculate lightning effect for specific pixel on ball's surface
- COLORREF CVectorCtl::CalcLight (double dx, double dy, double dz)
- {
- double NL = dx * m_dVec[0] + dy * m_dVec[1] + dz * m_dVec[2],
- RV = 2.0 * NL,
- rx = m_dVec[0] - (dx * RV),
- ry = m_dVec[1] - (dy * RV),
- rz = m_dVec[2] - (dz * RV);
- if (NL < 0.0) // Diffuse coefficient
- NL = 0.0;
- RV = max (0.0, -rz);
- RV = double(pow (RV, m_dSpecularExponent));
- int r = int ( double(GetRValue(m_clrDiffuse)) * NL + // Diffuse
- double(GetRValue(m_clrLight)) * RV + // Specular
- double(GetRValue(m_clrAmbient))), // Ambient
- g = int ( double(GetGValue(m_clrDiffuse)) * NL + // Diffuse
- double(GetGValue(m_clrLight)) * RV + // Specular
- double(GetGValue(m_clrAmbient))), // Ambient
- b = int ( double(GetBValue(m_clrDiffuse)) * NL + // Diffuse
- double(GetBValue(m_clrLight)) * RV + // Specular
- double(GetBValue(m_clrAmbient))); // Ambient
- r = min (255, r); // Cutoff highlight
- g = min (255, g);
- b = min (255, b);
- return RGB(BYTE(r),BYTE(g),BYTE(b));
- }
- // Start memory buffer bitmap and measure it
- void CVectorCtl::InitBitmap (LPDRAWITEMSTRUCT lpDrawItemStruct, CDC *pDC)
- {
- m_iWidth = lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left;
- m_iHeight = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top;
- m_bmpBuffer.CreateCompatibleBitmap (pDC, m_iWidth, m_iHeight);
- m_bBmpCreated = TRUE;
- m_dcMem.CreateCompatibleDC (pDC);
- m_pOldBitmap = m_dcMem.SelectObject (&m_bmpBuffer);
- SetRadius (max (min (m_iWidth, m_iHeight) - 2, 0) / 2);
- SetCenter (m_iWidth / 2, m_iHeight / 2);
- CreateBackground ();
- }
- // Set new specular intensity
- BOOL CVectorCtl::SetSpecularExponent (double dExp)
- {
- if (dExp < 1.0 || dExp > 200.0)
- return FALSE;
- m_dSpecularExponent = dExp;
- Redraw ();
- return TRUE;
- }
- // Rotate our vector around the X and Y axis
- void CVectorCtl::RotateByXandY (double XRot, double YRot)
- { // Angles are in radians
- if (XRot == 0.0 && YRot == 0.0)
- return;
- double cx = cos(XRot),
- sx = sin(XRot),
- cy = cos(YRot),
- sy = sin(YRot),
- dx = m_dVec[0] * cy + m_dVec[1] * sx * sy + m_dVec[2] * cx * sy,
- dy = m_dVec[1] * cx - m_dVec[2] * sx,
- dz = -m_dVec[0] * sy + m_dVec[1] * sx * cy + m_dVec[2] * cx * cy;
- if (!m_bFrontVector || dz >= 0.0) { // Vector is bounds free
- m_dVec[0] = dx;
- m_dVec[1] = dy;
- m_dVec[2] = dz;
- } else { // Otherwise, do not allow Z to be negative (light shines from behind)
- m_dVec[2] = 0.0;
- m_dVec[0] = dx;
- m_dVec[1] = dy;
- Normalize ();
- }
- Redraw ();
- }
- void CVectorCtl::UpdateAxisControls ()
- {
- CString cs;
- for (int i=0; i<3; i++)
- if (pCtl[i]) {
- cs.Format ("%+1.5f",m_dVec[i]);
- pCtl[i]->SetWindowText (cs);
- }
- }
- void CVectorCtl::SetAxisControl (int nXCtl, int nYCtl, int nZCtl)
- {
- pCtl[0] = GetParent()->GetDlgItem(nXCtl);
- pCtl[1] = GetParent()->GetDlgItem(nYCtl);
- pCtl[2] = GetParent()->GetDlgItem(nZCtl);
- }
- void CVectorCtl::SetRadius (UINT uRadius)
- {
- m_iRadius = uRadius;
- m_iSqrRadius = m_iRadius * m_iRadius;
- CreateBackground ();
- Redraw (TRUE);
- }
- void CVectorCtl::SetCenter (UINT uHorizPos, UINT uVertPos)
- {
- m_iXCenter = uHorizPos;
- m_iYCenter = uVertPos;
- CreateBackground ();
- Redraw (TRUE);
- }
- void CVectorCtl::SetAxis (double d, int nAxis)
- {
- if (fabs(d)>=1.0) {
- m_dVec[nAxis]=d > 1.0 ? 1.0 : -1.0;
- m_dVec[(nAxis+1) %3]=m_dVec[(nAxis+2) %3]=0.0;
- Redraw ();
- return;
- }
- m_dVec[nAxis] = d;
- Normalize ();
- Redraw ();
- }
- void CVectorCtl::SetVector (double dx, double dy, double dz)
- {
- m_dVec[0] = dx;
- m_dVec[1] = dy;
- m_dVec[2] = dz;
- Normalize ();
- Redraw ();
- }
- void CVectorCtl::SetBackgroundColor (COLORREF clrStart, COLORREF clrEnd)
- {
- ClearBackgroundBitmap ();
- m_clrBackgroundStart = clrStart;
- m_clrBackgroundEnd = clrEnd;
- CreateBackground ();
- }
- BOOL CVectorCtl::SetBackgroundImage (UINT uBackgroundBitmapID)
- {
- if (m_bBackgroundBitmapUsed) {
- ClearBackgroundBitmap ();
- CreateBackground ();
- }
- if (!m_bmpBack.LoadBitmap (uBackgroundBitmapID))
- return FALSE;
- m_bBackgroundBitmapUsed = TRUE;
- CreateBackground ();
- return TRUE;
- }
- void CVectorCtl::CreateBackground ()
- {
- if (!m_bBmpCreated)
- return; // No image yet
- if (!m_bBackgroundBitmapUsed) { // No background used - fill with gradient color
- double r = GetRValue (m_clrBackgroundStart),
- g = GetGValue (m_clrBackgroundStart),
- b = GetBValue (m_clrBackgroundStart),
- rd = double (GetRValue (m_clrBackgroundEnd) - r) / double (m_iHeight),
- gd = double (GetGValue (m_clrBackgroundEnd) - g) / double (m_iHeight),
- bd = double (GetBValue (m_clrBackgroundEnd) - b) / double (m_iHeight);
- for (int j=0; j<m_iHeight; j++) {
- for (int i=0; i<m_iWidth; i++)
- m_dcMem.SetPixelV (i,j, RGB (BYTE(r),BYTE(g),BYTE(b)));
- r+=rd; g+=gd; b+=bd;
- }
- Redraw (TRUE);
- return;
- }
- // Bitmap used : tile it in back
- CDC DCtmp;
- BITMAP tmpBitmap;
- m_bmpBack.GetBitmap (&tmpBitmap);
- int iTmpWidth = tmpBitmap.bmWidth,
- iTmpHeight = tmpBitmap.bmHeight;
- DCtmp.CreateCompatibleDC (&m_dcMem);
- m_pOldBitmap = DCtmp.SelectObject (&m_bmpBack);
- for (int i=0; i<m_iWidth; i++)
- for (int j=0; j<m_iHeight; j++)
- m_dcMem.SetPixelV (i,j, DCtmp.GetPixel (i % iTmpWidth, j % iTmpHeight));
- DCtmp.SelectObject (m_pOldBitmap);
- Redraw (TRUE);
- }
- void CVectorCtl::ClearBackgroundBitmap ()
- {
- if (!m_bBackgroundBitmapUsed)
- return;
- m_bmpBack.DeleteObject ();
- m_bBackgroundBitmapUsed = FALSE;
- }
- BOOL CVectorCtl::SetSensitivity (UINT uSens)
- {
- if (uSens == 0)
- return FALSE;
- m_dSensitivity = double(uSens);
- return TRUE;
- }
- void CVectorCtl::Redraw (BOOL bErase)
- {
- m_bImageChange = TRUE;
- UpdateAxisControls();
- Invalidate (bErase);
- }
- LRESULT CVectorCtl::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
- {
- if (message == WM_MOUSEMOVE && (wParam & MK_LBUTTON)) {
- // Mouse has moved and left button is down
- WORD wCurX = LOWORD(lParam);
- WORD wCurY = HIWORD(lParam);
- int iCurX = wCurX > 3000 ? int(int(wCurX) - 0xffff) : int(wCurX);
- int iCurY = wCurY > 3000 ? int(int(wCurY) - 0xffff) : int(wCurY);
- OnMouseDrag (m_iLastMouseX != VAL_NOT_IN_USE ? iCurX - m_iLastMouseX : 0,
- m_iLastMouseY != VAL_NOT_IN_USE ? iCurY - m_iLastMouseY : 0);
- m_iLastMouseX = iCurX;
- m_iLastMouseY = iCurY;
- }
- return CButton::WindowProc (message, wParam, lParam);
- }