OpenGL小探4——光照和键盘控制

光照和键盘控制
 
OpenGL——纹理过滤函数glTexParameteri()
图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.
  部分参数功能说明如下:
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  GL_TEXTURE_2D: 操作2D纹理.
  GL_TEXTURE_WRAP_S: S方向上的贴图模式.
  GL_CLAMP: 将纹理坐标限制在0.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充.
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  这里同上,只是它是T方向
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  这是纹理过滤
  GL_TEXTURE_MAG_FILTER: 放大过滤
  GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值.
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  GL_TEXTURE_MIN_FILTER: 缩小过滤
  GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.

 
BOOL light;  //光源开关
BOOL lp;  //L键是否按下
BOOL fp;  //F键是否按下
 
GLfloat xrot;   //绕x旋转角度步长
GLfloat yrot;   //绕y旋转步长
GLfloat xspeed;   //绕x旋转速度
GLfloat yspeed;   //绕y旋转速度
GLfloat z = -5.0f;  //深入屏幕的距离
 
//设置用来创建光源的数组,使用两种光:环境光、点光;若无环境光,漫射光未照到的地方会十分暗
GLfloat lightAmbient[] = [0.5f,0.5f,0.5f,1.0f]; //半亮的环境光
GLfloat lightDiffuse[] = [1.0f,1.0f,1.0f,1.0f]; //漫射光参数
GLfloat lightPosition[] = {0.0f,0.0f,2.0f,1.0f};  //光源位置
//最后一个参数告诉OpenGL这里指定的坐标就是光源的位置
 
GLuint filter; //滤波类型
GLuint texture[3]; //存储3种纹理
 
int LoadGLTextures(){  //载入位图并转换成纹理
    int Status = FALSE;  //状态指示器
    AUX_RGBImageRec* TextureImage[1]; //存储纹理
    memset(TextureImage,0,sizeof(void*)*1);
    //载入位图,
    if(TextureImage[0] = LoadBMP("Data/Create.bmp")){
        Status = TRUE; //载入成功
        glGenTextures(3,&Texture[0]); //创建纹理,分配一个纹理对象的编号
        //创建Nearest滤波贴图
        glBindTexture(GL_TETURE_2D,texture[0]); //绑定2D纹理,存储到texture[0]
        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,TextureImage[0]->sizeX,TextureImage[0]->sizeY,
                0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data); //把一幅图像载入为2D纹理
        //创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D,texture[1]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,
                0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
        //创建MipMapped纹理(贴图细化),可防止缩放时细节丢失
        glBindTexture(GL_TEXTURE_2D,texture[2]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
                        GL_LINEAR_MIPMAP_NEAREST);
        //生成mipmapped纹理,这里使用三种颜色来生成一个2D纹理
        gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,
                GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
        //释放存放位图数据的内存
        if(TextureImage[0]){    //纹理是否存在
            if(TextureImage[0]->data){  //纹理图像是否存在
                free(TextureImage[0]->data); //释放纹理图像所占内存
            }
            free(TextureImage[0]); //释放图像结构
        }
    }
    return Status;
}

//在ini InitGL(GLvoid)函数中添加下面的代码
glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient); //设置环境光
glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse); //设置漫射光
glLightfv(GL_LIGHT1,GL_POSITION,lightPosition); //设置光源位置
glEnable(GL_LIGHT1);  //启用一号光源!!!
 
int DrawGLScene(Glvoid){    //从这里开始所有的绘制
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTransLatef(0.0f,0.0f,z);
    glRotatef(xrot,1.0f,0.0f,0.0f);
    glRotatef(yrot,0.0f,1.0f,0.0f);
    glRotatef(zrot,0.0f,0.0f,1.0f);
 
    glBindTexture(GL_TEXTURE_2D,texture[filter]); //按下F键,filter会增加
    glBegin(GL_QUADS);  //开始绘制四边形
    //指定光源时必须指定一条法线,法线告诉OpenGL这个多边形的朝向,并指明正反面,法线应指向外侧
    //前侧面
    glNormal3f(0.0f,0.0f,1.0f); //法线指向观察者
    glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f,1.0f); //左下角
    glTexCoord2d(1.0f,0.0f); glVertex3f(1.0f,-1.0f,1.0f);
    glTexCoord2f(1.0f,1.0f); glVertex3f(1.0f,1.0f,1.0f);
    glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f,1.0f,1.0f);
    //后侧面
    glNormal3f(0.0f,0.0f,-1.0f); //法线背对观察者
    glTexCoord2f(1.0f,0.0f); glVertex3f(-1.0f,-1.0f,-1.0f); //右下角
    glTexCoord2f(1.0f,1.0f); glVertex3f(-1.0f,1.0f,-1.0f);
    glTexCoord2f(0.0f,1.0f); glVertex3f(1.0f,1.0f,-1.0f);
    glTexCoord2f(0.0f,0.0f); glVertex3f(1.0f,-1.0f,-1.0f);
    //顶面
    glNormal3f(0.0f,1.0f,0.0f); //法线向上
    glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f,1.0f,-1.0f); //左上角
    glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,1.0f,1.0f);
    glTexCoord2f(1.0f,0.0f); glVertex3f(1.0f,1.0f,1.0f);
    glTexCoord2f(1.0f,1.0f); glVertex3f(1.0f,1.0f,-1.0f);
    //底面
    glNormal3f(0.0f,-1.0f,0.0f); //法线朝下
    glTexCoord2f(1.0f,1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); //不明觉厉?
    glTexCoord2f(0.0f,1.0f); glVertex3f(1.0f,-1.0f,-1.0f);
    glTexCoord2f(0.0f,0.0f); glVertex3f(1.0f,-1.0f,1.0f);
    glTexCoord2f(1.0f,0.0f); glVertex3f(-1.0f,-1.0f,1.0f);
    //右侧面
    glNormal3f(1.0f,0.0f,0.0f); //法线向右
    glTexCoord2f(1.0f,0.0f); glVertex3f(1.0f,-1.0f,-1.0f);
    glTexCoord2f(1.0f,1.0f); glVertex3f(1.0f,1.0f,-1.0f);
    glTexCoord2f(0.0f,1.0f); glVertex3f(1.0f,1.0f,1.0f);
    glTexCoord2f(0.0f,0.0f); glVertex3f(1.0f,-1.0f,1.0f);
    //左侧面
    glNormal3f(-1.0,0.0f,0.0f); //法线向左
    glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f,-1.0f);
    glTexCoord2f(1.0f,0.0f); glVertex3f(-1.0f,-1.0f,1.0f);
    glTexCoord2f(1.0f,1.0f); glVertex3f(-1.0f,1.0f,1.0f);
    glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f,1.0f,-1.0f);
    glEnd();  //四边形绘制结束
 
    xrot += xspeed;
    yrot += yspeed;
    return TRUE;
}

 
//WinMain()
SwapBuffers(hDC);  //交换缓存
if(keys['L'] && !lp){   //L键被按下且松开了
    lp = TRUE;
    light = !light;
    if(!light){
        glDisable(GL_LIGHTING); //禁用光源
    }else{
        glEnable(GL_LIGHTING); //启用光源
    }
}
if(!keys['L']){ //若L键松开了
    lp = FALSE;
}
if(keys['F'] && !fp){
    fp = TRUE;
    filter += 1;
    if(filter > 2){
        filter = 0;
    }
}
if(!keys['F']){
    fp = FALSE;
}
if(keys[VK_PRIOR]) {    //PageUp按下
    z -= 0.02f;
}
if(keys[VK_NEXT]) {     //PageDown
    z += 0.02f;
}
if(keys[VK_UP]){
    xspeed -= 0.01f;
}
if(keys[VK_DOWN]){
    xspeed += 0.01f
}
if(keys[VK_RIGHT]){
    yspeed += 0.01f;
}
if(keys[VK_LEFT]){
    yspeed -= 0.01f;
}
 
if(keys[VK_F1]){
    keys[VK_F1]  =  FALSE;
    killGLWindow(); //摧毁当前窗口
    fullscreen = !fullscreen;
    if(!CreateGLWindow("kai",640,480,16,fullscreen)){
        return 0; //无法创建窗口,退出
    }
}
 
killGLWindow(); //销毁窗口
return (msg.wParam); //退出程序



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值