OpenGL学习(九)纹理初步

来源:互联网 发布:上海巨人网络工资原画 编辑:程序博客网 时间:2024/06/05 10:19
// Tunnel.cpp// Demonstrates mipmapping and using texture objects// OpenGL SuperBible// Richard S. Wright Jr.#include <GLTools.h>#include <GLShaderManager.h>#include <GLFrustum.h>#include <GLBatch.h>#include <GLFrame.h>#include <GLMatrixStack.h>#include <GLGeometryTransform.h>#ifdef __APPLE__#include <glut/glut.h>#else#define FREEGLUT_STATIC#include <GL/glut.h>#endifGLShaderManagershaderManager;// Shader ManagerGLMatrixStackmodelViewMatrix;// Modelview MatrixGLMatrixStackprojectionMatrix;// Projection MatrixGLFrustumviewFrustum;// View FrustumGLGeometryTransformtransformPipeline;// Geometry Transform PipelineGLBatch             floorBatch;GLBatch             ceilingBatch;GLBatch             leftWallBatch;GLBatch             rightWallBatch;GLfloat             viewZ = -65.0f;// Texture objects#define TEXTURE_BRICK   0#define TEXTURE_FLOOR   1#define TEXTURE_CEILING 2#define TEXTURE_COUNT   3GLuint  textures[TEXTURE_COUNT];const char *szTextureFiles[TEXTURE_COUNT] = { "D:/CODE/Visual Studio/tunnle/brick.tga", "D:/CODE/Visual Studio/tunnle/floor.tga", "D:/CODE/Visual Studio/tunnle/ceiling.tga" };///////////////////////////////////////////////////////////////////////////////// Change texture filter for each texture objectvoid ProcessMenu(int value){    GLfloat fLargest;    GLint iLoop;        for(iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)        {        glBindTexture(GL_TEXTURE_2D, textures[iLoop]);                switch(value)            {            case 0:                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);                break;                            case 1:                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);                break;                            case 2:                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);                break;                        case 3:                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);                break;                        case 4:                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);                break;                            case 5:                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);                break;                            case 6:                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);                break;                            case 7:                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);                break;            }        }            // Trigger RedrawglutPostRedisplay();}//////////////////////////////////////////////////////////////////// This function does any needed initialization on the rendering// context.  Here it sets up and initializes the texture objects.void SetupRC()    {    GLbyte *pBytes;    GLint iWidth, iHeight, iComponents;    GLenum eFormat;    GLint iLoop;    // Black backgroundglClearColor(0.0f, 0.0f, 0.0f,1.0f);        shaderManager.InitializeStockShaders();    // Load textures    glGenTextures(TEXTURE_COUNT, textures);    for(iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)        {        // Bind to next texture object        glBindTexture(GL_TEXTURE_2D, textures[iLoop]);                // Load texture, set filter and wrap modes        pBytes = gltReadTGABits(szTextureFiles[iLoop],&iWidth, &iHeight,                              &iComponents, &eFormat);        // Load texture, set filter and wrap modes        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);        glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);        glGenerateMipmap(GL_TEXTURE_2D);                // Don't need original texture data any more        free(pBytes);        }            // Build Geometry    GLfloat z;    floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);    for(z = 60.0f; z >= 0.0f; z -=10.0f)        {        floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);        floorBatch.Vertex3f(-10.0f, -10.0f, z);                 floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);        floorBatch.Vertex3f(10.0f, -10.0f, z);                 floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);        floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);                 floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);        floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);        }    floorBatch.End();        ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);    for(z = 60.0f; z >= 0.0f; z -=10.0f)        {        ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);        ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);                ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);        ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);                ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);        ceilingBatch.Vertex3f(-10.0f, 10.0f, z);        ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);        ceilingBatch.Vertex3f(10.0f, 10.0f, z);        }    ceilingBatch.End();        leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);    for(z = 60.0f; z >= 0.0f; z -=10.0f)        {        leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);        leftWallBatch.Vertex3f(-10.0f, -10.0f, z);                leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);        leftWallBatch.Vertex3f(-10.0f, 10.0f, z);                leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);        leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);        leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);        leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);        }    leftWallBatch.End();            rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);    for(z = 60.0f; z >= 0.0f; z -=10.0f)        {        rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);        rightWallBatch.Vertex3f(10.0f, -10.0f, z);                rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);        rightWallBatch.Vertex3f(10.0f, 10.0f, z);                rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);        rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);        rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);        rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);        }    rightWallBatch.End();    }    ///////////////////////////////////////////////////// Shutdown the rendering context. Just deletes the// texture objectsvoid ShutdownRC(void)    {    glDeleteTextures(TEXTURE_COUNT, textures);    }    ///////////////////////////////////////////////////// Respond to arrow keys, move the viewpoint back// and forthvoid SpecialKeys(int key, int x, int y){if(key == GLUT_KEY_UP)        viewZ += 0.5f;if(key == GLUT_KEY_DOWN)        viewZ -= 0.5f;// Refresh the WindowglutPostRedisplay();}/////////////////////////////////////////////////////////////////////// Change viewing volume and viewport.  Called when window is resizedvoid 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;    // Produce the perspective projectionviewFrustum.SetPerspective(80.0f,fAspect,1.0,120.0);    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);    }///////////////////////////////////////////////////////// Called to draw scenevoid RenderScene(void)    {    // Clear the window with current clearing color    glClear(GL_COLOR_BUFFER_BIT);    modelViewMatrix.PushMatrix();        modelViewMatrix.Translate(0.0f, 0.0f, viewZ);                shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(), 0);        glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_FLOOR]);        floorBatch.Draw();                glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_CEILING]);        ceilingBatch.Draw();                glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BRICK]);        leftWallBatch.Draw();        rightWallBatch.Draw();            modelViewMatrix.PopMatrix();    // Buffer swap    glutSwapBuffers();    }//////////////////////////////////////////////////////// Program entry pointint main(int argc, char *argv[])    {    gltSetWorkingDirectory(argv[0]);    // Standard initialization stuff    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);    glutInitWindowSize(800, 600);    glutCreateWindow("Anisotropic Tunnel");    glutReshapeFunc(ChangeSize);    glutSpecialFunc(SpecialKeys);    glutDisplayFunc(RenderScene);        // Add menu entries to change filter    glutCreateMenu(ProcessMenu);    glutAddMenuEntry("GL_NEAREST",0);    glutAddMenuEntry("GL_LINEAR",1);    glutAddMenuEntry("GL_NEAREST_MIPMAP_NEAREST",2);    glutAddMenuEntry("GL_NEAREST_MIPMAP_LINEAR", 3);    glutAddMenuEntry("GL_LINEAR_MIPMAP_NEAREST", 4);    glutAddMenuEntry("GL_LINEAR_MIPMAP_LINEAR", 5);    glutAddMenuEntry("Anisotropic Filter", 6);    glutAddMenuEntry("Anisotropic Off", 7);    glutAttachMenu(GLUT_RIGHT_BUTTON);        GLenum err = glewInit();    if (GLEW_OK != err) {        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));        return 1;}        // Startup, loop, shutdown    SetupRC();    glutMainLoop();    ShutdownRC();        return 0;    }          

0 0