I am trying to use a derived class of Mesh to create a new object SolidRectangle(bad name), I also am trying to transform my vertices before sending them to the shader.
Every time I load a vertex, I save two copies: one in vertices, one in vertlets.
My plan is to multiple the position of the vertex by the transformation matrix and store these values in verlets. So that I can translate, rotate, scale my objects, and then pass them to the shader which multiples by the projection matrix to get the final position.
I traced my code and the matrix-vector multiplication is coming out right but it doesn’t work. It’s as if the transformation isn’t been applied. I already tried making my std::vector into <Vertex*> with pointers and it broke everything even after I changed “.” to “->” on everything. Do I need to bind to the vertex buffer object every frame when I update my vertices? I was on the impression it was saving the location in memory of the Vertex array and I could update these values each frame?
class Mesh
{
private:
string filename;
GLuint ibo = 0;
GLuint vbo = 0;
GLuint vao = 0;
vec_int elements;
vec_vertex vertices;
vec_vertex vertlets;
Transform* transform;
void addElements();
void addVertices();
void addVertlets();
public:
Mesh();
~Mesh();
void addElement(int value);
void addVertex(Vertex value);
void Compile();
void Update(float dt);
void Render();
int getNumOfElements() { return elements.size(); }
int getNumOfVertices() { return vertices.size(); }
std::vector<int> getElements(){ return elements; }
std::vector<Vertex> getVertices(){ return vertices; }
Transform* getTransform() { return transform; }
};
...
void Mesh::addVertlets()
{
if (vbo)
{
//Bind
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//Load Vertices
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)* vertlets.size(), &vertlets[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)sizeof(Vector3f));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(Vector3f)+sizeof(Vector3f)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(Vector3f)+sizeof(Vector3f)+sizeof(Vector3f)));
glEnableVertexAttribArray(3);
}
}
...
void Mesh::Compile()
{
glBindVertexArray(vao);
//Add Object
addElements();
addVertlets();
glBindVertexArray(0);
}
void Mesh::Update(float dt)
{
Matrix4f transformation = getTransform()->getTransformation();
for (int i = 0; i < getNumOfVertices(); i++)
{
vertlets[i].setPosition(transformation * vertices[i].getPosition());
}
}
void Mesh::Render()
{
//Bind
glBindVertexArray(vao);
if (elements.size() == 36)
{
cout << "Position: " << vertlets[0].getPosition().getX() << endl;
}
glDrawElements(GL_TRIANGLES, elements.size(), GL_UNSIGNED_INT, 0);
//Unbind
glBindVertexArray(0);
//Disable Attributes
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
}
void Mesh::addElement(int value) { elements.push_back(value); }
void Mesh::addVertex(Vertex value) { vertices.push_back(value); vertlets.push_back(value); }
...
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include "Mesh.h"
class SolidRectangle : public Mesh
{
private:
float width;
float height;
float depth;
public:
SolidRectangle();
SolidRectangle(float width, float height, float depth);
void Update(float dt);
void Render();
};
#endif
...
SolidRectangle::SolidRectangle()
{
width = 1;
height = 1;
depth = 1;
generateFaceTop(this);
generateFaceBot(this);
generateFaceFront(this);
generateFaceBack(this);
//Compile Mesh
Compile();
getTransform()->setPosition(0, 0, 0);
getTransform()->setRotation(0, 0, 0);
getTransform()->setScale(1.0f, 1.0f, 1.0f);
}
SolidRectangle::SolidRectangle(float width, float height, float depth)
{
this->width = width;
this->height = height;
this->depth = depth;
generateFaceTop(this);
generateFaceBot(this);
generateFaceFront(this);
generateFaceBack(this);
//Compile Mesh
Compile();
getTransform()->setPosition(0, 0, 0);
getTransform()->setRotation(0, 0, 0);
getTransform()->setScale(width/2, height/2, depth/2);
}
...
static void generateFaceFront(Mesh* mesh)
{
int size = mesh->getNumOfVertices();
mesh->addElement(size + 0); mesh->addElement(size + 2); mesh->addElement(size + 1);
mesh->addElement(size + 0); mesh->addElement(size + 3); mesh->addElement(size + 2);
//Back Plane
mesh->addVertex(Vertex(Vector3f(10, 10, -10), Vector3f(1, 1, 1), Vector3f(0, 0, -1), Vector2f(1, 1)));
mesh->addVertex(Vertex(Vector3f(-10, 10, -10), Vector3f(1, 1, 1), Vector3f(0, 0, -1), Vector2f(0, 1)));
mesh->addVertex(Vertex(Vector3f(-10, -10, -10), Vector3f(1, 1, 1), Vector3f(0, 0, -1), Vector2f(0, 0)));
mesh->addVertex(Vertex(Vector3f(10, -10, -10), Vector3f(1, 1, 1), Vector3f(0, 0, -1), Vector2f(1, 0)));
}
...
//Setup Player
player = new Player();
player->setMesh(new SolidRectangle(50.0f, 100.0f, 30.0f));
player->setPosition(Vector3f(0, 100.0f, 0));
...
//Update Player Position in Transform
mesh->getTransform()->setPosition(Position);
//Update Mesh Transformation
mesh->Update(dt);
...
void Game::Update(float dt)
{
temp += dt;
player->setPosition(Vector3f(10.0f * sin(temp), 0, 10.0f * cos(temp)));
player->Update(dt);
}
The width of that hallway is 200.0f and the faces start out at 20 width and should be position so its above the floor and scaled. It should be much larger…
[ATTACH=CONFIG]823[/ATTACH]
When I switch everything over to Vertex*, the line that fails is:
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)* vertlets.size(), &vertlets[0], GL_STATIC_DRAW);
When I use std::vector then passing &verlets[0] works fine. But for std::vector<Vertex*> this won’t work. How do I fix this?
On the StackOverflow they suggest:
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)* vertlets.size(), vertlets.data(), GL_STATIC_DRAW);
But this does not work for me either.
Edit:
Changed to GL_DYNAMIC_DRAW, still not working. I have verified through cout’ing the position that the data is being updated properly the line before glDrawElements() is called. Still not working.
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)* vertlets.size(), %vertlets[0] GL_DYANMIC_DRAW);