Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Тихомиров Ю. Программирование трёхмерной графики / Files / Transform / TransformView
.cpp// 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 = δ
ticky = tinytick;
px = &start;
}
else if ( 1 == axis_id ) // ось Y
{
pdy = δ
tickx = tinytick;
py = &start;
}
else // ось Z
{
pdz = δ
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