NLS Engine  v0.1
The Next Logical Step in game engine design.
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines
HeightmapRenderable.cpp
Go to the documentation of this file.
00001 
00007 #pragma once
00008 
00009 #include <cassert>
00010 
00011 #include <EngineConfig.h>
00012 #include <CImg-1.5.0_beta/CImg.h>
00013 
00014 #include "../../../sharedbase/EventLogger.h"
00015 
00016 #include "../../RenderModule.h"
00017 
00018 #include "GRID.H"
00019 #include "HeightmapRenderable.h"
00020 
00021 namespace GraphicsCore {
00022 
00023   HeightmapRenderable::HeightmapRenderable(EntitySPTR owner, ModuleInterface* core, LPDIRECT3DDEVICE9 pd3dDevice) :
00024       RenderableComponent(owner, core) {
00025     this->pd3dDevice = pd3dDevice;
00026     
00027     this->grid = NULL;
00028     
00029     this->texture = NULL;
00030   }
00031   
00032   HeightmapRenderable::~HeightmapRenderable() {
00033 
00034   }
00035 
00036   void HeightmapRenderable::Render(LPDIRECT3DDEVICE9 pd3dDevice) {
00037     if (this->texture != NULL) {
00038       pd3dDevice->SetTexture(0, this->texture);
00039     }
00040     
00041     if (this->grid != NULL) {
00042       this->grid->DrawDirectXMesh(pd3dDevice);
00043     }
00044   }
00045 
00046   bool HeightmapRenderable::LoadHeightmapFromFile(const std::string& file) {
00047     float width, height;
00048     
00049     width = height = 256.0f;
00050     
00051     D3DXVECTOR3 v0(0.0f, 0.0f, 0.0f);
00052     D3DXVECTOR3 v1(width, 0.0f, 0.0f);
00053     D3DXVECTOR3 v2(width, 40.0f, height);
00054     D3DXVECTOR3 v3(0.0f, 0.0f, height);
00055     
00056     cimg_library::CImg<float> image;
00057     try {
00058       image = cimg_library::CImg<float>((NLS_ENGINE_DATA_PATH + file).c_str());
00059     }
00060     catch (cimg_library::CImgIOException&) {
00061       LOG(LOG_PRIORITY::MISSRESS, "Heightmap failed to load!");
00062       return false;
00063     }
00064 
00065     if (image.data() == NULL) {
00066       LOG(LOG_PRIORITY::MISSRESS, "Heightmap is empty.");
00067       return false;
00068     }
00069 
00070     MAP map;
00071     map.width = 128; // this is the biggest a 16 bit mesh can handle unfortunately.
00072     map.height = 128;
00073     map.array = new float[map.width * map.height];
00074     
00075     float value;
00076     unsigned int stepi = image.width() / map.width; // Compensate for scaling issues between the mesh and the image.
00077     unsigned int stepj = image.height() / map.height;
00078     
00079     for (unsigned int y = 0, k = 0, i = 0; y < map.height; ++y, i += stepi) {
00080       for (unsigned int x = 0, j = 0; x < map.width; ++x, ++k, j += stepj) {
00081         value = (image(i, j, 0, 0) + image(i, j, 0, 1) + image(i, j, 0, 2)) / 3.0f; // Use the average value of the channels (IE: greyscale value)
00082         map.array[k] = value / 255.0f; // Assuming a range of [0,255] for the input values, wanting [0.0f,1.0f].
00083       }
00084     }
00085 
00086     Grid* grid = new Grid(map, &v0, &v1, &v2, &v3);
00087     
00088     grid->setTexScale(1.0f / float(map.width));
00089     
00090     grid->CreateDirectXMesh(this->pd3dDevice);
00091     
00092     this->grid = grid;
00093     
00094     return true;
00095   }
00096 
00097   bool HeightmapRenderable::LoadTextureFromFile(const std::string& file) {
00098     HRESULT result;
00099     RenderModule* renderModule = this->GetRenderModule();
00100     
00101     // Verify that we actually have a pointer to a RenderModule
00102     assert(renderModule != NULL);
00103     
00104     result = renderModule->TextureFactory(NLS_ENGINE_DATA_PATH + file, &texture);
00105     
00106     return SUCCEEDED(result);
00107   }
00108 
00109 }