PDA

View Full Version : How to make a rectangular grid of triangles?



cjntifo
07-02-2016, 04:20 PM
I'm using OpenGL, GLFW and GLEW to create a simulation of water waves for a school project. I'm using a textured grid and will manipulate said grid in the vertex shader.

I tried to create the grid by adapting the GeometryGenerator class in Frank Luna's book "Introduction to 3D Game Programming". I created the function but it gives me an odd scalene triangle instead of the grid.
I have attempted multiple of my own fixes and forums to no success.

Can anyone suggest a fix or a different function which would work better?

Here are the relevant snippets of code:


struct vertex
{
GLfloat x, y, z;
GLfloat u, v;
};

struct index
{
GLuint a, b, c;
};

struct MeshData
{
std::vector<vertex> Vertices;
std::vector<index> Indices;
//std::vector<GLuint> Indices;
};
void CreateGrid(float width, float depth, int m, int n, MeshData& meshData)
{
int vertexCount = m*n;
int faceCount = (m-1)*(n-1)*2;
// Create the vertices.

float halfWidth = 0.5f*width;
float halfDepth = 0.5f*depth;

float dx = width / (n-1);
float dz = depth / (m-1);

float du = 1.0f / (n-1);
float dv = 1.0f / (m-1);


meshData.Vertices.resize(vertexCount);
for(GLfloat i = 0.0f; i < m; ++i)
{
GLfloat z = halfDepth - i*dz;
for(GLfloat j = 0.0f; j < n; ++j)
{
//code
GLfloat x = -halfWidth + j*dx;

meshData.Vertices[i*n+j].x = x;
meshData.Vertices[i*n+j].y = 0.0f;
meshData.Vertices[i*n+j].z = z;

meshData.Vertices[i*n+j].u = j*du;
meshData.Vertices[i*n+j].v = i*dv;

//vertex temp = {x, 0.0f, z, j*du, i*dv};
//meshData.Vertices.push_back(temp);
}
}
//indices
meshData.Indices.resize(faceCount);

GLuint offset = 0;
for(GLuint i = 0; i < m-1; ++i)
{
for(GLuint j = 0; j < n-1; ++j)
{
//offset = x * m;
index temp =
{
i*n+j,
i*n+j+1,
(i+1)*n+j
};

index temp_2 =
{
(i+1)*n+j,
i*n+j+1,
(i+1)*n+j+1
};

meshData.Indices.push_back(temp);
meshData.Indices.push_back(temp_2);
}
}
}


Also passing the data to the VAO.



#pragma region "object_initialization"
// Set the object data (buffers, vertex attributes)

MeshData grid;

CreateGrid(30, 20, 2.0f, 3.0f, grid);

// Setup plane VAO
GLuint planeVAO, planeVBO, planeEBO;
glGenVertexArrays(1, &planeVAO);

glGenBuffers(1, &planeVBO);
glGenBuffers(1, &planeEBO);
glBindVertexArray(planeVAO);

glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex) * grid.Vertices.size(), &grid.Vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, planeEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index) * grid.Indices.size(), &grid.Indices, GL_STATIC_DRAW);


glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glBindVertexArray(0);

// Load textures
GLuint floorTexture = loadTexture("C://path to.../brushwater.png");
#pragma endregion

Here is the rendering code:


while(!glfwWindowShouldClose(window))
{
// Set frame time
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;

// Check and call events
glfwPollEvents();
Do_Movement();

// Clear the colorbuffer
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Draw objects
shader.Use();
glm::mat4 model;
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(camera.Zoom, (float)screenWidth/(float)screenHeight, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(shader.Pro gram, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(shader.Pro gram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
// Floor
glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
model = glm::mat4();
glUniformMatrix4fv(glGetUniformLocation(shader.Pro gram, "model"), 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 3*grid.Indices.size());
glBindVertexArray(0);


// Swap the buffers
glfwSwapBuffers(window);
}

My outputs now are textured scalene triangles.
Thanks in advanced for reading it though, and thanks for your help!

john_connor
07-03-2016, 02:02 PM
there is NO WAY to render lines of a grid if you use:
glDrawArrays(GL_TRIANGLES, ...);
because GL_TRIANGLES ONLY generates triangles, if you pass only 2 points, it will rener nothing

you have to use GL_LINES (or GL_LINE_LOOP) as rendering mode in the draw call if you want to render lines


ps: shouldnt it be

glBufferData(GL_ARRAY_BUFFER, sizeof(vertex) * grid.Vertices.size(), &grid.Vertices.data(), GL_STATIC_DRAW);
rather than

glBufferData(GL_ARRAY_BUFFER, sizeof(vertex) * grid.Vertices.size(), &grid.Vertices, GL_STATIC_DRAW);
?