| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include "HeightMap.h"
- #include "stb_image.h"
- #include "Vector.h"
- #include "LevelObject.h"
- #include <GL/freeglut.h>
- #include <iostream>
- #include <string>
- #include "World.h"
- #define RED 0
- #define GREEN 1
- #define BLUE 2
- #define ALPHA 3
- HeightMap::HeightMap(const std::string &file, World* world)
- {
- int bpp;
- unsigned char* imgData = stbi_load(file.c_str(), &width, &height, &bpp, 4);
- auto heightAt = [&](int x, int y)
- {
- return (imgData[(x + y * width) * 4 ] / 256.0f) * 50.0f;
- };
- auto valueAt = [&](int x, int y, int offset = 0)
- {
- return imgData[(x + y * width) * 4 + offset];
- };
- for (int y = 0; y < height-1; y++)
- {
- for (int x = 0; x < width-1; x++)
- {
- int offsets[4][2] = { { 0, 0 },{ 1, 0 },{ 1, 1 },{ 0, 1 } };
- Vec3f ca(0, heightAt(x, y + 1) - heightAt(x, y), 1);
- Vec3f ba(1, heightAt(x + 1, y) - heightAt(x, y), 0);
- if (valueAt(x, y, GREEN) > 0)
- {
- world->addLevelObject(new LevelObject(world->getObjectFromValue(valueAt(x, y, GREEN)).first, Vec3f(x, heightAt(x, y), y), Vec3f(0, 0, 0), 1, world->getObjectFromValue(valueAt(x, y, GREEN)).second));
- }
- Vec3f normal = ca.cross(ba);
- normal.Normalize();
- for (int i = 0; i < 4; i++)
- {
- float h = heightAt(x + offsets[i][0], y + offsets[i][1]);
- vertices.push_back(Vertex{ (float)(x + offsets[i][0]), h, (float)(y + offsets[i][1]),
- normal.x, normal.y, normal.z,
- (x + offsets[i][0]) / (float)height, (y + offsets[i][1]) / (float)width } );
- }
- }
- }
- glGenTextures(1, &imageIndex);
- glBindTexture(GL_TEXTURE_2D, imageIndex);
- glTexImage2D(GL_TEXTURE_2D,
- 0, //level
- GL_RGBA, //internal format
- width, //width
- height, //height
- 0, //border
- GL_RGBA, //data format
- GL_UNSIGNED_BYTE, //data type
- imgData); //data
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- stbi_image_free(imgData);
- }
- HeightMap::~HeightMap()
- {
- glDeleteTextures(1, &imageIndex);
- }
- void HeightMap::Draw()
- {
- glEnable(GL_LIGHTING);
- float color[] = { 0.7f, 0.7f, 0.7f, 1 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, imageIndex);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- //glEnableClientState(GL_COLOR_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, sizeof(Vertex), ((float*)vertices.data()) + 0);
- glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), ((float*)vertices.data()) + 6);
- glNormalPointer(GL_FLOAT, sizeof(Vertex), ((float*)vertices.data()) + 3);
- glDrawArrays(GL_QUADS, 0, vertices.size());
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- //glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- }
- float HeightMap::GetHeight(float x, float y)
- {
- int ix = x;
- int iy = y;
- int index = (ix + (width - 1) * iy) * 4;
- if (index + 3 >= vertices.size())
- index = vertices.size() - 4;
- if (index < 0)
- index = 0;
- Vertex& a = vertices[index];
- Vertex& b = vertices[index+1];
- Vertex& c = vertices[index+3];
- float lowervalue = ((b.z - c.z)*(a.x - c.x) + (c.x - b.x)*(a.z - c.z));
- float labda1 = ((b.z - c.z)*(x - c.x) + (c.x - b.x)*(y - c.z)) / lowervalue;
- float labda2 = ((c.y - a.y)*(x - c.x) + (a.x - c.x)*(y - c.y)) / lowervalue;
- float labda3 = 1 - labda1 - labda2;
- Vertex z = a * labda1 + b * labda2 + c * labda3;
- // Vertex z = (a * labda1) + (b * labda2) ;
- return z.y;
- }
- int HeightMap::GetSize()
- {
- return height >= width ? height : width;
- }
- void HeightMap::SetTexture(const std::string &file)
- {
- int bpp, width2, height2;
- unsigned char* imgData = stbi_load(file.c_str(), &width2, &height2, &bpp, 4);
- glBindTexture(GL_TEXTURE_2D, imageIndex);
- glTexImage2D(GL_TEXTURE_2D,
- 0, //level
- GL_RGBA, //internal format
- width2, //width
- height2, //height
- 0, //border
- GL_RGBA, //data format
- GL_UNSIGNED_BYTE, //data type
- imgData); //data
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- stbi_image_free(imgData);
- }
|