@Pigmon
2016-12-01T20:06:27.000000Z
字数 23307
阅读 1155
上课
老师的Cgcourse-examples环境的配置方法 (pdf)
链接:http://pan.baidu.com/s/1jI2ToUE 密码:yxea
拼凑大作业指南+参考大作业1指南
https://www.zybuluo.com/Pigmon/note/582224
参考大作业2,即整合Nehe Lesson10 场景漫游 + 环境贴图的那个。
修改建议:
- 改场景贴图,地板,天花板分别是场景模型的前2个,和第3-4个三角形
- 修改场景地形,在world.txt里面
- 加几个光源
- 加天空盒,或者背景贴图
- 把手动移动环境球,变成自动按顺序走动
后面是程序和 world.txt。world.txt选好存放位置后,不要忘了修改程序里的路径。
如果程序执行闪退看看是不是贴图或world.txt的路径不对。
仔细看中文注释
我也不会,所以很粗糙
/*
-----------------------------------------------------------------------
This source file is part of "cgcourse-examples"
(Examples for Computer Graphics Course of CCCE GUCAS.)
Copyright (C) 2011 Xue Jian (jian.xue.cn@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-----------------------------------------------------------------------
*/
/*
NeHe (nehe.gamedev.net) OpenGL tutorial series
GLUT port.in 2001 by milix (milix_gr@hotmail.com)
Most comments are from the original tutorials found in NeHe.
For VC++ users, create a Win32 Console project and link
the program with glut32.lib, glu32.lib, opengl32.lib
*/
#include <stdlib.h>
#include <stdio.h> // Standard C/C++ Input-Output
#include <math.h> // Math Functions (NEW)
#include <windows.h> // Standard Header For MSWindows Applications
#include <gl/glut.h> // The GL Utility Toolkit (GLUT) Header
#include <GL/glext.h>
#include <iostream>
#include "glinc.h"
#include "trackball.h"
#include "quaternion.h"
#include "camera.h"
#include "FreeImage.h"
#include "mitkBMPReader.h"
#include "mitkVolume.h"
#include "mitkPLYReader.h"
#include "mitkTriangleMesh.h"
void display();
// -----------------------------------------------------------------------
// Nehe
// -----------------------------------------------------------------------
#define TEXTURES_NUM 3 // We Have 3 Textures
#define PI_OVER_180 0.0174532925f
typedef struct _VERTEX {
float x, y, z;
float u, v;
} VERTEX;
typedef struct _TRIANGLE {
VERTEX vertex[3];
} TRIANGLE;
typedef struct _SECTOR {
int numtriangles;
TRIANGLE* triangle;
} SECTOR;
// Global Variables
bool g_gamemode; // GLUT GameMode ON/OFF
bool g_fullscreen; // Fullscreen Mode ON/OFF (When g_gamemode Is OFF)
bool g_blend = false; // Blending ON/OFF
GLfloat g_xpos = 0.f; // Position In X-Axis
GLfloat g_zpos = 0.f; // Position In Z-Axis
GLfloat g_yrot = 0.0f; // Y Rotation
GLfloat g_xspeed = 0.0f; // X Rotation Speed
GLfloat g_yspeed = 0.0f; // Y Rotation Speed
GLfloat g_z = 2.0f; // Depth Into The Screen
GLfloat g_heading = 0.0f;
GLfloat g_walkbias = 0.0f; // Gives The Illusion That We Are Walking (NEW)
GLfloat g_walkbiasangle = 0.0f; // Gives The Illusion That We Are Walking (NEW)
GLfloat g_lookupdown = 5.0f; // Look Position In The Z-Axis (NEW)
//GLuint g_filter = 1; // Which Filter To Use
GLuint g_texid[TEXTURES_NUM]; // Our Textures' Id List
SECTOR g_sector1; // Our Model Goes Here:
bool g_key[255]; // Lookup Table For Key's State (NEW)
float g_step_speed = 0.001f;
float g_rot_speed = 0.05f;
int g_window_size = 500;
// -----------------------------------------------------------------------
// cg course
// -----------------------------------------------------------------------
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmap;
GLenum g_face_target[6] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};
GLuint g_fbo; // Our handle to the FBO
GLuint g_depth_buffer; // Our handle to the depth render buffer
GLsizei g_cm_width;
GLsizei g_cm_height;
GLuint g_cm_texture_id[3];
GLuint g_texture_id[6];
float g_light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
float g_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float g_light_position[] = { 0.0f, 0.0f, 10.0f, 1.0f };
float g_light_direction[] = { 0.0f, 0.0f, -1.0f, 0.0f };
float g_light_rot = 0.0f;
float g_light_rot_speed = 2.0f;
float g_light_rot2 = 0.0f;
float g_light_rot_speed2 = 6.0f;
float g_material_ambient[] = { 1.0f, 0.57f, 0.04f, 1.0f };
float g_material_diffuse[] = { 1.0f, 0.57f, 0.04f, 1.0f };
float g_material_specular[] = { 0.33f, 0.33f, 0.52f, 1.0f };
float g_material_emission[] = { 0.0f, 0.0f, 0.0f, 0.0f };
float g_material_specular_power = 80.0f;
int g_texgen_mode = GL_REFLECTION_MAP;
int g_tex_wrap = GL_CLAMP_TO_EDGE;
unsigned int g_filter = 2; // Which Filter To Use
Cameraf g_cam;
Vectorf g_objpos(0.0f, 0.0f, 4.0f);
Vectorf g_campos(0.0f, 0.0f, 5.0f);
// -----------------------------------------------------------------------
// Nehe
// -----------------------------------------------------------------------
FIBITMAP* load_image(char const *filename, int flag = 0)
{
FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(filename, 0);
if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(filename);
if (fif == FIF_UNKNOWN) return false;
return FreeImage_Load(fif, filename, flag);
}
void readstr(FILE* f, char* string)
{
do {
fgets(string, 255, f);
} while ((string[0] == '/') || (string[0] == '\n'));
}
/// 通过world.txt的内容来构建场景
void setupWorld()
{
float x, y, z, u, v;
int numtriangles;
FILE *filein;
char oneline[255];
filein = fopen("data/test2/world.txt", "rt"); // File To Load World Data From
readstr(filein, oneline);
sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles);
g_sector1.triangle = new TRIANGLE[numtriangles];
g_sector1.numtriangles = numtriangles;
for (int loop = 0; loop < numtriangles; loop++) {
for (int vert = 0; vert < 3; vert++) {
readstr(filein, oneline);
sscanf(oneline, "%f %f %f %f %f %f %f", &x, &y, &z, &u, &v);
g_sector1.triangle[loop].vertex[vert].x = x * 10.0f;
g_sector1.triangle[loop].vertex[vert].y = y * 10.0f;
g_sector1.triangle[loop].vertex[vert].z = z * 10.0f;
g_sector1.triangle[loop].vertex[vert].u = u;
g_sector1.triangle[loop].vertex[vert].v = v;
}
}
fclose(filein);
return;
}
bool load_nehe_textures()
{
FIBITMAP *tdib = load_image("data/test2/rockwall.tga");
if (!tdib) return false;
bool status(false);
unsigned int bpp = FreeImage_GetBPP(tdib);
FIBITMAP *dib = tdib;
if (bpp != 24) dib = FreeImage_ConvertTo24Bits(tdib);
BYTE *bits = FreeImage_GetBits(dib);
unsigned int width = FreeImage_GetWidth(dib);
unsigned int height = FreeImage_GetHeight(dib);
GLenum format = FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR ? GL_BGR : GL_RGB;
RGBQUAD *pal = FreeImage_GetPalette(dib);
if (bits != 0 && width>0 && height>0) {
status = true; // Set The Status To TRUE
glGenTextures(TEXTURES_NUM, g_texid); // Create Three Textures
// Create Nearest Filtered Texture
glBindTexture(GL_TEXTURE_2D, g_texid[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, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, bits);
// Create Linear Filtered Texture
glBindTexture(GL_TEXTURE_2D, g_texid[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, bits);
// Create MipMapped Texture
glBindTexture(GL_TEXTURE_2D, g_texid[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, bits);
}
if (bpp != 24) FreeImage_Unload(dib);
FreeImage_Unload(tdib);
return status; // Return The Status
}
// Our Keyboard Handler For Special Keys (Like Arrow Keys And Function Keys)
void special_keys(int a_keys, int x, int y)
{
switch (a_keys) {
case GLUT_KEY_F1:
// We Can Switch Between Windowed Mode And Fullscreen Mode Only
if (!g_gamemode) {
g_fullscreen = !g_fullscreen; // Toggle g_fullscreen Flag
if (g_fullscreen) glutFullScreen(); // We Went In Fullscreen Mode
else glutReshapeWindow(500, 500); // We Went In Windowed Mode
}
break;
default:
g_key[a_keys] = true;
break;
}
}
// Our Keyboard Handler For Special Key Releases.
void special_keys_up(int key, int x, int y)
{
g_key[key] = false;
}
// Our Game Function. Check The User Input And Performs The Rendering
void game_function()
{
// Process User Input
if (g_key[GLUT_KEY_PAGE_UP]) {
g_z -= 0.02f;
g_lookupdown -= g_rot_speed;
}
if (g_key[GLUT_KEY_PAGE_DOWN]) {
g_z += 0.02f;
g_lookupdown += g_rot_speed;
}
if (g_key[GLUT_KEY_UP]) {
g_xpos -= (float)sin(g_heading*PI_OVER_180) * g_step_speed;
g_zpos -= (float)cos(g_heading*PI_OVER_180) * g_step_speed;
//if (g_walkbiasangle >= 359.0f) g_walkbiasangle = 0.0f;
//else g_walkbiasangle += 10;
//g_walkbias = (float)sin(g_walkbiasangle*PI_OVER_180) / 20.0f;
}
if (g_key[GLUT_KEY_DOWN]) {
g_xpos += (float)sin(g_heading*PI_OVER_180) * g_step_speed;
g_zpos += (float)cos(g_heading*PI_OVER_180) * g_step_speed;
//if (g_walkbiasangle <= 1.0f) g_walkbiasangle = 359.0f;
//else g_walkbiasangle -= 10;
//g_walkbias = (float)sin(g_walkbiasangle*PI_OVER_180) / 20.0f;
}
if (g_key[GLUT_KEY_RIGHT]) {
g_heading -= g_rot_speed;
g_yrot = g_heading;
}
if (g_key[GLUT_KEY_LEFT]) {
g_heading += g_rot_speed;
g_yrot = g_heading;
}
// Do The Rendering
display();
}
// -----------------------------------------------------------------------
// cg course
// -----------------------------------------------------------------------
void set_material()
{
GLenum face = GL_FRONT_AND_BACK;
//glMaterialfv(face, GL_AMBIENT, g_material_ambient);
glMaterialfv(face, GL_AMBIENT, g_material_diffuse);
glMaterialfv(face, GL_DIFFUSE, g_material_diffuse);
glMaterialfv(face, GL_SPECULAR, g_material_specular);
glMaterialfv(face, GL_EMISSION, g_material_emission);
glMaterialf(face, GL_SHININESS, g_material_specular_power);
}
bool is_extension_supported(const char *extension)
{
const GLubyte *extensions = NULL;
const GLubyte *start;
GLubyte *where, *terminator;
/* Extension names should not have spaces. */
where = (GLubyte *)strchr(extension, ' ');
if (where || *extension == '\0') return false;
extensions = glGetString(GL_EXTENSIONS);
/* It takes a bit of care to be fool-proof about parsing the
OpenGL extensions string. Don't be fooled by sub-strings,
etc. */
start = extensions;
for (;;)
{
where = (GLubyte *)strstr((const char *)start, extension);
if (!where)
break;
terminator = where + strlen(extension);
if (where == start || *(where - 1) == ' ')
if (*terminator == ' ' || *terminator == '\0')
return true;
start = terminator;
}
return false;
}
bool init_extfuncs()
{
if (!is_extension_supported("GL_EXT_framebuffer_object")) return false;
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffersEXT");
glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbufferEXT");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffersEXT");
glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbufferEXT");
glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffersEXT");
glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorageEXT");
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress("glGenerateMipmapEXT");
if (glGenFramebuffers == 0
|| glBindFramebuffer == 0
|| glDeleteFramebuffers == 0
|| glFramebufferRenderbuffer == 0
|| glFramebufferTexture2D == 0
|| glCheckFramebufferStatus == 0
|| glGenRenderbuffers == 0
|| glBindRenderbuffer == 0
|| glDeleteRenderbuffers == 0
|| glRenderbufferStorage == 0
|| glGenerateMipmap == 0)
{
std::cout << "glGenFramebuffers: " << glGenFramebuffers << std::endl
<< "glBindFramebuffer: " << glBindFramebuffer << std::endl
<< "glDeleteFramebuffers " << glDeleteFramebuffers << std::endl
<< "glFramebufferRenderbuffer " << glFramebufferRenderbuffer << std::endl
<< "glFramebufferTexture2D: " << glFramebufferTexture2D << std::endl
<< "glCheckFramebufferStatus: " << glCheckFramebufferStatus << std::endl
<< "glGenRenderbuffers: " << glGenRenderbuffers << std::endl
<< "glBindRenderbuffer: " << glBindRenderbuffer << std::endl
<< "glDeleteRenderbuffers: " << glDeleteRenderbuffers << std::endl
<< "glRenderbufferStorage: " << glRenderbufferStorage << std::endl
<< "glGenerateMipmap: " << glGenerateMipmap << std::endl;
return false;
}
return true;
}
bool init_fbo()
{
// Setup our FBO
glGenFramebuffers(1, &g_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, g_fbo);
// Create the render buffer for depth
glGenRenderbuffers(1, &g_depth_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, g_depth_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, g_cm_height, g_cm_height);
// Attach the depth render buffer to the FBO as it's depth attachment
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_depth_buffer);
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind the FBO for now
return true;
}
void update_texgen()
{
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, g_texgen_mode);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, g_texgen_mode);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, g_texgen_mode);
}
void update_wrap()
{
glBindTexture(GL_TEXTURE_CUBE_MAP, g_cm_texture_id[g_filter]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, g_tex_wrap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, g_tex_wrap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, g_tex_wrap);
}
// ----------------------------------------------------------------------
/// 袁胜:其实这个函数就是初始化cubemap的6个贴图,我也不知道怎么简化掉,
/// 所以就只留了一个cm_top.bmp
/// 你可以把这个路径改成你项目的路径,只拷贝这个cm_top
/// 如果能把整个这个函数简化掉更好了
bool load_cube_map_textures()
{
mitkBMPReader *reader = new mitkBMPReader();
reader->AddFileName("data/dyncubemap/cm_top.bmp");
reader->AddFileName("data/dyncubemap/cm_top.bmp");
reader->AddFileName("data/dyncubemap/cm_top.bmp");
reader->AddFileName("data/dyncubemap/cm_top.bmp");
reader->AddFileName("data/dyncubemap/cm_top.bmp");
reader->AddFileName("data/dyncubemap/cm_top.bmp");
bool success = reader->Run();
if (success)
{
mitkVolume *teximgs = reader->GetOutput();
g_cm_width = teximgs->GetWidth();
g_cm_height = teximgs->GetHeight();
glGenTextures(3, g_cm_texture_id);
for (int loop = 0; loop<6; loop++)
{
// Create Nearest Filtered Texture
glBindTexture(GL_TEXTURE_CUBE_MAP, g_cm_texture_id[0]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(g_face_target[loop], 0, GL_RGB, g_cm_width, g_cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, teximgs->GetSliceData(loop));
// Create Linear Filtered Texture
glBindTexture(GL_TEXTURE_CUBE_MAP, g_cm_texture_id[1]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(g_face_target[loop], 0, GL_RGB, g_cm_width, g_cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, teximgs->GetSliceData(loop));
// Create MipMapped Texture
glBindTexture(GL_TEXTURE_CUBE_MAP, g_cm_texture_id[2]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(g_face_target[loop], GL_RGB, g_cm_width, g_cm_height, GL_RGB, GL_UNSIGNED_BYTE, teximgs->GetSliceData(loop));
}
teximgs->Delete();
}
reader->Delete();
return success;
}
bool init()
{
if (!load_nehe_textures()) return false;
if (!load_cube_map_textures()) {
std::cout << "init: failed to load cube map textures!" << std::endl;
return false;
}
if (!init_extfuncs()) {
std::cout << "init: failed to initialize ext functions!" << std::endl;
return false;
}
if (!init_fbo()) {
std::cout << "init: failed to initialize frame buffer object!" << std::endl;
return false;
}
update_texgen();
update_wrap();
glEnable(GL_NORMALIZE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Pixel Storage Mode To Byte Alignment
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Set The Blending Function (NEW)
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background (CHANGED)
glClearDepth(1.0f); // Depth Buffer Setup
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
ShowCursor(FALSE); // WiN API - Hides The Mouse Pointer (NEW)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glLightfv(GL_LIGHT0, GL_AMBIENT, g_light_ambient); // Setup The Ambient Light
glLightfv(GL_LIGHT0, GL_DIFFUSE, g_light_diffuse); // Setup The Diffuse Light
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 1.0f);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 60.0f);
glEnable(GL_LIGHT0); // Enable Light One
setupWorld();
memset(g_key, 0, sizeof(g_key));
return true;
}
// -----------------------------------------------------------------------
/// 绘制整个场景的地方。
/// 整个大作业最核心的部分就是把dyncubemap例子中
/// 动态创建cubemap的函数(create_dynamic_cube_map)
/// 中绘制盒子的函数替换成这个
void draw_scene()
{
GLfloat x_m, y_m, z_m, u_m, v_m;
int numtriangles;
GLfloat xtrans = -g_xpos;
GLfloat ztrans = -g_zpos;
GLfloat ytrans = -g_walkbias - 0.25f;
GLfloat sceneroty = 360.0f - g_yrot;
glRotatef(g_lookupdown, 1.0f, 0, 0);
glRotatef(sceneroty, 0, 1.0f, 0);
glTranslatef(xtrans, ytrans, ztrans);
glBindTexture(GL_TEXTURE_2D, g_texid[g_filter]);
glEnable(GL_TEXTURE_2D);
numtriangles = g_sector1.numtriangles;
// Process Each Triangle
for (int loop_m = 0; loop_m < numtriangles; loop_m++)
{
glBegin(GL_TRIANGLES);
glNormal3f(0.0f, 0.0f, 1.0f);
x_m = g_sector1.triangle[loop_m].vertex[0].x;
y_m = g_sector1.triangle[loop_m].vertex[0].y;
z_m = g_sector1.triangle[loop_m].vertex[0].z;
u_m = g_sector1.triangle[loop_m].vertex[0].u;
v_m = g_sector1.triangle[loop_m].vertex[0].v;
glTexCoord2f(u_m, v_m); glVertex3f(x_m, y_m, z_m);
x_m = g_sector1.triangle[loop_m].vertex[1].x;
y_m = g_sector1.triangle[loop_m].vertex[1].y;
z_m = g_sector1.triangle[loop_m].vertex[1].z;
u_m = g_sector1.triangle[loop_m].vertex[1].u;
v_m = g_sector1.triangle[loop_m].vertex[1].v;
glTexCoord2f(u_m, v_m); glVertex3f(x_m, y_m, z_m);
x_m = g_sector1.triangle[loop_m].vertex[2].x;
y_m = g_sector1.triangle[loop_m].vertex[2].y;
z_m = g_sector1.triangle[loop_m].vertex[2].z;
u_m = g_sector1.triangle[loop_m].vertex[2].u;
v_m = g_sector1.triangle[loop_m].vertex[2].v;
glTexCoord2f(u_m, v_m); glVertex3f(x_m, y_m, z_m);
glEnd();
}
}
/// 动态创建cubemap
void create_dynamic_cube_map()
{
// First we bind the FBO so we can render to it
glBindFramebuffer(GL_FRAMEBUFFER, g_fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
// Save the view port and set it to the size of the texture
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, g_cm_width, g_cm_height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//MUST USE 90 degree FOV!
g_cam.Perspective(90.0f, 1.0f, 0.1f, 5000.0f);
glMatrixMode(GL_MODELVIEW);
float facepos[6][6] = {
{ 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f },
{ -5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f },
{ 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 1.0f },
{ 0.0f, -5.0f, 0.0f, 0.0f, 0.0f, -1.0f },
{ 0.0f, 0.0f, 5.0f, 0.0f, -1.0f, 0.0f },
{ 0.0f, 0.0f, -5.0f, 0.0f, -1.0f, 0.0f }
};
glBindTexture(GL_TEXTURE_CUBE_MAP, g_cm_texture_id[g_filter]);
for (int face = 0; face<6; ++face) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, g_face_target[face], g_cm_texture_id[g_filter], 0);
Vectorf up(facepos[face][3], facepos[face][4], facepos[face][5]);
g_campos.ele[0] = facepos[face][0];
g_campos.ele[1] = facepos[face][1];
g_campos.ele[2] = facepos[face][2];
g_campos.ele[3] = 1.0f;
g_campos += g_objpos;
g_campos.ele[3] = 1.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
g_cam.LookAt(g_objpos.ele[0], g_objpos.ele[1], g_objpos.ele[2], g_campos.ele[0], g_campos.ele[1], g_campos.ele[2], up.ele[0], up.ele[1], up.ele[2]);
glLightfv(GL_LIGHT0, GL_POSITION, g_light_position); // Position The Light
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, g_light_direction);
glPushMatrix();
draw_scene(); /// 这里是关键
glPopMatrix();
glPopMatrix();
glFlush();
}
if (g_filter == 2) glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
// Restore old view port and set rendering back to default frame buffer
glPopAttrib();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
create_dynamic_cube_map();
g_campos.ele[0] = 0.0f;
g_campos.ele[1] = 0.0f;
g_campos.ele[2] = 5.0f;
g_campos.ele[3] = 1.0f;
Vectorf up(0.0f, 1.0f, 0.0f);
g_campos += g_objpos;
g_campos.ele[3] = 1.0f;
g_cam.LookAt(g_campos.ele[0], g_campos.ele[1], g_campos.ele[2], g_objpos.ele[0], g_objpos.ele[1], g_objpos.ele[2], up.ele[0], up.ele[1], up.ele[2]);
glLightfv(GL_LIGHT0, GL_POSITION, g_light_position); // Position The Light
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, g_light_direction);
glPushMatrix();
glDisable(GL_LIGHTING);
g_material_diffuse[0] = 0.9f;
g_material_diffuse[1] = 0.9f;
g_material_diffuse[2] = 0.9f;
set_material();
glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S (NEW)
glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T (NEW)
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_CUBE_MAP);
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(1, 50, 50);
glPopMatrix();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_CUBE_MAP);
glEnable(GL_LIGHTING);
glPushMatrix();
draw_scene();
glPopMatrix();
glutSwapBuffers();
g_light_rot += g_light_rot_speed;
if (g_light_rot > 360.0f) g_light_rot = 0.0f;
g_light_rot2 += g_light_rot_speed2;
if (g_light_rot2 > 360.0f) g_light_rot2 = 0.0f;
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio And Set The Clipping Volume
if (h == 0) h = 1;
gluPerspective(45.0f, (float)w / (float)h, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
}
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("参考大作业2");
if (!init()) return 1;
glutKeyboardFunc(keyboard);
glutSpecialFunc(special_keys);
glutSpecialUpFunc(special_keys_up);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(game_function);
glutMainLoop();
return 0;
}
NUMPOLLIES 36
// Floor 1
-3.0 0.0 -3.0 0.0 6.0
-3.0 0.0 3.0 0.0 0.0
3.0 0.0 3.0 6.0 0.0
-3.0 0.0 -3.0 0.0 6.0
3.0 0.0 -3.0 6.0 6.0
3.0 0.0 3.0 6.0 0.0
// Ceiling 1
-3.0 1.0 -3.0 0.0 6.0
-3.0 1.0 3.0 0.0 0.0
3.0 1.0 3.0 6.0 0.0
-3.0 1.0 -3.0 0.0 6.0
3.0 1.0 -3.0 6.0 6.0
3.0 1.0 3.0 6.0 0.0
// A1
-2.0 1.0 -2.0 0.0 1.0
-2.0 0.0 -2.0 0.0 0.0
-0.5 0.0 -2.0 1.5 0.0
-2.0 1.0 -2.0 0.0 1.0
-0.5 1.0 -2.0 1.5 1.0
-0.5 0.0 -2.0 1.5 0.0
// A2
2.0 1.0 -2.0 2.0 1.0
2.0 0.0 -2.0 2.0 0.0
0.5 0.0 -2.0 0.5 0.0
2.0 1.0 -2.0 2.0 1.0
0.5 1.0 -2.0 0.5 1.0
0.5 0.0 -2.0 0.5 0.0
// B1
-2.0 1.0 2.0 2.0 1.0
-2.0 0.0 2.0 2.0 0.0
-0.5 0.0 2.0 0.5 0.0
-2.0 1.0 2.0 2.0 1.0
-0.5 1.0 2.0 0.5 1.0
-0.5 0.0 2.0 0.5 0.0
// B2
2.0 1.0 2.0 2.0 1.0
2.0 0.0 2.0 2.0 0.0
0.5 0.0 2.0 0.5 0.0
2.0 1.0 2.0 2.0 1.0
0.5 1.0 2.0 0.5 1.0
0.5 0.0 2.0 0.5 0.0
// C1
-2.0 1.0 -2.0 0.0 1.0
-2.0 0.0 -2.0 0.0 0.0
-2.0 0.0 -0.5 1.5 0.0
-2.0 1.0 -2.0 0.0 1.0
-2.0 1.0 -0.5 1.5 1.0
-2.0 0.0 -0.5 1.5 0.0
// C2
-2.0 1.0 2.0 2.0 1.0
-2.0 0.0 2.0 2.0 0.0
-2.0 0.0 0.5 0.5 0.0
-2.0 1.0 2.0 2.0 1.0
-2.0 1.0 0.5 0.5 1.0
-2.0 0.0 0.5 0.5 0.0
// D1
2.0 1.0 -2.0 0.0 1.0
2.0 0.0 -2.0 0.0 0.0
2.0 0.0 -0.5 1.5 0.0
2.0 1.0 -2.0 0.0 1.0
2.0 1.0 -0.5 1.5 1.0
2.0 0.0 -0.5 1.5 0.0
// D2
2.0 1.0 2.0 2.0 1.0
2.0 0.0 2.0 2.0 0.0
2.0 0.0 0.5 0.5 0.0
2.0 1.0 2.0 2.0 1.0
2.0 1.0 0.5 0.5 1.0
2.0 0.0 0.5 0.5 0.0
// Upper hallway - L
-0.5 1.0 -3.0 0.0 1.0
-0.5 0.0 -3.0 0.0 0.0
-0.5 0.0 -2.0 1.0 0.0
-0.5 1.0 -3.0 0.0 1.0
-0.5 1.0 -2.0 1.0 1.0
-0.5 0.0 -2.0 1.0 0.0
// Upper hallway - R
0.5 1.0 -3.0 0.0 1.0
0.5 0.0 -3.0 0.0 0.0
0.5 0.0 -2.0 1.0 0.0
0.5 1.0 -3.0 0.0 1.0
0.5 1.0 -2.0 1.0 1.0
0.5 0.0 -2.0 1.0 0.0
// Lower hallway - L
-0.5 1.0 3.0 0.0 1.0
-0.5 0.0 3.0 0.0 0.0
-0.5 0.0 2.0 1.0 0.0
-0.5 1.0 3.0 0.0 1.0
-0.5 1.0 2.0 1.0 1.0
-0.5 0.0 2.0 1.0 0.0
// Lower hallway - R
0.5 1.0 3.0 0.0 1.0
0.5 0.0 3.0 0.0 0.0
0.5 0.0 2.0 1.0 0.0
0.5 1.0 3.0 0.0 1.0
0.5 1.0 2.0 1.0 1.0
0.5 0.0 2.0 1.0 0.0
// Left hallway - Lw
-3.0 1.0 0.5 1.0 1.0
-3.0 0.0 0.5 1.0 0.0
-2.0 0.0 0.5 0.0 0.0
-3.0 1.0 0.5 1.0 1.0
-2.0 1.0 0.5 0.0 1.0
-2.0 0.0 0.5 0.0 0.0
// Left hallway - Hi
-3.0 1.0 -0.5 1.0 1.0
-3.0 0.0 -0.5 1.0 0.0
-2.0 0.0 -0.5 0.0 0.0
-3.0 1.0 -0.5 1.0 1.0
-2.0 1.0 -0.5 0.0 1.0
-2.0 0.0 -0.5 0.0 0.0
// Right hallway - Lw
3.0 1.0 0.5 1.0 1.0
3.0 0.0 0.5 1.0 0.0
2.0 0.0 0.5 0.0 0.0
3.0 1.0 0.5 1.0 1.0
2.0 1.0 0.5 0.0 1.0
2.0 0.0 0.5 0.0 0.0
// Right hallway - Hi
3.0 1.0 -0.5 1.0 1.0
3.0 0.0 -0.5 1.0 0.0
2.0 0.0 -0.5 0.0 0.0
3.0 1.0 -0.5 1.0 1.0
2.0 1.0 -0.5 0.0 1.0
2.0 0.0 -0.5 0.0 0.0