/* File: Main.cpp; Mode: C++; Tab-width: 3; Author: Simon Flannery; */
#define STRICT
#define WIN32_LEAN_AND_MEAN
#define _USE_MATH_DEFINES
#include <stdio.h>
#include <stdlib.h>
#include <windows.h> /* Must Include before GL/gl.h. */
#include <time.h>
#include "glew.h" /* OpenGL. */
#include "Texture.h"
#include "TextureDigit.h"
#include "Shader.h"
#include "Camera.h"
#include "Vector.h"
#include "MD2.h"
#define FAN_SPEED 256.0f
float lightHeight = 20.0f;
struct texture
{
float u, v;
};
struct texture_normal_vertex
{
// GL_T2F_N3F_V3F
texture t;
vector n;
vertex v;
float& operator[](int i)
{
return v[i];
}
float operator[](int i) const
{
return v[i];
}
};
float g_mouse_x = 45.0f, g_mouse_y = -45.0f, g_mouse_z = 0.0f;
bool key[256];
Camera my_camera;
Shader my_shadow_shader, my_fade_shader, my_bump_shader;
Texture2d my_tile, my_bump, my_skin, my_weapon_skin, my_grey;
TextureDigit my_fps;
Model_md2 my_model, my_weapon, my_fan;
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
HWND BuildWindow(LPCTSTR, HINSTANCE, int, int);
BOOL HeartBeat(HWND, HDC);
void CreateTangentVectorSpace(const vertex&, const vertex&, const vertex&, float, float, float, float, float, float, vertex& tangent, vertex& binormal, vertex& normal);
void CalculateTangentForEachVertex(const texture_normal_vertex*, vertex*, vertex*, vertex*, size_t m);
void Initialize();
void ShutDown();
void ReshapeScene(int, int);
void RenderFloor(float, const vertex&);
void IllustrateScene();
int GetFPS()
{
static int FPS = 0;
static int rFPS = 0;
DWORD now_millisecond = 0;
static DWORD next_millisecond = 0;
FPS++;
now_millisecond = GetTickCount();
if (now_millisecond >= next_millisecond)
{
next_millisecond = now_millisecond + 1000;
rFPS = FPS;
FPS = 0;
}
return rFPS;
}
/* The application's entry point. */
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd = NULL;
if ((hWnd = BuildWindow("Framework Test", hInstance, 800, 600)) != NULL)
{
HDC hdc = GetDC(hWnd);
HGLRC hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
glewInit(); /* Very little error checking is done here. */
if (GLEW_ARB_shader_objects != false)
{
Initialize();
ShowWindow(hWnd, nCmdShow);
HeartBeat(hWnd, hdc);
ShutDown();
}
else
{
MessageBox(NULL, "Sorry. One or more GL_ARB_shader_objects functions were not detected.", "Error", MB_OK | MB_ICONEXCLAMATION);
}
wglMakeCurrent(hdc, NULL);
wglDeleteContext(hrc);
ReleaseDC(hWnd, hdc);
DestroyWindow(hWnd);
}
return 0;
}
/* Message handler for our window. */
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static POINT last_mouse = {0, 0};
static POINT current_mouse = {0, 0};
static bool bXYMousing = false;
static bool bZMousing = false;
switch (msg)
{
case WM_SIZE:
ReshapeScene(LOWORD(lParam), HIWORD(lParam));
return 0;
break;
case WM_MOUSEMOVE:
current_mouse.x = LOWORD(lParam);
current_mouse.y = HIWORD(lParam);
if (bXYMousing != false)
{
g_mouse_x -= (current_mouse.x - last_mouse.x);
g_mouse_y -= (current_mouse.y - last_mouse.y);
my_camera.ViewRotate((float) (current_mouse.x - last_mouse.x));
}
if (bZMousing != false)
{
g_mouse_z -= (current_mouse.y - last_mouse.y);
my_camera.Zoom((float) (current_mouse.y - last_mouse.y));
}
last_mouse.x = current_mouse.x;
last_mouse.y = current_mouse.y;
break;
case WM_LBUTTONDOWN:
last_mouse.x = current_mouse.x = LOWORD (lParam);
last_mouse.y = current_mouse.y = HIWORD (lParam);
bXYMousing = true;
break;
case WM_LBUTTONUP:
bXYMousing = false;
break;
case WM_RBUTTONDOWN:
last_mouse.x = current_mouse.x = LOWORD(lParam);
last_mouse.y = current_mouse.y = HIWORD(lParam);
bZMousing = true;
break;
case WM_RBUTTONUP:
bZMousing = false;
break;
case WM_KEYDOWN:
key[wParam] = true;
break;
case WM_KEYUP:
key[wParam] = false;
break;
case WM_CHAR:
if (wParam == VK_ESCAPE) /* ESC key. */
{
PostQuitMessage(0);
}
return 0;
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
/* Registers the type of window and then creates the window. The pixel format
is also described. */
HWND BuildWindow(LPCTSTR szTitle, HINSTANCE hInstance, int nWidth, int nHeight)
{
int pf = 0;
HDC hdc = NULL;
HWND hWnd = NULL;
WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW | CS_OWNDC, WindowProc, 0, 0, hInstance,
LoadIcon(NULL, IDI_APPLICATION),
LoadCursor(NULL, IDC_ARROW),
NULL, NULL, "OpenGL" };
PIXELFORMATDESCRIPTOR pfd = {0};
RegisterClass(&wndClass);
hWnd = CreateWindow("OpenGL", szTitle,
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
nWidth, nHeight,
NULL, NULL,
hInstance, NULL);
hdc = GetDC(hWnd);
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cDepthBits = 24;
pfd.cColorBits = 32;
pfd.cStencilBits = 8;
pf = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, pf, &pfd);
// DescribePixelFormat(hdc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
ReleaseDC(hWnd, hdc);
return hWnd;
}
/* Responsible for the message loop. Renders scene and swaps buffer each iteration. */
BOOL HeartBeat(HWND hWnd, HDC hdc)
{
MSG msg = {0}; /* Message. */
BOOL bActive = TRUE, bMsg = FALSE;
while (msg.message != WM_QUIT)
{
if (bActive != FALSE)
{
bMsg = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
}
else
{
bMsg = GetMessage(&msg, NULL, 0, 0);
}
bActive = !IsIconic(hWnd);
if (bMsg != FALSE)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (key[VK_UP] != false) /* Up Arrow Key. */
{
my_model.SetNextAnimation(RUN);
my_weapon.SetNextAnimation(RUN);
if (my_model.GetAnimation() == RUN)
{
my_camera.WalkForward(1.0f);
}
}
if (key[VK_LEFT] != false) /* Left Arrow Key. */
{
my_camera.WalkRotate(5.0f);
my_camera.ViewRotate(-5.0f);
}
else if (key[VK_RIGHT] != false) /* Right Arrow Key. */
{
my_camera.WalkRotate(-5.0f);
my_camera.ViewRotate(5.0f);
}
if (key['I'] != false)
{
lightHeight += 0.1;
}
else if (key['O'] != false)
{
lightHeight -= 0.1;
}
if (key[90 /* 'z' */] != false) /* Attack. */
{
my_model.SetNextAnimation(ATTACK);
my_weapon.SetNextAnimation(ATTACK);
}
else if (key[88 /* 'x' */] != false) /* Taunt. */
{
my_model.SetNextAnimation(FALLBACK);
my_weapon.SetNextAnimation(FALLBACK);
}
else if (key[67 /* 'c' */] != false) /* Bloc
- 1
- 2
- 3
前往页