- •Министерство образования и науки российской федерации
- •Введение
- •1.WindowsApi. Определение и задачи.
- •2. Интерфейс программирования приложенийWin32
- •2.1 Расширение функциональности WinMain.
- •2.2 Класс окна
- •2.3 Создание окна
- •2.4 Расширение функциональности WndProc
- •3. С чего начать? Переход от Win32 к Win64
- •3.1 Операционная система x64
- •4.1 Как сделать код совместимым с Win64
- •4.2 Отладка
- •Заключение
- •5. Приложения
- •5.1 Приложение 1.
- •5.2 Приложение 2.
- •Литература
5.2 Приложение 2.
Header.h
#include<windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <glut.h>
HWND hWnd;
HGLRC hGLRC;
HDC hDC;
double xSide=0.0;
double ySide=0.0;
double zSide=0.0;
double xSideO=0.0;
double ySideO=0.0;
double zSideO=0.0;
double Scale=1.0;
double ScaleO=1.0;
double TurnX=0.0;
double TurnY=0.0;
double TurnZ=0.0;
double TurnXO=0.0;
double TurnYO=0.0;
double TurnZO=0.0;
int objCount=1;
MSG msg;
bool keys[256];
GLuint filter; // Используемый фильтр для текстур
GLuint fogMode[]= { GL_EXP, GL_EXP2, GL_LINEAR }; // Хранит три типа тумана
GLuint fogHint[]= { GL_NICEST, GL_FASTEST, GL_DONT_CARE };
GLuint fogfilter= 1; // Тип используемого тумана
GLuint foghint= 2;
GLfloat fogColor[4]= {0.5f, 0.5f, 0.5f, 1.0f}; // Цвет тумана
double fogDensity = 0.1f;
API.cpp
#include "Header.h"
BOOL SetWindowPixelFormat(HWND);
BOOL display (HWND);
BOOL resize (int, int);
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
void newRotate (float a, float x, float y, float z)
{
float m[16];
glGetFloatv (GL_MODELVIEW_MATRIX, m);
glLoadIdentity ();
glRotatef (a,x,y,z);
glMultMatrixf (m);
}
void newTranslate (float x, float y, float z)
{
float m[16];
glGetFloatv (GL_MODELVIEW_MATRIX, m);
glLoadIdentity ();
glTranslatef (x,y,z);
glMultMatrixf (m);
}
void DispalyList () {
glNewList(1,GL_COMPILE);
glBegin(GL_LINES);
glColor3d(15.0,0.0,0.0);
glVertex3d(-50.0, 0.0, 0.0);
glVertex3d(50.0, 0.0, 0.0);
glEnd();
glBegin(GL_LINES);
glColor3d(0.0,15.0,0.0);
glVertex3d(0.0, -50.0, 0.0);
glVertex3d(0.0, 50.0, 0.0);
glEnd();
glBegin(GL_LINES);
glColor3d(15.0,15.0,15.0);
glVertex3d(0.0, 0.0, -50.0);
glVertex3d(0.0, 0.0, 50.0);
glEnd();
glEndList();
glNewList(2,GL_COMPILE);
glPushMatrix();
glTranslated(0.5,0,0);
glColor3d(1,0,0);
glutSolidSphere(1.3,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(-0.5,0,0);
glColor3d(1,0,0);
glutSolidSphere(1.3,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(0,0.5,0);
glColor3d(1,0,0);
glutSolidSphere(1.3,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(0,-0.5,0);
glColor3d(1,0,0);
glutSolidSphere(1.3,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(0,0,0.5);
glColor3d(1,0,0);
glutSolidSphere(1.3,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(0,0,-0.5);
glColor3d(1,0,0);
glutSolidSphere(1.3,20,20);
glPopMatrix();
glEndList();
glNewList(3,GL_COMPILE);
glPushMatrix();
glTranslated(1.5,1.5,1.5);
glColor3d(1,1,1);
glutSolidSphere(0.8,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(-1.5,-1.5,-1.5);
glColor3d(1,1,1);
glutSolidSphere(0.8,20,20);
glPopMatrix();
glEndList();
glNewList(4,GL_COMPILE);
glPushMatrix();
glTranslated(3,3,3);
glColor3d(1,0,1);
glutSolidSphere(0.8,20,20);
glPopMatrix();
glPushMatrix(); // сохраняем текущие координаты
glTranslated(-3,-3,-3); // сдвигаемся по оси Х
glColor3d(0,1,1);
glutSolidSphere(0.9,20,20); // рисуем сферу
glPopMatrix(); // возвращаемся к старой системе координат
glPushMatrix();
glTranslated(-3,0,0);
glColor3d(1,1,0);
glutSolidSphere(0.8,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(3,0,0);
glColor3d(0,0,1);
glutSolidSphere(0.7,20,20);
glPopMatrix();
glEndList();
glNewList(5,GL_COMPILE);
glPushMatrix();
glTranslated(-4,4,4);
glColor3d(1,1,0);
glutSolidSphere(0.5,20,20);
glPopMatrix();
glPushMatrix(); // сохраняем текущие координаты
glTranslated(4,-4,-4); // сдвигаемся по оси Х
glColor3d(1,0,0);
glutSolidSphere(0.4,20,20); // рисуем сферу
glPopMatrix(); // возвращаемся к старой системе координат
glPushMatrix();
glTranslated(0,-4,0);
glColor3d(0,1,0);
glutSolidSphere(0.3,20,20);
glPopMatrix();
glPushMatrix();
glTranslated(0,4,0);
glColor3d(0,1,1);
glutSolidSphere(0.6,20,20);
glPopMatrix();
glEndList();
}
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str,int nWinMode){
WNDCLASS wclass;
wclass.hInstance=hThisInst;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wclass.hIcon = NULL;
wclass.lpfnWndProc = WindowFunc;
wclass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wclass.lpszMenuName = NULL;
wclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wclass.lpszClassName = L"Window";
RegisterClass(&wclass);
hWnd = CreateWindowA("Window", "Win API WND",
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
50, //CW_USEDEFAULT
50, //CW_USEDEFAULT
800, //CW_USEDEFAULT
800, //CW_USEDEFAULT
HWND_DESKTOP, NULL, hThisInst, NULL);
if (!hWnd) return 0;
ShowWindow(hWnd,nWinMode);
UpdateWindow(hWnd);
DispalyList ();
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
display (hWnd);
}
return msg.wParam;
}
BOOL SetWindowPixelFormat(HWND hWnd)
{
int m_GLPixelIndex;
PIXELFORMATDESCRIPTOR pfd;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cRedBits = 8;
pfd.cRedShift = 16;
pfd.cGreenBits = 8;
pfd.cGreenShift = 8;
pfd.cBlueBits = 8;
pfd.cBlueShift = 0;
pfd.cAlphaBits = 0;
pfd.cAlphaShift = 0;
pfd.cAccumBits = 64;
pfd.cAccumRedBits = 16;
pfd.cAccumGreenBits = 16;
pfd.cAccumBlueBits = 16;
pfd.cAccumAlphaBits = 0;
pfd.cDepthBits = 32;
pfd.cStencilBits = 8;
pfd.cAuxBuffers = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.bReserved = 0;
pfd.dwLayerMask = 0;
pfd.dwVisibleMask = 0;
pfd.dwDamageMask = 0;
m_GLPixelIndex = ChoosePixelFormat( hDC, &pfd);
if(m_GLPixelIndex==0) // Let's choose a default index.
{
m_GLPixelIndex = TRUE;
if(DescribePixelFormat(hDC,m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pfd)==0)
return FALSE;
}
if (SetPixelFormat( hDC, m_GLPixelIndex, &pfd)==FALSE)
return FALSE;
return TRUE;
}
BOOL resize(int width,int height)
{
glViewport(0,0,width,height);//выбор порта
glMatrixMode( GL_PROJECTION );
glLoadIdentity(); ////???
//glOrtho(-5,5, -5,5, 2,12);//отртографическая(параллельная проекция)
gluPerspective(90.0, width/height, 0.2, 100.0);
glMatrixMode( GL_MODELVIEW );
return TRUE;
}
BOOL display(HWND hWnd)
{
int rot=0;
glClearColor(0.5f,0.5f,0.5f,1.0f); // Будем очищать экран, заполняя его цветом тумана
glEnable(GL_FOG); // Включаем туман (GL_FOG)
glFogi(GL_FOG_MODE, fogMode[fogfilter]);// Выбираем тип тумана
glFogfv(GL_FOG_COLOR, fogColor); // Устанавливаем цвет тумана
glFogf(GL_FOG_DENSITY, fogDensity); // Определяем, на сколько густым будет туман (fogDensity)
glHint(GL_FOG_HINT, fogHint[foghint]); // Вспомогательная установка тумана
glFogf(GL_FOG_START, 1.0f); // Глубина, с которой начинается туман
glFogf(GL_FOG_END, 5.0f); // Глубина, где туман заканчивается.
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glCallList(1);
glPushMatrix();
glTranslated (0.0f+xSide,0.0f+ySide,0.0f+zSide);
glScaled (0.0f+Scale,0.0f+Scale,0.0f+Scale);
glRotated (TurnX, 1, 0, 0);
glRotated (TurnY, 0, 1, 0);
glRotated (TurnZ, 0, 0, 1);
glCallList(2);
glPushMatrix();
glTranslated (0.0f+xSideO,0.0f+ySideO,0.0f+zSideO);
glScaled (0.0f+ScaleO,0.0f+ScaleO,0.0f+ScaleO);
glRotated (TurnXO, 1, 0, 0);
glRotated (TurnYO, 0, 1, 0);
glRotated (TurnZO, 0, 0, 1);
for (int i = 1; i <= objCount; i++){
rot = 360/objCount;
if (i<5) {
glRotated(rot*i, 1, 0, 0);
glRotated(rot*(i-1), 0, 1, 0);
glRotated(rot*(i-2), 0, 0, 1);
glCallList(3);
}
if (i>=5) {
glRotated(rot*i, 1, 0, 0);
glRotated(rot*(i-1), 0, 1, 0);
glRotated(rot*(i-2), 0, 0, 1);
glCallList(4);
glRotated(rot*i, 1, 0, 0);
glRotated(rot*(i-1), 0, 1, 0);
glRotated(rot*(i-2), 0, 0, 1);
glCallList(5);
}
}
glPopMatrix();
glPopMatrix();
glEnd();
SwapBuffers(wglGetCurrentDC());
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){
float pos[4] = {3,3,3,1};
float dir[3] = {-1,-1,-1};
switch(msg){
case WM_CREATE:
hDC = GetDC(hWnd); // получаем контекст устройства нашего окна
SetWindowPixelFormat(hWnd); // устанавливаем параметры контекста воспроизведения OpenGL
hGLRC = wglCreateContext(hDC); // создаем контекст воспроизведения OpenGL
wglMakeCurrent(hDC, hGLRC); // делаем его текущим
glEnable(GL_ALPHA_TEST); // тест прозрачности, т.е. будет учитываться четвертый параметр в glColor
glEnable(GL_DEPTH_TEST); // тест глубины
glEnable(GL_COLOR_MATERIAL); // glColor будет устанавливать свойства материала
glEnable(GL_LIGHTING); // разрешаем освещение
glEnable(GL_LIGHT0); // включаем нулевую лампу
glEnable(GL_BLEND); // разрешаем смешение цветов
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// устанавливаем положение нулевой лампы
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
return 0;
case WM_DESTROY:
if (hGLRC) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hGLRC); // удаляем созданный выше контекст воспроизведения OpenGL
}
ReleaseDC(hWnd, hDC); // освобождаем контекст устройства нашего окна
PostQuitMessage(0);
return 0;
case WM_SIZE:
resize(LOWORD(lParam), HIWORD(lParam));
return 0;
case WM_KEYDOWN: // Была ли нажата кнопка?
switch (wParam)
{
case VK_DECIMAL: // NUM .
foghint+=1;
if(foghint>2) foghint=0;
break;
case VK_NUMPAD0: // NUM 0
fogfilter+=1;
if(fogfilter>2) fogfilter=0;
break;
case VK_MULTIPLY: // NUM *
fogDensity+=0.025;
if(fogDensity>=0.5)
fogDensity=0.5;
break;
case VK_DIVIDE: // NUM /
fogDensity-=0.025;
if(fogDensity<=0.05)
fogDensity=0.05;
break;
case VK_ADD: // NUM +
objCount+=1;
if(objCount>=10)
objCount=10;
break;
case VK_SUBTRACT: // NUM -
objCount-=1;
if(objCount<=1)
objCount=1;
break;
case 0x57: //W
newTranslate(0,0,1);
//xSideObj+=1.5f;
break;
case 0x53: //S
newTranslate(0,0,-1);
//xSideObj-=1.5f;
break;
case 0x41: //A
newTranslate(1,0,0);
//ySideObj+=1.5f;
break;
case 0x44: //D
newTranslate(-1,0,0);
//ySideObj-=1.5f;
break;
case 0x20:// space
newTranslate(0,-1,0);
//zSideObj+=1.5f;
break;
case 0x11:// ctrl
newTranslate(0,1,0);
//zSideObj-=1.5f;
break;
case VK_UP:
newRotate(5,1,0,0);
/*ySide=1.5f;*/
break;
case VK_DOWN:
newRotate(-5,1,0,0);
/*ySide=-1.5f;*/
break;
case VK_LEFT:
newRotate(-5,0,1,0);
/*xSide=-1.5f;*/
break;
case VK_RIGHT:
newRotate(5,0,1,0);
/*xSide=1.5f;*/
break;
case 0x45://E
newRotate(-5,0,0,1);
/*zSide=-1.5f;*/
break;
case 0x51://Q
newRotate(5,0,0,1);
/*zSide=1.5f;*/
break;
case VK_OEM_PLUS:
Scale+=0.01;
break;
case VK_OEM_MINUS:
Scale-=0.01;
break;
//case 0x50: //P
// glLoadIdentity();
// Scale=0.8;
// break;
case 0x54: //T
xSide+=1;
break;
case 0x47: //G
xSide-=1;
break;
case 0x48: //H
ySide+=1;
break;
case 0x46: //F
ySide-=1;
break;
case 0x59: //Y
zSide+=1;
break;
case 0x52: //R
zSide-=1;
break;
case VK_NUMPAD6:
TurnY+=5;
break;
case VK_NUMPAD4:
TurnY-=5;
break;
case VK_NUMPAD8:
TurnX+=5;
break;
case VK_NUMPAD2:
TurnX-=5;
break;
case VK_NUMPAD9:
TurnZ+=5;
break;
case VK_NUMPAD7:
TurnZ-=5;
break;
case 0x49:
TurnYO+=5;
break;
case 0x4B:
TurnYO-=5;
break;
case 0x4C:
TurnXO+=5;
break;
case 0x4A:
TurnXO-=5;
break;
case 0x55:
TurnZO+=5;
break;
case 0x4F:
TurnZO-=5;
break;
case 0x4E:
ScaleO+=0.01;
break;
case 0x4D:
ScaleO-=0.01;
break;
}
return 0;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return DefWindowProc (hWnd,msg,wParam,lParam);
}
Руководство пользователя.
Данное приложение является полностью графическим приложением, разработанное на базе Win32 API с помощью библиотек OPENGL. В приложении представлена модель абстрактного вещества. Есть возможность свободного полета "камеры" - точки обзора наблюдателя, движение атома по всем 3-м осям (х, y, z) и управление параметрами тумана: изменение формул прорисовки тумана и густоты тумана. Управление камерой происходит с помощью кнопок:
W/S - движение камеры вперед и назад.
A/D - движение камеры влево и вправо (straif).
CTRL/SPACE - движение камеры вверх и вниз.
UP/DOWN - поднятие и опускание камеры.
LEFT/RIGHT - повороты камеры влево и вправо.
Q/R - поворот камеры относительно оси, перпендикулярной экрана.
+/- на боковой цифровой клавиатуре увеличивает число атомов, находящихся вокруг ядра.
*и / - увеличивают или уменьшают густоту тумана.
NUMPAD0 - меняет качество прорисовки.