Цветное движущееся изображение: песочные часы

Автор работы: Пользователь скрыл имя, 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

Содержимое работы - 1 файл

Report.docx

— 84.66 Кб (Скачать файл)

    models_.back()->setColor(Color(0, 127, 255));

    models_.push_back(new StandModel(2.5, 0.5, 3.2));

    models_.back()->setColor(Color(0, 180, 0));

    models_.back()->setLineColor(Color(0, 180, 0));

    models_.push_back(new StandModel(2.5, 0.5, -3.7));

    models_.back()->setColor(Color(0, 180, 0));

    models_.back()->setLineColor(Color(0, 180, 0));

}

 

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()->getHandle();

    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->getClientRect());

}

 

void GlRenderer::cleanup()

{

    if (device_)

    {

        if (renderDevice_)

        {

            wglMakeCurrent(NULL, NULL);

            wglDeleteContext(renderDevice_);

        }

        MainWindow::instance()->releaseDevice(device_);

    }

}

 

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_.getAngle(), 0.0, 0.0, 1.0);

    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::instance()->getClientRect());

}

 

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::decorateWindow()

{

    HWND window = MainWindow::instance()->getHandle();

    SetWindowText(window, TEXT("Hourglass: DirectX Renderer"));

}

 

void DirectRenderer::initialize()

{

    MainWindow* mainWindow = MainWindow::instance();

    device_ = mainWindow->getDevice();

 

    direct_ = NULL;

    renderDevice_ = NULL;

 

    direct_ = Direct3DCreate9(D3D_SDK_VERSION);

    D3DDISPLAYMODE dm;

    direct_->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm);

 

    D3DPRESENT_PARAMETERS pp;

    memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));

 

    pp.BackBufferFormat = dm.Format;

    pp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    pp.Windowed = true;

 

    direct_->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,

        mainWindow->getHandle(), D3DCREATE_SOFTWARE_VERTEXPROCESSING,

        &pp, &renderDevice_);

    setViewport();

 

    renderDevice_->SetRenderState(D3DRS_LIGHTING, false);

}

 

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(D3DTS_WORLD, &trans);

}

 

DirectRenderer::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(D3DTS_VIEW, &trans);

    D3DXMatrixRotationZ(&trans, scene_.getAngle() / 180.0 * 3.14);

    renderDevice_->MultiplyTransform(D3DTS_VIEW, &trans);

    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()->getClientRect(),

        NULL, NULL);

}

 

void DirectRenderer::updateViewport()

{

    setViewport();

}

 

Scene& DirectRenderer::getScene()

{

    return scene_;

}

 

DirectRenderer::~DirectRenderer()

{

    cleanup();

}

3. ТРЕБОВАНИЯ К СИСТЕМЕ ПОЛЬЗОВАТЕЛЯ

3.1. Требования к программному обеспечению

  • Операционная система Microsoft Windows XP/Vista/7;
  • Microsoft Visual C++ 2008 Redistributable;
  • DirectX 9;
  • OpenGL 2.

3.2. Минимальные требования к аппаратному  обеспечению

  • Оперативная память: 256 Мбайт для Microsoft Windows XP, 512 Мбайт для Microsoft Windows 7, 1 Гбайт для Microsoft Windows Vista;
  • Процессор с частотой от 1 ГГц;
  • Видеокарта с поддержкой аппаратного режима DirectX 9 с видеопамятью от 128 Мбайт.

4. ПРИМЕРЫ РАБОТЫ ПРОГРАММЫ

Так как  внешних отличий в изображениях, построенных средствами OpenGL и DirectX, практически не наблюдается, имеет смысл показать только различие изображений водяных (рис. 4.1) и песочных (рис. 4.2) часов.

 

Рис. 4.1. Водяные часы.

Рис. 4.2. Песочные часы.

БИБЛИОГРАФИЧЕСКИЙ СПИСОК

  1. OpenGL. Программирование компьютерной графики / Ф. Хилл. — Спб.: Питер, 2006.
  2. DirectX и C++. Искусство программирования / М. Фленов. — Спб.: БХВ, 2006.
  3. Win32 API. Эффективная разработка приложений / Ю.А. Щупак. — Спб.: Питер, 2007.
  4. Windows для профессионалов / Дж. Рихтер. — Спб.: Питер, 2000.

Информация о работе Цветное движущееся изображение: песочные часы