首页 > 代码库 > Lane-学习OpenGL(4)-4个进阶例子

Lane-学习OpenGL(4)-4个进阶例子

运行环境:

(1)Windows 7

(2)CodeBlocks

(3)GLUT

(4)Author:Lane

2014-12-19

1.经过纹理贴图的棋盘

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];

static GLuint texName;

void makeCheckImage(void){
    int i,j,c;
    for(i = 0; i < checkImageHeight; i++){
        for(j = 0; j < checkImageWidth; j++){
            c = (((i&0x8)==0)^((j&0x8))==0)*255;
            checkImage[i][j][0] = (GLubyte)c;
            checkImage[i][j][1] = (GLubyte)c;
            checkImage[i][j][2] = (GLubyte)c;
            checkImage[i][j][3] = (GLubyte)255;
        }
    }
}

void init(void){
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    makeCheckImage();
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glGenTextures(1,&texName);
    glBindTexture(GL_TEXTURE_2D,texName);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,checkImageWidth,checkImageHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,checkImage);
}

void display(void){
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
    glBindTexture(GL_TEXTURE_2D,texName);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0,0.0);
        glVertex3f(-2.0,-1.0,0.0);
        glTexCoord2f(0.0,1.0);
        glVertex3f(-2.0,1.0,0.0);
        glTexCoord2f(1.0,1.0);
        glVertex3f(0.0,1.0,0.0);
        glTexCoord2f(1.0,0.0);
        glVertex3f(0.0,-1.0,0.0);

        glTexCoord2f(0.0,0.0);
        glVertex3f(1.0,-1.0,0.0);
        glTexCoord2f(0.0,1.0);
        glVertex3f(1.0,1.0,0.0);
        glTexCoord2f(1.0,1.0);
        glVertex3f(2.41421,1.0,-1.41421);
        glTexCoord2f(1.0,0.0);
        glVertex3f(2.41421,-1.0,-1.41421);
    glEnd();
    glFlush();
    glDisable(GL_TEXTURE_2D);
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,30.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0,0.0,-3.6);
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(256,256);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    //glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}

技术分享

2.替换纹理子图像

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

#define checkImageWidth 64
#define checkImageHeight 64

#define subImageWidth 16
#define subImageHeight 16

static GLubyte checkImage[checkImageHeight][checkImageWidth][4];

static GLubyte subImage[subImageHeight][subImageWidth][4];

static GLuint texName;

void makeCheckImage(void){
    int i,j,c;
    for(i = 0; i < checkImageHeight; i++){
        for(j = 0; j < checkImageWidth; j++){
            c = (((i&0x8)==0)^((j&0x8))==0)*255;
            checkImage[i][j][0] = (GLubyte)c;
            checkImage[i][j][1] = (GLubyte)c;
            checkImage[i][j][2] = (GLubyte)c;
            checkImage[i][j][3] = (GLubyte)255;
        }
    }

    for(i = 0; i < subImageHeight; i++){
        for(j = 0; j < subImageWidth; j++){
            c = (((i&0x4)==0)^((j&0x4)==0)*255);
            subImage[i][j][0] = (GLubyte)c;
            subImage[i][j][1] = (GLubyte)0;
            subImage[i][j][2] = (GLubyte)0;
            subImage[i][j][3] = (GLubyte)255;
        }
    }
}

void keyboard(unsigned char key,int x,int y){
    switch(key){
        case 's':
        case 'S':
            glBindTexture(GL_TEXTURE_2D,texName);
            glTexSubImage2D(GL_TEXTURE_2D,0,12,44,
                            subImageWidth,subImageHeight,GL_RGBA,
                            GL_UNSIGNED_BYTE,subImage);
            glutPostRedisplay();
            break;
        case 'r':
        case 'R':
            glBindTexture(GL_TEXTURE_2D,texName);
            glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,
                         checkImageWidth,checkImageHeight,0,
                         GL_RGBA,GL_UNSIGNED_BYTE,checkImage);
            glutPostRedisplay();
            break;
        case 27:
            exit(0);
            break;
        default:
            break;
    }
}

void init(void){
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    makeCheckImage();
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glGenTextures(1,&texName);
    glBindTexture(GL_TEXTURE_2D,texName);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,checkImageWidth,checkImageHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,checkImage);
}

void display(void){
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
    glBindTexture(GL_TEXTURE_2D,texName);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0,0.0);
        glVertex3f(-2.0,-1.0,0.0);
        glTexCoord2f(0.0,1.0);
        glVertex3f(-2.0,1.0,0.0);
        glTexCoord2f(1.0,1.0);
        glVertex3f(0.0,1.0,0.0);
        glTexCoord2f(1.0,0.0);
        glVertex3f(0.0,-1.0,0.0);

        glTexCoord2f(0.0,0.0);
        glVertex3f(1.0,-1.0,0.0);
        glTexCoord2f(0.0,1.0);
        glVertex3f(1.0,1.0,0.0);
        glTexCoord2f(1.0,1.0);
        glVertex3f(2.41421,1.0,-1.41421);
        glTexCoord2f(1.0,0.0);
        glVertex3f(2.41421,-1.0,-1.41421);
    glEnd();
    glFlush();
    glDisable(GL_TEXTURE_2D);
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,30.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0,0.0,-3.6);
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(256,256);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}
技术分享

3.使用求值器进行纹理处理

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

GLfloat ctrlpoints[4][4][3] = {
    {{-1.5,-1.5,4.0},{-0.5,-1.5,2.0},
     {0.5,-1.5,-1.0},{1.5,-1.5,2.0}},
    {{-1.5,-0.5,1.0},{-0.5,-0.5,3.0},
     {0.5,-0.5,0.0},{1.5,-0.5,-1.0}},
    {{-1.5,0.5,4.0},{-0.5,0.5,0.0},
     {0.5,0.5,3.0},{1.5,0.5,4.0}},
    {{-1.5,-1.5,-2.0},{-0.5,1.5,-2.0},
     {0.5,1.5,0.0},{1.5,1.5,-1.0}}
};
GLfloat texpts[2][2][2]={{{0.0,0.0},{0.0,1.0}},{{1.0,0.0},{1.0,1.0}}};

void display(void){
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glColor3f(1.0,1.0,1.0);
    glEvalMesh2(GL_FILL,0,20,0,20);
    glFlush();
}

#define imageWidth 64
#define imageHeight 64

GLubyte image[3*imageWidth*imageHeight];
void makeImage(void){
    int i,j;
    float ti,tj;

    for(i = 0; i < imageWidth;i++){
        ti = 2.0 * 3.14159265*i/imageWidth;
        for(j = 0; j < imageHeight; j++){
            tj = 2.0 * 3.14169265*j/imageHeight;
            image[3*(imageHeight*i+j)]=(GLubyte)127*(1.0+sin(ti));
            image[3*(imageHeight*i+j)]=(GLubyte)127*(1.0+cos(2*tj));
            image[3*(imageHeight*i+j)+2]=(GLubyte)127*(1.0+cos(ti+tj));
        }
    }
}

void init(void){
    glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&ctrlpoints[0][0][0]);
    glMap2f(GL_MAP2_TEXTURE_COORD_2,0,1,2,2,0,1,4,2,&texpts[0][0][0]);
    glEnable(GL_MAP2_TEXTURE_COORD_2);
    glEnable(GL_MAP2_VERTEX_3);
    glMapGrid2f(20,0.0,1.0,20,0.0,1.0);
    makeImage();
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D,0,3,imageWidth,imageHeight,0,GL_RGB,GL_UNSIGNED_BYTE,image);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_FLAT);
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(w <= h)
        glOrtho(-4.0,4.0,-4.0*(GLfloat)h/(GLfloat)w,4.0*(GLfloat)h/(GLfloat)w,-4.0,4.0);
    else
        glOrtho(-4.0*(GLfloat)w/(GLfloat)h,4.0*(GLfloat)w/(GLfloat)h,-4.0,4.0,-4.0,4.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(35.0,1.0,1.0,1.0);
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

技术分享

4.NURBS表面

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

#ifdef CALLBACK
#define CALLBACK
#endif // CALLBACK

GLfloat ctlpoints[4][4][3];
int showPoints = 0;

GLUnurbsObj *theNurb;

void init_surface(void){
    int u,v;
    for(u=0;u<4;u++){
        for(v=0;v<4;v++){
            ctlpoints[u][v][0]=2.0*((GLfloat)u-1.5);
            ctlpoints[u][v][1]=2.0*((GLfloat)v-1.5);
            if((u==1||u==2)&&(v==1||v==2))
                ctlpoints[u][v][2]=3.0;
            else
                ctlpoints[u][v][2]=-3.0;
        }
    }
}

void CALLBACK nurbsError(GLenum errorCode){
    const GLubyte *estring;
    estring = gluErrorString(errorCode);
    fprintf(stderr,"Nurbs Error:%s \n ",estring);
    exit(0);
}

void init(void){
    GLfloat mat_diffuse[] = {0.7,0.7,0.7,1.0};
    GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
    GLfloat mat_shininess[] = {100.0};

    glClearColor(0.0,0.0,0.0,0.0);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_AUTO_NORMAL);
    glEnable(GL_NORMALIZE);

    init_surface();
    theNurb = gluNewNurbsRenderer();
    gluNurbsProperty(theNurb,GLU_SAMPLING_TOLERANCE,25.0);
    gluNurbsProperty(theNurb,GLU_DISPLAY_MODE,GLU_FILL);
    gluNurbsCallback(theNurb,GLU_ERROR,(void (__stdcall *)(void))nurbsError);
}

void display(void){
    GLfloat knots[8]={0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0};
    int i,j;

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glRotatef(330.0,1.0,0.0,0.0);
    glScalef(0.5,0.5,0.5);

    gluBeginSurface(theNurb);
    gluNurbsSurface(theNurb,8,knots,8,knots,4*3,8,&ctlpoints[0][0][0],4,4,GL_MAP2_VERTEX_3);
    gluEndSurface(theNurb);

    if(showPoints){
        glPointSize(5.0);
        glDisable(GL_LIGHTING);
        glColor3f(1.0,1.0,0.0);
        glBegin(GL_POINTS);
        for(i=0;i<4;i++){
            for(j=0;j<4;j++){
                glVertex3f(ctlpoints[i][j][0],ctlpoints[i][j][1],ctlpoints[i][j][2]);
            }
        }
        glEnd();
        glEnable(GL_LIGHTING);
    }
    glPopMatrix();
    glFlush();
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,(GLdouble)w/(GLdouble)h,3.0,8.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0,0.0,-5.0);
}

void keyboard(unsigned char key,int x,int y){
    switch(key){
        case 'c':
        case 'C':
            showPoints = !showPoints;
            glutPostRedisplay();
            break;
        case 27:
            exit(0);
            break;
        default:
            break;
    }
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}
技术分享

Lane-学习OpenGL(4)-4个进阶例子