Скачиваний:
29
Добавлен:
02.05.2014
Размер:
8.62 Кб
Скачать
// TransformView.cpp : implementation of the COpenGLView class
//

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

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

#include <gl\glaux.h>

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

/////////////////////////////////////////////////////////////////////////////
// CTransformView

IMPLEMENT_DYNCREATE(CTransformView, COpenGLView)

CTransformView::CTransformView()
{
}

CTransformView::~CTransformView()
{
}

BEGIN_MESSAGE_MAP(CTransformView, COpenGLView)
	//{{AFX_MSG_MAP(CTransformView)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTransformView diagnostics

#ifdef _DEBUG
void CTransformView::AssertValid() const
{
	CView::AssertValid();
}

void CTransformView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CTransformDoc* CTransformView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTransformDoc)));
	return (CTransformDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTransformView drawing

void CTransformView::OnInitialUpdate() 
{
	COpenGLView::OnInitialUpdate();

  // Устанавливаем параметры источника света и материала для
  // получения реалистичного изображения
  GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
	GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat light_position[] = { 0.0f, 1.0f, 2.0f, 0.0f };

	::glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
	::glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
	::glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
	::glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	::glEnable(GL_LIGHTING);
	::glEnable(GL_LIGHT0);
	::glEnable(GL_AUTO_NORMAL);
	::glEnable(GL_NORMALIZE);
	::glDepthFunc(GL_LEQUAL);
	::glEnable(GL_DEPTH_TEST);
	::glShadeModel (GL_FLAT);

	GLfloat material_ambient[]   = { 0.0f, 0.0f, 0.0f, 1.0f };
	GLfloat material_diffuse[]   = { 0.1f, 0.5f, 0.8f, 1.0f };
	GLfloat material_specular[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat material_shininess[] = { 100.0f };
	GLfloat material_emission[]  = { 0.0f, 0.0f, 0.0f, 1.0f };

	::glMaterialfv(GL_FRONT, GL_AMBIENT,   material_ambient );
	::glMaterialfv(GL_FRONT, GL_DIFFUSE,   material_diffuse );
	::glMaterialfv(GL_FRONT, GL_SPECULAR,  material_specular );
	::glMaterialfv(GL_FRONT, GL_SHININESS, material_shininess );
	::glMaterialfv(GL_FRONT, GL_EMISSION,  material_emission );
	
  // Определяем цвет фона используемый по умолчанию
  ::glClearColor(0.8f, 0.8f, 0.8f, 1.0f);

  m_dlgMatrix.Create(this);
}

void CTransformView::OnDraw(CDC* pDC)
{
	CTransformDoc* pDoc = GetDocument();
  ASSERT_VALID(pDoc);

  // Здесь размещается код рисования
  ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  ::glPushMatrix();
    DrawLeftView();
  ::glPopMatrix();
  
  ::glMatrixMode(GL_PROJECTION);
  ::glPushMatrix();
    ::glLoadMatrixf(&m_dlgMatrix.m_matrixProj[0][0]);
    ::glMatrixMode(GL_MODELVIEW);

    ::glPushMatrix();
      DrawRightView();
    ::glPopMatrix();

    ::glMatrixMode(GL_PROJECTION);
  ::glPopMatrix();
  
  ::glMatrixMode(GL_MODELVIEW);

  ::SwapBuffers(::wglGetCurrentDC());
}

/////////////////////////////////////////////////////////////////////////////
// CTransformView message handlers

void CTransformView::OnSize(UINT nType, int cx, int cy) 
{
	COpenGLView::OnSize(nType, cx, cy);

	// Непосредственное отслеживание размеров области вывода OpenGL

	// Выбор объема видимости
  ::glMatrixMode(GL_PROJECTION);
  if(m_dlgMatrix.m_nMatrix == 1){
    ::glLoadMatrixf(&m_dlgMatrix.m_matrixProj[0][0]);
  }
  else{
    ::glLoadIdentity();

	  GLfloat aspect;

    if(m_width <= m_height){
		  aspect = (GLfloat)m_height/(GLfloat)m_width;
		  ::glFrustum(-2.5, 2.5,
                  -2.5*aspect, 2.5*aspect, 4.0, 25.0);
    }
    else{
	    aspect = (GLfloat)m_width/(GLfloat)m_height;
		  ::glFrustum(-2.5*aspect, 2.5*aspect,
                  -2.5, 2.5, 4.0, 25.0);
    }
  }
	
	// делаем текущей видовую матрицу
  ::glMatrixMode( GL_MODELVIEW );
}

void CTransformView::DrawLeftView()
{
	// Левое изображение

	// Установка области вывода
	::glViewport( 0, 0, m_width, m_height );

  GLfloat aspect;

  ::glMatrixMode(GL_PROJECTION);
  ::glLoadIdentity();  // загружаем единичную матрицу
  if(m_width <= m_height){
    aspect = (GLfloat)m_height/(GLfloat)m_width;
	  ::glFrustum(-2.5, 2.5,
                -2.5*aspect, 2.5*aspect, 4.0, 25.0);
  }
  else{
	  aspect = (GLfloat)m_width/(GLfloat)m_height;
	  ::glFrustum(-2.5*aspect, 2.5*aspect,
                -2.5, 2.5, 4.0, 25.0);
  }

  ::glMatrixMode( GL_MODELVIEW );
  ::glLoadIdentity();  // загружаем единичную матрицу
  ::glTranslatef(0.0f, -1.0f, -8.0f);
	::glRotatef(15.0f, 1.0f, 0.0f, 0.0f);
	::glRotatef(-25.0f, 0.0f, 1.0f, 0.0f);

  DrawCommonStockScene();

  DrawCommonScene();
}

void CTransformView::DrawRightView()
{
	// Правое изображение

	// Установка области вывода
	::glViewport( m_width, 0, m_width, m_height );

  ::glMatrixMode( GL_MODELVIEW );
  glPushMatrix();
    ::glLoadIdentity();  // загружаем единичную матрицу
    if(m_dlgMatrix.m_Projection){
      ::glTranslatef(0.0f, -1.0f, -8.0f);
	    ::glRotatef(15.0f, 1.0f, 0.0f, 0.0f);
	    ::glRotatef(-25.0f, 0.0f, 1.0f, 0.0f);
    }

	  DrawCommonStockScene();
    
  // Использовать параметры введенные в блоке диалога
	  ::glMultMatrixf( (float *) m_dlgMatrix.m_PreMatrix);
	  ::glMultMatrixf( (float *) m_dlgMatrix.m_CurMatrix);

    DrawCommonScene();
  glPopMatrix();
}

void CTransformView::DrawCommonStockScene()
{
  // Рисуем оси координат; освещение при этом не нужно
	::glDisable(GL_LIGHTING);
	Draw3DAxes(-5.0f, 5.0f, 10);
	::glEnable(GL_LIGHTING);
}

void CTransformView::DrawCommonScene()
{
  // Конструируем букву "E"
  ::glPushMatrix();
    ::glTranslatef( -0.5f, 0.0f, 0.0f );
    ::glScalef(1.0f, 4.0f, 1.0f );
    ::auxSolidCube( 0.5f );
  ::glPopMatrix();

  ::glPushMatrix();
    ::glTranslatef( 0.0f, -0.25f, 0.0f );
    ::auxSolidCube( 0.5f );
  ::glPopMatrix();

  ::glPushMatrix();
    ::glTranslatef( -0.0f, -1.25f, 0.0f );
    ::glScalef( 3.0f, 1.0f, 1.0f );
    ::auxSolidCube( 0.5f );
  ::glPopMatrix();

  ::glPushMatrix();
    ::glTranslatef(0.25f, 0.75f, 0.0f );
    ::glScalef(2.0f, 1.0f, 1.0f );
    ::auxSolidCube(0.5f );
  ::glPopMatrix();

  ::glFinish();
}

void CTransformView::Draw3DAxes(float start, float finish, int ticks)
{
	if ( start > finish )
		{
		float temp = start;
		start = finish;
		finish = start;
		}

  	if ( 0 > ticks )
		{
		float delta = finish-start;
		ticks = delta > 1.0 ? (int)delta : 0;
		}

	Draw3DAxesLine( start, finish, 0, ticks );
	Draw3DAxesLine( start, finish, 1, ticks );
	Draw3DAxesLine( start, finish, 2, ticks );
}

void CTransformView::Draw3DAxesLine(float start, float finish, int axis_id, int ticks)
{
	float *px, *py, *pz, zero = 0.0f;
	float tickx, ticky, tickz;
	float *pdx, *pdy, *pdz, tinytick, delta = (finish-start)/(ticks<1?1:ticks);
	GLfloat negativeColor[3] = { 0.8f, 0.0f, 0.0f };
	GLfloat positiveColor[3] = { 0.0f, 0.8f, 0.0f };

	pdx = pdy = pdz = px = py = pz = &zero;
	tickx = ticky = tickz = 0.0f;
	tinytick = 0.08f;

	if ( 0 == axis_id ) // ось X
		{
		pdx = &delta;	  
		ticky = tinytick;	  
		px = &start;	  
		}
	else if ( 1 == axis_id ) // ось Y
		{
		pdy = &delta;	  
		tickx = tinytick;	  
		py = &start;	  
		}
	else 	// ось Z
		{
		pdz = &delta;	  
		ticky = tinytick;	  
		pz = &start;	  
		}

    ::glPushMatrix();
    ::glBegin(GL_LINES);

	    ::glColor3fv( negativeColor );
	    ::glVertex3f( *px, *py, *pz );
	    ::glVertex3f( 0.0f, 0.0f, 0.0f );

	    ::glColor3fv( positiveColor );
	    ::glVertex3f( 0.0f, 0.0f, 0.0f );
	    ::glVertex3f( *px+*pdx*ticks, *py+*pdy*ticks, *pz+*pdz*ticks );

	    for (int i = 0; i < ticks  ; i++ )
		  {
		    if ( i < ticks/2 )
			  {
			    ::glColor3fv( negativeColor );
			  }
		    else{
			    ::glColor3fv( positiveColor );
			  }

		    ::glVertex3f( *px-tickx, *py-ticky, *pz-tickz );
		    ::glVertex3f( *px+tickx, *py+ticky, *pz+tickz );

		    *px += *pdx;
		    *py += *pdy;
		    *pz += *pdz;
		  }

	  ::glEnd();
  ::glPopMatrix();
}
Соседние файлы в папке Transform