engine.cpp
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:38k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* 3D Engine
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include "pbuffer.h"
  20. #include "console.h"
  21. #include "frustum.h"
  22. #include "meshvbo.h"
  23. #include "bsp.h"
  24. #include "position.h"
  25. #include "object.h"
  26. #include "light.h"
  27. #include "fog.h"
  28. #include "mirror.h"
  29. #include "shader.h"
  30. #include "texture.h"
  31. #include "material.h"
  32. #include "physic.h"
  33. #include "map.h"
  34. #include "engine.h"
  35. char *Engine::vendor;
  36. char *Engine::renderer;
  37. char *Engine::version;
  38. char *Engine::extensions;
  39. int Engine::screen_width = 1024;
  40. int Engine::screen_height = 512;
  41. int Engine::screen_multisample = 0;
  42. PBuffer *Engine::screen;
  43. Texture *Engine::screen_texture;
  44. Material *Engine::screen_material;
  45. Console *Engine::console;
  46. Position Engine::camera;
  47. Frustum *Engine::frustum;
  48. Bsp *Engine::bsp;
  49. int Engine::num_objects;
  50. Object **Engine::objects;
  51. int Engine::num_lights;
  52. Light **Engine::lights;
  53. int Engine::num_visible_lights;
  54. Light **Engine::visible_lights;
  55. Light *Engine::current_light;
  56. int Engine::num_fogs;
  57. Fog **Engine::fogs;
  58. int Engine::num_visible_fogs;
  59. Fog **Engine::visible_fogs;
  60. Fog *Engine::current_fog;
  61. int Engine::num_mirrors;
  62. Mirror **Engine::mirrors;
  63. int Engine::num_visible_mirrors;
  64. Mirror **Engine::visible_mirrors;
  65. Mirror *Engine::current_mirror;
  66. GLuint Engine::query_id;
  67. Mesh *Engine::sphere_mesh;
  68. Shader *Engine::shadow_volume_shader;
  69. float Engine::time;
  70. vec4 Engine::light;
  71. vec4 Engine::light_color;
  72. vec4 Engine::fog_color;
  73. int Engine::viewport[4];
  74. mat4 Engine::projection;
  75. mat4 Engine::modelview;
  76. mat4 Engine::imodelview;
  77. mat4 Engine::transform;
  78. mat4 Engine::itransform;
  79. float Engine::ifps;
  80. int Engine::frame;
  81. int Engine::num_triangles;
  82. int Engine::have_occlusion;
  83. int Engine::have_stencil_two_side;
  84. int Engine::wareframe_toggle;
  85. int Engine::scissor_toggle;
  86. int Engine::shadows_toggle;
  87. int Engine::show_shadows_toggle;
  88. int Engine::fog_toggle;
  89. int Engine::mirror_toggle;
  90. int Engine::physic_toggle;
  91. std::vector<char*> Engine::path;
  92. std::vector<char*> Engine::defines;
  93. int Engine::texture_filter = Texture::LINEAR_MIPMAP_LINEAR;
  94. std::map<std::string,Shader*> Engine::shaders;
  95. std::map<std::string,Texture*> Engine::textures;
  96. std::map<std::string,Material*> Engine::materials;
  97. std::map<std::string,Mesh*> Engine::meshes;
  98. void (*Engine::extern_load)(void*) = NULL;
  99. void *Engine::extern_load_data;
  100. int Engine::stderr_fd;
  101. /*****************************************************************************/
  102. /*                                                                           */
  103. /* console commands                                                          */
  104. /*                                                                           */
  105. /*****************************************************************************/
  106. static void define(int argc,char **argv,void*) {
  107. if(argc == 1) {
  108. Engine::console->printf("defines: ");
  109. for(int i = 0; i < (int)Engine::defines.size(); i++) {
  110. Engine::console->printf("%s%s",Engine::defines[i],i == (int)Engine::defines.size() - 1 ? "" : ", ");
  111. }
  112. Engine::console->printf("n");
  113. } else {
  114. for(int i = 1; i < argc; i++) Engine::define(argv[i]);
  115. }
  116. }
  117. static void undef(int argc,char **argv,void*) {
  118. if(argc == 1) Engine::console->printf("undef: missing argumentn");
  119. else {
  120. for(int i = 1; i < argc; i++) Engine::undef(argv[i]);
  121. }
  122. }
  123. static void load(int argc,char **argv,void*) {
  124. if(argc == 1) Engine::console->printf("load: missing argumentn");
  125. else Engine::load(argv[1]);
  126. }
  127. static void reload(int argc,char **argv,void*) {
  128. if(argc == 1) Engine::reload();
  129. else {
  130. if(!strcmp(argv[1],"shaders")) Engine::reload_shaders();
  131. else if(!strcmp(argv[1],"textures")) Engine::reload_textures();
  132. else if(!strcmp(argv[1],"materials")) Engine::reload_materials();
  133. else Engine::console->printf("reload: unknown argument (shaders, textures, materials)n");
  134. }
  135. }
  136. static void status(int,char**,void*) {
  137. Engine::console->printf("lights: %dnfogs: %dnmirrors: %dnobjects: %dn",
  138. Engine::num_lights,Engine::num_fogs,Engine::num_mirrors,Engine::num_objects);
  139. }
  140. static void extensions(int,char**,void*) {
  141. Engine::console->printf("%sn",Engine::extensions);
  142. }
  143. /*****************************************************************************/
  144. /*                                                                           */
  145. /* Engine                                                                    */
  146. /*                                                                           */
  147. /*****************************************************************************/
  148. /*
  149.  */
  150. int Engine::init(const char *config) {
  151. // bind system stderr to Engine::console
  152. #ifndef _WIN32
  153. int fd[2];
  154. pipe(fd);
  155. stderr_fd = fd[0];
  156. fcntl(stderr_fd,F_SETFL,O_NONBLOCK);
  157. stderr = fdopen(fd[1],"w");
  158. setbuf(stderr,NULL);
  159. #else
  160. HANDLE read,write;
  161. SECURITY_ATTRIBUTES security;
  162. security.nLength = sizeof(security);
  163. security.bInheritHandle = TRUE;
  164. security.lpSecurityDescriptor = NULL;
  165. CreatePipe(&read,&write,&security,1024 - 1);
  166. DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT;
  167. SetNamedPipeHandleState(read,&mode,NULL,NULL);
  168. SetNamedPipeHandleState(write,&mode,NULL,NULL);
  169. stderr_fd = _open_osfhandle((long)read,O_RDONLY | O_BINARY);
  170. FILE *file = fdopen(_open_osfhandle((long)write,O_WRONLY | O_BINARY),"w");
  171. *stderr = *file;
  172. setbuf(stderr,NULL);
  173. #endif
  174. // load config
  175. if(config) {
  176. FILE *file = fopen(config,"rb");
  177. if(!file) fprintf(stderr,"Engine::init(): error open "%s" filen",config);
  178. else {
  179. char buf[1024];
  180. while(fscanf(file,"%s",buf) == 1) {
  181. if(buf[0] == '#' || (buf[0] == '/' && buf[1] == '/')) while(fread(buf,1,1,file) == 1 && buf[0] != 'n');
  182. else if(!strcmp(buf,"screen_width")) fscanf(file,"%d",&screen_width);
  183. else if(!strcmp(buf,"screen_height")) fscanf(file,"%d",&screen_height);
  184. else if(!strcmp(buf,"screen_multisample")) fscanf(file,"%d",&screen_multisample);
  185. else if(!strcmp(buf,"texture_filter")) {
  186. texture_filter = 0;
  187. fgets(buf,sizeof(buf),file);
  188. char *s = buf;
  189. while(*s) {
  190. if(isalpha(*s)) {
  191. char *d = s;
  192. while(*d && !strchr(" tn",*d)) d++;
  193. if(*d) *d++ = '';
  194. if(!strcmp(s,"nearest")) texture_filter |= Texture::NEAREST;
  195. else if(!strcmp(s,"linear")) texture_filter |= Texture::LINEAR;
  196. else if(!strcmp(s,"nearest_mipmap_nearest")) texture_filter |= Texture::NEAREST_MIPMAP_NEAREST;
  197. else if(!strcmp(s,"linear_mipmap_nearest")) texture_filter |= Texture::LINEAR_MIPMAP_NEAREST;
  198. else if(!strcmp(s,"linear_mipmap_linear")) texture_filter |= Texture::LINEAR_MIPMAP_LINEAR;
  199. else if(!strcmp(s,"anisotropy_1")) texture_filter |= Texture::ANISOTROPY_1;
  200. else if(!strcmp(s,"anisotropy_2")) texture_filter |= Texture::ANISOTROPY_2;
  201. else if(!strcmp(s,"anisotropy_4")) texture_filter |= Texture::ANISOTROPY_4;
  202. else if(!strcmp(s,"anisotropy_8")) texture_filter |= Texture::ANISOTROPY_8;
  203. else if(!strcmp(s,"anisotropy_16")) texture_filter |= Texture::ANISOTROPY_16;
  204. s = d;
  205. }
  206. else if(strchr(" t",*s)) s++;
  207. else {
  208. fprintf(stderr,"Engine::init(): unknown token "%s" in "%s" filen",s,config);
  209. break;
  210. }
  211. }
  212. }
  213. else fprintf(stderr,"Engine::init(): unknown token "%s" in "%s" filen",buf,config);
  214. }
  215. }
  216. }
  217. // init OpenGL extensions win32 only
  218. #ifdef _WIN32
  219. glext_init();
  220. #endif
  221. // console
  222. FILE *log = fopen(ENGINE_LOG_NAME,"wb");
  223. console = new Console(findFile(ENGINE_FONT_NAME),log);
  224. console->printf(1,1,1,"3D Enginenhttp://frustum.orgnn");
  225. // renderer abilities
  226. vendor = (char*)glGetString(GL_VENDOR);
  227. renderer = (char*)glGetString(GL_RENDERER);
  228. version = (char*)glGetString(GL_VERSION);
  229. extensions = (char*)glGetString(GL_EXTENSIONS);
  230. console->printf("vendor: %snrenderer: %snversion: %snn",vendor,renderer,version);
  231. have_occlusion = 0;
  232. have_stencil_two_side = 0;
  233. wareframe_toggle = 0;
  234. scissor_toggle = 1;
  235. shadows_toggle = 1;
  236. show_shadows_toggle = 0;
  237. fog_toggle = 1;
  238. mirror_toggle = 1;
  239. physic_toggle = 1;
  240. if(!strstr(extensions,"GL_ARB_vertex_program")) { // fatal error
  241. console->printf("can`t find GL_ARB_vertex_program extension");
  242. return 0;
  243. }
  244. if(strstr(extensions,"GL_ARB_occlusion_query")) {
  245. have_occlusion = 1;
  246. console->printf("find GL_ARB_occlusion_query extensionn");
  247. }
  248. if(strstr(extensions,"GL_EXT_stencil_two_side")) {
  249. have_stencil_two_side = 1;
  250. console->printf("find GL_EXT_stencil_two_side extensionn");
  251. }
  252. if(strstr(extensions,"GL_NV_depth_clamp")) {
  253. define("DEPTH_CLAMP");
  254. console->printf("find GL_NV_depth_clamp extensionn");
  255. }
  256. if(strstr(extensions,"GL_NV_fragment_program")) { // nv3x cards
  257. define("NV3X");
  258. define("TEYLOR");
  259. define("OFFSET");
  260. define("HORIZON");
  261. console->printf("using GL_NV_fragment_program shaders coden");
  262. }
  263. else if(strstr(extensions,"GL_ARB_fragment_program")) { // radeons
  264. define("RADEON");
  265. define("TEYLOR");
  266. define("OFFSET");
  267. define("HORIZON");
  268. console->printf("using GL_ARB_fragment_program shaders coden");
  269. }
  270. else if(strstr(extensions,"GL_ARB_texture_env_combine")) { // hm
  271. define("VERTEX");
  272. if(!isDefine("DEPTH_CLAMP")) shadows_toggle = 0;
  273. fog_toggle = 0;
  274. mirror_toggle = 0;
  275. console->printf("using GL_ARB_texture_env_combine "shaders" coden");
  276. } else {
  277. console->printf("pls upgrade you video card...n");
  278. return 0;
  279. }
  280. console->addBool("wareframe",&wareframe_toggle);
  281. console->addBool("scissor",&scissor_toggle);
  282. console->addBool("shadows",&shadows_toggle);
  283. console->addBool("show_shadows",&show_shadows_toggle);
  284. console->addBool("fog",&fog_toggle);
  285. console->addBool("mirror",&mirror_toggle);
  286. console->addBool("physic",&physic_toggle);
  287. console->addCommand("define",::define,NULL);
  288. console->addCommand("undef",::undef,NULL);
  289. console->addCommand("load",::load,NULL);
  290. console->addCommand("reload",::reload,NULL);
  291. console->addCommand("extensions",::extensions,NULL);
  292. // screen
  293. if(screen_multisample == 1) screen = new PBuffer(screen_width,screen_height,PBuffer::RGB | PBuffer::DEPTH | PBuffer::STENCIL | PBuffer::MULTISAMPLE_2);
  294. else if(screen_multisample == 2) screen = new PBuffer(screen_width,screen_height,PBuffer::RGB | PBuffer::DEPTH | PBuffer::STENCIL | PBuffer::MULTISAMPLE_4);
  295. else screen = new PBuffer(screen_width,screen_height,PBuffer::RGB | PBuffer::DEPTH | PBuffer::STENCIL);
  296. screen->enable();
  297. glEnable(GL_DEPTH_TEST);
  298. glEnable(GL_CULL_FACE);
  299. screen->disable();
  300. screen_texture = new Texture(screen_width,screen_height,Texture::TEXTURE_2D,Texture::RGB | Texture::CLAMP | Texture::LINEAR);
  301. screen_material = loadMaterial(ENGINE_SCREEN_MATERIAL);
  302. // create new objects
  303. if(!frustum) frustum = new Frustum;
  304. bsp = NULL;
  305. num_objects = 0;
  306. objects = NULL;
  307. num_lights = 0;
  308. lights = NULL;
  309. num_visible_lights = 0;
  310. lights = NULL;
  311. num_fogs = 0;
  312. fogs = NULL;
  313. num_visible_fogs = 0;
  314. visible_fogs = NULL;
  315. num_mirrors = 0;
  316. mirrors = NULL;
  317. num_visible_mirrors = 0;
  318. visible_mirrors = NULL;
  319. glGenQueriesARB(1,&query_id);
  320. sphere_mesh = loadMesh(ENGINE_SPHERE_MESH);
  321. shadow_volume_shader = loadShader(ENGINE_SHADOW_VOLUME_SHADER);
  322. time = 0;
  323. frame = 0;
  324. console->printf("ninit okn");
  325. return 1;
  326. }
  327. /*
  328.  */
  329. void Engine::clear() {
  330. // objects
  331. if(num_objects) {
  332. for(int i = 0; i < num_objects; i++) delete objects[i];
  333. delete objects;
  334. objects = NULL;
  335. num_objects = 0;
  336. }
  337. // lights
  338. if(num_lights) {
  339. for(int i = 0; i < num_lights; i++) delete lights[i];
  340. delete lights;
  341. lights = NULL;
  342. num_lights = 0;
  343. delete visible_lights;
  344. visible_lights = NULL;
  345. num_visible_lights = 0;
  346. }
  347. // fogs
  348. if(num_fogs) {
  349. for(int i = 0; i < num_fogs; i++) delete fogs[i];
  350. delete fogs;
  351. fogs = NULL;
  352. num_fogs = 0;
  353. delete visible_fogs;
  354. visible_fogs = NULL;
  355. num_visible_fogs = 0;
  356. }
  357. // mirrors
  358. if(num_mirrors) {
  359. for(int i = 0; i < num_fogs; i++) delete mirrors[i];
  360. delete mirrors;
  361. mirrors = NULL;
  362. num_mirrors = 0;
  363. delete  visible_mirrors;
  364. visible_mirrors = NULL;
  365. num_visible_mirrors = 0;
  366. }
  367. // bsp at the end
  368. if(bsp) delete bsp;
  369. bsp = NULL;
  370. // shaders
  371. std::map<std::string,Shader*>::iterator shaders_it;
  372. for(shaders_it = shaders.begin(); shaders_it != shaders.end(); shaders_it++) delete shaders_it->second;
  373. shaders.clear();
  374. // textures
  375. std::map<std::string,Texture*>::iterator textures_it;
  376. for(textures_it = textures.begin(); textures_it != textures.end(); textures_it++) delete textures_it->second;
  377. textures.clear();
  378. // materials
  379. std::map<std::string,Material*>::iterator materials_it;
  380. for(materials_it = materials.begin(); materials_it != materials.end(); materials_it++) delete materials_it->second;
  381. materials.clear();
  382. // meshes
  383. std::map<std::string,Mesh*>::iterator meshes_it;
  384. for(meshes_it = meshes.begin(); meshes_it != meshes.end(); meshes_it++) delete meshes_it->second;
  385. meshes.clear();
  386. screen_material = loadMaterial(ENGINE_SCREEN_MATERIAL);
  387. sphere_mesh = loadMesh(ENGINE_SPHERE_MESH);
  388. shadow_volume_shader = loadShader(ENGINE_SHADOW_VOLUME_SHADER);
  389. }
  390. /*****************************************************************************/
  391. /*                                                                           */
  392. /* loaders                                                                   */
  393. /*                                                                           */
  394. /*****************************************************************************/
  395. /* support '|' as "OR" operation, '?' as ANY symbol and '*' as ANY string
  396.  */
  397. int Engine::match(const char *mask,const char *name) {
  398. char *m = (char*)mask;
  399. char *n = (char*)name;
  400. int match = 1;
  401. while(1) {
  402. if((match && *m == '*')|| *m == '') break;
  403. if(*m == '|') {
  404. if(match) break;
  405. m++;
  406. n = (char*)name;
  407. match = 1;
  408. } else {
  409. if(*m != '?' && *m != *n) match = 0;
  410. if(*n) n++;
  411. m++;
  412. }
  413. }
  414. return match;
  415. }
  416. /*
  417.  */
  418. void Engine::addPath(const char *path) {
  419. char *s = (char*)path;
  420. while(1) {
  421. char *p = new char[strlen(s) + 1];
  422. char *d = p;
  423. while(*s != '' && *s != ',') *d++ = *s++;
  424. *d = '';
  425. Engine::path.push_back(p);
  426. if(*s == '') break;
  427. else s++;
  428. }
  429. }
  430. const char *Engine::findFile(const char *name) {
  431. static char buf[1024];
  432. for(char *s = (char*)name; *s != ''; s++) {
  433. if(*s == '%' && *(s + 1) == 's') {
  434. static char complex_name[1024];
  435. sprintf(complex_name,name,"px");
  436. s = (char*)findFile(complex_name);
  437. if(strcmp(s,name)) {
  438. for(s = buf + strlen(buf); s > buf; s--) {
  439. if(*s == 'x' && *(s - 1) == 'p') {
  440. *s = 's';
  441. *(s - 1) = '%';
  442. break;
  443. }
  444. }
  445. return buf; // hm
  446. }
  447. break;
  448. }
  449. }
  450. for(int i = (int)path.size() - 1; i >= -1; i--) {
  451. if(i == -1) sprintf(buf,"%s",name);
  452. else sprintf(buf,"%s%s",path[i],name);
  453. FILE *file = fopen(buf,"rb");
  454. if(file) {
  455. fclose(file);
  456. return buf;
  457. }
  458. }
  459. fprintf(stderr,"Engine::findFile(): can`t find "%s" filen",name);
  460. return name;
  461. }
  462. /*
  463.  */
  464. void Engine::define(const char *define) {
  465. int i;
  466. for(i = 0; i < (int)defines.size(); i++) if(!strcmp(defines[i],define)) break;
  467. if(i == (int)defines.size()) {
  468. char *d = new char[strlen(define) + 1];
  469. strcpy(d,define);
  470. defines.push_back(d);
  471. }
  472. }
  473. void Engine::undef(const char *define) {
  474. for(int i = 0; i < (int)defines.size(); i++) {
  475. if(!strcmp(defines[i],define)) {
  476. delete defines[i];
  477. defines.erase(defines.begin() + i);
  478. }
  479. }
  480. }
  481. int Engine::isDefine(const char *define) {
  482. for(int i = 0; i < (int)defines.size(); i++) if(!strcmp(defines[i],define)) return 1;
  483. return 0;
  484. }
  485. /*
  486.  */
  487. void Engine::load(const char *name) {
  488. clear();
  489. Map::load(findFile(name));
  490. if(extern_load) extern_load(extern_load_data);
  491. console->printf("load "%s" okn",name);
  492. }
  493. /*
  494.  */
  495. Shader *Engine::loadShader(const char *name) {
  496. std::map<std::string,Shader*>::iterator it = shaders.find(name);
  497. if(it == shaders.end()) {
  498. Shader *shader = new Shader(findFile(name));
  499. shaders[name] = shader;
  500. return shader;
  501. }
  502. return it->second;
  503. }
  504. Texture *Engine::loadTexture(const char *name,GLuint target,int flag) {
  505. std::map<std::string,Texture*>::iterator it = textures.find(name);
  506. if(it == textures.end()) {
  507. Texture *texture = new Texture(findFile(name),target,flag);
  508. textures[name] = texture;
  509. return texture;
  510. }
  511. return it->second;
  512. }
  513. Material *Engine::loadMaterial(const char *name) {
  514. std::map<std::string,Material*>::iterator it = materials.find(name);
  515. if(it == materials.end()) {
  516. Material *material = new Material(findFile(name));
  517. materials[name] = material;
  518. return material;
  519. }
  520. return it->second;
  521. }
  522. Mesh *Engine::loadMesh(const char *name) {
  523. std::map<std::string,Mesh*>::iterator it = meshes.find(name);
  524. if(it == meshes.end()) {
  525. Mesh *mesh = new MeshVBO(findFile(name));
  526. meshes[name] = mesh;
  527. return mesh;
  528. }
  529. return it->second;
  530. }
  531. /* reload functions
  532.  */
  533. void Engine::reload() {
  534. reload_shaders();
  535. reload_textures();
  536. reload_materials();
  537. }
  538. void Engine::reload_shaders() {
  539. std::map<std::string,Shader*>::iterator it;
  540. for(it = shaders.begin(); it != shaders.end(); it++) {
  541. it->second->~Shader();
  542. it->second->load(findFile(it->first.c_str()));
  543. }
  544. }
  545. void Engine::reload_textures() {
  546. std::map<std::string,Texture*>::iterator it;
  547. for(it = textures.begin(); it != textures.end(); it++) {
  548. it->second->~Texture();
  549. it->second->load(findFile(it->first.c_str()),it->second->target,it->second->flag);
  550. }
  551. }
  552. void Engine::reload_materials() {
  553. std::map<std::string,Material*>::iterator it;
  554. for(it = materials.begin(); it != materials.end(); it++) {
  555. it->second->~Material();
  556. it->second->load(findFile(it->first.c_str()));
  557. }
  558. }
  559. void Engine::setExternLoad(void (*func)(void*),void *data) {
  560. extern_load = func;
  561. extern_load_data = data;
  562. }
  563. /* objects managment
  564.  */
  565. void Engine::addObject(Object *object) {
  566. if(num_objects % ENGINE_GAP_SIZE == 0) {
  567. Object **objects = new Object*[num_objects + ENGINE_GAP_SIZE];
  568. for(int i = 0; i < num_objects; i++) objects[i] = Engine::objects[i];
  569. if(Engine::objects) delete Engine::objects;
  570. Engine::objects = objects;
  571. }
  572. object->update(0.0);
  573. objects[num_objects++] = object;
  574. }
  575. void Engine::removeObject(Object *object) {
  576. if(object->pos.sector != -1) Bsp::sectors[object->pos.sector].removeObject(object);
  577. for(int i = 0; i < num_objects; i++) {
  578. if(objects[i] == object) {
  579. num_objects--;
  580. for(; i < num_objects; i++) objects[i] = objects[i + 1];
  581. return;
  582. }
  583. }
  584. }
  585. /*
  586.  */
  587. void Engine::addLight(Light *light) {
  588. if(num_lights % ENGINE_GAP_SIZE == 0) {
  589. Light **lights = new Light*[num_lights + ENGINE_GAP_SIZE];
  590. for(int i = 0; i < num_lights; i++) lights[i] = Engine::lights[i];
  591. if(Engine::lights) delete Engine::lights;
  592. Engine::lights = lights;
  593. if(visible_lights) delete visible_lights;
  594. visible_lights = new Light*[num_lights + ENGINE_GAP_SIZE];
  595. }
  596. light->update(0.0);
  597. lights[num_lights++] = light;
  598. }
  599. void Engine::removeLight(Light *light) {
  600. for(int i = 0; i < num_lights; i++) {
  601. if(lights[i] == light) {
  602. num_lights--;
  603. for(; i < num_lights; i++) lights[i] = lights[i + 1];
  604. return;
  605. }
  606. }
  607. }
  608. /*
  609.  */
  610. void Engine::addFog(Fog *fog) {
  611. if(num_fogs % ENGINE_GAP_SIZE == 0) {
  612. Fog **fogs = new Fog*[num_fogs + ENGINE_GAP_SIZE];
  613. for(int i = 0; i < num_fogs; i++) fogs[i] = Engine::fogs[i];
  614. if(Engine::fogs) delete Engine::fogs;
  615. Engine::fogs = fogs;
  616. if(visible_fogs) delete visible_fogs;
  617. visible_fogs = new Fog*[num_lights + ENGINE_GAP_SIZE];
  618. }
  619. fogs[num_fogs++] = fog;
  620. }
  621. void Engine::removeFog(Fog *fog) {
  622. for(int i = 0; i < num_fogs; i++) {
  623. if(fogs[i] == fog) {
  624. num_fogs--;
  625. for(; i < num_fogs; i++) fogs[i] = fogs[i + 1];
  626. return;
  627. }
  628. }
  629. }
  630. /*
  631.  */
  632. void Engine::addMirror(Mirror *mirror) {
  633. if(num_mirrors % ENGINE_GAP_SIZE == 0) {
  634. Mirror **mirrors = new Mirror*[num_mirrors + ENGINE_GAP_SIZE];
  635. for(int i = 0; i < num_mirrors; i++) mirrors[i] = Engine::mirrors[i];
  636. if(Engine::mirrors) delete Engine::mirrors;
  637. Engine::mirrors = mirrors;
  638. if(visible_mirrors) delete visible_mirrors;
  639. visible_mirrors = new Mirror*[num_mirrors + ENGINE_GAP_SIZE];
  640. }
  641. mirrors[num_mirrors++] = mirror;
  642. }
  643. void Engine::removeMirror(Mirror *mirror) {
  644. for(int i = 0; i < num_mirrors; i++) {
  645. if(mirrors[i] == mirror) {
  646. num_mirrors--;
  647. for(; i < num_mirrors; i++) mirrors[i] = mirrors[i + 1];
  648. return;
  649. }
  650. }
  651. }
  652. /*****************************************************************************/
  653. /*                                                                           */
  654. /* update                                                                    */
  655. /*                                                                           */
  656. /*****************************************************************************/
  657. void Engine::update(float ifps) {
  658. Engine::ifps = ifps;
  659. // new frame
  660. frame++;
  661. // read stderr
  662. char buf[1024];
  663. while(1) {
  664. int ret = read(stderr_fd,buf,sizeof(buf));
  665. if(ret > 0) {
  666. buf[ret] = '';
  667. console->printf(1,0,0,"%s",buf);
  668. if(console->getActivity() == 0) console->keyPress('`');
  669. } else break;
  670. }
  671. // update time
  672. time += ifps;
  673. // update lights
  674. for(int i = 0; i < num_visible_lights; i++) {
  675. visible_lights[i]->update(ifps);
  676. }
  677. // update objects
  678. Object *objects[Sector::NUM_OBJECTS];
  679. for(int i = 0; i < Bsp::num_visible_sectors; i++) {
  680. Sector *s = Bsp::visible_sectors[i];
  681. for(int j = 0; j < s->num_objects; j++) objects[j] = s->objects[j];
  682. int num_objects = s->num_objects;
  683. for(int j = 0; j < num_objects; j++) {
  684. Object *o = objects[j];
  685. if(o->frame == -Engine::frame) continue;
  686. o->update(ifps);
  687. o->frame = -Engine::frame;
  688. }
  689. }
  690. }
  691. /*****************************************************************************/
  692. /*                                                                           */
  693. /* renderers                                                                 */
  694. /*                                                                           */
  695. /*****************************************************************************/
  696. /* main bottleneck :)
  697.  */
  698. void Engine::render_light() {
  699. glDepthMask(GL_FALSE);
  700. if(have_occlusion) {
  701. glDisable(GL_CULL_FACE);
  702. glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
  703. }
  704. // find visible lights
  705. num_visible_lights = 0;
  706. for(int i = 0; i < num_lights; i++) {
  707. Light *l = lights[i];
  708. for(int j = 0; j < l->pos.num_sectors; j++) {
  709. if(Bsp::sectors[l->pos.sectors[j]].frame != frame) continue;
  710. if(frustum->inside(l->pos,l->radius) == 0) continue;
  711. if(have_occlusion && (l->pos - camera).length() > l->radius) {
  712. glPushMatrix();
  713. glTranslatef(l->pos.x,l->pos.y,l->pos.z);
  714. glScalef(l->radius,l->radius,l->radius);
  715. glBeginQueryARB(GL_SAMPLES_PASSED_ARB,query_id);
  716. sphere_mesh->render();
  717. glEndQueryARB(GL_SAMPLES_PASSED_ARB);
  718. glPopMatrix();
  719. GLuint samples;
  720. glGetQueryObjectuivARB(query_id,GL_QUERY_RESULT_ARB,&samples);
  721. if(samples == 0) continue;
  722. }
  723. visible_lights[num_visible_lights++] = l;
  724. break;
  725. }
  726. }
  727. // find visible fogs
  728. num_visible_fogs = 0;
  729. if(fog_toggle) {
  730. for(int i = 0; i < num_fogs; i++) {
  731. Fog *fog = fogs[i];
  732. for(int j = 0; j < fog->pos.num_sectors; j++) {
  733. if(Bsp::sectors[fog->pos.sectors[j]].frame != frame) continue;
  734. if(frustum->inside(fog->getMin(),fog->getMax()) == 0) continue;
  735. if(have_occlusion && !fog->inside(camera)) {
  736. glBeginQueryARB(GL_SAMPLES_PASSED_ARB,query_id);
  737. fog->mesh->render();
  738. glEndQueryARB(GL_SAMPLES_PASSED_ARB);
  739. GLuint samples;
  740. glGetQueryObjectuivARB(query_id,GL_QUERY_RESULT_ARB,&samples);
  741. if(samples == 0) continue;
  742. }
  743. visible_fogs[num_visible_fogs++] = fog;
  744. break;
  745. }
  746. }
  747. }
  748. if(have_occlusion) {
  749. glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
  750. glEnable(GL_CULL_FACE);
  751. }
  752. if(scissor_toggle) glEnable(GL_SCISSOR_TEST);
  753. if(shadows_toggle) glEnable(GL_STENCIL_TEST);
  754. // render lights
  755. for(int i = 0; i < num_visible_lights; i++) {
  756. Light *l = visible_lights[i];
  757. current_light = l;
  758. light = vec4(l->pos,1.0 / (l->radius * l->radius));
  759. light_color = l->color;
  760. int stencil_value = 0;
  761. // scissor
  762. int scissor[4];
  763. l->getScissor(scissor);
  764. if(scissor_toggle) glScissor(scissor[0],scissor[1],scissor[2],scissor[3]);
  765. // shadows
  766. if(shadows_toggle && l->shadows) {
  767. if(show_shadows_toggle) {
  768. glEnable(GL_BLEND);
  769. glBlendFunc(GL_ONE,GL_ONE);
  770. } else {
  771. glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
  772. }
  773. // shadow volume extrusion and depth clamp on ATI
  774. shadow_volume_shader->enable();
  775. shadow_volume_shader->bind();
  776. // depth clamp extension
  777. if(isDefine("NV3X")) glEnable(GL_DEPTH_CLAMP_NV);
  778. if(have_stencil_two_side) {
  779. glDisable(GL_CULL_FACE);
  780. glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  781. glActiveStencilFaceEXT(GL_BACK);
  782. glStencilFunc(GL_ALWAYS,0,~0);
  783. glStencilOp(GL_KEEP,GL_KEEP,GL_INCR_WRAP);
  784. glActiveStencilFaceEXT(GL_FRONT);
  785. glStencilFunc(GL_ALWAYS,0,~0);
  786. glStencilOp(GL_KEEP,GL_KEEP,GL_DECR_WRAP);
  787. }
  788. // shadow volumes
  789. for(int i = 0; i < l->pos.num_sectors; i++) {
  790. Sector *s = &Bsp::sectors[l->pos.sectors[i]];
  791. if(s->portal) frustum->addPortal(camera,s->portal->points);
  792. // static objects
  793. for(int j = 0; j < s->num_node_objects; j++) {
  794. Object *o = s->node_objects[j];
  795. if(o->shadows == 0) continue;
  796. for(int i = 0; i < o->num_opacities; i++) {
  797. int j = o->opacities[i];
  798. if(o->materials[j]->alpha_test) continue;
  799. if(frustum->inside(light,l->radius,o->getCenter(j),o->getRadius(j)) == 0) continue;
  800. glFlush();
  801. o->findSilhouette(vec4(light,1),j);
  802. stencil_value += o->getNumIntersections(light,camera,j);
  803. if(have_stencil_two_side) {
  804. num_triangles += o->renderShadowVolume(j);
  805. } else {
  806. glCullFace(GL_FRONT);
  807. glStencilFunc(GL_ALWAYS,0,~0);
  808. glStencilOp(GL_KEEP,GL_KEEP,GL_INCR_WRAP);
  809. num_triangles += o->renderShadowVolume(j);
  810. glCullFace(GL_BACK);
  811. glStencilFunc(GL_ALWAYS,0,~0);
  812. glStencilOp(GL_KEEP,GL_KEEP,GL_DECR_WRAP);
  813. num_triangles += o->renderShadowVolume(j);
  814. }
  815. }
  816. }
  817. // dynamic objects
  818. for(int j = 0; j < s->num_objects; j++) {
  819. Object *o = s->objects[j];
  820. if(o->shadows == 0) continue;
  821. // object may be present in many sectors
  822. if(o->pos.sector != l->pos.sectors[i]) continue;
  823. o->enable();
  824. vec3 icamera = itransform * camera;
  825. vec3 ilight = itransform * vec3(light);
  826. for(int i = 0; i < o->num_opacities; i++) {
  827. int j = o->opacities[i];
  828. if(o->materials[j]->alpha_test) continue;
  829. if(frustum->inside(light,l->radius,o->pos + o->getCenter(j),o->getRadius(j)) == 0) continue;
  830. glFlush();
  831. o->findSilhouette(vec4(ilight,1),j);
  832. stencil_value += o->getNumIntersections(ilight,icamera,j);
  833. if(have_stencil_two_side) {
  834. num_triangles += o->renderShadowVolume(j);
  835. } else {
  836. glCullFace(GL_FRONT);
  837. glStencilFunc(GL_ALWAYS,0,~0);
  838. glStencilOp(GL_KEEP,GL_KEEP,GL_INCR_WRAP);
  839. num_triangles += o->renderShadowVolume(j);
  840. glCullFace(GL_BACK);
  841. glStencilFunc(GL_ALWAYS,0,~0);
  842. glStencilOp(GL_KEEP,GL_KEEP,GL_DECR_WRAP);
  843. num_triangles += o->renderShadowVolume(j);
  844. }
  845. }
  846. o->disable();
  847. }
  848. if(s->portal) frustum->removePortal();
  849. }
  850. if(have_stencil_two_side) {
  851. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  852. glEnable(GL_CULL_FACE);
  853. }
  854. if(isDefine("NV3X")) glDisable(GL_DEPTH_CLAMP_NV);
  855. shadow_volume_shader->disable();
  856. if(show_shadows_toggle) {
  857. glDisable(GL_BLEND);
  858. } else {
  859. glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
  860. }
  861. if((camera.sector == -1 || Bsp::sectors[camera.sector].inside(camera) == 0) && --stencil_value < 0) stencil_value = 0;
  862. glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
  863. glStencilFunc(GL_EQUAL,stencil_value,~0);
  864. }
  865. if(shadows_toggle && l->shadows == 0) glDisable(GL_STENCIL_TEST);
  866. glDepthFunc(GL_EQUAL);
  867. glEnable(GL_BLEND);
  868. glBlendFunc(GL_ONE,GL_ONE);
  869. // all visible opacitie objects
  870. for(int i = 0; i < Bsp::num_visible_sectors; i++) {
  871. Sector *s = Bsp::visible_sectors[i];
  872. Portal *p = (s->frame == Engine::frame) ? s->portal : NULL;
  873. if(p) {
  874. int portal_scissor[4];
  875. p->getScissor(portal_scissor);
  876. portal_scissor[2] += portal_scissor[0];
  877. portal_scissor[3] += portal_scissor[1];
  878. if(portal_scissor[0] < scissor[0]) portal_scissor[0] = scissor[0];
  879. if(portal_scissor[1] < scissor[1]) portal_scissor[1] = scissor[1];
  880. if(portal_scissor[2] > scissor[0] + scissor[2]) portal_scissor[2] = scissor[0] + scissor[2];
  881. if(portal_scissor[3] > scissor[1] + scissor[3]) portal_scissor[3] = scissor[1] + scissor[3];
  882. portal_scissor[2] -= portal_scissor[0];
  883. portal_scissor[3] -= portal_scissor[1];
  884. if(portal_scissor[2] < 0 || portal_scissor[3] < 0) continue;
  885. if(scissor_toggle) glScissor(portal_scissor[0],portal_scissor[1],portal_scissor[2],portal_scissor[3]);
  886. } else {
  887. if(scissor_toggle) glScissor(scissor[0],scissor[1],scissor[2],scissor[3]);
  888. }
  889. for(int j = 0; j < s->num_visible_objects; j++) {
  890. Object *o = s->visible_objects[j];
  891. if((o->pos + o->getCenter() - light).length() < o->getRadius() + l->radius) {
  892. num_triangles += o->render(Object::RENDER_OPACITY);
  893. }
  894. }
  895. }
  896. if(scissor_toggle) glScissor(viewport[0],viewport[1],viewport[2],viewport[3]);
  897. // mirrors
  898. for(int i = 0; i < num_visible_mirrors; i++) {
  899. if(visible_mirrors[i]->material && visible_mirrors[i]->material->blend == 0) {
  900. visible_mirrors[i]->render();
  901. }
  902. }
  903. // disable material
  904. if(Material::old_material) Material::old_material->disable();
  905. glDisable(GL_BLEND);
  906. glDepthFunc(GL_LEQUAL);
  907. if(shadows_toggle && l->shadows == 0) glEnable(GL_STENCIL_TEST);
  908. // clear stensil only if it is needed
  909. if(l != visible_lights[num_visible_lights - 1]) glClear(GL_STENCIL_BUFFER_BIT);
  910. }
  911. current_light = NULL;
  912. if(shadows_toggle) glDisable(GL_STENCIL_TEST);
  913. if(scissor_toggle) {
  914. glScissor(viewport[0],viewport[1],viewport[2],viewport[3]);
  915. glDisable(GL_SCISSOR_TEST);
  916. }
  917. glDepthMask(GL_TRUE);
  918. }
  919. /*
  920.  */
  921. void Engine::render_transparent() {
  922. glDepthMask(GL_FALSE);
  923. // volume fogs
  924. if(fog_toggle) {
  925. for(int i = 0; i < num_visible_fogs; i++) {
  926. Fog *fog = visible_fogs[i];
  927. current_fog = fog;
  928. fog->enable();
  929. // all visible objects
  930. for(int i = 0; i < Bsp::num_visible_sectors; i++) {
  931. Sector *s = Bsp::visible_sectors[i];
  932. for(int j = 0; j < s->num_visible_objects; j++) {
  933. Object *o = s->visible_objects[j];
  934. if((o->pos + o->getCenter() - fog->getCenter()).length() < o->getRadius() + fog->getRadius()) {
  935. num_triangles += o->render(Object::RENDER_ALL);
  936. }
  937. }
  938. }
  939. fog->disable();
  940. num_triangles += fog->render();
  941. }
  942. }
  943. current_fog = NULL;
  944. glEnable(GL_BLEND);
  945. glDisable(GL_CULL_FACE);
  946. // transparent objects
  947. // ambient shader
  948. int save_num_visible_lights = num_visible_lights;
  949. num_visible_lights = 0;
  950. for(int i = 0; i < num_visible_mirrors; i++) {
  951. if(visible_mirrors[i]->material && visible_mirrors[i]->material->blend == 1) {
  952. visible_mirrors[i]->render();
  953. }
  954. }
  955. for(int i = Bsp::num_visible_sectors - 1; i >= 0; i--) {
  956. Sector *s = Bsp::visible_sectors[i];
  957. for(int j = 0; j < s->num_visible_objects; j++) {
  958. Object *o = s->visible_objects[j];
  959. num_triangles += o->render(Object::RENDER_TRANSPARENT);
  960. }
  961. }
  962. // light shader
  963. num_visible_lights = save_num_visible_lights;
  964. for(int i = 0; i < num_visible_mirrors; i++) {
  965. if(visible_mirrors[i]->material && visible_mirrors[i]->material->blend == 1) {
  966. visible_mirrors[i]->render();
  967. }
  968. }
  969. for(int i = 0; i < num_visible_lights; i++) {
  970. Light *l = visible_lights[i];
  971. current_light = l;
  972. light = vec4(l->pos,1.0 / (l->radius * l->radius));
  973. light_color = l->color;
  974. for(int i = Bsp::num_visible_sectors - 1; i >= 0; i--) {
  975. Sector *s = Bsp::visible_sectors[i];
  976. for(int j = 0; j < s->num_visible_objects; j++) {
  977. Object *o = s->visible_objects[j];
  978. if((o->pos + o->getCenter() - light).length() < o->getRadius() + l->radius) {
  979. num_triangles += o->render(Object::RENDER_TRANSPARENT);
  980. }
  981. }
  982. }
  983. }
  984. current_light = NULL;
  985. // disable all materials
  986. if(Material::old_material) Material::old_material->disable();
  987. glEnable(GL_CULL_FACE);
  988. glDisable(GL_BLEND);
  989. glDepthMask(GL_TRUE);
  990. }
  991. /*
  992.  */
  993. void Engine::render(float ifps) {
  994. // get matrixes
  995. glGetFloatv(GL_PROJECTION_MATRIX,projection);
  996. glGetFloatv(GL_MODELVIEW_MATRIX,modelview);
  997. imodelview = modelview.inverse();
  998. transform.identity();
  999. itransform.identity();
  1000. // get camera
  1001. camera = imodelview * vec3(0,0,0);
  1002. // set frustum
  1003. frustum->set(projection * modelview);
  1004. // global triangle counter
  1005. num_triangles = 0;
  1006. /* render to pbuffer
  1007.  */
  1008. screen->enable();
  1009. // get viewport
  1010. glGetIntegerv(GL_VIEWPORT,viewport);
  1011. // set matrixes
  1012. glMatrixMode(GL_PROJECTION);
  1013. glLoadMatrixf(projection);
  1014. glMatrixMode(GL_MODELVIEW);
  1015. glLoadMatrixf(modelview);
  1016. // ambient pass
  1017. // clear depth buffer
  1018. glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  1019. glDepthFunc(GL_LESS);
  1020. // number of visible lights
  1021. // zero - ambient shader
  1022. num_visible_lights = 0;
  1023. // render bsp
  1024. if(bsp) bsp->render();
  1025. // disable material
  1026. if(Material::old_material) Material::old_material->disable();
  1027. // find visible mirrors
  1028. num_visible_mirrors = 0;
  1029. if(mirror_toggle) {
  1030. if(have_occlusion) {
  1031. glDisable(GL_CULL_FACE);
  1032. glDepthMask(GL_FALSE);
  1033. glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
  1034. }
  1035. for(int i = 0; i < num_mirrors; i++) {
  1036. Mirror *mirror = mirrors[i];
  1037. if(mirror->pos.sector == -1 || Bsp::sectors[mirror->pos.sector].frame != frame) continue;
  1038. if(frustum->inside(mirror->getMin(),mirror->getMax()) == 0) continue;
  1039. if(have_occlusion) {
  1040. glBeginQueryARB(GL_SAMPLES_PASSED_ARB,query_id);
  1041. mirror->mesh->render();
  1042. glEndQueryARB(GL_SAMPLES_PASSED_ARB);
  1043. GLuint samples;
  1044. glGetQueryObjectuivARB(query_id,GL_QUERY_RESULT_ARB,&samples);
  1045. if(samples == 0) continue;
  1046. }
  1047. visible_mirrors[num_visible_mirrors++] = mirror;
  1048. break;
  1049. }
  1050. if(have_occlusion) {
  1051. glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
  1052. glDepthMask(GL_TRUE);
  1053. glEnable(GL_CULL_FACE);
  1054. }
  1055. }
  1056. // render mirrors
  1057. if(num_visible_mirrors) {
  1058. // save state
  1059. if(bsp) bsp->saveState();
  1060. // without any mirrors
  1061. int save_num_visible_mirrors = num_visible_mirrors;
  1062. num_visible_mirrors = 0;
  1063. for(int i = 0; i < save_num_visible_mirrors; i++) {
  1064. frame++; // new frame
  1065. Mirror *mirror = visible_mirrors[i];
  1066. current_mirror = mirror;
  1067. mirror->enable();
  1068. // clear
  1069. glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  1070. glDepthFunc(GL_LESS);
  1071. // ambient mirror pass
  1072. num_visible_lights = 0;
  1073. if(bsp) bsp->render();
  1074. // light mirror pass
  1075. render_light();
  1076. // transparent mirror pass
  1077. render_transparent();
  1078. mirror->disable();
  1079. }
  1080. num_visible_mirrors = save_num_visible_mirrors;
  1081. // restore state
  1082. if(bsp) bsp->restoreState(++frame);
  1083. }
  1084. current_mirror = NULL;
  1085. // ambient mirror pass
  1086. num_visible_lights = 0;
  1087. for(int i = 0; i < num_visible_mirrors; i++) {
  1088. if(visible_mirrors[i]->material && visible_mirrors[i]->material->blend == 0) {
  1089. visible_mirrors[i]->render();
  1090. }
  1091. }
  1092. // light pass
  1093. render_light();
  1094. // transparent pass
  1095. render_transparent();
  1096. // disable material
  1097. if(Material::old_material) Material::old_material->disable();
  1098. // wareframe
  1099. if(wareframe_toggle) {
  1100. glColor3f(0,1,0);
  1101. glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
  1102. glEnable(GL_POLYGON_OFFSET_LINE);
  1103. glPolygonOffset(-0.5,0.0);
  1104. for(int i = 0; i < Bsp::num_visible_sectors; i++) {
  1105. Sector *s = Bsp::visible_sectors[i];
  1106. for(int j = 0; j < s->num_visible_objects; j++) {
  1107. Object *o = s->visible_objects[j];
  1108. num_triangles += o->render(Object::RENDER_ALL);
  1109. }
  1110. }
  1111. glDisable(GL_POLYGON_OFFSET_LINE);
  1112. glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
  1113. }
  1114. glFlush();
  1115. /* calculate physics
  1116.  */
  1117. if(physic_toggle) Physic::update(Engine::ifps);
  1118. /* render light flares
  1119.  */
  1120. for(int i = 0; i < num_visible_lights; i++) {
  1121. visible_lights[i]->renderFlare();
  1122. }
  1123. /* disable pbuffer
  1124.  */
  1125. screen_texture->bind();
  1126. screen_texture->copy();
  1127. screen->disable();
  1128. // get viewport
  1129. glGetIntegerv(GL_VIEWPORT,viewport);
  1130. // postprocessing
  1131. glMatrixMode(GL_PROJECTION);
  1132. glLoadIdentity();
  1133. glOrtho(-1,1,-1,1,-1,1);
  1134. glMatrixMode(GL_MODELVIEW);
  1135. glLoadIdentity();
  1136. glDisable(GL_DEPTH_TEST);
  1137. glDepthMask(GL_FALSE);
  1138. screen_material->enable();
  1139. screen_material->bind();
  1140. screen_material->bindTexture(0,screen_texture);
  1141. screen_texture->render();
  1142. screen_material->disable();
  1143. // console
  1144. console->enable(viewport[2],viewport[3]);
  1145. console->render(ifps,40);
  1146. console->disable();
  1147. }
  1148. /*****************************************************************************/
  1149. /*                                                                           */
  1150. /*                                                                           */
  1151. /*                                                                           */
  1152. /*****************************************************************************/
  1153. /*
  1154.  */
  1155. Object *Engine::intersection(const vec3 &line0,const vec3 &line1,vec3 &point,vec3 &normal) {
  1156. vec3 p,n;
  1157. point = line1;
  1158. Object *object = NULL;
  1159. for(int i = 0; i < Bsp::num_visible_sectors; i++) {
  1160. Sector *s = Bsp::visible_sectors[i];
  1161. for(int j = 0; j < s->num_visible_objects; j++) {
  1162. Object *o = s->visible_objects[j];
  1163. if(o->is_identity) {
  1164. if(o->intersection(line0,point,p,n)) {
  1165. point = p;
  1166. normal = n;
  1167. object = o;
  1168. }
  1169. } else {
  1170. vec3 l0 = o->itransform * line0;
  1171. vec3 l1 = o->itransform * point;
  1172. if(o->intersection(l0,l1,p,n)) {
  1173. point = o->transform * p;
  1174. normal = o->transform.rotation() * n;
  1175. object = o;
  1176. }
  1177. }
  1178. }
  1179. }
  1180. return object;
  1181. }