使用纹理及阴影实现日地月系统

说明

  1. 使用图形学的两个最常用的阴影技术之一,Shadow Mapping方法(另一种是Shadow Volumes方法)。
  2. 使用多重纹理。
  3. 使用双缓冲。

参考网址

实现大概过程

第一次绘制:关闭光照效果,普通,阴影;将视角放在光源处,绘制物体(记得剔除正面),获得深度。
恢复矩阵,初始化纹理自动生成坐标。清空缓冲区。
第二次绘制:
1、打开光照效果,关闭光源(相当于只使用环境光),打开普通贴图,关闭阴影纹理,绘制物体,获得环境光下物体的颜色。
2、将环境光置为0(即关闭环境光),打开光源(打开光照效果),打开普通贴图和阴影纹理,绘制物体(当深度和纹理相等时绘制)。
恢复环境光,渲染物体。

代码

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <windows.h>

#define PI  3.14159265359

/********************全局变量及函数的预定义**********************************/
float day=0;//地球自转角度
float month=0;//月亮自转和公转角度
float year=0;//地球公转角度
float sun=0;//太阳自转角度

GLuint tex_walls[3], tex_shadow;
GLuint frame_buffer_s;

int shadow_w=1366, shadow_h=768;

GLfloat lightPos[] = {
    0.0, 0.0, 0.0 };//点光源位置
GLfloat lookat[] = {
    1.0, 0.0, 0.0 };//向前方向
GLfloat up[] = {
    0.0, 1.0, 0.0 };//向上方向

GLfloat texData[1366*768];

/****函数的预定义****/
void tex_init(void);

/******************glut回调函数**********************************************/

void Keyboard(unsigned char key, int x, int y){
   
    if(key==27)//按下Esc键退出
        exit(0);
}

void Timer(int millis){
   
//    float dday = 6,speed = 4;
    float dday = 18,speed = 12;
    float dmonth = speed*dday/29.5;//月亮自转和公转角度的增量
    float dyear = speed*dday/365.2475;//地球公转角度的增量
    float dsun = speed*dday/27.5;//太阳自转角度的增量
    day = fmod(day+dday,360);//计算地球自转角度
    month = fmod(month+dmonth,360);//计算月亮自转和公转角度
    year = fmod(year+dyear,360);//计算地球公转角度
    sun = fmod(sun+dsun,360);//计算太阳自转角度
    glutPostRedisplay();//调用场景绘制函数
    glutTimerFunc(millis,Timer,millis);//指定定时器函数,参数为间隔毫秒数,函数名,函数参数值
}

void Reshape(int w,int h){
   //窗口变化回调函数
    glViewport(0,0,w,h);//视口的位置和大小
    glMatrixMode(GL_PROJECTION);//当前变换类型为投影变换
    glLoadIdentity();//当前矩阵为单位矩阵
    //定义投影变换,参数为:y向张角;x/y;近平面;远平面
    gluPerspective(30,(float) w/h,1,1000);
    glTranslatef(0,0,-8);//适当远移
    glRotatef(30,1,0,0);//调整观察角度
    glMatrixMode(GL_MODELVIEW);//当前变换类型为视图造型变换
    glLoadIdentity();
}

/******************非功能函数************************************************/

void transposeMatrix( GLfloat m[16] )//置换矩阵
{
   
    GLfloat  tmp;
#define Swap( a, b )    tmp = a; a = b; b = tmp
    Swap( m[1],  m[4]  );
    Swap( m[2],  m[8]  );
    Swap( m[3],  m[12] );
    Swap( m[6],  m[9]  );
    Swap( m[7],  m[13] );
    Swap( m[11], m[14] );
#undef Swap
}

/******************纹理及阴影************************************************/

void init(){
   
    glEnable(GL_DEPTH_TEST);//打开深度测试,用于比较远近
    float gac[4] = {
   0.4f, 0.4f, 0.4f, 1};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gac);//设置环境光亮度

    tex_init();//初始化普通贴图,阴影纹理,缓冲
}

//普通贴图,阴影纹理,缓冲
void tex_init()
{
   
    glActiveTexture(GL_TEXTURE0); // 普通贴图
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );//设置纹理自动产生坐标,GL_OBJECT_LINEAR
    glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
    glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
    glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);
    glEnable(GL_TEXTURE_GEN_R);
    glEnable(GL_TEXTURE_GEN_Q);

    {
   
        //读取文件,获取图片数据,太阳纹理
        FILE *file = fopen("C:/Users/Administrator/Desktop/QTProjects/Planetary/1sun.bmp", "rb"); // 打开文件
        fseek(file, sizeof(BITMAPFILEHEADER), SEEK_SET); // 跳过文件头
        BITMAPINFOHEADER info; // 位图信息头
        fread
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值