3D球体代码(OpenGL)

时间:2021-10-13 12:37:34

3D球体代码(OpenGL)

 

/**
* function:动态3D球体
* author:顾博君
* time:2013-1-19
* 编译器:codeblocks
* 本程序为OpenGL代码,需要OpenGL的类库
*/
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#define IDR_MAIN 101
#define IDM_RED_TH 40001
#define IDM_GREEN_TH 40002
#define IDM_BLUE_TH 40003
#define IDM_DEFAULT_TH 40004
#define IDM_RED_BG 40007
#define IDM_GREEN_BG 40008
#define IDM_BLUE_BG 40009
#define IDM_DEFAULT_BG 40010

#define IDM_RED2_TH 40011
#define IDM_GREEN2_TH 40012
#define IDM_BLUE2_TH 40013
#define IDM_RED2_BG 40017
#define IDM_GREEN2_BG 40018
#define IDM_BLUE2_BG 40019

#define IDM_ROTATE_QUICK 40020
#define IDM_ROTATE_SLOW 40021
#define IDM_ROTATE_DEFAULT 40022
#define IDM_ROTATE_STOP 40024

#define IDM_ROTATE_X 40030
#define IDM_ROTATE_Y 40031
#define IDM_ROTATE_Z 40032
#define IDM_ROTATE_FAN 40023
#define IDM_ROTATE_XYZ_DEFAULT 40033

#define IDM_SIZE_SMALL 40040
#define IDM_SIZE_LARGE 40041
#define IDM_SIZE_DEFAULT 40042

#define IDM_MOVE_UP 40050
#define IDM_MOVE_DOWN 40051
#define IDM_MOVE_LEFT 40052
#define IDM_MOVE_RIGHT 40053
#define IDM_MOVE_FORWARD 40054
#define IDM_MOVE_BACKWARD 40055
#define IDM_MOVE_DEFAULT 40056

//背景色
GLfloat BG_ClearColorRed,BG_ClearColorGreen,BG_ClearColorBlue;
//光照
GLfloat light_ambient[]={0.0,1.8,0.0,1.0};
GLfloat light_diffuse[]={1.0,1.0,1.0,1.0};
GLfloat light_specular[]={1.0,1.0,1.0,1.0};
GLfloat light_position[]={1.0,1.0,1.0,0.0};
//旋转速度
float RotateSpeed=0.8f;
//旋转方向
int fangxiang=0;
//物体缩放
float thing_size=1.0;
//平移
GLfloat Move_X=0.0F;
GLfloat Move_Y=0.0F;
GLfloat Move_Z=0.0F;

char *className = "OpenGL";
char *windowName = "OpenGL Cube";
int winX = 500, winY = 200;
int winWidth = 500, winHeight = 500;
HDC hDC;
HGLRC hGLRC;
HPALETTE hPalette;
HMENU hRoot;

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void EnableOpenGL(HWND hwnd, HDC*, HGLRC*);
void DisableOpenGL(HWND, HDC, HGLRC);
void CreateMyMenu();//创建菜单
void init(void);
void redraw(HDC hDC);
void resize(void);
//void setupPalette(HDC hDC);


int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
CreateMyMenu();//创建菜单
WNDCLASSEX wcex;
HWND hwnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
float theta = 0.0f;
float space=0.1f;

GLfloat mat_diffuse[4]={1,0.5,0.5,1.0};
GLfloat mat_specular[4]={1.0,1.0,1.0,1.0};
GLfloat mat_shininess[1]={100.0};

GLfloat light_position0[4]={0,500,500,0};

/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW|CS_VREDRAW;//CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "GLSample";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;


if (!RegisterClassEx(&wcex))
return 0;

/* create main window */
hwnd = CreateWindowEx(0,
"GLSample",
windowName,//"OpenGL Sample",
WS_OVERLAPPEDWINDOW/*后面是后来加的*/|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
winX,//CW_USEDEFAULT,
winY,//CW_USEDEFAULT,
winWidth,//256,
winHeight,//256,
NULL,
hRoot,
hInstance,
NULL);

ShowWindow(hwnd, nCmdShow);

/* enable OpenGL for the window */
//setupPixelFormat(hwnd, &hDC, &hRC);
EnableOpenGL(hwnd, &hDC, &hRC);
//init();

glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT0,GL_POSITION,light_position0);
glEnable(GL_LIGHT0);

GLfloat light_position1[4]={1000,-1000,1000,0};
GLfloat mat_diffuse1[4]={0.5,0.5,1.0,1.0};
glLightfv(GL_LIGHT1,GL_DIFFUSE,mat_diffuse1);
glLightfv(GL_LIGHT1,GL_SPECULAR,mat_specular);
glLightfv(GL_LIGHT1,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT1,GL_POSITION,light_position1);
glEnable(GL_LIGHT1);

glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);

glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);

/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else if(0)
{
/* OpenGL animation code goes here */

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);


glPushMatrix();
glRotatef(theta,0.0f , 0.0f, 1.0f);

glBegin(GL_TRIANGLES);

glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(0.87f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(-0.87f, -0.5f);

glEnd();

glPopMatrix();

SwapBuffers(hDC);

theta += 1.0f;
//Sleep (1);
}
else{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
space+=0.005;
if(space>1.0) space=0.1;
theta += 1.0f;
if(theta>360.0) theta-=360.0;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glPushMatrix();
//glScalef(space,space,space);
glRotatef(theta,0.0,1.0,0.0);
glRotatef(theta,0.0,0.0,1.0);
glRotatef(theta,1.0,0.0,0.0);

glutSolidSphere(1.0,10,10);
glPopMatrix();
glFlush();
SwapBuffers(hDC);
}
}

/* shutdown OpenGL */
DisableOpenGL(hwnd, hDC, hRC);

/* destroy the window explicitly */
DestroyWindow(hwnd);

return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
/*case WM_CREATE:
hDC = GetDC(hwnd);
setupPalette(hDC);
hGLRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hGLRC);
init();
return 0;*/
case WM_COMMAND:
{
// 取出资源Id值
// 并判断用户选择了哪个菜单项
switch(LOWORD(wParam))
{
//-------------------------------物体颜色
case IDM_RED_TH:
light_ambient[0]=10.0;
light_ambient[1]=0.0;
light_ambient[2]=0.0;
light_ambient[3]=1.0;
break;
case IDM_GREEN_TH:
light_ambient[0]=0.0;
light_ambient[1]=10.0;
light_ambient[2]=0.0;
light_ambient[3]=1.0;
break;
case IDM_BLUE_TH:
light_ambient[0]=0.0;
light_ambient[1]=0.0;
light_ambient[2]=10.0;
light_ambient[3]=1.0;
break;
case IDM_RED2_TH:
light_ambient[0]+=1.0;
break;
case IDM_GREEN2_TH:
light_ambient[1]+=1.0;
break;
case IDM_BLUE2_TH:
light_ambient[2]+=1.0;
break;
case IDM_DEFAULT_TH:
light_ambient[0]=0.0;
light_ambient[1]=1.8;
light_ambient[2]=0.0;
light_ambient[3]=1.0;
break;
//-------------------------------背景颜色
case IDM_RED_BG:
BG_ClearColorRed=1.0f;
BG_ClearColorGreen=0.0f;
BG_ClearColorBlue=0.0f;
//MessageBox(hwnd,"背景色改为红色。","提示",MB_OK);
break;
case IDM_GREEN_BG:
BG_ClearColorRed=0.0f;
BG_ClearColorGreen=1.0f;
BG_ClearColorBlue=0.0f;
//MessageBox(hwnd,"背景色改为绿色。","提示",MB_OK);
break;
case IDM_BLUE_BG:
BG_ClearColorRed=0.0f;
BG_ClearColorGreen=0.0f;
BG_ClearColorBlue=1.0f;
//MessageBox(hwnd,"背景色改为蓝色。","提示",MB_OK);
break;
case IDM_RED2_BG:
BG_ClearColorRed+=0.1f;
break;
case IDM_GREEN2_BG:
BG_ClearColorGreen+=0.1f;
break;
case IDM_BLUE2_BG:
BG_ClearColorBlue+=0.1f;
break;
case IDM_DEFAULT_BG:
BG_ClearColorRed=0.3f;
BG_ClearColorGreen=0.0f;
BG_ClearColorBlue=0.7f;
//MessageBox(hwnd,"背景色改为默认颜色。","提示",MB_OK);
break;
//-------------------------------旋转速度
case IDM_ROTATE_QUICK:
RotateSpeed+=2.0f;Move_X=0.0f;
Move_Y=0.0f;
Move_Z=0.0f;
break;
case IDM_ROTATE_SLOW:
RotateSpeed=0.1f;Move_X=0.0f;
Move_Y=0.0f;
Move_Z=0.0f;
break;
case IDM_ROTATE_DEFAULT:
RotateSpeed=0.8f;Move_X=0.0f;
Move_Y=0.0f;
Move_Z=0.0f;
break;
case IDM_ROTATE_STOP:
RotateSpeed=0;
break;
//-------------------------------旋转方向
case IDM_ROTATE_X:
fangxiang=1;
break;
case IDM_ROTATE_Y:
fangxiang=2;
break;
case IDM_ROTATE_Z:
fangxiang=3;
break;
case IDM_ROTATE_FAN:
RotateSpeed=-RotateSpeed;
break;
case IDM_ROTATE_XYZ_DEFAULT:
fangxiang=0;
break;
//-------------------------------物体缩放
case IDM_SIZE_LARGE:
thing_size+=0.1f;
break;
case IDM_SIZE_SMALL:
if(thing_size>0)
thing_size-=0.1f;
break;
case IDM_SIZE_DEFAULT:
thing_size=1.0f;
break;
//-------------------------------物体平移
case IDM_MOVE_UP:
Move_X+=0.1f;RotateSpeed=0;
break;
case IDM_MOVE_DOWN:
Move_X-=0.1f;RotateSpeed=0;
break;
case IDM_MOVE_LEFT:
Move_Y+=0.1f;RotateSpeed=0;
break;
case IDM_MOVE_RIGHT:
Move_Y-=0.1f;RotateSpeed=0;
break;
case IDM_MOVE_FORWARD:
Move_Z+=0.1f;RotateSpeed=0;
break;
case IDM_MOVE_BACKWARD:
Move_Z-=0.1f;RotateSpeed=0;
break;
case IDM_MOVE_DEFAULT:
Move_X=0.0f;
Move_Y=0.0f;
Move_Z=0.0f;RotateSpeed=0;
break;
default:
break;
}
}
return 0;
case WM_CLOSE:
PostQuitMessage(0);
break;

case WM_DESTROY:
/*//------------------
if(hGLRC){
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hGLRC);
}
if(hPalette){
DeleteObject(hPalette);
}
ReleaseDC(hwnd,hDC);
PostQuitMessage(0);
//====================*/
return 0;
//------------------------
case WM_SIZE:
//跟踪窗口大小改变
hGLRC=1;
if(hGLRC){
winWidth=(int)LOWORD(lParam);
winHeight=(int)LOWORD(lParam);
resize();
return 0;
}
case WM_PALETTECHANGED:
//如果它不是当前窗口,则实现调色板与hDC的对应
if(hGLRC && hPalette && (HWND) wParam != hwnd){
UnrealizeObject(hPalette);
SelectPalette(hDC,hPalette,FALSE);
//ReadlizePalette(hDC);
redraw(hDC);
break;
}
break;
//=========================
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
}
break;

default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}

void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;

int iFormat;

/* get the device context (DC) */
*hDC = GetDC(hwnd);

/* set the pixel format for the DC */
ZeroMemory(&pfd, sizeof(pfd));

pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;

iFormat = ChoosePixelFormat(*hDC, &pfd);

SetPixelFormat(*hDC, iFormat, &pfd);

/* create and enable the render context (RC) */
*hRC = wglCreateContext(*hDC);

wglMakeCurrent(*hDC, *hRC);
}

void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hwnd, hDC);
}

void init(void){
//设置视图投影
glMatrixMode(GL_PROJECTION);
glFrustum(-0.5F,0.5F,-0.5F,0.5F,1.0F,4.0F);
//视区定位
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0F,0.0F,-2.0F);//平移
glScalef(1.0f,1.0f,1.0f);//缩放
//物体定位
glRotatef(30.0F,1.0F,0.0F,0.0F);
glRotatef(30.0F,0.0F,1.0F,0.0F);


glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//光照
glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
//glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
//glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
//glLightfv(GL_LIGHT0,GL_POSITION,light_position);
//背景颜色
BG_ClearColorRed=0.3f;
BG_ClearColorGreen=0.0f;
BG_ClearColorBlue=0.7f;
}
void redraw(HDC hDC){
//清除颜色和深度缓冲区
glClearColor( BG_ClearColorRed, BG_ClearColorGreen, BG_ClearColorBlue, 0.0f);
//glClearDepth(2.0);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
//画立方体的6个面
glBegin(GL_QUADS);
glNormal3f( 0.0F, 0.0F, 1.0F);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);
//1----------------------------
glNormal3f( 0.0F, 0.0F,-1.0F);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glVertex3f( 0.5f, 0.5f,-0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);
//2----------------------------
glNormal3f( 0.0F, 1.0F, 0.0F);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
//3----------------------------
glNormal3f( 0.0F,-1.0F, 0.0F);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);
//4----------------------------
glNormal3f( 1.0F, 0.0F, 0.0F);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);
glVertex3f( 0.5f, 0.5f,-0.5f);
//5----------------------------
glNormal3f(-1.0F, 0.0F, 0.0F);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
//6----------------------------*/
glEnd();
SwapBuffers(hDC);
}
void resize(void){
//设置视区,使之覆盖整个窗口
glViewport(0,0,winWidth,winHeight);
}
void CreateMyMenu()
{
hRoot = CreateMenu();
if(!hRoot)
return;
//-----------------------------------菜单1
HMENU pop1 = CreatePopupMenu();
AppendMenu(hRoot,
MF_POPUP,(UINT_PTR)pop1,"物体颜色");
// 使用AppendMenu函数
AppendMenu(pop1,
MF_STRING,IDM_RED_TH,"红色");
AppendMenu(pop1,
MF_STRING,IDM_GREEN_TH,"绿色");
AppendMenu(pop1,
MF_STRING,IDM_BLUE_TH,"蓝色");
AppendMenu(pop1,
MF_STRING,IDM_RED2_TH,"红色+");
AppendMenu(pop1,
MF_STRING,IDM_GREEN2_TH,"绿色+");
AppendMenu(pop1,
MF_STRING,IDM_BLUE2_TH,"蓝色+");
AppendMenu(pop1,
MF_STRING,IDM_DEFAULT_TH,"默认");
//------------------------------------菜单2
HMENU pop2 = CreatePopupMenu();
AppendMenu(hRoot,
MF_POPUP,(UINT_PTR)pop2,"背景颜色");
// 使用AppendMenu函数
AppendMenu(pop2,
MF_STRING,IDM_RED_BG,"红色");
AppendMenu(pop2,
MF_STRING,IDM_GREEN_BG,"绿色");
AppendMenu(pop2,
MF_STRING,IDM_BLUE_BG,"蓝色");
AppendMenu(pop2,
MF_STRING,IDM_RED2_BG,"红色+");
AppendMenu(pop2,
MF_STRING,IDM_GREEN2_BG,"绿色+");
AppendMenu(pop2,
MF_STRING,IDM_BLUE2_BG,"蓝色+");
AppendMenu(pop2,
MF_STRING,IDM_DEFAULT_BG,"默认");
//------------------------------------菜单3
HMENU pop3 = CreatePopupMenu();
AppendMenu(hRoot,
MF_POPUP,(UINT_PTR)pop3,"旋转速度");
AppendMenu(pop3,
MF_STRING,IDM_ROTATE_QUICK,"变快");
AppendMenu(pop3,
MF_STRING,IDM_ROTATE_SLOW,"变慢");
AppendMenu(pop3,
MF_STRING,IDM_ROTATE_DEFAULT,"默认");
AppendMenu(pop3,
MF_STRING,IDM_ROTATE_STOP,"停止");

//------------------------------------菜单4
HMENU pop4 = CreatePopupMenu();
AppendMenu(hRoot,
MF_POPUP,(UINT_PTR)pop4,"旋转方向");
AppendMenu(pop4,
MF_STRING,IDM_ROTATE_X,"X轴");
AppendMenu(pop4,
MF_STRING,IDM_ROTATE_Y,"Y轴");
AppendMenu(pop4,
MF_STRING,IDM_ROTATE_Z,"Z轴");
AppendMenu(pop4,
MF_STRING,IDM_ROTATE_FAN,"反向");
AppendMenu(pop4,
MF_STRING,IDM_ROTATE_XYZ_DEFAULT,"默认");
//------------------------------------菜单5
HMENU pop5 = CreatePopupMenu();
AppendMenu(hRoot,
MF_POPUP,(UINT_PTR)pop5,"缩放");
AppendMenu(pop5,
MF_STRING,IDM_SIZE_LARGE,"大");
AppendMenu(pop5,
MF_STRING,IDM_SIZE_SMALL,"小");
AppendMenu(pop5,
MF_STRING,IDM_SIZE_DEFAULT,"默认");
//------------------------------------菜单6
HMENU pop6 = CreatePopupMenu();
AppendMenu(hRoot,
MF_POPUP,(UINT_PTR)pop6,"平移");
AppendMenu(pop6,
MF_STRING,IDM_MOVE_UP,"上移");
AppendMenu(pop6,
MF_STRING,IDM_MOVE_DOWN,"下移");
AppendMenu(pop6,
MF_STRING,IDM_MOVE_LEFT,"左移");
AppendMenu(pop6,
MF_STRING,IDM_MOVE_RIGHT,"右移");
AppendMenu(pop6,
MF_STRING,IDM_MOVE_FORWARD,"前移");
AppendMenu(pop6,
MF_STRING,IDM_MOVE_BACKWARD,"后移");
AppendMenu(pop6,
MF_STRING,IDM_MOVE_DEFAULT,"默认");
}

/*
void setupPalette(HDC hDC){
int pixelFormat = GetPixelFormat(hDC);
PIXELFORMATDESCRIPTOR pfd;
LOGPALETTE* pPal;
int paletteSize;
DescribePixelFormat(hDC,pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR),&pfd);
if(pfd.dwFlags & PFD_NEED_PALETTE){
paletteSize = 1 << pfd.cColorBits;
}
else{
return ;
}
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE)+paletteSize*sizeof(PALETTEENTRY));
pPal->palVersion=0x300;
pPal->palNumEntries = paletteSize;
//建一个简单的RGB调色板
{
int redMask = (1 << pfd.cRedBits) - 1;
int greemMask = (1 << pfd.cGreenBits) - 1;
int blueMask = (1 << pfd.cBlueBits) - 1;
int i;
for(i=0;i<paletteSize;i++){
pPal->palPalEntry[i].peRed =
(((i >> pfd.cRedShift) & redMask) * 255)/redMask;
//pPal->palPalEntry[i]-peGreen =

}
}

}
*/