Im trying to make a terrain from a grid of vertices and i have a bug and just cant find it.Im stuck with it for 3 hours.Im using c++ and opengl.Im plan to use a blendmap for texturing and a height map later.Anyway here's the code:
Heres how it should look like: http://postimg.org/image/9431kcvy7/
Heres how it looks: http://postimg.org/image/xxsoesqkp/
As you can see the tringles are separated by a 1 unit rectagle and it look like all the bottom points form a triangle with the point that has coordinates (0,0,0)
I know this problem might seem easy to solve but ive lost already 3 hours trying.Please help:)
Map.h
#ifndef MAP_H
#define MAP_H
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <windows.h>
using namespace std;
struct coordinate{
float x,y,z;
};
struct face{
int v[3];
int n[3];
};
struct uv{
float x;
float y;
};
class Map
{
private:
int mapX,mapY;
vector<coordinate> vertex;
vector<uv>textureCoordinates;
vector<coordinate>normals;
vector< vector<face> > faces;
string fileNameString;
sf::Image image[5];
sf::Color faceColor,blendPixel,p0,p1,p2;
sf::Image texture;
sf::Uint8 pixels[256*256*4];
unsigned int imageID[3],textureID;
public:
void load(const char *fileName);
void draw();
};
#endif // MAP_H
And Map.cpp
#include "Map.h"
#define blendMap 3
#define heightMap 4
void Map::load(const char *fileName)
{
int i,j;
fileNameString=fileName;
vector<face> F;
coordinate v;
face f;
image[0].loadFromFile(fileNameString+"/0.png");
image[1].loadFromFile(fileNameString+"/1.png");
image[2].loadFromFile(fileNameString+"/2.png");
image[blendMap].loadFromFile(fileNameString+"/blendMap.png");
image[heightMap].loadFromFile(fileNameString+"/heightMap.png");
mapX=image[blendMap].getSize().x;
mapY=image[blendMap].getSize().y;
for(i=-mapY/2;i<mapY/2;i++)
for(j=-mapX/2;j<mapX/2;j++)
{
v.x=j*0.5;
v.z=i*0.5;
vertex.push_back(v);
}
for(i=0;i<mapY-1;i++)
{
for(j=0;j<2*(mapX-1);j++)
F.push_back(f);
faces.push_back(F);
}
for(i=0;i<mapY-1;i++)
for(j=0;j<(mapX-1)*2;j+=2)
{
faces[i][j].v[0]=i*mapX+j;
faces[i][j].v[1]=i*mapX+j+1;
faces[i][j].v[2]=(i+1)*mapX+j;
faces[i][j+1].v[0]=i*mapX+j+1;
faces[i][j+1].v[1]=(i+1)*mapX+j+1;
faces[i][j+1].v[2]=(i+1)*mapX+j;
}
for(i=0;i<mapX*mapY;i++)
{
color=image[heightMap].getPixel(i/mapX,i%mapX);
vertex[i].y=0;//(float)color.r/25.5-10;
}
}
void Map::draw()
{
unsigned int i,j;
for(i=0;i<mapY-1;i++)
for(j=0;j<(mapX-1)*2;j+=2)
{
glBindTexture(GL_TEXTURE_2D,imageID[0]);
glBegin(GL_TRIANGLES);
glTexCoord2f (0,0);
glVertex3f(vertex[faces[i][j].v[0]].x , vertex[faces[i][j].v[0]].y , vertex[faces[i][j].v[0]].z);
glTexCoord2f (1,0);
glVertex3f(vertex[faces[i][j].v[1]].x , vertex[faces[i][j].v[1]].y , vertex[faces[i][j].v[1]].z);
glTexCoord2f (0,1);
glVertex3f(vertex[faces[i][j].v[2]].x , vertex[faces[i][j].v[2]].y , vertex[faces[i][j].v[2]].z);
glTexCoord2f (0,0);
glVertex3f(vertex[faces[i][j+1].v[0]].x , vertex[faces[i][j+1].v[0]].y , vertex[faces[i][j+1].v[0]].z);
glTexCoord2f (1,0);
glVertex3f(vertex[faces[i][j+1].v[1]].x , vertex[faces[i][j+1].v[1]].y , vertex[faces[i][j+1].v[1]].z);
glTexCoord2f (0,1);
glVertex3f(vertex[faces[i][j+1].v[2]].x , vertex[faces[i][j+1].v[2]].y , vertex[faces[i][j+1].v[2]].z);
glEnd();
}
}
A few things:
for(i=-mapY/2;i<mapY/2;i++)
This is dangerous and probably not the intention of the loop, anyway. You want to loop mapY
times. However, if mapY
is odd, you will loop only mapY - 1
times. E.g. if mapY = 3
, then -mapY / 2 = -1; mapY / 2 = 1
. So you will loop with the values -1
and 0
. That's a first problem, which results in too few vertices in your buffer (this is probably the main problem). Instead do the shifting on the coordinate level:
for(i = 0; i < mapY; i++)
for(j = 0; j < mapX; j++)
{
v.x = j * 0.5 - mapY / 2.0;
v.z = i * 0.5 - mapX / 2.0;
vertex.push_back(v);
}
Is there a reason why you use a vector<vector<...>>
for the faces? It will give you all kinds of problems regarding indexing as you already noticed. Just use a vector<Face>
and put all your faces in there. Usually, you create this structure once and never touch it again. So the 2D indexing is probably not necessary. If you want to stay with the 2D indexing, this loop has wrong bounds:
for(j=0;j<(mapX-1)*2;j+=2)
This upper bound is an inclusive bound. Therefore, use
for(j = 0; j <= (mapX - 1) * 2; j += 2)