Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
13
Добавлен:
01.05.2014
Размер:
14.87 Кб
Скачать
// 3DProjectDlg.cpp : implementation file
//

#include "stdafx.h"
#include "3DProject.h"
#include "3DProjectDlg.h"
#include "resource.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()

/////////////////////////////////////////////////////////////////////////////
// C3DProjectDlg dialog

C3DProjectDlg::C3DProjectDlg(CWnd* pParent /*=NULL*/)
	: CDialog(C3DProjectDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(C3DProjectDlg)
	m_bLamp1 = FALSE;
	m_bLamp2 = FALSE;
	m_bLamp3 = FALSE;
	m_bLightOn = FALSE;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void C3DProjectDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(C3DProjectDlg)
	DDX_Control(pDX, IDC_XROTATE, m_ctrlXRotate);
	DDX_Control(pDX, IDC_XTRANSLATE, m_ctrlXTranslate);
	DDX_Control(pDX, IDC_YROTATE, m_ctrlYRotate);
	DDX_Control(pDX, IDC_YTRANSLATE, m_ctrlYTranslate);
	DDX_Control(pDX, IDC_ZROTATE, m_ctrlZRotate);
	DDX_Control(pDX, IDC_ZTRANSLATE, m_ctrlZTranslate);
	DDX_Control(pDX, IDC_ANGLEROTATE, m_ctrlAngleRotate);
	DDX_Control(pDX, IDC_CENTERY, m_ctrlCenterY);
	DDX_Control(pDX, IDC_EYEZ, m_ctrlEyeZ);
	DDX_Control(pDX, IDC_EYEY, m_ctrlEyeY);
	DDX_Control(pDX, IDC_EYEX, m_ctrlEyeX);
	DDX_Control(pDX, IDC_CENTERZ, m_ctrlCenterZ);
	DDX_Control(pDX, IDC_CENTERX, m_ctrlCenterX);
	DDX_Control(pDX, IDC_ZNEAR, m_ctrlZNear);
	DDX_Control(pDX, IDC_ZFAR, m_ctrlZFar);
	DDX_Control(pDX, IDC_ASPECT, m_ctrlAspect);
	DDX_Control(pDX, IDC_ANGLEY, m_ctrlAngleY);
	DDX_Check(pDX, IDC_LAMP1, m_bLamp1);
	DDX_Check(pDX, IDC_LAMP2, m_bLamp2);
	DDX_Check(pDX, IDC_LAMP3, m_bLamp3);
	DDX_Check(pDX, IDC_LIGHTON, m_bLightOn);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(C3DProjectDlg, CDialog)
	//{{AFX_MSG_MAP(C3DProjectDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_CREATE()
	ON_WM_HSCROLL()
	ON_BN_CLICKED(IDC_LAMP1, OnLamp1)
	ON_BN_CLICKED(IDC_LAMP2, OnLamp2)
	ON_BN_CLICKED(IDC_LAMP3, OnLamp3)
	ON_BN_CLICKED(IDC_LIGHTON, OnLighton)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// C3DProjectDlg message handlers

BOOL C3DProjectDlg::OnInitDialog()
{
	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

	//Controls settings
	//Rotate
	m_ctrlAngleRotate.SetRange(0,360,true);
	m_ctrlAngleRotate.SetPos(290);

	m_ctrlXRotate.SetRange(-100, 100,true);
	m_ctrlXRotate.SetPos(-39);

	m_ctrlYRotate.SetRange(-100, 100,true);
	m_ctrlYRotate.SetPos(-4);

	m_ctrlZRotate.SetRange(-100, 100,true);
	m_ctrlZRotate.SetPos(-54);

	//Translate
	m_ctrlXTranslate.SetRange(-100, 100,true);
	m_ctrlXTranslate.SetPos(-8);

	m_ctrlYTranslate.SetRange(-100, 100,true);
	m_ctrlYTranslate.SetPos(-65);

	m_ctrlZTranslate.SetRange(-100, 100,true);
	m_ctrlZTranslate.SetPos(-48);

	//projection
	m_ctrlAngleY.SetRange(0,180,true);
	m_ctrlAngleY.SetPos(45);

	m_ctrlAspect.SetRange(1,90,true);
	m_ctrlAspect.SetPos(1);

	m_ctrlZNear.SetRange(0,100,true);
	m_ctrlZNear.SetPos(0);

	m_ctrlZFar.SetRange(0,100,true);
	m_ctrlZFar.SetPos(100);
	
	//LookAt	
	m_ctrlEyeX.SetRange(-100,100,true);
	m_ctrlEyeX.SetPos(-12);
	
	m_ctrlEyeY.SetRange(-100,100,true);
	m_ctrlEyeY.SetPos(58);
	
	m_ctrlEyeZ.SetRange(-100,100,true);
	m_ctrlEyeZ.SetPos(70);

	m_ctrlCenterX.SetRange(-100,100,true);
	m_ctrlCenterX.SetPos(34);
	
	m_ctrlCenterY.SetRange(-100,100,true);
	m_ctrlCenterY.SetPos(42);
	
	m_ctrlCenterZ.SetRange(-100,100,true);
	m_ctrlCenterZ.SetPos(0);

	//set image rect
	GetClientRect(&m_rImageRect);
	m_rImageRect.right /= 2;

	m_bLightOn = m_bLamp1 = m_bLamp2 = true;
	CDataExchange dx(this, FALSE);
	DoDataExchange(&dx);
	//recalc all EditBox`s
	RecalcEdit();

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

void C3DProjectDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 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 C3DProjectDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	if (IsIconic())
	{

		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);
	}
	else
	{
		CDialog::OnPaint();
		OnDraw(&dc);
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR C3DProjectDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void C3DProjectDlg::OnDraw(CDC* pDC)
{
	wglMakeCurrent(pDC->m_hDC, m_hRC);
	
	//set a drawing rect
	glViewport(0, 0, m_rImageRect.Width(), m_rImageRect.Height()); 
 
	//draw 3D picture
	DrawWithOpenGL();

	wglMakeCurrent(pDC->m_hDC, NULL);
}

void C3DProjectDlg::DrawWithOpenGL()
{
	//set all transformations(rotate, translate,...)
	SetTransformations();

	//on lamps
	EnableLamps();

	//drawing 3D figure
	Draw3DFigure();

	//off lamps
	DisableLamps();
}

void C3DProjectDlg::SetTransformations()
{
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//set all transformations, making by user
	glTranslatef(m_ctrlXTranslate.GetPos()/100.0f, m_ctrlYTranslate.GetPos()/100.0f, m_ctrlZTranslate.GetPos()/100.0f);
	glRotatef(m_ctrlAngleRotate.GetPos()*1.0f, m_ctrlXRotate.GetPos()/100.0f, m_ctrlYRotate.GetPos()/100.0f, m_ctrlZRotate.GetPos()/100.0f);
	gluLookAt(m_ctrlEyeX.GetPos()/100.0f, m_ctrlEyeY.GetPos()/100.0f, m_ctrlEyeZ.GetPos()/100.0f, m_ctrlCenterX.GetPos()/100.0f, m_ctrlCenterY.GetPos()/100.0f, m_ctrlCenterZ.GetPos()/100.0f, 0/100.0f, -8/100.0f, 100/100.0f);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	//set perspective projection
	gluPerspective(m_ctrlAngleY.GetPos(), m_ctrlAspect.GetPos(), m_ctrlZNear.GetPos(), m_ctrlZFar.GetPos());

	glMatrixMode(GL_MODELVIEW);
}

void C3DProjectDlg::EnableLamps()
{
	//on lamps
	if (m_bLightOn)	
		glEnable(GL_LIGHTING);

	if (m_bLamp1)	
		glEnable(GL_LIGHT1);

	if (m_bLamp2)	
		glEnable(GL_LIGHT2);

	if (m_bLamp3)	
		glEnable(GL_LIGHT3);
}

void C3DProjectDlg::DisableLamps()
{
	//off lamps
	if (m_bLightOn)	
		glDisable(GL_LIGHTING);

	if (m_bLamp1)	
		glDisable(GL_LIGHT1);

	if (m_bLamp2)	
		glDisable(GL_LIGHT2);

	if (m_bLamp3)	
		glDisable(GL_LIGHT3);
}

//make settings for 3 lamps
void C3DProjectDlg::SetLamps()
{
	//lamp1
	GLfloat light1_ambient[] = { 1.0f, 1.0f, 0.0f, 1.0f };
	GLfloat light1_diffuse[] = { 1.0f, 1.0f, 0.0f, 1.0f };
	GLfloat light1_specular[] = { 1.0f, 1.0f, 0.0f, 1.0f };
	GLfloat light1_position[] = { 1.0f, 1.0f, 1.0f, 1.0f };

	//lamp2
	GLfloat light2_ambient[] = { 1.0f, 0.0f, 0.0f, 1.0f };
	GLfloat light2_diffuse[] = { 1.0f, 0.0f, 0.0f, 1.0f };
	GLfloat light2_specular[] = { 1.0f, 0.0f, 0.0f, 0.0f };
	GLfloat light2_position[] = { -1.0f, -1.0f, -1.0f, 1.0f };

	//lamp3
	GLfloat light3_ambient[] = { 0.8f, 0.9f, 1.0f, 1.0f };
	GLfloat light3_diffuse[] = { 0.5f, 0.75f, 0.75f, 1.0f };
	GLfloat light3_specular[] = { 0.22f, 1.0f, .035f, 1.0f };
	GLfloat light3_position[] = { 0.25f, 0.0f, -0.25f, 1.0f };

	//direction for all lamps
	GLfloat spot_direction[] = { 0.25f, 0.25f, 0.25f };

	glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
	glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
	glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
	glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5f);
	glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.5f);
	glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.2f);
	glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 100.0f);
	glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
	glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 128.0f);

	glLightfv(GL_LIGHT2, GL_AMBIENT, light2_ambient);
	glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_diffuse);
	glLightfv(GL_LIGHT2, GL_SPECULAR, light2_specular);
	glLightfv(GL_LIGHT2, GL_POSITION, light2_position);
	glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, 1.5f);
	glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, 0.5f);
	glLightf(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, 0.2f);
	glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 100.0f);
	glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, spot_direction);
	glLightf(GL_LIGHT2, GL_SPOT_EXPONENT, 128.0f);

	glLightfv(GL_LIGHT3, GL_AMBIENT, light3_ambient);
	glLightfv(GL_LIGHT3, GL_DIFFUSE, light3_diffuse);
	glLightfv(GL_LIGHT3, GL_SPECULAR, light3_specular);
	glLightfv(GL_LIGHT3, GL_POSITION, light3_position);
	glLightf(GL_LIGHT3, GL_CONSTANT_ATTENUATION, 3.7f);
	glLightf(GL_LIGHT3, GL_LINEAR_ATTENUATION, 4.0f);
	glLightf(GL_LIGHT3, GL_QUADRATIC_ATTENUATION, 0.2f);
	glLightf(GL_LIGHT3, GL_SPOT_CUTOFF, 100.0f);
	glLightfv(GL_LIGHT3, GL_SPOT_DIRECTION, spot_direction);
	glLightf(GL_LIGHT3, GL_SPOT_EXPONENT, 128.0f);
}

//set material of the figure
void C3DProjectDlg::SetMaterial()
{
	float mat_dif[]={0.8f,0.6f,0.8f};
	float mat_amb[]= {0.2f,0.6f,0.2f};
	float mat_spec[]={0.5f,0.7f,1.0f};
	float shininess=0.5f;

	glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,mat_amb);
	glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,mat_dif);
	glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,mat_spec);
	glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess);
	glShadeModel (GL_SMOOTH);
}

//draw figure
void C3DProjectDlg::Draw3DFigure()
{
	GLUquadricObj* p = gluNewQuadric();
	glColor3f(1.0f, 0.0f, 0.0f);
	gluSphere(p, 0.2f, 20, 20);
}

int C3DProjectDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
    PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR), // Structure size.
        1,                             // Structure version number.
        PFD_DRAW_TO_WINDOW |           // Property flags.
            PFD_SUPPORT_OPENGL,
        PFD_TYPE_RGBA,
        24,                            // 24-bit color.
        0, 0, 0, 0, 0, 0,              // Not concerned with these.
        0, 0, 0, 0, 0, 0, 0,           // No alpha or accum buffer.
        32,                            // 32-bit depth buffer.
        0, 0,                          // No stencil or aux buffer.
        PFD_MAIN_PLANE,                // Main layer type.
        0,                             // Reserved.
        0, 0, 0                        // Unsupported.
    };

    CClientDC clientDC(this);

    int pixelFormat =
        ChoosePixelFormat(clientDC.m_hDC, &pfd);
    BOOL success =
        SetPixelFormat(clientDC.m_hDC, pixelFormat, &pfd);

	m_hRC = wglCreateContext(clientDC.m_hDC);

	//make settings for drawing
	wglMakeCurrent(clientDC.m_hDC, m_hRC);
	SetMaterial();
	SetLamps();
	wglMakeCurrent(clientDC.m_hDC, NULL);

	return 0;
}

void C3DProjectDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	RecalcEdit();
	InvalidateRect(&m_rImageRect);
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void C3DProjectDlg::RecalcEdit()
{
	//Rotate
	SetDlgItemInt(IDC_XROTATEEDIT, m_ctrlXRotate.GetPos());
	SetDlgItemInt(IDC_YROTATEEDIT, m_ctrlYRotate.GetPos());
	SetDlgItemInt(IDC_ZROTATEEDIT, m_ctrlZRotate.GetPos());
	SetDlgItemInt(IDC_ANGLEROTATEEDIT, m_ctrlAngleRotate.GetPos());

	//Translate
	SetDlgItemInt(IDC_XTRANSLATEEDIT, m_ctrlXTranslate.GetPos());
	SetDlgItemInt(IDC_YTRANSLATEEDIT, m_ctrlYTranslate.GetPos());
	SetDlgItemInt(IDC_ZTRANSLATEEDIT, m_ctrlZTranslate.GetPos());

	//Eye
	SetDlgItemInt(IDC_EYEXEDIT, m_ctrlEyeX.GetPos());
	SetDlgItemInt(IDC_EYEYEDIT, m_ctrlEyeY.GetPos());
	SetDlgItemInt(IDC_EYEZEDIT, m_ctrlEyeZ.GetPos());

	//Center
	SetDlgItemInt(IDC_CENTERXEDIT, m_ctrlCenterX.GetPos());
	SetDlgItemInt(IDC_CENTERYEDIT, m_ctrlCenterY.GetPos());
	SetDlgItemInt(IDC_CENTERZEDIT, m_ctrlCenterZ.GetPos());

	//Up

	//Projection
	SetDlgItemInt(IDC_ANGLEYEDIT, m_ctrlAngleY.GetPos());
	SetDlgItemInt(IDC_ASPECTEDIT, m_ctrlAspect.GetPos());
	SetDlgItemInt(IDC_ZNEAREDIT, m_ctrlZNear.GetPos());
	SetDlgItemInt(IDC_ZFAREDIT, m_ctrlZFar.GetPos());
}

void C3DProjectDlg::OnLamp1() 
{
	m_bLamp1 = !m_bLamp1;
	InvalidateRect(&m_rImageRect);
}

void C3DProjectDlg::OnLamp2() 
{
	m_bLamp2 = !m_bLamp2;
	InvalidateRect(&m_rImageRect);
}

void C3DProjectDlg::OnLamp3() 
{
	m_bLamp3 = !m_bLamp3;
	InvalidateRect(&m_rImageRect);
}

void C3DProjectDlg::OnLighton() 
{
	CWnd* pWnd;

	m_bLightOn = !m_bLightOn;

	pWnd = GetDlgItem(IDC_LAMP1);
	pWnd->EnableWindow(m_bLightOn);

	pWnd = GetDlgItem(IDC_LAMP2);
	pWnd->EnableWindow(m_bLightOn);

	pWnd = GetDlgItem(IDC_LAMP3);
	pWnd->EnableWindow(m_bLightOn);

	InvalidateRect(&m_rImageRect);
}
Соседние файлы в папке Лабораторная работа №33