std::shared_ptr<Terrain> ResourceManager::LoadTerrain(const std::string& filePath)
{
int nrChannels;
unsigned int vertexCount;
int width;
int length;
float w = 10.0f, l = 10.0f;
unsigned char* data = stbi_load(filePath.c_str(),&width, &length,&nrChannels,0);
std::vector<glm::vec3> vertices(width * length);
std::vector<unsigned int> triangles;
if (data == NULL)
{
std::cout << "Cannot load the heightmap!" << std::endl;
}
for (int z = 0; z < length; z++)
{
for (int x = 0; x < width; x++)
{
// normalizing the x and z of the vector
glm::vec3 vertex = glm::vec3(x/(float)width,0,z/(float)length);
// multiplying by the width and length
vertex.x *= w;
vertex.z *= l;
// shifting the center to be in the center of the object.
vertex.x -= width/2;
vertex.z -= length/2;
vertices[vertexCount] = vertex;
// unsigned char* pixelOffset = data + (z + this->length * x) * nrChannels;
// std::cout << "red " << static_cast<unsigned int>(pixelOffset[0]) << std::endl;
if ((vertexCount+1 % width) != 0 && z+1 < length)
{
triangles.push_back(vertexCount);
triangles.push_back(vertexCount + width);
triangles.push_back(vertexCount + width + 1);
triangles.push_back(vertexCount);
triangles.push_back(vertexCount + width + 1);
triangles.push_back(vertexCount + 1);
}
vertexCount++;
}
}
stbi_image_free(data);
// OPENGL Part
GLuint IBO, VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * triangles.size(), triangles.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,12,(void*)0);
std::shared_ptr<Terrain> terrain = std::make_shared<Terrain>(Terrain(VBO, IBO, triangles.size(), Transform()));
terrain->transform.SetScale(glm::vec3(1.0f,1.0f,1.0f));
terrain->transform.SetPosition(glm::vec3(0.0f,0.0f,0.0f));
for (int i = 0; i < triangles.size(); i++)
{
std::cout << triangles[i] << std::endl;
}
return terrain;
}
void Terrain::Bind()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
}
void Terrain::Unbind()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
EDIT : The code for the rendering is below :
Renderer.cpp
void Renderer::Draw(std::unique_ptr<Scene>& scene, std::shared_ptr<Terrain> terrain)
{
glm::mat4 projection = scene->camera.GetProjectionMatrix();
glm::mat4 view = scene->camera.GetViewMatrix();
this->shader.Use();
this->shader.SetMat4("projection", projection);
this->shader.SetMat4("view", view);
this->shader.SetMat4("model", terrain->transform.getWorldMatrix());
std::cout << glGetError() << std::endl;
terrain->Render();
std::cout << glGetError() << "after render" << std::endl;
for (int i = 0 ; i < scene->gameObjects.size(); i++)
{
glm::mat4 model = scene->gameObjects[i]->transform.getWorldMatrix();
this->shader.SetMat4("model", model);
scene->gameObjects[i]->Render();
}
}