I'm attempting to create a terrain, however the same error keeps on appearing. Where triangles form links between verices that are not close to each other, i.e. v1 to v100, causing malformed triangles to form when rendering.
The code to reproduce this:
class Generator
{
TerrainMesh gen_emptyTerrainMesh = TerrainMesh();
/* Parameters for the class */
int gen_size;
/**
\brief for loop from 0 to n, making x, y, z
coordinates, n's default is 128
\param arr Array to store the vertices in
**/
void gen(std::vector<vec3>* arr) const
{
float x = 0.0f, y = 0.0f, z = 0.0f;
for (int j = 0; j < gen_size; j++)
{
for (int i = 0; i < gen_size; i++)
{
x = static_cast<float>(i);
// y += rand() % 10 - 1.0f;
z = static_cast<float>(j);
arr->push_back(vec3(x, y, z));
// DEBUG
// printf("[BUILD INFO]: x: %F, y: %F, z: %F \n", x, y, z);
}
}
}
/**
*\brief Using struct Triangle and vector convert x, y z
* coordinates from vertices into quads made up of 2 triangles
* stored sequentially.
*
*
* Triangle {
*
* p: n
*
* p2: n + 1 \ n + 2 + size
*
* p3: n + 2 + size \ n + 1 + size
*
* }
*
* At the same time work out normals for each Triangle
**/
void toTriangle(const std::vector<vec3>* arr, std::vector<Triangle>* tri_arr) const
{
int crrPointer = 0;
// Convert vector float to vector Triangle/Quad format
for (int n = 0; n < arr->size(); n++)
{
if (n % gen_size == 0)
crrPointer += 1;
if (crrPointer < (gen_size - 1) && n % (gen_size - 1) != 0) {
tri_arr->push_back(Triangle{arr->at(n), arr->at(n + 1), arr->at(n + 2 + gen_size)});
tri_arr->push_back(Triangle{arr->at(n), arr->at(n + 2 + gen_size), arr->at(n + 1 + gen_size), true});
}
}
// Work out the normal for each triangle
// needs to be done
}
static void toVectorArray(std::vector<float>* vertices, const std::vector<Triangle>* tri_arr)
{
for (auto &tri : *tri_arr)
{
vertices->push_back(tri.p.x);
vertices->push_back(tri.p.y);
vertices->push_back(tri.p.z);
vertices->push_back(tri.normal.x);
vertices->push_back(tri.normal.y);
vertices->push_back(tri.normal.z);
vertices->push_back(0.0);
vertices->push_back(1.0);
vertices->push_back(tri.p2.x);
vertices->push_back(tri.p2.y);
vertices->push_back(tri.p2.z);
vertices->push_back(tri.normal.x);
vertices->push_back(tri.normal.y);
vertices->push_back(tri.normal.z);
vertices->push_back(1.0);
vertices->push_back(1.0);
vertices->push_back(tri.p3.x);
vertices->push_back(tri.p3.y);
vertices->push_back(tri.p3.z);
vertices->push_back(tri.normal.x);
vertices->push_back(tri.normal.y);
vertices->push_back(tri.normal.z);
if (!tri.isP4)
{
vertices->push_back(1.0);
vertices->push_back(0.0);
} else
{
vertices->push_back(0.0);
vertices->push_back(0.0);
}
}
}
// DEBUG
//----------------------------------------------------------------------------
static std::string getTime()
{
time_t result = time(nullptr);
char str[26];
ctime_s(str, sizeof str, &result);
// Remove the "\n" source: https://stackoverflow.com/a/41705582
if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0';
return str;
}
//----------------------------------------------------------------------------
public:
Generator(std::vector<float>* p_vecArray, int p_size = 128): gen_size(p_size)
{
std::vector<vec3> tempVec;
std::vector<Triangle> triangles;
// Make the vertices, gen_size * gen_size
gen(&tempVec);
// Turn them into Triangles so its easier
// to work out normals and texture coordinates
toTriangle(&tempVec, &triangles);
std::cout << p_vecArray->size() << "\n";
// turn the triangles into
// x, y, z, nx, ny, nz, texX, texY
// for each vertex
toVectorArray(p_vecArray, &triangles);
std::cout << p_vecArray->size() << "\n";
// printTriangles(&triangles);
}
};
Triangle struct
struct Triangle
{
vec3 p;
vec3 p2;
vec3 p3;
bool isP4 = false;
vec3 normal = {0, 0, 0};
};
I've tried to use Quad instead of triangles to see if that helped but to no avail.
I think the error has to do with how they are being converted into trianlges or how they are in order inside the vertices
vector, checked online to see if that was the case but haven't come across anything meaningful to suggest that order is important inside opengl.