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;
}

运行效果:

  

  

  

原文地址:https://www.cnblogs.com/airduce/p/9778058.html