#include <windows.h>
#include <GL\gl.h>
#include <GL\glu.h>
struct sample_MATERIAL{
GLfloat ambient[3];
GLfloat diffuse[3];
GLfloat specular[3];
GLfloat emission[3];
GLfloat alpha;
GLfloat phExp;
int texture;
};
static sample_MATERIAL materials [4] = {
{{0.117647f,0.117647f,0.117647f}, {0.752941f,0.752941f,0.752941f}, {0.752941f,0.752941f,0.752941f}, {0.0f,0.0f,0.0f}, 1.0f,8.0f,-1}, //Explorer Default
{{1.0f,0.0f,0.0f}, {1.0f,0.0f,0.0f}, {0.628627f,0.628627f,0.628627f}, {0.0f,0.0f,0.0f}, 1.0f,4.0f,-1}, //red
{{0.0f,1.0f,0.0f}, {0.0f,1.0f,0.0f}, {0.628627f,0.628627f,0.628627f}, {0.0f,0.0f,0.0f}, 1.0f,4.0f,-1}, //green
{{0.0f,0.470588f,1.0f}, {0.0f,0.470588f,1.0f}, {0.628627f,0.628627f,0.628627f}, {0.0f,0.0f,0.0f}, 1.0f,4.0f,-1} //blue
};
// 6 Verticies
// 7 Texture Coordinates
// 5 Normals
// 8 Triangles
static BYTE face_indicies[8][9] = {
// Pyramid01
{0,4,1 ,0,0,0 ,0,1,2 }, {1,4,2 ,0,0,0 ,3,4,2 }, {2,4,3 ,0,0,0 ,2,4,0 },
{3,4,0 ,0,0,0 ,0,4,5 }
// Object-red
, {5,2,3 ,1,1,1 ,6,0,2 }
// Object02-g
, {5,3,0 ,2,2,2 ,6,0,2 }
// Object03-b
, {5,1,2 ,3,3,3 ,6,0,2 }
// Object04
, {5,0,1 ,4,4,4 ,6,0,2 }
};
static GLfloat vertices [6][3] = {
{-0.5f,-0.5f,-0.333333f},{0.5f,-0.5f,-0.333333f},{0.5f,0.5f,-0.333333f},
{-0.5f,0.5f,-0.333333f},{-1.49378e-08f,1.02206e-08f,-0.333333f},{-1.49378e-08f,1.02206e-08f,0.333333f}
};
static GLfloat normals [5][3] = {
{0.0f,0.0f,-1.0f},{0.0f,0.8f,0.6f},{-0.8f,0.0f,0.6f},
{0.8f,0.0f,0.6f},{0.0f,-0.8f,0.6f}
};
static GLfloat textures [7][2] = {
{0.0f,1.0f},{0.5f,0.5f},{1.0f,1.0f},
{1.0f,2.0f},{0.5f,1.5f},{0.0f,2.0f},
{0.5f,2.0f}
};
/*Material indicies*/
/*{material index,face count}*/
static int material_ref [5][2] = {
{0,4},
{1,1},
{2,1},
{3,1},
{0,1}
};
float sizex,sizey;
LONG WINAPI WndProc (HWND, UINT, WPARAM, LPARAM);
GLsizei glnWidth, glnHeight;
GLdouble gldAspect;
void SetDCPixelFormat (HWND,HDC);
void InitializeRC (void);
void DrawScene (HDC, UINT,UINT);
HPALETTE hPalette = NULL;
GLfloat nSize = 0.0f;
GLfloat nCol = 0.0f;
GLfloat nTop = 1.0f;
GLfloat nBottom = 0.0f;
int bFlag = 1;
char wndname[256]="";
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szAppName[] = "3D Exploration Exported APP";
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
RegisterClass (&wc);
hwnd = CreateWindow (szAppName, szAppName,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
HWND_DESKTOP, NULL, hInstance, NULL);
ShowWindow (hwnd, nCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
/*
* WndProc processes messages to the main window.
*/
LONG WINAPI WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HDC hdc;
static HGLRC hrc;
PAINTSTRUCT ps;
static UINT nAngle = 0;
static UINT nAngle2 = 0;
static UINT nTimer;
int n;
switch (msg) {
case WM_CREATE:
//
// Create a rendering context and set a timer.
//
hdc = GetDC (hwnd);
SetDCPixelFormat (hwnd,hdc);
hrc = wglCreateContext (hdc);
wglMakeCurrent (hdc, hrc);
InitializeRC ();
nTimer = SetTimer (hwnd, 1, 1, NULL);
return 0;
case WM_SIZE:
//
// Redefine the viewing volume and viewport when the window size
// changes.
//
glnWidth = (GLsizei) LOWORD (lParam);
glnHeight = (GLsizei) HIWORD (lParam);
return 0;
case WM_PAINT:{
//
// Draw the scene.
//
BeginPaint (hwnd, &ps);
DrawScene (hdc, nAngle,nAngle2);
EndPaint (hwnd, &ps);
}return 0;
case WM_TIMER:
//
// Update the rotation angle and force a repaint.
//
nAngle += 2;
if (nAngle >= 360)
nAngle -= 360;
nAngle2 += 1;
if (nAngle2 >= 360)
nAngle2 -= 360;
if (bFlag == 1)
nSize += 0.05f;
nCol += 0.01f;
if (nSize >= nTop)
bFlag = 0;
if (bFlag == 0)
nSize -= 0.05f;
nCol -= 0.01f;
if (nSize <= nBottom)
bFlag = 1;
InvalidateRect (hwnd, NULL, FALSE);
return 0;
case WM_QUERYNEWPALETTE:
//
// If the program is using a color palette, realize the palette
// and update the client area when the window receives the input
// focus.
//
if (hPalette != NULL) {
if (n = RealizePalette (hdc))
InvalidateRect (hwnd, NULL, FALSE);
return n;
}
break;
case WM_PALETTECHANGED:
//
// If the program is using a color palette, realize the palette
// and update the colors in the client area when another program
// realizes its palette.
//
if ((hPalette != NULL) && ((HWND) wParam != hwnd)) {
if (RealizePalette (hdc))
UpdateColors (hdc);
return 0;
}
break;
case WM_DESTROY:
//
// Clean up and terminate.
//
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hrc);
ReleaseDC (hwnd, hdc);
if (hPalette != NULL)
DeleteObject (hPalette);
KillTimer (hwnd, nTimer);
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, msg, wParam, lParam);
}
/*
* SetDCPixelFormat sets the pixel format for a device context in
* preparation for creating a rendering context.
*
* Input parameters:
* hdc = Device context handle
*
* Returns:
* Nothing
*/
void SetDCPixelFormat (HWND hwnd,HDC hdc)
{
HANDLE hHeap;
int nColors, i;
LPLOGPALETTE lpPalette;
BYTE byRedMask, byGreenMask, byBlueMask;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version number
PFD_DRAW_TO_WINDOW | // Flags
PFD_SUPPORT_OPENGL |
PFD_GENERIC_ACCELERATED|
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // RGBA pixel values
24, // 24-bit color
0, 0, 0, 0, 0, 0, // Don't care about these
0, 0, // No alpha buffer
0, 0, 0, 0, 0, // No accumulation buffer
32, // 32-bit depth buffer
0, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Layer type
0, // Reserved (must be 0)
0, 0, 0 // No layer masks
};
int nPixelFormat;
nPixelFormat = ChoosePixelFormat (hdc, &pfd);
SetPixelFormat (hdc, nPixelFormat, &pfd);
if (pfd.dwFlags & PFD_NEED_PALETTE) {
nColors = 1 << pfd.cColorBits;
hHeap = GetProcessHeap ();
(LPLOGPALETTE) lpPalette = (LPLOGPALETTE)HeapAlloc (hHeap, 0,
sizeof (LOGPALETTE) + (nColors * sizeof (PALETTEENTRY)));
lpPalette->palVersion = 0x300;
lpPalette->palNumEntries = nColors;
byRedMask = (1 << pfd.cRedBits) - 1;
byGreenMask = (1 << pfd.cGreenBits) - 1;
byBlueMask = (1 << pfd.cBlueBits) - 1;
for (i=0; i<nColors; i++) {
lpPalette->palPalEntry[i].peRed =
(((i >> pfd.cRedShift) & byRedMask) * 255) / byRedMask;
lpPalette->palPalEntry[i].peGreen =
(((i >> pfd.cGreenShift) & byGreenMask) * 255) / byGreenMask;
lpPalette->palPalEntry[i].peBlue =
(((i >> pfd.cBlueShift) & byBlueMask) * 255) / byBlueMask;
lpPalette->palPalEntry[i].peFlags = 0;
}
hPalette = CreatePalette (lpPalette);
HeapFree (hHeap, 0, lpPalette);
if (hPalette != NULL) {
SelectPalette (hdc, hPalette, FALSE);
RealizePalette (hdc);
}
}
}
/*
* InitializeRC initializes the current rendering context.
*
* Input parameters:
* None
*
* Returns:
* Nothing
*/
void InitializeRC (void)
{
GLfloat glfLightAmbient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
GLfloat glfLightDiffuse[] = { 1.2f, 1.2f, 1.2f, 1.0f };
GLfloat glfLightSpecular[] = { 0.9f, 0.9f, 0.9f, 1.0f };
//
// Add a light to the scene.
//
glLightfv (GL_LIGHT0, GL_AMBIENT, glfLightAmbient);
glLightfv (GL_LIGHT0, GL_DIFFUSE, glfLightDiffuse);
glLightfv (GL_LIGHT0, GL_SPECULAR, glfLightSpecular);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
//
// Enable depth testing and backface culling.
//
glEnable (GL_DEPTH_TEST);
glEnable (GL_CULL_FACE);
}
void MyMaterial(GLenum mode,GLfloat *f,GLfloat alpha)
{
GLfloat d[4];
d[0]=f[0];
d[1]=f[1];
d[2]=f[2];
d[3]=alpha;
glMaterialfv (GL_FRONT_AND_BACK,mode,d);
}
/*
* SelectMaterial uses OpenGL commands to define facet colors.
*
* Returns:
* Nothing
*/
void SelectMaterial(int i)
{
//
// Define the reflective properties of the 3D Object faces.
//
glEnd();
GLfloat alpha=materials[i].alpha;
MyMaterial (GL_AMBIENT, materials[i].ambient,alpha);
MyMaterial (GL_DIFFUSE, materials[i].diffuse,alpha);
MyMaterial (GL_SPECULAR, materials[i].specular,alpha);
MyMaterial (GL_EMISSION, materials[i].emission,alpha);
glMaterialf (GL_FRONT_AND_BACK,GL_SHININESS,materials[i].phExp);
glBegin(GL_TRIANGLES);
}
/*
* DrawScene uses OpenGL commands to draw a object.
*
* Input parameters:
* hdc = Device context handle
* nAngle = Angle of rotation for object
*
* Returns:
* Nothing
*/
void DrawScene (HDC hdc, UINT nAngle,UINT nAngle2)
{
sizex=glnWidth;
sizey=glnHeight;
gldAspect = (GLdouble) glnWidth / (GLdouble) glnHeight;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (30.0, // Field-of-view angle
gldAspect, // Aspect ratio of viewing volume
1.0, // Distance to near clipping plane
10.0); // Distance to far clipping plane
glViewport (0, 0, glnWidth, glnHeight);
//
// Clear the color and depth buffers.
//
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
// Define the modelview transformation.
//
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0.0f, 0.0f, -8.0f);
glRotatef (30.0f, 1.0f, 0.0f, 0.0f);
glRotatef ((GLfloat) nAngle, 0.0f, 1.0f, 0.0f);
glRotatef ((GLfloat) nAngle2, 1.0f, 0.0f, 0.0f);
glScalef (nSize+2.5f,nSize+2.5f,nSize+2.5f);
int mcount=0;
int mindex=0;
glBegin (GL_TRIANGLES);
for(int i=0;i<sizeof(face_indicies)/sizeof(face_indicies[0]);i++)
{
if(!mcount)
{
SelectMaterial(material_ref[mindex][0]);
mcount=material_ref[mindex][1];
mindex++;
}
mcount--;
for(int j=0;j<3;j++)
{
int vi=face_indicies[i][j];
int ni=face_indicies[i][j+3];
int ti=face_indicies[i][j+6];
glNormal3f (normals[ni][0],normals[ni][1],normals[ni][2]);
glTexCoord2f(textures[ti][0],textures[ti][1]);
glVertex3f (vertices[vi][0],vertices[vi][1],vertices[vi][2]);
}
}
glEnd ();
//
// Swap the buffers.
//
glFlush();
SwapBuffers (hdc);
};
注意添加:
#pragma comment( lib, "glaux.lib")
#pragma comment( lib, "opengl32.lib" )
#pragma comment( lib, "glu32.lib" )
#pragma comment( lib, "glaux.lib" )