opengl 球纹理旋转源代码

专注java已6年,欢迎加入java核心技术QQ群:135138817,每周五晚有群主进行技术讲座。

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glaux.h>
#include <stdio.h>
#include <io.h>

HWND   hWnd;
HDC    hDC;
HGLRC   hRC=NULL;   //定义渲染环境
HINSTANCE hInstance;   //得到程序的例子

RECT   rect;

int    sw = 640;
int    sh = 480;

bool   fullscreen = 1;

GLfloat   aspect;

GLfloat xrot;     // X轴旋转 ( 新 )
GLfloat yrot;     // Y轴旋转 ( 新 )
GLfloat zrot;     // Z轴旋转 ( 新 )

GLuint texture[1];    //纹理的存储空间 ( 新 )

#pragma comment( lib, "opengl32.lib" )        // 链接时使用OpenGL32.lib
#pragma comment( lib, "glu32.lib" )         // 链接时使用GLu32.lib
#pragma comment( lib, "glaux.lib" )         // 链接时使用GLaux.lib

AUX_RGBImageRec *LoadBMP(char *Filename)     // 读取位图图象
{
FILE *File=NULL;          // 文件句柄

if (!Filename)           // 确定文件名已给出
{
   return NULL;          // 如果文件名未给出则返回NULL
}

File=fopen(Filename,"r");        // 检测文件是否存在

if (File)            // 文件是否存在?
{
   fclose(File);          // 关闭文件
   return auxDIBImageLoad(Filename);     // 读取位图并返回一个指针
}

return NULL;           //如果调用文件失败则返回NULL
}

int LoadGLTextures()          //调用Bitmap并转换成纹理
{
int Status=FALSE;          //状态确定

AUX_RGBImageRec *TextureImage[1];      //为纹理创建存储空间

memset(TextureImage,0,sizeof(void *)*1);           //将指针设为NULL

//读取位图,检查错误。如果位图不存在则退出
if (TextureImage[0]=LoadBMP("Data/TX.bmp"))
{
   Status=TRUE;          //设Status为TRUE

   glGenTextures(1, &texture[0]);      //创建纹理

   //用位图中的数据进行典型的纹理生成
   glBindTexture(GL_TEXTURE_2D, texture[0]);
   glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}

if (TextureImage[0])          //纹理是否存在
{
   if (TextureImage[0]->data)        //纹理图象是否存在
   {
    free(TextureImage[0]->data);      //释放纹理图象所占用内存
   }

   free(TextureImage[0]);         //释放图象结构
}

return Status;           //返回Status的值
}

void SceneInit(int w, int h)
{
LoadGLTextures();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);        //允许平滑着色
glClearColor( 0.0, 0.0, 0.0, 0.5 );
glClearDepth(1.0f);          //设置深度缓冲区
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);         //深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void SceneResizeViewport(GLsizei w, GLsizei h)
{
if(h==0)
{
   h=1;
}
aspect = (GLfloat)w/(GLfloat)h;

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);       //选择投影矩阵
glLoadIdentity();

gluPerspective( 45.0f, aspect, 0.1f, 100.0f );
glMatrixMode(GL_MODELVIEW);  
glLoadIdentity();

}

void SceneShow(GLvoid)          //这里进行所有的绘图工作
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清屏和清除深度缓冲区
glLoadIdentity();          //重置当前Modelview矩阵
glTranslatef(0.0f,0.0f,-5.0f);

glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);

//glBindTexture(GL_TEXTURE_2D, texture[0]);

glBegin(GL_QUADS);
GLUquadricObj *quadObj = gluNewQuadric();//创建一个二次曲面物体
    gluQuadricTexture(quadObj,GL_TRUE);        //启用该二次曲面的纹理
    glBindTexture(GL_TEXTURE_2D, texture[0]);//绑定纹理
     
     gluSphere(quadObj,1,20,20); //画圆
gluDeleteQuadric(quadObj);
    glEnd();
   

xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;

}

void EnableOpenGL()
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;

hDC = GetDC( hWnd );

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 = 16;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;

iFormat = ChoosePixelFormat( hDC, &pfd );

SetPixelFormat( hDC, iFormat, &pfd );

hRC = wglCreateContext( hDC );
wglMakeCurrent( hDC, hRC );
}


// 取消 OpenGL
void DisableOpenGL()
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hRC );
ReleaseDC( hWnd, hDC );
}

bool ChangeResolution(int w, int h, int bitdepth)
{
DEVMODE devMode;
int   modeSwitch;
int   closeMode = 0;

EnumDisplaySettings(NULL, closeMode, &devMode);

devMode.dmBitsPerPel = bitdepth;
devMode.dmPelsWidth = w;
devMode.dmPelsHeight = h;
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

modeSwitch = ChangeDisplaySettings(&devMode, CDS_FULLSCREEN);

if(modeSwitch == DISP_CHANGE_SUCCESSFUL)
{
   return true;
}
else
{
   ChangeDisplaySettings(NULL, 0);
   return false;
}
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
        WPARAM wParam, LPARAM lParam )
{

switch ( message )
{
   case WM_CREATE:
    GetWindowRect(hWnd, &rect);
    sw = rect.right - rect.left;
    sh = rect.bottom - rect.top;
    SceneResizeViewport(sw, sh);
    return 0;

   case WM_SIZE:

    if(!fullscreen)
    {
     GetWindowRect(hWnd, &rect);
     sw = rect.right - rect.left;
     sh = rect.bottom - rect.top;
     if(sw>0 && sh>0)
      SceneResizeViewport(sw, sh);
    }
    else
    {
     SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),
          GetSystemMetrics( SM_CYSCREEN ));
    }

    return 0;

   case WM_CLOSE:
    ShowWindow (hWnd, SW_HIDE);
    PostQuitMessage( 0 );
    return 0;

   case WM_DESTROY:
    return 0;

   case WM_KEYDOWN:
    switch( wParam )
    {
    case VK_ESCAPE:
     PostMessage(hWnd, WM_CLOSE, 0, 0);
    break;
    }
    return 0;
   default:
   return DefWindowProc( hWnd,message, wParam, lParam );
}
}


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
   WNDCLASS wc;
MSG msg;
bool bQuit = false;

if (MessageBox(NULL,"是否选择全屏显示模式?", "全屏方式运行?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
   fullscreen=0;        //窗口模式
}

wc.style = CS_OWNDC;
wc.lpfnWndProc = 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)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "Name";
RegisterClass( &wc );


if(fullscreen)
{
   ChangeResolution(640, 480, 16);
   hWnd = CreateWindow(
         "Name",
         "Lesson1",
         WS_POPUP | WS_CLIPSIBLINGS | WS_VISIBLE,
         0, 0,
         GetSystemMetrics( SM_CXSCREEN ),
         GetSystemMetrics( SM_CYSCREEN ),
         NULL, NULL,
         hInstance,
         NULL );
}else
{
   hWnd = CreateWindow(
        "Name",
        "Lesson1",
        WS_TILEDWINDOW | WS_VISIBLE,
        GetSystemMetrics( SM_CXSCREEN )/2-sw/2,
        GetSystemMetrics( SM_CYSCREEN )/2-sh/2,
        sw,
        sh,
        NULL, NULL,
        hInstance,
        NULL );
   ChangeDisplaySettings(NULL, 0);
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);

//Initialisation
EnableOpenGL();
SceneInit(sw, sh);

if(!fullscreen)
{
   GetWindowRect(hWnd, &rect);
   sw = rect.right - rect.left;
   sh = rect.bottom - rect.top;
   if(sw>0 && sh>0)
    SceneResizeViewport(sw, sh);
}
else
{
   SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),
        GetSystemMetrics( SM_CYSCREEN ));
}

while ( !bQuit )
{
   if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    if ( msg.message == WM_QUIT )
     bQuit = true;
    else
    {
     TranslateMessage( &msg );
     DispatchMessage( &msg );
    }
   else
   {

    // OpenGL 动画
    SceneShow();
    SwapBuffers(hDC);

   }
}

//关闭,退出程序
DisableOpenGL();

ShowWindow (hWnd, SW_HIDE);
DestroyWindow( hWnd );

ChangeDisplaySettings(NULL, 0);

return msg.wParam;

return 0;
}

posted @ 2010-01-28 16:41  沙琪玛  阅读(4502)  评论(2编辑  收藏  举报