PDA

View Full Version : Mesh doesn't show on screen



Bailey Carter
10-04-2017, 01:53 AM
Hello, I made a simple cloth simulator using OpenGL fixed function pipeline a while back. I wanted to go back to that project and perform modern OpenGL rendering techniques (programmable pipeline) so that the simulation is more efficient. I don't know where I am going wrong, but here is the code I hope someone can help me. The commented code is the old fixed function pipeline way:



// This function stores all the vertices in a vector container instead of immediately sending it to GPU
void Cloth::DrawTriangle(Particle* _p1, Particle* _p2, Particle* _p3, Vector3D _color)
{
//glColor3f(_color.GetX(), _color.GetY(), _color.GetZ()); Ignore this

//glVertex3f(_p1->GetPos().GetX(), _p1->GetPos().GetY(), _p1->GetPos().GetZ());
m_vertices.push_back(glm::vec3(_p1->GetPos().GetX(), _p1->GetPos().GetY(), _p1->GetPos().GetZ()));
//glVertex3f(_p2->GetPos().GetX(), _p2->GetPos().GetY(), _p2->GetPos().GetZ());
m_vertices.push_back(glm::vec3(_p2->GetPos().GetX(), _p2->GetPos().GetY(), _p2->GetPos().GetZ()));
//glVertex3f(_p3->GetPos().GetX(), _p3->GetPos().GetY(), _p3->GetPos().GetZ());
m_vertices.push_back(glm::vec3(_p3->GetPos().GetX(), _p3->GetPos().GetY(), _p3->GetPos().GetZ()));
}

// This function calls the function above to create the vertices and then sends them to OpenGL using vertex buffer objects
void Cloth::GetVertices()
{
//glBegin(GL_TRIANGLES);
for (int i = 0; i < m_width - 1; ++i)
{
for (int j = 0; j < m_height - 1; ++j)
{
Vector3D Color(0.5f, 0.7f, 1.0f);
DrawTriangle(GetParticle(i + 1, j), GetParticle(i, j), GetParticle(i, j + 1), Color);
DrawTriangle(GetParticle(i + 1, j + 1), GetParticle(i + 1, j), GetParticle(i, j + 1), Color);
}
}
//glEnd();
glGenVertexArrays(1, &m_VAO);
glBindVertexArray(m_VAO);

glGenBuffers(1, &m_VBO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(glm::vec3), &m_vertices[0], GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

// This function simply draws the cloth and also calls the first function above because we want to update the cloth every frame
void Cloth::Draw()
{
for (int i = 0; i < m_width - 1; ++i)
{
for (int j = 0; j < m_height - 1; ++j)
{
Vector3D Color(0.5f, 0.7f, 1.0f);
DrawTriangle(GetParticle(i + 1, j), GetParticle(i, j), GetParticle(i, j + 1), Color);
DrawTriangle(GetParticle(i + 1, j + 1), GetParticle(i + 1, j), GetParticle(i, j + 1), Color);
}
}

shader.UseProgram();
//shader.UpdateTransform(clothTransform, camera);

glBindVertexArray(m_VAO);

glDrawArrays(GL_TRIANGLES, 0, m_numberOfVertices);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

Vertex Shader

#version 430 core

// Attributes
layout (location = 0) in vec3 vertex_position;

// Uniforms
uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

void main()
{
//gl_Position = Projection * View * Model * vec4(vertex_position, 1.0f); // Results in black screen
gl_Position = vec4(vertex_position, 1.0f); // Results in red mesh stuck on screen
}

Fragment Shader

#version 430 core

out vec4 Fragment_Color;

void main()
{
Fragment_Color = vec4(1.0f, 0.0f, 0.0f, 1.0f); // Draw cloth in red color for now
}

This is the result without using the MVP in the Vertex Shader. I feel like I'm really close but for some reason it's not rendering correctly. In fact, no matter where I set the camera position, this red mesh (which I assume is the cloth) is like glued to the screen.

Please help, thank you very much in advance.
2496

PixelClear
10-06-2017, 12:51 PM
I think you need to multiply vertices by matrix in vertex shader.
I am assuming you are not sending vertices already in NDC space.
After vertex shader stage there will be many steps but in this case rasterizer will run after you vertex shader and will create fragments for vertices.
For this process rasterizer needs positions in NDC space and proper window transformation matrix that you will set via call to glViewPort().

Second thing either you have not posted whole code or you are really missing calls to update you uniform variables in vertex shader.
That could be a problem. So in your draw function


GLuint modelMatrixLocation;

GLuint viewMatrixLocation;

GLuint projectionMatrixLocation;

glm::mat4 projection;


function where you link shaders

{

// after linking
glUseProgram(progObject);
modelMatrixLocation = getUniformLocation(progObject,"Model"); //Exact name as in shader
viewMatrixLocation = getUniformLocation(progObject,"View"); //Exact name as in shader
projectionMatrixLocation = getUniformLocation(progObject,"Projection"); //Exact name as in shader

glUseProgram(0);
}

void ChangeSize(int w, int h)
{
glClearColor(0.0,0.0,0.0,1.0);
glViewport(0,0,w,h);
projection = glm:: perspective(45.0f,w/(float)h,0.1f, 1000.0f);
}

Draw()
{

glUserProgram(progObject);

//If you use glm for maths build matrix as follows
glm::mat4 view = glm::lookAt(glm::vec3(0.0,0.0,0.0),glm::vec3(0.0,0 .0,-5.0),glm::vec3(0.0,1.0,0.0));
glm::mat4 model= glm::translate(glm::mat4(1.0),glm::vec3(0.0,-3.0,-5)); //Adjust parameters here and above

//for projection matrix register change size function and calculate and set projection matrix there
//See change Size function you can register this using glut

//You need following calls
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE , &model[0][0]);
glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE , &view[0][0]);
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE , &projection[0][0]);

}


Please try this . Hope this will help.

Regards
PixelClear