Teapot

Draw our teapot with the techniques of texture mapping, shadow-maps and normal mapping.
Step 1:
load OBJ file.

void readFile(char *filename, struct point *vertex, struct point *normal, struct coord *vt,
         struct point *vx, struct point *vy, struct match **face) {
    FILE *fptr;
    char buf[100];
    fptr = fopen(filename, "r");
    do{
        fgets(buf,100,fptr);
    } while(buf[0]=='#');
    int i = 0; int j = 0; int k = 0; int p = 0; int q = 0; int r = 0;
    while(fscanf(fptr, "%s", buf) != EOF)  {
        if (strcmp(buf, "v") == 0) {
            fscanf(fptr, "%lf %lf %lf",
                &vertex[i].x, &vertex[i].y, &vertex[i].z);  
            i++;
        } else if (strcmp(buf, "vn") == 0) {
            fscanf(fptr, "%lf %lf %lf",
                &normal[j].x, &normal[j].y, &normal[j].z);
            j++;    
        } else if (strcmp(buf, "f") == 0) {
            fscanf(fptr, "%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", 
                &face[k][0].v, &face[k][0].t, &face[k][0].n, &face[k][1].v, &face[k][1].t, &face[k][1].n, 
                &face[k][2].v, &face[k][2].t, &face[k][2].n, &face[k][3].v, &face[k][3].t, &face[k][3].n);
            k++;    
        } else if (strcmp(buf, "vt") == 0 ) {
            fscanf(fptr, "%lf %lf",
                &vt[p].x, &vt[p].y);    
            p++;
        } else if (strcmp(buf, "vx") == 0 ) {
            fscanf(fptr, "%lf %lf %lf",
                &vx[q].x, &vx[q].y, &vx[q].z);  
            q++;
        } else if (strcmp(buf, "vy") == 0 ) {
            fscanf(fptr, "%lf %lf %lf",
                &vy[r].x, &vy[r].y, &vy[r].z);  
            r++;
        }
    }
    fclose(fptr);
}

Step 2.
load texture,we use three textures for ground,back and teapot respectively

void load_texture(char *filename,unsigned int tid)
{
    FILE *fopen(), *fptr;
    char buf[512];
    int im_size, im_width, im_height, max_color;
    unsigned char *texture_bytes, *parse; 

    fptr=fopen(filename,"r");
    fgets(buf,512,fptr);
    do{
        fgets(buf,512,fptr);
    } while(buf[0]=='#');
    parse = strtok(buf," \t");
    im_width = atoi(parse);

    parse = strtok(NULL," \n");
    im_height = atoi(parse);

    fgets(buf,512,fptr);
    parse = strtok(buf," \n");
    max_color = atoi(parse);

    im_size = im_width*im_height;
    texture_bytes = (unsigned char *)calloc(3,im_size);
    fread(texture_bytes,3,im_size,fptr);
    fclose(fptr);

    glBindTexture(GL_TEXTURE_2D,tid);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,im_width,im_height,0,GL_RGB, 
        GL_UNSIGNED_BYTE,texture_bytes);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
    free(texture_bytes);
}

Step 4.
draw the shadow of the teapot!

void build_shadowmap()
{
    glBindTexture(GL_TEXTURE_2D,1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, XRES, YRES, 0, 

    GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebufferEXT(GL_FRAMEBUFFER,1);
    glDrawBuffer(GL_NONE); 
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,1,0);
    glBindFramebufferEXT(GL_FRAMEBUFFER,0);
}

Step 4.
set shaders
.frag

uniform sampler2D mytexture; 
uniform sampler2D groundtexture; 
uniform sampler2D mynormalmap;
uniform int times;
varying vec3 ec_vnormal, ec_vposition, ec_vtangent, ec_vbitangent;
varying vec4 tcoords;
void main()
{
    float pi = 3.14159;
    vec3 P, N, L, V, H, mapN, tcolor;
    vec4 pccoords;
    vec4 diffuse_color; 
    vec4 specular_color; 
    float shininess = gl_FrontMaterial.shininess;
    float depthsample, clarity;
    P = ec_vposition;
    N = normalize(ec_vnormal);
    L = normalize(gl_LightSource[0].position.xyz - P);
    V = normalize(-P);               
    H = normalize(L+V);
    pccoords = tcoords/tcoords.w ;
    depthsample = texture2D(mytexture,pccoords.st).z;
    clarity = 1.0;
    if (times == 1) {
        if(depthsample < pccoords.z) clarity = 0.8;
        diffuse_color *= clarity*max(dot(N,L),0.0);
        specular_color *= clarity*pow(max(dot(H,N),0.0),shininess);
        gl_FragColor = 0.5*(diffuse_color + specular_color);    
    } else if(times == 2 || times == 3) {
        if (times == 2) {
            tcolor = vec3(texture2D(groundtexture,gl_TexCoord[0].st));
        } else if (times == 3) {
            mat3 tform;
            tform = mat3(ec_vtangent,ec_vbitangent,ec_vnormal);
            mapN = vec3(texture2D(mynormalmap,gl_TexCoord[0].st));
            mapN.xy = 2.0*mapN.xy - vec2(1.0,1.0);
            N = normalize(tform*normalize(mapN));
            tcolor = vec3(texture2D(mytexture,gl_TexCoord[0].st));
        }
        diffuse_color = vec4(tcolor,1.0)*max(dot(N,L),0.0);
        specular_color = gl_FrontMaterial.specular*pow(max(dot(H,N),0.0),shininess);
        specular_color *= (shininess+2.0)/(8.0*pi);
        gl_FragColor = diffuse_color + specular_color;
        if (times == 2) {
            if(depthsample < pccoords.z)  {
                clarity = 0.8;
                diffuse_color *= clarity*max(dot(N,L),0.0);
                specular_color *= clarity*pow(max(dot(H,N),0.0),shininess);
                gl_FragColor = 0.5*(diffuse_color + specular_color);
            }
        }
    }   
}

.vert

varying vec3 ec_vnormal, ec_vposition, ec_vtangent, ec_vbitangent;
varying vec4 tcoords;
attribute vec3 tangent, bitangent;

void main()
{
    ec_vnormal = (gl_NormalMatrix*gl_Normal).xyz;
    ec_vposition = (gl_ModelViewMatrix*gl_Vertex).xyz;
    gl_Position = gl_ProjectionMatrix*gl_ModelViewMatrix*gl_Vertex;
    tcoords = gl_TextureMatrix[7]*gl_Vertex;
    ec_vtangent = gl_NormalMatrix*tangent;
    ec_vbitangent = gl_NormalMatrix*bitangent;
    gl_TexCoord[0] = gl_MultiTexCoord0;
}

Step 4.
draw the stuff!
glutDisplayFunc(do_stuff);

void do_stuff() {
    struct point eyepoint, viewpoint;       
    glBindFramebufferEXT(GL_FRAMEBUFFER,1); 
    glUseProgram(0);

    eyepoint.x = light0_position[0]; 
    eyepoint.y = light0_position[1]; 
    eyepoint.z = light0_position[2]; 
    viewpoint.x = light0_direction[0]+light0_position[0];
    viewpoint.y = light0_direction[1]+light0_position[1];
    viewpoint.z = light0_direction[2]+light0_position[2];
    view_volume(eyepoint,viewpoint);

    glClearColor(0.8,0.6,0.62,1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    lights();
    drawpot();

    glBindFramebufferEXT(GL_FRAMEBUFFER,0); 
    save_matrix(eyepoint,viewpoint);
    glUseProgram(sprogram);
    set_uniform(sprogram, 1);
    glActiveTexture(GL_TEXTURE7);
    glBindTexture(GL_TEXTURE_2D,1);

    eyepoint.x = 3; eyepoint.y = 3; eyepoint.z = 3;
    viewpoint.x = 0.0; viewpoint.y = 1; viewpoint.z = 0.0;
    view_volume(eyepoint,viewpoint);

    lights();
    drawquads(); 
    drawBack();
    drawpot();
    glutSwapBuffers();
}

drawquads()//draw the ground
drawBack()//draw the background
drawpot()//draw the teapot

void drawquads() {
    float bottom[4][3]={{-GROUND_SIZE, 0, -GROUND_SIZE}, {-GROUND_SIZE, 0, GROUND_SIZE},
                {GROUND_SIZE, 0, GROUND_SIZE}, {GROUND_SIZE, 0, -GROUND_SIZE}};
    float mytexcoords[4][2] = {{0.0,0.0}, {1.0,0.0}, {1.0,1.0}, {0.0,1.0}}; 

    glUseProgram(sprogram);
    set_uniform(sprogram, 2);
        glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D,4);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_QUADS);
    glNormal3f(0.0,1.0,0.0);
    int i;
    for(i=0;i<4;i++){
        glTexCoord2fv(mytexcoords[i]);
        glVertex3f(bottom[i][0],bottom[i][1],bottom[i][2]);
    }
    glDisable(GL_TEXTURE_2D);
    glEnd();
}


void drawBack() {
    float back[4][3]={{-WALL_SIZE, 0, -WALL_SIZE}, {-WALL_SIZE, 2 * WALL_SIZE, -WALL_SIZE},
                {WALL_SIZE, 2 * WALL_SIZE, -WALL_SIZE}, {WALL_SIZE ,0, -WALL_SIZE}};
    float backtexcoords[4][2] = {{0.0,1.0},{0.0,0.0},{1.0,0.0},{1.0,1.0}};  
    float left[4][3]={{-WALL_SIZE,0,-WALL_SIZE},{-WALL_SIZE,2*WALL_SIZE,-WALL_SIZE},
                {-WALL_SIZE,2*WALL_SIZE,WALL_SIZE},{-WALL_SIZE,0,WALL_SIZE}};
    float lefttexcoords[4][2] = {{1.0,1.0},{1.0,0.0},{0.0,0.0},{0.0,1.0}};  
    glUseProgram(0);    
        glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D,5);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_QUADS);
    glNormal3f(1.0,0.0,1.0);
    int i;
    for(i=0;i<4;i++){
        glTexCoord2fv(backtexcoords[i]);
        glVertex3f(back[i][0],back[i][1],back[i][2]);
    }
    for(i=0;i<4;i++){
        glTexCoord2fv(lefttexcoords[i]);
        glVertex3f(left[i][0],left[i][1],left[i][2]);
    }
    glEnd();
    glDisable(GL_TEXTURE_2D);
}

void drawpot() {    
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, 2);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, 3);
    glEnable(GL_TEXTURE_2D);    

    glUseProgram(sprogram);
    set_uniform(sprogram, 3);

    GLint tangent = glGetAttribLocation(sprogram,"tangent");
        GLint bitangent = glGetAttribLocation(sprogram,"bitangent");
    set_material();
    glBegin(GL_QUADS);
    int i;
    for (i = 0;i < numOfFaces;++i) {
        int j;      
        for (j = 0;j < 4;++j) {
            int vi = face[i][j].v - 1;
            int ti = face[i][j].t - 1;
            int ni = face[i][j].n - 1;
            glNormal3f(normal[ni].x, normal[ni].y, normal[ni].z);
            glTexCoord2f(vt[ti].x, vt[ti].y);       
            glVertexAttrib3f(tangent, vx[vi].x, vx[vi].y, vx[vi].z);  
            glVertexAttrib3f(bitangent, vy[vi].x, vy[vi].y, vy[vi].z);      
            glVertex3f(vertex[vi].x, vertex[vi].y, vertex[vi].z);
        }
    }   
    glEnd();
    glDisable(GL_TEXTURE_2D);
}

Out teapot:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值