Автор работы: Пользователь скрыл имя, 15 Мая 2013 в 13:45, курсовая работа
Перечень вопросов, подлежащих разработке:
1.Обеспечить построение движущегося изображения (отсчитывающих время песочных часов) средствами OpenGL и DirectX.
2.Предусмотреть возможность регулировки скорости и приостановки анимации пользователем с помощью мыши и/или клавиатуры.
3.Предусмотреть удобный пользовательский интерфейс (элементы управления и меню) для управления анимацией в соответствии с п. 2.
1. Алгоритмические особенности реализации 4
1.1. Модель колбы песочных часов 4
1.2. Модель перетекающей воды 5
1.3. Модель пересыпающегося песка 5
1.4. Объект сцены и построение изображения 5
2. Исходные тексты программы 7
2.1. Модель песочных часов 7
2.2. Объект сцены 9
2.3. Построение изображения средствами OpenGL 12
2.4. Построение изображения средствами DirectX 15
3. Требования к системе пользователя 18
3.1. Требования к программному обеспечению 18
3.2. Минимальные требования к аппаратному обеспечению 18
4. Примеры работы программы 19
Библиографический список 21
models_.back()->setColor(
models_.push_back(new StandModel(2.5, 0.5, 3.2));
models_.back()->setColor(
models_.back()->setLineColor(
models_.push_back(new StandModel(2.5, 0.5, -3.7));
models_.back()->setColor(
models_.back()->setLineColor(
}
unsigned int Scene::count()
{
return models_.size();
}
const IModel& Scene::operator [](unsigned int index)
{
return *(models_[index]);
}
void Scene::synchronize()
{
if (!isPaused_)
{
models_[2]->setState(
(state_ < 20) ? (200 - (double)state_) / 200 :
(state_ < 820) ? 0.0 : 1.0);
models_[3]->setState(
(state_ < 0) ? 0.0 :
(state_ < 800) ? ((double)state_) / 800 : 1.0);
double state4 = (820 - ((double)state_ - 20)) / 820;
models_[4]->setState(
(state_ < 20) ? 1.0 :
(state_ < 820) ?
(isSand_ ? state4 + 1.0 : state4) : 0.0);
angle_ = (state_ < 820) ? 0.0 : (state_ - 820) * 1.0;
state_ = (state_ + speed_) % 1000 + 1;
}
}
void Scene::setSand(bool isSand)
{
isSand_ = isSand;
Color cl = (isSand_) ? Color(255, 127, 0) : Color(0, 127, 255);
models_[2]->setColor(cl);
models_[3]->setColor(cl);
models_[4]->setColor(cl);
}
double Scene::getAngle()
{
return angle_;
}
bool Scene::pause()
{
return isPaused_ = !isPaused_;
}
bool Scene::increaseSpeed()
{
if (speed_ >= 20)
return false;
++speed_;
return true;
}
bool Scene::decreaseSpeed()
{
if (speed_ <= 1)
return false;
--speed_;
return true;
}
bool Scene::isPaused()
{
return isPaused_;
}
unsigned int Scene::getSpeed()
{
return speed_;
}
void Scene::setSpeed(unsigned int speed)
{
if ((speed >= 1) && (speed <= 20))
speed_ = speed;
}
Scene::~Scene()
{
while (models_.size() > 0)
{
delete models_.back();
models_.pop_back();
}
}
2.3. Построение изображения средствами OpenGL
Листинг 2.5. Файл GlRenderer.h
#ifndef GLRENDERER_HEADER
#define GLRENDERER_HEADER
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include "IRenderer.h"
#include "HourglassModel.h"
class GlRenderer : public IRenderer
{
private:
HDC device_; // контекст устройства Windows
HGLRC renderDevice_; // контекст устройства OpenGL
Scene scene_; // объект сцены
void decorateWindow(); // устанавливает атрибуты окна
void initialize(); // инициализирует OpenGL
void cleanup(); // освобождает ресурсы OpenGL
bool formatPixel(); // устанавливает формат пикселя
void setViewport(RECT viewport); // устанавливает размеры области просмотра
public:
GlRenderer();
virtual void tick(); // переход к рисованию следующего кадра
virtual void render(); // построение изображения
virtual void updateViewport(); // обновление размеров области просмотра
virtual Scene& getScene(); // возвращает объект сцены
~GlRenderer();
};
#endif // GLRENDERER_HEADER
Листинг 2.6. Файл GlRenderer.cpp
#include "GlRenderer.h"
#include "MainWindow.h"
void GlRenderer::decorateWindow()
{
HWND window = MainWindow::instance()->
SetWindowLong(window, GWL_STYLE,
GetWindowLong(window, GWL_STYLE) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
SetWindowText(window, TEXT("Hourglass: OpenGL Renderer"));
}
void GlRenderer::initialize()
{
MainWindow* mainWindow = MainWindow::instance();
device_ = mainWindow->getDevice();
if (!formatPixel())
PostQuitMessage(1);
renderDevice_ = wglCreateContext(device_);
wglMakeCurrent(device_, renderDevice_);
setViewport(mainWindow->
}
void GlRenderer::cleanup()
{
if (device_)
{
if (renderDevice_)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(renderDevice_
}
MainWindow::instance()->
}
}
bool GlRenderer::formatPixel()
{
PIXELFORMATDESCRIPTOR pfd;
int pixelFormat;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.dwLayerMask = PFD_MAIN_PLANE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.cAccumBits = 0;
pfd.cStencilBits = 0;
if (FALSE == (pixelFormat = ChoosePixelFormat(device_, &pfd)))
{
MessageBox(NULL, TEXT("Unable to choose pixel format."),
TEXT("OpenGL Renderer"), MB_OK);
return false;
}
if (FALSE == SetPixelFormat(device_, pixelFormat, &pfd))
{
MessageBox(NULL, TEXT("Unable to set pixel format."),
TEXT("OpenGL Renderer"), MB_OK);
return false;
}
return true;
}
void GlRenderer::setViewport(RECT viewport)
{
int width = viewport.right - viewport.left;
int height = viewport.bottom - viewport.top;
if (0 == height)
height = 1;
glViewport(viewport.left, viewport.top, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
GlRenderer::GlRenderer()
{
decorateWindow();
initialize();
}
void GlRenderer::tick()
{
scene_.synchronize();
}
void GlRenderer::render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef((GLfloat)scene_.
for (unsigned int i = 0; i < scene_.count(); ++i)
{
unsigned char r = scene_[i].getColor().r;
unsigned char g = scene_[i].getColor().g;
unsigned char b = scene_[i].getColor().b;
PolygonMap poly = scene_[i].getPolygonMap();
for (PolygonMap::iterator pos = poly.begin();
pos != poly.end();
++pos)
{
glBegin(GL_POLYGON);
for (PointMap::iterator pt = pos->begin(); pt != pos->end(); ++pt)
{
glColor3ub(r, g, b);
glVertex3d(pt->x, pt->y, 0.0);
}
glEnd();
}
glTranslatef(0.0, 0.0, 0.001);
}
glFinish();
SwapBuffers(device_);
}
void GlRenderer::updateViewport()
{
setViewport(MainWindow::
}
Scene& GlRenderer::getScene()
{
return scene_;
}
GlRenderer::~GlRenderer()
{
cleanup();
}
2.4. Построение изображения средствами DirectX
Листинг 2.7. Файл DirectRenderer.h
#ifndef DIRECTRENDERER_HEADER
#define DIRECTRENDERER_HEADER
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include "IRenderer.h"
#include "DirectVertex.h"
class DirectRenderer : public IRenderer
{
private:
Scene scene_; // объект сцены
IDirect3D9* direct_; // объект DirectX
IDirect3DDevice9* renderDevice_; // объект устройства (видеокарты)
void decorateWindow(); // устанавливает атрибуты окна
void initialize(); // инициализирует DirectX
void cleanup(); // освобождает ресурсы DirectX
void setViewport(); // устанавливает размеры области просмотра
public:
DirectRenderer();
virtual void tick(); // переход к рисованию следующего кадра
virtual void render(); // построение изображения
virtual void updateViewport(); // обновление размеров области просмотра
virtual Scene& getScene(); // возвращает объект сцены
~DirectRenderer();
};
#endif // DIRECTRENDERER_HEADER
Листинг 2.8. Файл DirectRenderer.cpp
#include "DirectRenderer.h"
#include "MainWindow.h"
void DirectRenderer::
{
HWND window = MainWindow::instance()->
SetWindowText(window, TEXT("Hourglass: DirectX Renderer"));
}
void DirectRenderer::initialize()
{
MainWindow* mainWindow = MainWindow::instance();
device_ = mainWindow->getDevice();
direct_ = NULL;
renderDevice_ = NULL;
direct_ = Direct3DCreate9(D3D_SDK_
D3DDISPLAYMODE dm;
direct_->
D3DPRESENT_PARAMETERS pp;
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS))
pp.BackBufferFormat = dm.Format;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.Windowed = true;
direct_->CreateDevice(
mainWindow->getHandle(),
D3DCREATE_SOFTWARE_
&pp, &renderDevice_);
setViewport();
renderDevice_->SetRenderState(
}
void DirectRenderer::cleanup()
{
if (NULL != renderDevice_)
renderDevice_->Release();
if (NULL != direct_)
direct_->Release();
}
void DirectRenderer::setViewport()
{
D3DXMATRIX identity;
D3DXMatrixIdentity(&identity);
D3DXMATRIX trans;
D3DXMatrixOrthoLH(&trans, 10.0, 10.0, -5.0, 5.0);
renderDevice_->SetTransform(
}
DirectRenderer::
{
decorateWindow();
initialize();
}
void DirectRenderer::tick()
{
scene_.synchronize();
}
void DirectRenderer::render()
{
renderDevice_->Clear(
0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
D3DXMATRIX trans;
D3DXMatrixIdentity(&trans);
renderDevice_->SetTransform(
D3DXMatrixRotationZ(&trans, scene_.getAngle() / 180.0 * 3.14);
renderDevice_->
renderDevice_->BeginScene();
for (unsigned int s = 0; s < scene_.count(); ++s)
{
PolygonMap map = scene_[s].getPolygonMap();
DWORD color = D3DCOLOR_ARGB(255, scene_[s].getColor().r,
scene_[s].getColor().g, scene_[s].getColor().b);
if (map.size() > 0)
{
ID3DXMesh* model;
D3DXCreateMeshFVF(2 * map.size(), 4 * map.size(), D3DXMESH_MANAGED,
D3DFVF_XYZ | D3DFVF_DIFFUSE, renderDevice_, &model);
DirectVertex* vertex = 0;
model->LockVertexBuffer(0, (void **)&vertex);
unsigned int n = 0;
for (PolygonMap::iterator pos = map.begin();
pos != map.end();
++pos)
{
for (PointMap::iterator pt = pos->begin();
pt != pos->end();
++pt)
{
vertex[n] = DirectVertex(
(float)pt->x, (float)pt->y, 0.0, color);
++n;
}
}
model->UnlockVertexBuffer();
WORD* index = 0;
model->LockIndexBuffer(0, (void**)&index);
int j = 0;
WORD k = 0;
for (unsigned int i = 0; i < map.size(); ++i)
{
index[j++] = k;
index[j++] = k + 1;
index[j++] = k + 2;
index[j++] = k;
index[j++] = k + 2;
index[j++] = k + 3;
k += 4;
}
model->UnlockIndexBuffer();
DWORD* attr = 0;
model->LockAttributeBuffer(0, &attr);
for (unsigned int i = 0; i < 2 * map.size(); ++i)
attr[i] = 0;
model->UnlockAttributeBuffer()
model->DrawSubset(0);
model->Release();
}
}
renderDevice_->EndScene();
renderDevice_->Present(NULL,
&MainWindow::instance()->
NULL, NULL);
}
void DirectRenderer::
{
setViewport();
}
Scene& DirectRenderer::getScene()
{
return scene_;
}
DirectRenderer::~
{
cleanup();
}
3. ТРЕБОВАНИЯ К СИСТЕМЕ
3.1.
Требования к программному
3.2.
Минимальные требования к
4. ПРИМЕРЫ РАБОТЫ ПРОГРАММЫ
Так как
внешних отличий в
Рис. 4.1. Водяные часы.
Рис. 4.2. Песочные часы.
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
Информация о работе Цветное движущееся изображение: песочные часы