zoukankan      html  css  js  c++  java
  • openGL绘制一个带有纹理、光照效果的金字塔

    openglsb.h:

    ////////////////////////////////////////////////
    // Here, we will try to isolate as many platform
    // dependencies here as possible so that all sample
    // programs contain as few headers and are as self
    // contained as possible.
    
    // Windows... Visual C++
    #ifdef _WIN32
    // Standard Windows includes
    #include <windows.h>
    #include <gl/gl.h>
    #include <gl/glu.h>
    #include "glut.h"
    #include "glext.h"
    #include "wglext.h"
    // Mac OS X
    #elif defined __APPLE__
    
    #include <Carbon/Carbon.h>
    #include <GLUT/glut.h>
    #include <OpenGL/glext.h>
    
    #define APIENTRY
    #define INT_PTR int*
    #define Sleep(x)
    
    // Assume Linux
    #else
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>
    #include <GL/glext.h>
    #include <sys/time.h>
    #endif

    pyramid.c:

      

    // Pyramid.c
    // Demonstrates Simple Texture Mapping
    // OpenGL SuperBible
    // Richard S. Wright Jr.
    #include "../../common/openglsb.h"    // System and OpenGL Stuff
    #include "../../common/gltools.h"    // OpenGL toolkit
    
    // Rotation amounts
    static GLfloat xRot = 0.0f;
    static GLfloat yRot = 0.0f;
    
    
    // Change viewing volume and viewport.  Called when window is resized
    void ChangeSize(int w, int h)
    {
        GLfloat fAspect;
    
        // Prevent a divide by zero
        if(h == 0)
            h = 1;
    
        // Set Viewport to window dimensions
        glViewport(0, 0, w, h);
    
        fAspect = (GLfloat)w/(GLfloat)h;
    
        // 指定当前操作矩阵为投影矩阵。
        glMatrixMode(GL_PROJECTION);
    
        //重置坐标系统
        glLoadIdentity();
    
        // Produce the perspective projection 产生透视投影 
        gluPerspective(35.0f, fAspect, 1.0, 40.0);
    
        //指定当前操作矩阵为模型视图矩阵。
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    
    
    // This function does any needed initialization on the rendering
    // context.  Here it sets up and initializes the lighting for
    // the scene.
    void SetupRC()
    {
        GLubyte *pBytes;
        GLint iWidth, iHeight, iComponents;
        GLenum eFormat;
    
        // Light values and coordinates
        GLfloat  whiteLight[] = { 0.05f, 0.05f, 0.05f, 1.0f };
        GLfloat  sourceLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };
        GLfloat     lightPos[] = { -10.f, 5.0f, 5.0f, 1.0f };
    
        glEnable(GL_DEPTH_TEST);    // Hidden surface removal
        glFrontFace(GL_CCW);        // Counter clock-wise polygons face out
        glEnable(GL_CULL_FACE);        // Do not calculate inside of jet
    
        // Enable lighting
        glEnable(GL_LIGHTING);
    
        // Setup and enable light 0
        //设置光照模式:缺省的环境照明
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight); 
    
        //设置环境光
        glLightfv(GL_LIGHT0,GL_AMBIENT,sourceLight);
    
        //设置散射光
        glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
    
        //设置光照位置
        glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    
        //启用此光照
        glEnable(GL_LIGHT0);
    
        //启用颜色追踪
        glEnable(GL_COLOR_MATERIAL);
    
        //多边形正面材料环境和散射颜色 追踪glcolor
        glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    
        // Black blue background
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
    
        // Load texture
        //设置像素提取方式
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
        //加载到内存
        pBytes = gltLoadTGA("stone.tga", &iWidth, &iHeight, &iComponents, &eFormat); //iComponents 为颜色成分
        //从内存中载入纹理
        glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
        free(pBytes);
    
        //进行了一些参数设置
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//放大过滤器:线性过滤
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//缩小过滤器:线性过滤
    
        //设置环绕模式为:限制双线性过滤。(不这样做可能在金字塔的底部会出现瓷砖缝)。
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
        //指定环境模式为:纹理单位颜色与几何图形颜色相乘。
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    
        //启用纹理
        glEnable(GL_TEXTURE_2D);
    }
    
    // Respond to arrow keys
    void SpecialKeys(int key, int x, int y)
    {
        if(key == GLUT_KEY_UP)
            xRot-= 5.0f;
    
        if(key == GLUT_KEY_DOWN)
            xRot += 5.0f;
    
        if(key == GLUT_KEY_LEFT)
            yRot -= 5.0f;
    
        if(key == GLUT_KEY_RIGHT)
            yRot += 5.0f;
    
        xRot = (GLfloat)((const int)xRot % 360);
        yRot = (GLfloat)((const int)yRot % 360);
    
        // Refresh the Window
        glutPostRedisplay();
    }
    
    
    // Called to draw scene
    void RenderScene(void)
    {
        GLTVector3 vNormal;
        GLTVector3 vCorners[5] = { 
            { 0.0f, .80f, 0.0f },     // Top           0
            { -0.5f, 0.0f, -.50f },    // Back left     1
            { 0.5f, 0.0f, -0.50f },    // Back right    2
            { 0.5f, 0.0f, 0.5f },      // Front right   3
            { -0.5f, 0.0f, 0.5f }        // Front left    4
        };    
    
        // Clear the window with current clearing color
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        // Save the matrix state and do the rotations
        glPushMatrix();
        // Move object back and do in place rotation
        glTranslatef(0.0f, -0.25f, -4.0f); //因为十点在(0,0,0)点,所以要稍作调整
        glRotatef(xRot, 1.0f, 0.0f, 0.0f);
        glRotatef(yRot, 0.0f, 1.0f, 0.0f);
    
        // Draw the Pyramid
        glColor3f(1.0f, 1.0f, 1.0f);
        glBegin(GL_TRIANGLES);
            // Bottom section - two triangles
            glNormal3f(0.0f, -1.0f, 0.0f); //法线向下
    
            glTexCoord2f(1.0f, 1.0f);
            glVertex3fv(vCorners[2]);    //后右
    
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[4]);    //前左
    
            glTexCoord2f(0.0f, 1.0f);
            glVertex3fv(vCorners[1]);    //后左
    
    
            glTexCoord2f(1.0f, 1.0f);
            glVertex3fv(vCorners[2]);    //后右
    
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[3]);    //前右
    
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[4]);    //前左
    
            // Front Face
            gltGetNormalVector(vCorners[0], vCorners[4], vCorners[3], vNormal);
            glNormal3fv(vNormal);
    
            glTexCoord2f(0.5f, 1.0f);
            glVertex3fv(vCorners[0]);//
    
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[4]);//前左
    
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[3]);//前右
    
            // Left Face
            gltGetNormalVector(vCorners[0], vCorners[1], vCorners[4], vNormal);//计算法线
            glNormal3fv(vNormal);
    
            glTexCoord2f(0.5f, 1.0f);
            glVertex3fv(vCorners[0]);
    
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[1]);
    
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[4]);
    
            // Back Face
            gltGetNormalVector(vCorners[0], vCorners[2], vCorners[1], vNormal);
            glNormal3fv(vNormal);
            glTexCoord2f(0.5f, 1.0f);
            glVertex3fv(vCorners[0]);
    
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[2]);
    
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[1]);
    
            // Right Face
            gltGetNormalVector(vCorners[0], vCorners[3], vCorners[2], vNormal);
            glNormal3fv(vNormal);
            glTexCoord2f(0.5f, 1.0f);
            glVertex3fv(vCorners[0]);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[3]);
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[2]);
        glEnd();
    
    
        // Restore the matrix state
        glPopMatrix();
    
        // Buffer swap
        glutSwapBuffers();
    }
    
    
    
    int main(int argc, char *argv[])
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutInitWindowSize(800, 600);
        glutCreateWindow("Textured Pyramid");
        glutReshapeFunc(ChangeSize);
        glutSpecialFunc(SpecialKeys);
        glutDisplayFunc(RenderScene);
        SetupRC();
        glutMainLoop();
    
        return 0;
    }

    运行效果:

      

      

      

  • 相关阅读:
    洛谷P1661 扩散
    Vijos1056 图形面积
    Python爬取猪肉价格网并获取Json数据
    C#中巧用Lambda表达式实现对象list进行截取
    Winform中在ZedGraph中最多可以添加多少条曲线
    Nginx配置实例-动静分离实例:搭建静态资源服务器
    解决pip使用异常No module named 'pip'
    C#在循环中使用Random时生成的随机数相同的解决办法
    Winform中自定义ZedGraph右键复制成功后的提示
    C#中巧用Lambda进行数据的筛选查询等处理
  • 原文地址:https://www.cnblogs.com/airduce/p/9778058.html
Copyright © 2011-2022 走看看