三维茶壶

来源:互联网 发布:h3c端口聚合配置静态 编辑:程序博客网 时间:2024/04/28 09:20

HeaderFiles

geometry3.h

/**** Basic setup for defining and drawing objects ****/// Moved to a header for the second and subsequent OpenGL programs#ifndef __INCLUDEGEOMETRY#define __INCLUDEGOEMETRYconst int numobjects = 2 ; // ** NEW ** number of objects for buffer const int numperobj  = 3 ;const int ncolors = 4 ; GLuint buffers[numperobj*numobjects+ncolors+1] ; // ** NEW ** List of buffers for geometric data GLuint objects[numobjects] ; // ** NEW ** For each objectGLenum PrimType[numobjects] ;GLsizei NumElems[numobjects] ; // ** NEW ** Floor Geometry is specified with a vertex array// ** NEW ** Same for other Geometry // The Buffer Offset Macro is from Red Book, page 103, 106#define BUFFER_OFFSET(bytes) ((GLubyte *) NULL + (bytes))#define NumberOf(array) (sizeof(array)/sizeof(array[0])) enum {Vertices, Colors, Elements} ; // For arrays for object enum {FLOOR, CUBE} ; // For objects, for the floorconst GLfloat floorverts[4][3] = {    {0.5, 0.5, 0.0}, {-0.5, 0.5, 0.0}, {-0.5, -0.5, 0.0}, {0.5, -0.5, 0.0}} ; const GLfloat floorcol[4][3] = {    {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}} ; const GLubyte floorinds[1][4] = { {0, 1, 2, 3} } ; const GLfloat floortex[4][2] = {     {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}} ;// CUBES FOR ADDING TO THE SCENEconst GLfloat wd = 0.1 ; const GLfloat ht = 0.5 ; const GLfloat _cubecol[4][3] = {     {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {1.0, 1.0, 0.0} } ;     const GLfloat cubeverts[8][3] = {        {-wd, -wd, 0.0}, {-wd, wd, 0.0}, {wd, wd, 0.0}, {wd, -wd, 0.0},        {-wd, -wd, ht}, {wd, -wd, ht}, {wd, wd, ht}, {-wd, wd, ht}    } ; GLfloat cubecol[8][3] ;const GLubyte cubeinds[6][4] = {     {0, 1, 2, 3}, // BOTTOM     {4, 5, 6, 7}, // TOP     {0, 4, 7, 1}, // LEFT     {0, 3, 5, 4}, // FRONT    {3, 2, 6, 5}, // RIGHT     {1, 7, 6, 2}  // BACK} ; void initobject(GLuint object, GLfloat * vert, GLint sizevert, GLfloat * col, GLint sizecol, GLubyte * inds, GLint sizeind, GLenum type) ;void initobjectnocol(GLuint object, GLfloat * vert, GLint sizevert, GLubyte * inds, GLint sizeind, GLenum type) ;void drawobject(GLuint object) ; void initcolorscube (void) ;void drawcolor(GLuint object, GLuint color) ;void inittexture (const char * filename, GLuint program) ;void drawtexture(GLuint object, GLuint texture) ;// This function takes in a vertex, color, index and type array // And does the initialization for an object.  // The partner function below it draws the object void initobject(GLuint object, GLfloat * vert, GLint sizevert, GLfloat * col, GLint sizecol, GLubyte * inds, GLint sizeind, GLenum type) {    int offset = object * numperobj ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ;     glBufferData(GL_ARRAY_BUFFER, sizevert, vert,GL_STATIC_DRAW);    glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_VERTEX_ARRAY) ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors+offset]) ;     glBufferData(GL_ARRAY_BUFFER, sizecol, col,GL_STATIC_DRAW);    glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_COLOR_ARRAY) ;     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeind, inds,GL_STATIC_DRAW);    PrimType[object] = type ;     NumElems[object] = sizeind ; }// Very basic code to read a ppm file// And then set up buffers for texture coordinatesvoid inittexture (const char * filename, GLuint program) {    int i,j,k ;    FILE * fp ;     GLint err ;     assert(fp = fopen(filename,"rb")) ;    fscanf(fp,"%*s %*d %*d %*d%*c") ;    for (i = 0 ; i < 256 ; i++)        for (j = 0 ; j < 256 ; j++)            for (k = 0 ; k < 3 ; k++)                fscanf(fp,"%c",&(woodtexture[i][j][k])) ;    fclose(fp) ;      // Set up Texture Coordinates    glGenTextures(1, texNames) ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[numobjects*numperobj+ncolors]) ;     glBufferData(GL_ARRAY_BUFFER, sizeof (floortex), floortex,GL_STATIC_DRAW);    glActiveTexture(GL_TEXTURE0) ;     glEnable(GL_TEXTURE_2D) ;     glTexCoordPointer(2,GL_FLOAT,0,BUFFER_OFFSET(0)) ;     glEnableClientState(GL_TEXTURE_COORD_ARRAY) ;     glBindTexture (GL_TEXTURE_2D, texNames[0]) ;     glTexImage2D(GL_TEXTURE_2D,0,GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE,            woodtexture) ;    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ;     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ;     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) ;    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) ;    // Define a sampler.  See page 709 in red book, 7th ed.    GLint texsampler ;     texsampler = glGetUniformLocation(program, "tex") ;     glUniform1i(texsampler,0) ; // Could also be GL_TEXTURE0     istex = glGetUniformLocation(program,"istex") ; }// Simple function to set the color separately.  Takes out colorsvoid initobjectnocol(GLuint object, GLfloat * vert, GLint sizevert, GLubyte * inds, GLint sizeind, GLenum type) {    int offset = object * numperobj ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ;     glBufferData(GL_ARRAY_BUFFER, sizevert, vert,GL_STATIC_DRAW);    glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_VERTEX_ARRAY) ;     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeind, inds,GL_STATIC_DRAW);    PrimType[object] = type ;     NumElems[object] = sizeind ; }// Simple function to init a bunch of color buffers for the cube void initcolorscube (void) {    int base = numobjects * numperobj ;     for (int i = 0 ; i < ncolors ; i++) {        for (int j = 0 ; j < 8 ; j++)             for (int k = 0 ; k < 3 ; k++)                 cubecol[j][k] = _cubecol[i][k] ;         glBindBuffer(GL_ARRAY_BUFFER, buffers[base+i]) ;         glBufferData(GL_ARRAY_BUFFER, sizeof(cubecol), cubecol ,GL_STATIC_DRAW);        glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;         glEnableClientState(GL_COLOR_ARRAY) ;           }  }// And a function to draw with them, similar to drawobject but with colorvoid drawcolor(GLuint object, GLuint color) {    int offset = object * numperobj ;     int base = numobjects * numperobj ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ;     glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_VERTEX_ARRAY) ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[base+color]) ; // Set color correctly     glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_COLOR_ARRAY) ;     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;     glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)) ; }// And a function to draw with textures, similar to drawobjectvoid drawtexture(GLuint object, GLuint texture) {    int offset = object * numperobj ;     int base = numobjects * numperobj + ncolors ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ;     glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_VERTEX_ARRAY) ;     // Even with texturing, so we can blend if needed.    glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors+offset]) ;     glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_COLOR_ARRAY) ;     glActiveTexture(GL_TEXTURE0) ;     glEnable(GL_TEXTURE_2D) ;     glBindTexture(GL_TEXTURE_2D, texture) ;     glEnableClientState(GL_TEXTURE_COORD_ARRAY) ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[base]) ; // Set texcoords    glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;     glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)) ; }void drawobject(GLuint object) {    int offset = object * numperobj ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ;     glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_VERTEX_ARRAY) ;     glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors+offset]) ;     glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;     glEnableClientState(GL_COLOR_ARRAY) ;     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;     glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)) ; }#endif

shaders.h

#include <iostream>#include <string>#ifndef __INCLUDESHADERS #define __INCLUDESHADERS std::string textFileRead (const char * filename) ;void programerrors (const GLint program) ;void shadererrors (const GLint shader) ;GLuint initshaders (GLenum type, const char * filename) ;GLuint initprogram (GLuint vertexshader, GLuint fragmentshader) ;#endif 

SourceFiles

shaders.cpp

#include <iostream>#include <fstream>#include <cstring>#include <string>#include <gl/glew.h>#include <GL/glut.h>using namespace std ; // This is a basic program to initiate a shader// The textFileRead function reads in a filename into a string// programerrors and shadererrors output compilation errors// initshaders initiates a vertex or fragment shader// initprogram initiates a program with vertex and fragment shadersstring textFileRead (const char * filename) {    string str, ret = "" ;     ifstream in ;     in.open(filename) ;     if (in.is_open()) {        getline (in, str) ;         while (in) {            ret += str + "\n" ;             getline (in, str) ;         }        //    cout << "Shader below\n" << ret << "\n" ;         return ret ;     }    else {        cerr << "Unable to Open File " << filename << "\n" ;         throw 2 ;     }}void programerrors (const GLint program) {    GLint length ;     GLchar * log ;     glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length) ;     log = new GLchar[length+1] ;    glGetProgramInfoLog(program, length, &length, log) ;     cout << "Compile Error, Log Below\n" << log << "\n" ;     delete [] log ; }void shadererrors (const GLint shader) {    GLint length ;     GLchar * log ;     glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length) ;     log = new GLchar[length+1] ;    glGetShaderInfoLog(shader, length, &length, log) ;     cout << "Compile Error, Log Below\n" << log << "\n" ;     delete [] log ; }GLuint initshaders (GLenum type, const char *filename) {    // Using GLSL shaders, OpenGL book, page 679     GLuint shader = glCreateShader(type) ;     GLint compiled ;     string str = textFileRead (filename) ;     GLchar * cstr = new GLchar[str.size()+1] ;     const GLchar * cstr2 = cstr ; // Weirdness to get a const char    strcpy(cstr,str.c_str()) ;     glShaderSource (shader, 1, &cstr2, NULL) ;     glCompileShader (shader) ;     glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled) ;     if (!compiled) {         shadererrors (shader) ;         throw 3 ;     }    return shader ; }GLuint initprogram (GLuint vertexshader, GLuint fragmentshader) {    GLuint program = glCreateProgram() ;     GLint linked ;     glAttachShader(program, vertexshader) ;     glAttachShader(program, fragmentshader) ;     glLinkProgram(program) ;     glGetProgramiv(program, GL_LINK_STATUS, &linked) ;     if (linked) glUseProgram(program) ;     else {         programerrors(program) ;         throw 4 ;     }    return program ; }

mytest3.cpp

/***************************************************************************//* This is a simple demo program written for CS 184 by Ravi Ramamoorthi    *//* This program corresponds to the final OpenGL lecture on shading.        *//*                                                                         *//* This program draws some simple geometry, a plane with four pillars      *//* textures the ground plane, and adds in a teapot that moves              *//* Lighting effects are also included with fragment shaders                *//* The keyboard function should be clear about the keystrokes              *//* The mouse can be used to zoom into and out of the scene                 *//***************************************************************************/#include <stdio.h>#include <assert.h>#include <stdlib.h>#include <gl/glew.h>#include <GL/glut.h>#include <FreeImage.h>#include <iomanip>int mouseoldx, mouseoldy ; // For mouse motionint windowWidth = 500, windowHeight = 500; //Width/Height of OpenGL windowGLdouble eyeloc = 2.0 ; // Where to look from; initially 0 -2, 2GLfloat teapotloc = -0.5 ; // ** NEW ** where the teapot is locatedGLfloat rotamount = 0.0; // ** NEW ** amount to rotate teapot byGLint animate = 0 ; // ** NEW ** whether to animate or notGLuint vertexshader, fragmentshader, shaderprogram ; // shadersGLubyte woodtexture[256][256][3] ; // ** NEW ** texture (from grsites.com)GLuint texNames[1] ; // ** NEW ** texture bufferGLuint istex ;  // ** NEW ** blend parameter for texturingGLuint islight ; // ** NEW ** for lightingGLint texturing = 1 ; // ** NEW ** to turn on/off texturingGLint lighting = 1 ; // ** NEW ** to turn on/off lighting/* Variables to set uniform params for lighting fragment shader */GLuint light0dirn ; GLuint light0color ; GLuint light1posn ; GLuint light1color ; GLuint ambient ; GLuint diffuse ; GLuint specular ; GLuint shininess ; const int DEMO = 5 ; // ** NEW ** To turn on and off features#include "shaders.h"#include "geometry3.h"/* New helper transformation function to transform vector by modelview */ void transformvec (const GLfloat input[4], GLfloat output[4]) {    GLfloat modelview[16] ; // in column major order    glGetFloatv(GL_MODELVIEW_MATRIX, modelview) ;     for (int i = 0 ; i < 4 ; i++) {        output[i] = 0 ;         for (int j = 0 ; j < 4 ; j++)             output[i] += modelview[4*j+i] * input[j] ;     }}void display(void){    // clear all pixels      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;     // draw white polygon (square) of unit length centered at the origin    // Note that vertices must generally go counterclockwise    // Change from the first program, in that I just made it white.    // The old OpenGL code of using glBegin... glEnd no longer appears.     // The new version uses vertex buffer objects from init.       // Does the order of drawing matter?  What happens if I draw the ground     // after the pillars?  I will show this in class     //DEBUG    glUniform1i(islight,false) ; // Turn off lighting (except on teapot, later)    glUniform1i(istex,texturing) ;     drawtexture(FLOOR,texNames[0]) ; // Texturing floor     // drawobject(FLOOR) ;     glUniform1i(istex,0) ; // Other items aren't textured     // Now draw several cubes with different transforms, colors    // I continue to use the deprecated push-pop and matrix mode     // Since it is convenient (or you have to write your own stack).      glMatrixMode(GL_MODELVIEW) ;     // 1st pillar     glPushMatrix() ;     glTranslatef(-0.4,-0.4,0.0) ;     drawcolor(CUBE, 0) ;     glPopMatrix() ;     // 2nd pillar     glPushMatrix() ; glTranslatef(0.4,-0.4,0.0) ; drawcolor(CUBE, 1) ; glPopMatrix() ;     // 3rd pillar     glPushMatrix() ;     glTranslatef(0.4,0.4,0.0) ;     drawcolor(CUBE, 2) ;     glPopMatrix() ;     // 4th pillar     glPushMatrix() ;     glTranslatef(-0.4,0.4,0.0) ;     drawcolor(CUBE, 3) ;     glPopMatrix() ;     // Draw the glut teapot     // This is using deprecated old-style OpenGL certainly       /* New for Demo 3; add lighting effects */     const GLfloat one[] = {1, 1, 1, 1};    const GLfloat medium[] = {0.5, 0.5, 0.5, 1};    const GLfloat small[] = {0.2, 0.2, 0.2, 1};    const GLfloat high[] = {100} ;    const GLfloat zero[] = {0.0, 0.0, 0.0, 1.0} ;     const GLfloat light_specular[] = {1, 0.5, 0, 1};    const GLfloat light_specular1[] = {0, 0.5, 1, 1};    const GLfloat light_direction[] = {0.5, 0, 0, 0}; // Dir light 0 in w     const GLfloat light_position1[] = {0, -0.5, 0, 1};    GLfloat light0[4], light1[4] ;     // Set Light and Material properties for the teapot    // Lights are transformed by current modelview matrix.     // The shader can't do this globally.     // So we need to do so manually.      transformvec(light_direction, light0) ;     transformvec(light_position1, light1) ;     glUniform3fv(light0dirn, 1, light0) ;     glUniform4fv(light0color, 1, light_specular) ;     glUniform4fv(light1posn, 1, light1) ;     glUniform4fv(light1color, 1, light_specular1) ;     // glUniform4fv(light1color, 1, zero) ;     glUniform4fv(ambient,1,small) ;     glUniform4fv(diffuse,1,medium) ;     glUniform4fv(specular,1,one) ;     glUniform1fv(shininess,1,high) ;     // Enable and Disable everything around the teapot     // Generally, we would also need to define normals etc.     // But glut already does this for us     if (DEMO > 4)         glUniform1i(islight,lighting) ; // turn on lighting only for teapot.     //  ** NEW ** Put a teapot in the middle that animates     glColor3f(0.0,1.0,1.0) ; // Deprecated command to set the color     glPushMatrix() ;    //  I now transform by the teapot translation for animation     glTranslatef(teapotloc, 0.0, 0.0) ;    //  The following two transforms set up and center the teapot     //  Remember that transforms right-multiply the stack     glTranslatef(0.0,0.0,0.1) ;    glRotatef(rotamount, 0.0, 0.0, 1.0);    glRotatef(90.0,1.0,0.0,0.0) ;    glutSolidTeapot(0.15) ;     glUniform1i(islight,0) ; // turn off lighting     glPopMatrix() ;    // Does order of drawing matter?     // What happens if I draw the ground after the pillars?     // I will show this in class.    // drawobject(FLOOR) ;     // don't wait!      // start processing buffered OpenGL routines     glutSwapBuffers() ;     glFlush ();}// ** NEW ** in this assignment, is an animation of a teapot // Hitting p will pause this animation; see keyboard callbackvoid animation(void) {    teapotloc = teapotloc + 0.0025 ;    rotamount = rotamount + 0.25;    if (teapotloc > 0.5) teapotloc = -0.5 ;    if (rotamount > 360.0) rotamount = 0.0;    glutPostRedisplay() ;  }void moveTeapot() {    rotamount = 45.0;    teapotloc = -0.05;}// Defines a Mouse callback to zoom in and out // This is done by modifying gluLookAt         // The actual motion is in mousedrag           // mouse simply sets state for mousedrag       void mouse(int button, int state, int x, int y) {    if (button == GLUT_LEFT_BUTTON) {        if (state == GLUT_UP) {            // Do Nothing ;        }        else if (state == GLUT_DOWN) {            mouseoldx = x ; mouseoldy = y ; // so we can move wrt x , y         }    }    else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)     { // Reset gluLookAt        eyeloc = 2.0 ;         glMatrixMode(GL_MODELVIEW) ;        glLoadIdentity() ;        gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;        glutPostRedisplay() ;    }}void mousedrag(int x, int y) {    int yloc = y - mouseoldy  ;    // We will use the y coord to zoom in/out    eyeloc  += 0.005*yloc ;         // Where do we look from    if (eyeloc < 0) eyeloc = 0.0 ;    mouseoldy = y ;    /* Set the eye location */    glMatrixMode(GL_MODELVIEW) ;    glLoadIdentity() ;    gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;    glutPostRedisplay() ;}void printHelp() {    std::cout << "\nAvailable commands:\n"          << "press 'h' to print this message again.\n"          << "press Esc to quit.\n"          << "press 'o' to save a screenshot to \"./screenshot.png\".\n"          << "press 'i' to move teapot into position for HW0 screenshot.\n"          << "press 'p' to start/stop teapot animation.\n"          << "press 't' to turn texturing on/off.\n"          << "press 's' to turn shading on/off.\n";}void saveScreenshot() {    int pix = windowWidth * windowHeight;    BYTE *pixels = new BYTE[3*pix];    glReadBuffer(GL_FRONT);    glReadPixels(0,0,windowWidth,windowHeight,GL_BGR,GL_UNSIGNED_BYTE,pixels);    FIBITMAP *img = FreeImage_ConvertFromRawBits(pixels, windowWidth, windowHeight, windowWidth * 3, 24, 0xFF0000, 0x00FF00, 0x0000FF, false);    std::cout << "Saving screenshot: screenshot.png\n";    FreeImage_Save(FIF_PNG, img, "screenshot.png", 0);    delete pixels;}// Defines what to do when various keys are pressed void keyboard (unsigned char key, int x, int y) {    switch (key) {        case 'h':            printHelp();            break;        case 'o':            saveScreenshot();            break;        case 'i':            moveTeapot();                       eyeloc = 2.0f;            texturing = 1;            lighting = 1;            animate = 0;            glutIdleFunc(NULL);            glutPostRedisplay();            break;        case 27:  // Escape to quit            exit(0) ;            break ;        case 'p': // ** NEW ** to pause/restart animation            animate = !animate ;            if (animate) glutIdleFunc(animation) ;            else glutIdleFunc(NULL) ;            break ;        case 't': // ** NEW ** to turn on/off texturing ;             texturing = !texturing ;            glutPostRedisplay() ;             break ;        case 's': // ** NEW ** to turn on/off shading (always smooth) ;             lighting = !lighting ;            glutPostRedisplay() ;             break ;        default:            break ;    }}/* Reshapes the window appropriately */void reshape(int w, int h){    windowWidth = w;    windowHeight = h;    glViewport (0, 0, (GLsizei) w, (GLsizei) h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    // Think about the rationale for this choice for gluPerspective     // What would happen if you changed near and far planes?     gluPerspective(30.0, (GLdouble)w/(GLdouble)h, 1.0, 10.0) ;}void checkOpenGLVersion() {    const char *version_p = (const char *)glGetString(GL_VERSION);    float version = 0.0f;    if(version_p != NULL)        version = atof(version_p);    if(version < 2.1f) {        std::cout << std::endl << "*****************************************" << std::endl;        if(version_p != NULL) {            std::cout << "WARNING: Your OpenGL version is not supported." << std::endl;            std::cout << "We detected version " << std::fixed << std::setprecision(1) << version;            std::cout << ", but at least version 2.1 is required." << std::endl << std::endl;        } else {            std::cout << "WARNING: Your OpenGL version could not be detected." << std::endl << std::endl;        }        std::cout << "Please update your graphics drivers BEFORE posting on the forum. If this" << std::endl                  << "doesn't work, ensure your GPU supports OpenGL 2.1 or greater." << std::endl;        std::cout << "If you receive a 0xC0000005: Access Violation error, this is likely the reason." << std::endl;        std::cout << std::endl;        std::cout << "Additional OpenGL Info:" << std::endl;        std::cout << "(Please include with support requests)" << std::endl;        std::cout << "GL_VERSION: ";        std::cout << glGetString(GL_VERSION) << std::endl;        std::cout << "GL_VENDOR: ";        std::cout << glGetString(GL_VENDOR) << std::endl;        std::cout << "GL_RENDERER: ";        std::cout << glGetString(GL_RENDERER) << std::endl;        std::cout << std::endl << "*****************************************" << std::endl;        std::cout << std::endl << "Select terminal and press <ENTER> to continue." << std::endl;        std::cin.get();        std::cout << "Select OpenGL window to use commands below." << std::endl;    }}void init (void) {    //Warn students about OpenGL version before 0xC0000005 error    checkOpenGLVersion();    printHelp();    /* select clearing color    */    glClearColor (0.0, 0.0, 0.0, 0.0);    /* initialize viewing values  */    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    // Think about this.  Why is the up vector not normalized?    glMatrixMode(GL_MODELVIEW) ;    glLoadIdentity() ;    gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;    // Initialize the shaders    // vertexshader = initshaders(GL_VERTEX_SHADER, "shaders/tex.vert") ;    // fragmentshader = initshaders(GL_FRAGMENT_SHADER, "shaders/tex.frag") ;    vertexshader = initshaders(GL_VERTEX_SHADER, "shaders/light.vert.glsl") ;    fragmentshader = initshaders(GL_FRAGMENT_SHADER, "shaders/light.frag.glsl") ;    GLuint program = glCreateProgram() ;    shaderprogram = initprogram(vertexshader, fragmentshader) ;    GLint linked;    glGetProgramiv(shaderprogram, GL_LINK_STATUS, &linked) ;      // * NEW * Set up the shader parameter mappings properly for lighting.    islight = glGetUniformLocation(shaderprogram,"islight") ;            light0dirn = glGetUniformLocation(shaderprogram,"light0dirn") ;           light0color = glGetUniformLocation(shaderprogram,"light0color") ;           light1posn = glGetUniformLocation(shaderprogram,"light1posn") ;           light1color = glGetUniformLocation(shaderprogram,"light1color") ;           ambient = glGetUniformLocation(shaderprogram,"ambient") ;           diffuse = glGetUniformLocation(shaderprogram,"diffuse") ;           specular = glGetUniformLocation(shaderprogram,"specular") ;           shininess = glGetUniformLocation(shaderprogram,"shininess") ;      // Set up the Geometry for the scene.      // From OpenGL book pages 103-109       glGenBuffers(numperobj*numobjects+ncolors+1, buffers) ; // 1 for texcoords     initcolorscube() ;     // Initialize texture    // inittexture("wood.ppm", fragmentprogram) ;     inittexture("wood.ppm", shaderprogram) ;     // Initialize objects    initobject(FLOOR, (GLfloat *) floorverts, sizeof(floorverts), (GLfloat *) floorcol, sizeof (floorcol), (GLubyte *) floorinds, sizeof (floorinds), GL_POLYGON) ;     //       initobject(CUBE, (GLfloat *) cubeverts, sizeof(cubeverts), (GLfloat *) cubecol, sizeof (cubecol), (GLubyte *) cubeinds, sizeof (cubeinds), GL_QUADS) ;     initobjectnocol(CUBE, (GLfloat *) cubeverts, sizeof(cubeverts), (GLubyte *) cubeinds, sizeof (cubeinds), GL_QUADS) ;     // Enable the depth test    glEnable(GL_DEPTH_TEST) ;    glDepthFunc (GL_LESS) ; // The default option}int main(int argc, char** argv){    FreeImage_Initialise();    glutInit(&argc, argv);    // Requests the type of buffers (Single, RGB).    // Think about what buffers you would need...    // Request the depth if needed, later swith to double buffer     glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);    glutInitWindowSize (windowWidth, windowHeight);     //glutInitWindowPosition (100, 100);    glutCreateWindow ("Simple Demo with Shaders");    GLenum err = glewInit() ;     if (GLEW_OK != err) {         std::cerr << "Error: " << glewGetString(err) << std::endl;     }     init(); // Always initialize first    // Now, we define callbacks and functions for various tasks.    glutDisplayFunc(display);     glutReshapeFunc(reshape) ;    glutKeyboardFunc(keyboard);    glutMouseFunc(mouse) ;    glutMotionFunc(mousedrag) ;    glutMainLoop(); // Start the main code    FreeImage_DeInitialise();    return 0;   /* ANSI C requires main to return int. */}

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述


note

1.这次任务的代码框架包括GLM库。
2.程序中有一个贴有纹理的地面,上面有4个支柱和带有移动光照的茶壶。
3.注意在这个程序中,shader文件夹包含的是glsl着色器。这些文件是在OpenGL程序运行时加载和编译的,因此它们必须存在,但未必是Makefile或项目的一部分。
4.可以使用鼠标进行放大。mytest3.cpp中的keyboard函数,来了解可以按的键。p键可以开始或停止茶壶的动画。
5.一旦你的程序运行成功,按i键可以将茶壶移动。接下来,按o键将截图输出到程序的目录中。

反思:可以将茶壶上的红色光照改成黄色(黄色是通过红色和绿色混合而成,也就是颜色向量中的前两个元素:第三个元素代表蓝色)。对应的RGBA值为(1,1,0,1)。相关的颜色和代码在mytest3.cpp中的display函数中,在注释“add lighting effects”的地方。注意,红色光照原来是有点橙色的,它的RGBA值是(1,0.5,0,1)。将光照的颜色从红色改成黄色后,重新编译,运行,然后像之前一样先按i键再按o键来输出截图。

0 0
原创粉丝点击