Скачиваний:
29
Добавлен:
02.05.2014
Размер:
13 Кб
Скачать
// MatrixDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Transform.h"

#include "TransformDoc.h"
#include "TransformView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMatrixDlg dialog

CMatrixDlg::CMatrixDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMatrixDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMatrixDlg)
  m_Gl      = 0;
  m_Command = 0;
	m_Projection = 1;
	m_Param11 = 0.0f;	m_Param12 = 0.0f;	m_Param13 = 0.0f;
  m_Param14 = 0.0f; m_Param15 = 0.0f;	m_Param16 = 0.0f;
  m_Param21 = 0.0f;	m_Param22 = 0.0f;
  m_Param23 = 0.0f;	m_Param24 = 0.0f;
	m_Param31 = 1.0f;	m_Param32 = 1.0f;	m_Param33 = 1.0f;
	m_CurMatrix[0][0] = 1.0f;	m_CurMatrix[0][1] = 0.0f;
	m_CurMatrix[0][2] = 0.0f;	m_CurMatrix[0][3] = 0.0f;
	m_CurMatrix[1][0] = 0.0f;	m_CurMatrix[1][1] = 1.0f;
	m_CurMatrix[1][2] = 0.0f;	m_CurMatrix[1][3] = 0.0f;
	m_CurMatrix[2][0] = 0.0f;	m_CurMatrix[2][1] = 0.0f;
	m_CurMatrix[2][2] = 1.0f;	m_CurMatrix[2][3] = 0.0f;
	m_CurMatrix[3][0] = 0.0f;	m_CurMatrix[3][1] = 0.0f;
	m_CurMatrix[3][2] = 0.0f;	m_CurMatrix[3][3] = 1.0f;
  //}}AFX_DATA_INIT

  m_nMatrix = 0;
  m_pView = NULL;
}

void CMatrixDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMatrixDlg)
  DDX_Control(pDX, IDC_MATRIX, m_Matrix);
  DDX_Radio(pDX, IDC_GL, m_Gl);
  DDX_Radio(pDX, IDC_INP_COMMAND, m_Command);
  DDX_Radio(pDX, IDC_ORTHO_PROJ, m_Projection);
	DDX_Text(pDX, IDC_PARAM11, m_Param11);
	DDX_Text(pDX, IDC_PARAM12, m_Param12);
	DDX_Text(pDX, IDC_PARAM13, m_Param13);
	DDX_Text(pDX, IDC_PARAM14, m_Param14);
	DDX_Text(pDX, IDC_PARAM15, m_Param15);
	DDX_Text(pDX, IDC_PARAM16, m_Param16);
	DDX_Text(pDX, IDC_PARAM21, m_Param21);
	DDX_Text(pDX, IDC_PARAM22, m_Param22);
	DDX_Text(pDX, IDC_PARAM23, m_Param23);
	DDX_Text(pDX, IDC_PARAM24, m_Param24);
	DDX_Text(pDX, IDC_PARAM31, m_Param31);
	DDX_Text(pDX, IDC_PARAM32, m_Param32);
	DDX_Text(pDX, IDC_PARAM33, m_Param33);
  DDX_Text(pDX, IDC_EDIT11, m_CurMatrix[0][0]);
  DDX_Text(pDX, IDC_EDIT12, m_CurMatrix[1][0]);
	DDX_Text(pDX, IDC_EDIT13, m_CurMatrix[2][0]);
	DDX_Text(pDX, IDC_EDIT14, m_CurMatrix[3][0]);
	DDX_Text(pDX, IDC_EDIT21, m_CurMatrix[0][1]);
	DDX_Text(pDX, IDC_EDIT22, m_CurMatrix[1][1]);
	DDX_Text(pDX, IDC_EDIT23, m_CurMatrix[2][1]);
	DDX_Text(pDX, IDC_EDIT24, m_CurMatrix[3][1]);
	DDX_Text(pDX, IDC_EDIT31, m_CurMatrix[0][2]);
	DDX_Text(pDX, IDC_EDIT32, m_CurMatrix[1][2]);
	DDX_Text(pDX, IDC_EDIT33, m_CurMatrix[2][2]);
	DDX_Text(pDX, IDC_EDIT34, m_CurMatrix[3][2]);
	DDX_Text(pDX, IDC_EDIT41, m_CurMatrix[0][3]);
	DDX_Text(pDX, IDC_EDIT42, m_CurMatrix[1][3]);
	DDX_Text(pDX, IDC_EDIT43, m_CurMatrix[2][3]);
	DDX_Text(pDX, IDC_EDIT44, m_CurMatrix[3][3]);
  //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMatrixDlg, CDialog)
	//{{AFX_MSG_MAP(CMatrixDlg)
	ON_BN_CLICKED(IDC_ORTHO_PROJ, OnOrthoProj)
	ON_BN_CLICKED(IDC_FRUST_PROJ, OnFrustProj)
  ON_NOTIFY(TCN_SELCHANGE, IDC_MATRIX, OnMatrixChange)
  ON_CONTROL_RANGE(EN_SETFOCUS, IDC_EDIT11, IDC_EDIT44, OnMatrixFocus)
	ON_BN_CLICKED(IDC_APPLY, OnApply)
	ON_BN_CLICKED(IDC_INP_COMMAND, OnInpCommand)
	ON_BN_CLICKED(IDC_INP_MATRIX, OnInpMatrix)
  ON_BN_CLICKED(IDC_GL, OnLockGlGlu)
  ON_BN_CLICKED(IDC_GLU, OnLockGlGlu)
	ON_BN_CLICKED(IDC_APPEND, OnAppend)
	ON_BN_CLICKED(IDC_RESET, OnReset)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMatrixDlg message handlers

BOOL CMatrixDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	TC_ITEM TabCtrlItem;
	TabCtrlItem.mask = TCIF_TEXT;
    TabCtrlItem.pszText = "Преобразование перспективы";
	m_Matrix.InsertItem( 0, &TabCtrlItem );
    TabCtrlItem.pszText = "Видовое преобразование";
	m_Matrix.InsertItem( 1, &TabCtrlItem );

  SetMatrixIdentity(m_PreMatrix);
  GetMatrix(GL_PROJECTION);
  memcpy(m_CurMatrix, m_matrixProj, sizeof(float)*4*4);
  
  UpdateData(FALSE);

  SetMatrixIdentity(m_CurMatrix);

  SetProjection();

 	for(int i = 0; i < 4 ; i++ )
		for(int j = 0; j < 4 ; j++ )
			m_StoreView[i][j] = 0.0f;

  m_StoreView[0][0] =  0.4f;
  m_StoreView[1][1] =  0.4f;
  m_StoreView[2][2] = -1.0f;
  m_StoreView[3][3] =  1.0f;

  memcpy(m_StoreProj, m_matrixProj, sizeof(float)*4*4 );

  OnReset();

	return TRUE;  // return TRUE unless you set the focus to a control
}

void CMatrixDlg::SetMatrixIdentity(float m_Matrix[4][4])
{
	for(int i = 0; i < 4 ; i++ )
		for(int j = 0; j < 4 ; j++ )
			// Диагональные элементы устанавливаем в 1,
      // остальные в 0
			m_Matrix[i][j] = (i == j ? 1.0f : 0.0f );
}

void CMatrixDlg::OnMatrixChange(NMHDR* pNMHDR, LRESULT* pResult)
{
  ResetParam();

  int i, iBegin, iEnd;
  int nMatrix = m_Matrix.GetCurSel();

	switch(nMatrix){
	case 0:
    if(!m_Projection){
      memcpy(m_CurMatrix, m_StoreView, sizeof(float)*4*4);
    }
    else{
      memcpy(m_CurMatrix, m_StoreProj, sizeof(float)*4*4);
    }

    GetDlgItem(IDC_ORTHO_PROJ)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_FRUST_PROJ)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_TYPE_PROJ)->ShowWindow(SW_SHOW);
    SetProjection();
    GetDlgItem(IDC_COMMAND3)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_COMMAND2)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_COMMAND1)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_GL)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_GLU)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_PARAM31)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_PARAM32)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_PARAM33)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_PARAM14)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_PARAM15)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_PARAM16)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_APPEND)->EnableWindow(FALSE);
    if(m_Gl){
      iBegin = IDC_PARAM11;
      iEnd   = IDC_PARAM16;
    }
    else{
      iBegin = IDC_PARAM21;
      iEnd   = IDC_PARAM24;
    }
    for(i = iBegin; i <= iEnd; i++)
      GetDlgItem(i)->EnableWindow(FALSE);
		m_nMatrix = 1;
    break;
	case 1:
    SetMatrixIdentity(m_CurMatrix);
    SetMatrixIdentity(m_PreMatrix);
    GetDlgItem(IDC_ORTHO_PROJ)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_FRUST_PROJ)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_TYPE_PROJ)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_GL)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_GLU)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_COMMAND3)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_COMMAND2)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_COMMAND1)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_PARAM31)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_PARAM32)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_PARAM33)->ShowWindow(SW_SHOW);
    GetDlgItem(IDC_PARAM14)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_PARAM15)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_PARAM16)->ShowWindow(SW_HIDE);
    GetDlgItem(IDC_APPEND)->EnableWindow(TRUE);
    for(i = IDC_PARAM11; i <= IDC_PARAM24; i++)
      GetDlgItem(i)->EnableWindow(TRUE);
    m_nMatrix = 0;
    break;
	}
  UpdateData(FALSE);
	*pResult = 0;
}

void CMatrixDlg::OnOrthoProj() 
{
  UpdateData(TRUE);
  SetProjection();
  OnReset();
}

void CMatrixDlg::OnFrustProj() 
{
  UpdateData(TRUE);
  SetProjection();
  OnReset();
}

void CMatrixDlg::SetProjection()
{
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
    if(!m_Projection){
      SetDlgItemText(IDC_GL, "glOrtho");
      SetDlgItemText(IDC_GLU, "gluOrtho2D");
    }
    else{
      SetDlgItemText(IDC_GL, "glFrustum");
      SetDlgItemText(IDC_GLU, "gluPerspective");
    }
  glPopMatrix();

  m_Param11 = 0.0f; m_Param12 = 0.0f; m_Param13 = 0.0f;
  m_Param14 = 0.0f; m_Param15 = 0.0f; m_Param16 = 0.0f;
  m_Param21 = 0.0f; m_Param22 = 0.0f;
  m_Param23 = 0.0f; m_Param24 = 0.0f;
  
  UpdateData(FALSE);
}

BOOL CMatrixDlg::Create(CView * pView)
{
	m_pView = (CTransformView*)pView;
	return CDialog::Create(CMatrixDlg::IDD);
}

void CMatrixDlg::OnMatrixFocus(UINT nID)
{
  CheckRadioButton(IDC_INP_MATRIX, IDC_INP_COMMAND, IDC_INP_MATRIX);
  LockCommand();
}


void CMatrixDlg::OnInpCommand() 
{
	UnLockCommand();
}

void CMatrixDlg::OnInpMatrix() 
{
  LockCommand();
}

void CMatrixDlg::LockCommand()
{
  for(int i = IDC_COMMAND1; i <= IDC_GLU; i++)
    GetDlgItem(i)->EnableWindow(FALSE);
}

void CMatrixDlg::UnLockCommand()
{
  for(int i = IDC_COMMAND1; i <= IDC_GLU; i++)
    GetDlgItem(i)->EnableWindow(TRUE);
}

void CMatrixDlg::OnApply() 
{
	UpdateData(TRUE);
	int nMatrix = m_Matrix.GetCurSel();

	switch(nMatrix){
	case 0:
    SetMatrixIdentity(m_PreMatrix);
    ::glMatrixMode(GL_PROJECTION);

    if(!m_Command){
      ::glPushMatrix();
        ::glLoadIdentity();
  
        if(!m_Projection){
          if(!m_Gl)
            ::glOrtho(m_Param11, m_Param12, m_Param13,
                      m_Param14, m_Param15, m_Param16);
          else
            ::gluOrtho2D(m_Param21, m_Param22, m_Param23, m_Param24);
        }
        else{
          if(!m_Gl)
            ::glFrustum(m_Param11, m_Param12, m_Param13,
                        m_Param14, m_Param15, m_Param16);
          else
            ::gluPerspective(m_Param21, m_Param22, m_Param23, m_Param24);
        }
        ::glGetFloatv(GL_PROJECTION_MATRIX, &m_matrixProj[0][0]);
      ::glPopMatrix();
      
      if(!m_Projection){
        m_Projection = 0;
        memcpy(m_StoreView, m_matrixProj, sizeof(float)*4*4);
      }
      else{
        m_Projection = 1;
        memcpy(m_StoreProj, m_matrixProj, sizeof(float)*4*4);
      }
 
      memcpy(m_CurMatrix, m_matrixProj, sizeof(float)*4*4);
      UpdateData(FALSE);
    }
    else{
      memcpy(m_matrixProj, m_CurMatrix, sizeof(float)*4*4);
      UpdateData(FALSE);
    }

    ::glMatrixMode(GL_MODELVIEW);
    SetMatrixIdentity(m_CurMatrix);
    m_nMatrix = 1;
    break;
	case 1:
    SetMatrixIdentity(m_PreMatrix);
    if(!m_Command){
      GetMatrix(GL_MODELVIEW);
      UpdateData(FALSE);
    }
    if(!m_Projection){
      memcpy(m_matrixProj, m_StoreView, sizeof(float)*4*4);
    }
    else{
      memcpy(m_matrixProj, m_StoreProj, sizeof(float)*4*4);
    }

    m_nMatrix = 0;
    break;
	}

	m_pView->SendMessage(WM_PAINT);
}

void CMatrixDlg::OnAppend() 
{
	// Учитываем результаты предыдущего преобразования
	float result[4][4];

	for(int i = 0; i < 4 ; i++ )
	  for(int j = 0; j < 4 ; j++ ){
		  result[i][j] = 0.0f;
		  for(int k = 0 ; k < 4 ; k++ )
			  result[i][j] += m_PreMatrix[i][k] * m_CurMatrix[k][j];
    }

  memcpy(m_PreMatrix, result, sizeof(float)*4*4);

  UpdateData(TRUE);

  if(!m_Command){
    GetMatrix(GL_MODELVIEW);
    UpdateData(FALSE);
  }

  m_pView->SendMessage(WM_PAINT);
}

void CMatrixDlg::OnReset() 
{
  SetMatrixIdentity(m_PreMatrix);
  
  if(!m_Projection){
    memcpy(m_CurMatrix, m_StoreView, sizeof(float)*4*4);
    memcpy(m_matrixProj, m_StoreView, sizeof(float)*4*4);
  }
  else{
    memcpy(m_CurMatrix, m_StoreProj, sizeof(float)*4*4);
    memcpy(m_matrixProj, m_StoreProj, sizeof(float)*4*4);
  }

  int nMatrix = m_Matrix.GetCurSel();
  if(nMatrix){
    m_nMatrix = 0;
    SetMatrixIdentity(m_CurMatrix);
  }
  else{
    m_nMatrix = 1;
  }
  
  UpdateData(FALSE);
  SetMatrixIdentity(m_CurMatrix);

  m_pView->SendMessage(WM_PAINT);
}

void CMatrixDlg::GetMatrix(UINT mode)
{
  ::glMatrixMode(mode);

  if(mode == GL_MODELVIEW){
    ::glPushMatrix();
      ::glLoadIdentity();
      ::glTranslatef(m_Param11, m_Param12, m_Param13);
      ::glRotatef(m_Param21, m_Param22, m_Param23, m_Param24);
      ::glScalef(m_Param31, m_Param32, m_Param33);
      ::glGetFloatv(GL_MODELVIEW_MATRIX, &m_CurMatrix[0][0]);
    ::glPopMatrix();
  }
  else
    ::glGetFloatv(GL_PROJECTION_MATRIX, &m_matrixProj[0][0]);
  
  ::glMatrixMode(GL_MODELVIEW);
}

void CMatrixDlg::ResetParam()
{
	m_Param11 = 0.0f;	m_Param12 = 0.0f;	m_Param13 = 0.0f;
  m_Param14 = 0.0f; m_Param15 = 0.0f;	m_Param16 = 0.0f;
  m_Param21 = 0.0f;	m_Param22 = 0.0f;
  m_Param23 = 0.0f;	m_Param24 = 0.0f;
	m_Param31 = 1.0f;	m_Param32 = 1.0f;	m_Param33 = 1.0f;
}

void CMatrixDlg::OnLockGlGlu() 
{
  int i;

  UpdateData(TRUE);

  if(!m_Gl){
    for(i = IDC_PARAM21; i <= IDC_PARAM24; i++)
      GetDlgItem(i)->EnableWindow(FALSE);
    for(i = IDC_PARAM11; i <= IDC_PARAM16; i++)
      GetDlgItem(i)->EnableWindow(TRUE);
  } 
  else{
    for(i = IDC_PARAM21; i <= IDC_PARAM24; i++)
      GetDlgItem(i)->EnableWindow(TRUE);
    for(i = IDC_PARAM11; i <= IDC_PARAM16; i++)
      GetDlgItem(i)->EnableWindow(FALSE);
  }

  m_Param11 = 0.0f; m_Param12 = 0.0f; m_Param13 = 0.0f;
  m_Param14 = 0.0f; m_Param15 = 0.0f; m_Param16 = 0.0f;
  m_Param21 = 0.0f; m_Param22 = 0.0f;
  m_Param23 = 0.0f; m_Param24 = 0.0f;
  UpdateData(FALSE);
}
Соседние файлы в папке Transform