openGL程序示例代码——旋转的玉石

来源:互联网 发布:rhino js 编辑:程序博客网 时间:2024/04/29 03:15

最近交期末作业,学了一下openGL,作为初学者感觉会有用的在这列一下。

1、工程的建立:

      VS中,新建工程/win32/win32控制台应用程序。

2、在新建的控制台应用程序中添加 glut库的方法:

      <1>将下载的gult32库文件放在项目目录下。

      <2>VS中,项目/属性/连接器/输入/附加依赖项,在附加依赖项中输入glut32.lib

一、绘图

如果我们要绘制一个3D物体只需要绘制它的各个面即可, 只不过这里的顶点坐标是3维的,因此我们可以事先计算好各个顶点的坐标。

注意,在opengl中绘制每个面时,所有面给出的顶点的顺序都要按照逆时针或者顺时针(我这里采用的是逆时针),这样才能保证所绘制出来的图像时正确的。

二、光照

Opengl中使用光照时,首先定义了3个跟光滑有关的数组:前两个参数为{R,G,B,a}

  GLfloat lightAmbient[4] = { 0.5, 0.5, 0.5, 1.0 };//环境光——比较均匀,四面八方都有  GLfloat lightDiffuse[4] = { 1.0, 1.0, 1.0, 1.0 };//漫射光—特定位置发出的光    GLfloat lightPosition[4] = {0.0, 0.0, 2.0, 1.0 };//参数(x,y,z,a)

三、纹理映射

注意:所要加纹理的3D图的某个面上的顶点要 和 纹理图上的点对应起来。

代码举例:

//将2D的纹理坐标映射到3D的空间物体表面上glTexCoord2f(0.0,1.0);   //纹理坐标,需要计算的……glVertex3f(-0.3f,0.3f, -0.3f);//物体顶点


四、旋转用一个函数就行,如:glRotatef(yrot, 0, 1, 0);//沿y轴旋转 yrot度  ,然后每运行一次yrot加一个值



五、代码贴一下

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  //    本程序效果:旋转的棱形玉石//    交互:按“l”开启光照,按“L”关闭光照///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include<iostream>#include <Windows.h>#include "glut.h"#include "GLAUX.H"using namespace std;static float xrot = 0.0; static float yrot = 0.0; static float zrot = 0.0; GLuinttexture[1];// 存储一个纹理//3个与光照有关的数组GLfloat light_ambient[4]={1.0, 1.0, 1.0, 1.0};//环境光。参数为{R,G,B,A}。环境光一般比较均匀,四面八方都有GLfloat light_diffuse[4]={1.0, 1.0, 1.0, 1.0};//漫射光——特定位置发出的光GLfloat light_position[4]={0.5,0.5, 0.5, 0.0};//光源位置AUX_RGBImageRec *LoadBMP(char *Filename)// 载入位图图象{FILE *File=NULL;if (!Filename)// 确保文件名已提供{MessageBox(NULL,"纹理文件不存在!","警告!",MB_ICONWARNING);return NULL;// 如果没提供,返回 NULL}File=fopen(Filename,"r");// 尝试打开文件if (File)// 文件存在么?{fclose(File);// 关闭句柄return auxDIBImageLoad(Filename);// 载入位图并返回指针}return NULL;// 如果载入失败,返回 NULL}int LoadGLTextures()// 载入位图(调用上面的代码)并转换成纹理{int Status=FALSE;// 状态指示器AUX_RGBImageRec *TextureImage[1];// 创建纹理的存储空间memset(TextureImage,0,sizeof(void *)*1);// 将指针设为 NULLif (TextureImage[0]=LoadBMP("yu.bmp"))// 载入位图,检查有无错误,如果位图没找到则退出{Status=TRUE;// 将 Status 设为 TRUEglGenTextures(1, &texture[0]);// 创建纹理// 使用来自位图数据生成 的典型纹理glBindTexture(GL_TEXTURE_2D, texture[0]);// 生成纹理glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//当所显示的纹理比加载进来的纹理小时,采用GL_LINEAR的方法来处理        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//当所显示的纹理比加载进来的纹理大时,采用GL_LINEAR的方法来处理glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0])// 纹理是否存在{if (TextureImage[0]->data)// 纹理图像是否存在{free(TextureImage[0]->data);// 释放纹理图像占用的内存}free(TextureImage[0]);// 释放图像结构} return Status;// 返回 Status}void cube(){glBindTexture(GL_TEXTURE_2D, texture[0]);// 选择纹理glBegin(GL_TRIANGLES);// 开始画图//glColor4f(1.0f,1.0f,1.0f,1.0f);// 白色glTexCoord2f(0.5f, 1.0f); glVertex3f( 0.0f, 2.0f, 0.0f);// 顶点                                  aglTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,1.0f, 1.0f);// 左                                      bglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,1.0f, 1.0f);// 右                                          cglTexCoord2f(0.5f, 1.0f); glVertex3f( 0.0f, 2.0f, 0.0f);// Top Of Triangle (Right)       aglTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,1.0f, 1.0f);// Left Of Triangle (Right)           cglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,1.0f, -1.0f);// Right Of Triangle (Right)     dglTexCoord2f(0.5f, 1.0f); glVertex3f( 0.0f, 2.0f, 0.0f);// Top Of Triangle (Back)       aglTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,1.0f, -1.0f);// Left Of Triangle (Back)       dglTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,1.0f, -1.0f);// Right Of Triangle (Back)     eglTexCoord2f(0.5f, 1.0f);  glVertex3f( 0.0f, 2.0f, 0.0f);// Top Of Triangle (Left)         aglTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,1.0f,-1.0f);// Left Of Triangle (Left)         eglTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,1.0f, 1.0f);// Right Of Triangle (Left)       bglEnd();glBegin(GL_TRIANGLES);// Start Drawing A Triangle//glColor4f(0.0f,0.66f,0.91f,0.6f);// 白glTexCoord2f(0.5f, 1.0f); glVertex3f( 0.0f, -1.0f, 0.0f);// Top Of Triangle (Front)       fglTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,1.0f, 1.0f);// Left Of Triangle (Front)       bglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,1.0f, 1.0f);// Right Of Triangle (Front)         cglTexCoord2f(0.5f, 1.0f); glVertex3f( 0.0f, -1.0f, 0.0f);// Top Of Triangle (Right)       fglTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,1.0f, 1.0f);// Left Of Triangle (Right)            cglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,1.0f, -1.0f);// Right Of Triangle (Right)      dglTexCoord2f(0.5f, 1.0f); glVertex3f( 0.0f, -1.0f, 0.0f);// Top Of Triangle (Back)         aglTexCoord2f(0.0f, 0.0f);  glVertex3f( 1.0f,1.0f, -1.0f);// Left Of Triangle (Back)         dglTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,1.0f, -1.0f);// Right Of Triangle (Back)        eglTexCoord2f(0.5f, 1.0f); glVertex3f( 0.0f, -1.0f, 0.0f);// Top Of Triangle (Left)           aglTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,1.0f,-1.0f);// Left Of Triangle (Left)            eglTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,1.0f, 1.0f);// Right Of Triangle (Left)          bglEnd();}void display(void){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();    glTranslatef(0, 0, -5); //平移函数,将屏幕位置沿z轴移-10    glRotatef(yrot, 0, 1, 0);//沿y轴旋转 yrot度    //glPolygonMode(GL_FRONT, GL_LINE);    cube();    //xrot = xrot + 1;    yrot = yrot + 1;    //zrot = zrot + 1;Sleep(8);    glutSwapBuffers();}void reshape(int w, int h){    if(h==0) h = 1;    glViewport(0, 0, (GLsizei) w, (GLsizei) h);    glMatrixMode(GL_PROJECTION);//切换到投影矩阵,(要使用透视(3D).那么先要设置透视投影)    glLoadIdentity();  //然后把矩阵设为单位矩阵    gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 1, 100.0);//然后调用glFrustum()或gluPerspective(),它们生成的矩阵会与当前的矩阵相乘,生成透视的效果;//参数解释(视角,实际窗口的纵横比,眼睛到物体最近处的距离,眼睛到物体最远处的距离)    glMatrixMode(GL_MODELVIEW);//设置完成后开始画图,需要切换到 模型视图矩阵 才能正确画图// 画一个物体A (看起来是3D的),    // 如这时候需画一个 2D效果 的 物体A,那么又需要透视投影}void init(int width, int height ){    if(height == 0) height = 1;if (!LoadGLTextures())// 调用纹理载入子例程{MessageBox(NULL,"纹理载入失败","警告!",MB_ICONWARNING);return;// 如果未能载入,返回}glEnable(GL_TEXTURE_2D);// 启用纹理映射    glClearColor(0.0, 0.0, 0.0, 0.0);    glClearDepth(1.0);    glDepthFunc(GL_LESS);    glEnable(GL_DEPTH_TEST);    glShadeModel(GL_SMOOTH);glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//进行透视校正    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 1, 100.0);    glMatrixMode(GL_MODELVIEW);//*opengl中支持8个光源,即GL_LIGHT0~GL_LIGHT7*/    glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);//指定光源1的环境光参数    glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);//指定光源1的漫射光参数    glLightfv(GL_LIGHT1, GL_POSITION, light_position);//指定光源1的位置    glEnable(GL_LIGHT1);//允许光源1的使用    //glEnable(GL_LIGHTING);//我们还需要启动总光源开关,默认的时候不开,后面的L键来控制开启和关闭}void keyboard(unsigned char key, int w, int h){    if(key == 'l') // 开启光源        glEnable(GL_LIGHTING);    if(key == 'L') // 关闭光源    {        glDisable(GL_LIGHTING);    }    if(key == 27) // ESC退出程序        exit(0);}int main(int argc, char** argv){    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);    glutInitWindowPosition(400, 100);    glutInitWindowSize(640, 480);    glutCreateWindow("旋转的玉石");glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_BLEND);    glutDisplayFunc(display);    glutIdleFunc(display);if(yrot > 6.0){yrot = 0;}        glutReshapeFunc(reshape);    glutKeyboardFunc(keyboard);    init(640, 480);    glutMainLoop();    return 0;}



效果图:(自己做的gif图,效果不是很好)

   

用来贴图的图片这样:


用到的库函数到这里下载:http://download.csdn.net/detail/u013394782/7543095



0 0
原创粉丝点击