Line data Source code
1 : #include <cstdlib>
2 : #include <string.h>
3 : #include <dirent.h>
4 : #include <png.h>
5 :
6 : #include "Engine.h"
7 : #include "api.h"
8 : #include "buffer.h"
9 :
10 : #define PNG_HEADER_SIZE 8
11 :
12 : //------------------------------------------------------------------------------
13 28 : Engine::Engine() {
14 : // initialize resources used by the engine //
15 14 : keyState_.initKeyState();
16 14 : specialKeyState_.initKeyState();
17 :
18 14 : currentLevel_ = NULL;
19 14 : storedLevel_ = NULL;
20 :
21 : // setup game timer /////////////////////////
22 14 : if(!timer_.init()) {
23 0 : PRINT_ERROR("Timer initialization failed.\n");
24 0 : exit (1);
25 : }
26 : ///////////////////////////////////////////////
27 :
28 14 : fps_ = 0.0f;
29 :
30 : #if EDIT
31 : // terrain editing values //
32 : paint = false;
33 : paintColor = false;
34 :
35 : lastX = 0.0f;
36 : lastY = 0.0f;
37 :
38 : last_x = 0;
39 : last_z = 0;
40 : last_red = 0.0f;
41 : last_green = 0.0f;
42 : last_blue = 0.0f;
43 : last_height = 0.0f;
44 : last_type = 0;
45 : ////////////////////////////
46 : #endif
47 :
48 14 : luaState_ = NULL;
49 14 : mainCamera_ = c1_ = c2_ = c3_ = c4_ = NULL;
50 :
51 14 : isPaused_ = false;
52 :
53 14 : mouseX_ = 0.0f;
54 14 : mouseY_ = 0.0f;
55 :
56 14 : isRunning_ = true;
57 14 : isIntroRunning_ = false;
58 :
59 14 : alcDevice_ = NULL;
60 14 : alcContext_ = NULL;
61 28 : }
62 :
63 : //------------------------------------------------------------------------------
64 0 : bool Engine::loadGame(const std::string &file) {
65 : // If the lua state has not been initialized for this object, attempt to
66 : // initialize it.
67 0 : if (file == "" || luaState_ != NULL)
68 0 : return false;
69 :
70 0 : luaState_ = lua_open();
71 :
72 : // If the lua state still could not be initialized, then exit the game.
73 : // ... we can do something smarter with this in the finished product.
74 0 : if (!luaState_) {
75 0 : PRINT_ERROR("Could not create Lua state.\n");
76 0 : exit(-1);
77 : }
78 :
79 : // load Lua base libraries
80 0 : luaL_openlibs(luaState_);
81 :
82 : // Load our library
83 0 : luaopen_krigApi(luaState_);
84 :
85 : // load the script
86 : PRINT_DEBUG("Loading Lua game script '%s'...\n", file.c_str());
87 0 : luaL_dofile(luaState_, file.c_str());
88 :
89 : // Find the update function and call it
90 0 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_LOAD);
91 :
92 0 : if (lua_isfunction(luaState_, -1)) {
93 0 : lua_call(luaState_, 0, 0);
94 0 : }
95 : else {
96 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_LOAD);
97 0 : lua_pop(luaState_, 1);
98 : }
99 :
100 0 : return (true);
101 0 : }
102 :
103 : //------------------------------------------------------------------------------
104 0 : bool Engine::loadIntroCredits() {
105 : // load the intro script from the buffer
106 : PRINT_DEBUG("Loading Lua game script 'intro credits'...\n");
107 0 : loadLevelFromBuffer(intro_level_script_buffer);
108 :
109 0 : isIntroRunning_ = true;
110 :
111 0 : return (true);
112 : }
113 :
114 : //------------------------------------------------------------------------------
115 0 : void Engine::updateGame(const float &elapsedTime) {
116 : // Attempt to execute the script only if the lua state has already been
117 : // initialized with a script
118 0 : if (!luaState_)
119 0 : return;
120 :
121 : // Find the update function and call it
122 0 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_UPDATE);
123 :
124 0 : if (lua_isfunction(luaState_, -1)) {
125 0 : lua_pushnumber(luaState_, elapsedTime);
126 0 : lua_call(luaState_, 1, 0);
127 0 : }
128 : else {
129 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UPDATE);
130 0 : lua_pop(luaState_, 1);
131 : }
132 0 : }
133 :
134 : //------------------------------------------------------------------------------
135 13 : void Engine::unloadGame() {
136 : // Attempt to execute the on_unload function only if the lua state has
137 : // already been initialized with a script
138 13 : if (!luaState_)
139 13 : return;
140 :
141 : // Find the update function and call it
142 0 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_UNLOAD);
143 :
144 0 : if (lua_isfunction(luaState_, -1)) {
145 0 : lua_call(luaState_, 0, 0);
146 0 : }
147 : else {
148 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UNLOAD);
149 0 : lua_pop(luaState_, 1);
150 : }
151 :
152 0 : lua_close(luaState_);
153 0 : luaState_ = NULL;
154 13 : }
155 :
156 : //------------------------------------------------------------------------------
157 0 : void Engine::gameCycle() {
158 0 : timeElapsed_ = timer_.getElapsedSeconds();
159 0 : updateGame(timeElapsed_);
160 0 : fps_ = timer_.getFPS();
161 :
162 0 : if (currentLevel_ != NULL && !isPaused_)
163 0 : currentLevel_->setElapsedTime(timeElapsed_);
164 :
165 0 : if (currentLevel_ != NULL) {
166 0 : if (currentLevel_->checkComplete()) {
167 0 : if (isIntroRunning_) {
168 0 : unloadGame();
169 0 : loadGame("./scripts/main.lua");
170 0 : isIntroRunning_ = false;
171 0 : }
172 0 : }
173 : else {
174 0 : if (!isPaused_) {
175 0 : mainCamera_->update(currentLevel_->getElapsedTime());
176 :
177 0 : currentLevel_->animateLevel();
178 :
179 : //processCommands();
180 :
181 0 : currentLevel_->updateLevel();
182 0 : currentLevel_->prepareLevel(); // collision detection
183 :
184 : //currentLevel_->updateLevel();
185 :
186 0 : prepare();
187 :
188 : //Matrix m;
189 : //mainCamera_->worldRotation.buildRotationMatrix(m);
190 :
191 : //glMultMatrixf(m.data);
192 0 : currentLevel_->drawLevel();
193 :
194 0 : currentLevel_->getMusic()->Update();
195 :
196 0 : glClear(GL_DEPTH_BUFFER_BIT);
197 0 : glLoadIdentity();
198 :
199 0 : glDepthFunc(GL_ALWAYS);
200 0 : currentLevel_->postDraw();
201 0 : glDepthFunc(GL_LESS);
202 :
203 0 : glutSwapBuffers();
204 0 : }
205 : }
206 0 : }
207 :
208 0 : processCommands();
209 0 : }
210 :
211 : //------------------------------------------------------------------------------
212 0 : void Engine::prepare() {
213 0 : glClear(GL_DEPTH_BUFFER_BIT);
214 0 : glLoadIdentity();
215 :
216 0 : mainCamera_->prepareGLView();
217 :
218 0 : glDepthMask(GL_FALSE);
219 0 : currentLevel_->drawSky();
220 0 : glDepthMask(GL_TRUE);
221 :
222 : //glDepthFunc(GL_ALWAYS);
223 : // currentLevel_->postDraw();
224 : // glDepthFunc(GL_LESS);
225 :
226 0 : Matrix translationMatrix;
227 :
228 0 : Vector position = mainCamera_->getPosition();
229 :
230 0 : translationMatrix.setTranslation(-position.x, -position.y, -position.z);
231 :
232 0 : glMultMatrixf(translationMatrix.data);
233 0 : }
234 :
235 : //------------------------------------------------------------------------------
236 0 : void Engine::initGL() {
237 0 : loadModels();
238 :
239 0 : GLfloat shaderData[16] = {
240 : 0.4f, 0.4f, 0.4f, 0.7f, 0.7f, 0.7f, 1.0f, 1.0f,
241 : 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
242 : };
243 :
244 : //glClearColor(0.0f, 0.0f, 0.3f, 1.0f);
245 0 : glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
246 :
247 0 : glShadeModel(GL_SMOOTH); // use smooth shading
248 0 : glEnable(GL_DEPTH_TEST); // remove hidden surfaces
249 :
250 : // create 1D bitmap for lighting ////////////
251 0 : glGenTextures(1, &shaderTexture_[0]);
252 :
253 0 : glBindTexture(GL_TEXTURE_1D, shaderTexture_[0]);
254 0 : glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
255 0 : glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
256 :
257 0 : glTexImage1D(GL_TEXTURE_1D, 0, 1, 16, 0, GL_LUMINANCE, GL_FLOAT, shaderData);
258 : /////////////////////////////////////////////
259 :
260 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
261 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
262 0 : glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
263 0 : glGenTextures(MAX_TEXTURES, Object::textureIds);
264 0 : loadTextures();
265 :
266 0 : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
267 0 : glFrontFace(GL_CCW);
268 0 : glEnable(GL_CULL_FACE);
269 0 : glPolygonMode(GL_FRONT, GL_FILL);
270 0 : glEnable(GL_BLEND);
271 :
272 : // setup projection matrix //////////////////
273 0 : glMatrixMode(GL_PROJECTION);
274 0 : glLoadIdentity();
275 0 : gluPerspective (45.0, (800.0f / 600.0f), 0.001f, 300.0f);
276 0 : glMatrixMode(GL_MODELVIEW);
277 :
278 0 : glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
279 0 : glDisable(GL_LIGHTING);
280 0 : glBindTexture(GL_TEXTURE_1D, shaderTexture_[0]);
281 0 : glLineWidth(1.0f);
282 :
283 0 : glDepthFunc(GL_LESS);
284 :
285 : // setup display lists //////////////////////
286 0 : lists_ = glGenLists(3);
287 :
288 : // list to setup cel shading ////////////////
289 0 : glNewList(lists_, GL_COMPILE);
290 0 : glDisable(GL_BLEND);
291 : //glEnable (GL_DEPTH_TEST);
292 0 : glDepthFunc(GL_LEQUAL);
293 0 : glEnable(GL_TEXTURE_1D);
294 : //glBindTexture(GL_TEXTURE_1D, shaderTexture[0]);
295 0 : glLineWidth(1.0f);
296 0 : glEndList();
297 :
298 : // list to setup to draw outline ////////////
299 0 : glNewList(lists_ + 1, GL_COMPILE);
300 0 : glDisable(GL_TEXTURE_1D);
301 0 : glEnable(GL_BLEND);
302 0 : glDepthFunc(GL_LESS);
303 0 : glLineWidth(3.0f);
304 0 : glCullFace(GL_FRONT);
305 0 : glPolygonMode(GL_BACK, GL_LINE);
306 0 : glEndList();
307 :
308 : // list to reset display settings
309 0 : glNewList(lists_ + 2, GL_COMPILE);
310 0 : glPolygonMode(GL_BACK, GL_FILL);
311 0 : glDepthFunc(GL_LESS);
312 0 : glCullFace(GL_BACK);
313 0 : glEndList();
314 :
315 0 : glHint(GL_POLYGON_SMOOTH, GL_NICEST);
316 0 : glEnable(GL_POLYGON_SMOOTH);
317 0 : glEnable(GL_BLEND);
318 0 : }
319 :
320 : //------------------------------------------------------------------------------
321 0 : void Engine::initAL() {
322 : PRINT_DEBUG("Loading AL...\n");
323 0 : if (alcDevice_ || alcContext_) {
324 : PRINT_DEBUG("AL device or context already initialized; skipping init\n");
325 0 : return;
326 : }
327 :
328 0 : alcDevice_ = alcOpenDevice(NULL);
329 0 : if (!alcDevice_) {
330 : PRINT_DEBUG_LVL(1, "Could not initialize AL device; error code %d; skipping init\n", alGetError());
331 0 : return;
332 : }
333 :
334 0 : alcContext_ = alcCreateContext(alcDevice_, NULL);
335 0 : if (!alcContext_) {
336 : PRINT_DEBUG_LVL(1, "Could not create AL context; error code %d; skipping init\n", alGetError());
337 0 : alcCloseDevice(alcDevice_);
338 0 : return;
339 : }
340 :
341 0 : if (!alcMakeContextCurrent(alcContext_)) {
342 : PRINT_DEBUG_LVL(1, "Could not make AL context current; error code %d; skipping init\n", alGetError());
343 0 : }
344 0 : }
345 :
346 : //------------------------------------------------------------------------------
347 0 : void Engine::loadSoundFx() {
348 : PRINT_DEBUG("Loading SoundFx...\n");
349 0 : soundFx_.load();
350 0 : }
351 :
352 : //------------------------------------------------------------------------------
353 13 : void Engine::unloadSoundFx() {
354 : PRINT_DEBUG("Unloading SoundFx...\n");
355 13 : soundFx_.unload();
356 13 : }
357 :
358 : //------------------------------------------------------------------------------
359 1 : void Engine::processKeyUp(const int &key) {
360 : PRINT_DEBUG_LVL(1, "special key up (%d)\n", key);
361 1 : specialKeyState_.keys[key] = KEY_STATE_RELEASED;
362 1 : }
363 :
364 : //------------------------------------------------------------------------------
365 3 : void Engine::processKeyDown(const int &key) {
366 : PRINT_DEBUG_LVL(1, "special key down (%d)\n", key);
367 3 : specialKeyState_.keys[key] = KEY_STATE_PRESSED;
368 3 : }
369 :
370 : //------------------------------------------------------------------------------
371 1 : void Engine::processCommands() {
372 1 : keyState_.initKeyState();
373 1 : specialKeyState_.initKeyState();
374 1 : }
375 :
376 : //------------------------------------------------------------------------------
377 1 : void Engine::processNormalKeyUp(const unsigned char &key) {
378 : PRINT_DEBUG_LVL(1, "normal key up (%d)\n", key);
379 1 : keyState_.keys[key] = KEY_STATE_RELEASED;
380 1 : }
381 :
382 : //------------------------------------------------------------------------------
383 3 : void Engine::processNormalKeyDown(const unsigned char &key) {
384 : PRINT_DEBUG_LVL(1, "normal key down (%d)\n", key);
385 3 : keyState_.keys[key] = KEY_STATE_PRESSED;
386 :
387 : #if EDIT
388 : switch (key) {
389 : // Select current camera
390 : case '1':
391 : mainCamera_ = c1_;
392 : currentLevel_->setCamera(mainCamera_);
393 : break;
394 : case '2':
395 : mainCamera_ = c2_;
396 : currentLevel_->setCamera(mainCamera_);
397 : break;
398 : case '3':
399 : mainCamera_ = c3_;
400 : currentLevel_->setCamera(mainCamera_);
401 : break;
402 : case '4':
403 : mainCamera_ = c4_;
404 : currentLevel_->setCamera(mainCamera_);
405 : break;
406 :
407 : // Save terrain
408 : case 'O':
409 : case 'o':
410 : currentLevel_->saveTerrain("terrains/new_terrain.txt");
411 : break;
412 :
413 : // Toggle settings
414 : case 'G':
415 : case 'g':
416 : currentLevel_->toggleGrid();
417 : break;
418 : case 'B':
419 : case 'b':
420 : currentLevel_->toggleBoundingBoxes();
421 : break;
422 : case 'C':
423 : case 'c':
424 : currentLevel_->toggleControlTriangles();
425 : break;
426 :
427 : case '.':
428 : // used for profiling
429 : exit(0);
430 : break;
431 : }
432 : #endif
433 3 : }
434 :
435 : //------------------------------------------------------------------------------
436 0 : void Engine::prepLevelLoad() {
437 0 : if (currentLevel_)
438 0 : delete currentLevel_;
439 :
440 0 : if (!mainCamera_) {
441 : // setup camera(s) for the current level
442 0 : c1_ = new Camera(1); c1_->setProjectionMatrix();
443 0 : mainCamera_ = c1_;
444 :
445 0 : c2_ = new Camera(2); c2_->setProjectionMatrix();
446 0 : c3_ = new Camera(3); c3_->setProjectionMatrix();
447 0 : c4_ = new Camera(4); c4_->setProjectionMatrix();
448 :
449 0 : c2_->setPosition(0.0f, 100.0f, 0.0f);
450 0 : c2_->setRotationEuler(1.57, 0.0f, 0.0f);
451 0 : c3_->setPosition(0.0f, 0.0f, 0.0f);
452 0 : c4_->setPosition(0.0f, 0.0f, 0.0f);
453 0 : }
454 :
455 0 : mainCamera_->init();
456 0 : mainCamera_->unloadScript();
457 :
458 0 : currentLevel_ = new GameLevel(lists_);
459 0 : currentLevel_->setCamera(mainCamera_);
460 0 : }
461 :
462 : //------------------------------------------------------------------------------
463 0 : void Engine::loadLevel(const char* levelFile) {
464 0 : prepLevelLoad();
465 0 : currentLevel_->loadLevel(levelFile);
466 0 : timeElapsed_ = timer_.getElapsedSeconds();
467 0 : }
468 :
469 : //------------------------------------------------------------------------------
470 0 : void Engine::loadLevelFromBuffer(const char* buffer) {
471 0 : prepLevelLoad();
472 0 : currentLevel_->loadLevelFromBuffer(buffer);
473 0 : timeElapsed_ = timer_.getElapsedSeconds();
474 0 : }
475 :
476 : //------------------------------------------------------------------------------
477 0 : void Engine::loadModels() {
478 0 : DIR *dir = opendir("./models/");
479 :
480 0 : if (dir == NULL) {
481 : PRINT_DEBUG_LVL(2, "'models' directory not present; no models will be loaded.\n");
482 0 : return;
483 : }
484 :
485 : dirent *de;
486 : ModelStorage *model;
487 : char filePath[MAX_PATH_LEN];
488 0 : std::string hashKey;
489 :
490 0 : while ((de = readdir(dir)) != NULL) {
491 : // only consider model files with the .mdl extension //
492 0 : if (strstr(de->d_name, ".mdl") != NULL) {
493 : // build full path to load //
494 0 : strcpy(filePath, "./models/");
495 0 : strcat(filePath, de->d_name);
496 :
497 : // load model file into model storage //
498 : PRINT_DEBUG("Loading model file '%s'...\n", filePath);
499 :
500 0 : model = new ModelStorage();
501 0 : model->load(filePath);
502 :
503 : // TODO: Investigate progress on "shadows" feature
504 : //model->buildEdges();
505 :
506 : // insert model file into model hash //
507 0 : hashKey = std::string(de->d_name);
508 0 : ModelGameObject::modelHash[hashKey] = model;
509 0 : }
510 : }
511 :
512 0 : closedir(dir);
513 0 : }
514 :
515 : //------------------------------------------------------------------------------
516 0 : void Engine::loadTextures() {
517 0 : DIR *dir = opendir("./textures/");
518 :
519 0 : if (dir == NULL) {
520 : PRINT_DEBUG_LVL(2, "'textures' directory not present; no textures will be loaded.\n");
521 0 : return;
522 : }
523 :
524 : dirent *de;
525 : char filePath[MAX_PATH_LEN];
526 0 : std::string hashKey;
527 0 : int textureId = 0;
528 :
529 0 : while ((de = readdir(dir)) != NULL) {
530 0 : glBindTexture (GL_TEXTURE_2D, Object::textureIds[textureId]);
531 : // only load texture files with the .png extension //
532 0 : if (strstr(de->d_name, ".png") != NULL) {
533 : // build full path to load //
534 0 : strcpy(filePath, "./textures/");
535 0 : strcat(filePath, de->d_name);
536 :
537 : // load texture into storage
538 : PRINT_DEBUG("Loading texture file '%s'...\n", filePath);
539 :
540 0 : unsigned char* pixels = NULL;
541 0 : unsigned int format = 0;
542 0 : unsigned int height = 0;
543 0 : unsigned int width = 0;
544 :
545 0 : if (!loadPng(filePath, &pixels, &format, &height, &width)) {
546 0 : PRINT_ERROR("Could not load texture file. Skipping...\n");
547 0 : if (pixels != NULL) {
548 0 : delete[] pixels;
549 0 : }
550 0 : continue;
551 : }
552 :
553 0 : if (pixels != NULL) {
554 0 : gluBuild2DMipmaps( GL_TEXTURE_2D, 4, width, height,
555 0 : format, GL_UNSIGNED_BYTE, pixels );
556 :
557 0 : delete[] pixels;
558 0 : }
559 :
560 0 : hashKey = std::string(de->d_name);
561 0 : Object::textureHash[hashKey] = textureId++;
562 0 : }
563 : }
564 :
565 0 : closedir(dir);
566 0 : }
567 :
568 : //------------------------------------------------------------------------------
569 1 : void Engine::processMouseMove(const int &x, const int &y) {
570 1 : mouseX_ = x;
571 1 : mouseY_ = y;
572 1 : }
573 :
574 : //------------------------------------------------------------------------------
575 2 : void Engine::shutdown() {
576 2 : isRunning_ = false;
577 2 : }
578 :
579 : //------------------------------------------------------------------------------
580 26 : Engine::~Engine() {
581 13 : unloadGame();
582 13 : unload();
583 26 : }
584 :
585 : //------------------------------------------------------------------------------
586 13 : void Engine::unload() {
587 13 : if (currentLevel_)
588 0 : delete currentLevel_;
589 :
590 13 : if (storedLevel_)
591 0 : delete storedLevel_;
592 :
593 13 : if (mainCamera_) {
594 0 : delete c1_;
595 0 : delete c2_;
596 0 : delete c3_;
597 0 : delete c4_;
598 0 : }
599 :
600 13 : unloadSoundFx();
601 :
602 13 : currentLevel_ = storedLevel_ = NULL;
603 13 : c1_ = c2_ = c3_ = c4_ = mainCamera_ = NULL;
604 :
605 13 : alcMakeContextCurrent(NULL);
606 13 : alcDestroyContext(alcContext_);
607 13 : alcCloseDevice(alcDevice_);
608 13 : alcDevice_ = NULL;
609 13 : alcContext_ = NULL;
610 13 : }
611 :
612 : //------------------------------------------------------------------------------
613 0 : void Engine::pause() {
614 0 : isPaused_ = !isPaused_;
615 0 : }
616 :
617 : //------------------------------------------------------------------------------
618 0 : bool Engine::loadPng(const char* filePath, unsigned char** pixels, unsigned int* format, unsigned int* height, unsigned int* width) {
619 0 : FILE *fp = fopen(filePath, "rb");
620 0 : if (!fp) {
621 0 : return false;
622 : }
623 :
624 : unsigned char header[PNG_HEADER_SIZE];
625 :
626 0 : if (fread(header, 1, PNG_HEADER_SIZE, fp) != PNG_HEADER_SIZE) {
627 0 : fclose(fp);
628 0 : return false;
629 : }
630 :
631 0 : if (png_sig_cmp(header, 0, PNG_HEADER_SIZE)) {
632 0 : fclose(fp);
633 0 : return false;
634 : }
635 :
636 0 : png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
637 :
638 0 : if (!png_ptr) {
639 0 : fclose(fp);
640 0 : return false;
641 : }
642 :
643 0 : png_infop info_ptr = png_create_info_struct(png_ptr);
644 :
645 0 : if (!info_ptr) {
646 0 : png_destroy_read_struct(&png_ptr, NULL, NULL);
647 0 : fclose(fp);
648 0 : return false;
649 : }
650 :
651 0 : if (setjmp(png_jmpbuf(png_ptr))) {
652 0 : png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
653 0 : fclose(fp);
654 0 : return false;
655 : }
656 :
657 0 : png_init_io(png_ptr, fp);
658 0 : png_set_sig_bytes(png_ptr, PNG_HEADER_SIZE);
659 :
660 0 : png_read_info(png_ptr, info_ptr);
661 0 : *width = png_get_image_width(png_ptr, info_ptr);
662 0 : *height = png_get_image_height(png_ptr, info_ptr);
663 :
664 0 : if (png_get_bit_depth(png_ptr, info_ptr) < 8) {
665 0 : png_set_packing(png_ptr);
666 0 : }
667 :
668 0 : if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
669 0 : png_set_tRNS_to_alpha(png_ptr);
670 0 : }
671 :
672 0 : *format = 0;
673 0 : switch(png_get_color_type(png_ptr, info_ptr)) {
674 : case PNG_COLOR_TYPE_GRAY:
675 0 : png_set_gray_to_rgb(png_ptr);
676 0 : *format = GL_RGB;
677 0 : break;
678 : case PNG_COLOR_TYPE_GRAY_ALPHA:
679 0 : png_set_gray_to_rgb(png_ptr);
680 0 : *format = GL_RGBA;
681 0 : break;
682 : case PNG_COLOR_TYPE_PALETTE:
683 0 : *format = GL_RGB;
684 0 : png_set_expand(png_ptr);
685 0 : break;
686 : case PNG_COLOR_TYPE_RGB:
687 0 : *format = GL_RGB;
688 0 : break;
689 : case PNG_COLOR_TYPE_RGB_ALPHA:
690 0 : *format = GL_RGBA;
691 0 : break;
692 : default:
693 0 : *format = -1;
694 0 : }
695 :
696 0 : if (*format == -1) {
697 0 : png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
698 0 : fclose(fp);
699 0 : return false;
700 : }
701 :
702 0 : unsigned int bpp = (unsigned int)png_get_rowbytes(png_ptr, info_ptr) / *width;
703 :
704 0 : png_set_interlace_handling(png_ptr);
705 :
706 0 : png_read_update_info(png_ptr, info_ptr);
707 :
708 0 : int totalPixels = *width * *height * bpp;
709 0 : *pixels = new unsigned char [totalPixels];
710 0 : memset(*pixels, 0, totalPixels);
711 :
712 0 : png_bytep rows[*height];
713 :
714 0 : unsigned char* p = *pixels;
715 0 : for (int i = 0; i < *height; ++i) {
716 0 : rows[i] = p;
717 0 : p += (*width * bpp);
718 0 : }
719 :
720 0 : png_read_image(png_ptr, rows);
721 0 : png_read_end(png_ptr, NULL);
722 0 : png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
723 0 : fclose(fp);
724 :
725 0 : return true;
726 0 : }
727 :
728 : #if EDIT
729 : //------------------------------------------------------------------------------
730 : void Engine::getTerrainInfo(int &x, int &z, float &height, int &type, float &red, float &green, float &blue) {
731 : if (mainCamera_ == NULL)
732 : return;
733 :
734 : Vector position = c2_->getPosition();
735 :
736 : x = (int)(position.x / 5.0f);
737 : z = -(int)(position.z / 5.0f);
738 : currentLevel_->getTerrainInfo(x, z, height, type, red, green, blue);
739 : }
740 :
741 : //------------------------------------------------------------------------------
742 : void Engine::updateTerrain(int &x, int &z, float &height, int &type, float &red, float &green, float &blue) {
743 : if (!mainCamera_)
744 : return;
745 :
746 : if (mainCamera_->id_ == 2 || mainCamera_->id_ == 3) {
747 : Vector position = c2_->getPosition();
748 : x = (int)(position.x / 5.0f);
749 : z = -(int)(position.z / 5.0f);
750 : currentLevel_->updateTerrain(x,z,height,type,red,green,blue);
751 :
752 : last_x = x;
753 : last_z = z;
754 : last_type = type;
755 : last_red = red;
756 : last_green = green;
757 : last_blue = blue;
758 : last_height = height;
759 : }
760 : }
761 :
762 : //------------------------------------------------------------------------------
763 : void Engine::updateColor(float &red, float &green, float &blue) {
764 : if (!mainCamera_)
765 : return;
766 :
767 : if (mainCamera_->id_ == 2 || mainCamera_->id_ == 3) {
768 : Vector position = c2_->getPosition();
769 :
770 : int x = (int)(position.x / 5.0f);
771 : int z = -(int)(position.z / 5.0f);
772 : currentLevel_->updateColor(x, z, red, green, blue);
773 :
774 : last_red = red;
775 : last_green = green;
776 : last_blue = blue;
777 : }
778 : }
779 : #endif
|