The main problem is that if I only set the vertex attrib data (which is a wrapper of glBufferData and glVertexAttribPointer) in the Model::CreateInstance method, the model shows up, but the vertices are in the completely wrong place. However, if I set the vertex data in the Model::Draw method, the model shows up fine every time. Can anyone think of why this is happening?
#include "stdafx.h"
#include "Model.h"
#include <FreeImage.h>
Model::Model(std::string filename)
{
Initialize(filename, "model_basic.vert", "model_basic.frag", ModelType3DS);
}
Model::Model(std::string filename, std::string vertexShader, std::string fragmentShader)
{
Initialize(filename, vertexShader, fragmentShader, ModelType3DS);
}
Model::Model(std::string filename, std::string vertexShader, std::string fragmentShader, ModelType type)
{
Initialize(filename, vertexShader, fragmentShader, type);
}
void Model::Initialize(std::string filename, std::string vertexShader, std::string fragmentShader, ModelType type)
{
m_TotalFaces = 0;
m_VertexShader = vertexShader;
m_FragmentShader = fragmentShader;
m_model = lib3ds_file_load(filename.c_str());
// If loading the model failed, we throw an exception
if(!m_model)
{
throw strcat("Unable to load ", filename.c_str());
}
bbox = new BoundingBox();
glGenVertexArrays(1, &m_vaoHandle);
}
// Destructor
Model::~Model()
{
glDeleteBuffers(1, &m_vaoHandle);
if(m_model != NULL)
{
lib3ds_file_free(m_model);
}
for(int i = 0; i < m_Shaders.size(); i++) {
delete m_Shaders[i];
}
}
void Model::CreateInstance()
{
GLSLProgram *shader = new GLSLProgram(m_VertexShader, m_FragmentShader, 3);
if(shader->compile()) {
if(shader->link()) {
m_Positions.push_back(vec4());
m_Angles.push_back(0);
m_Scales.push_back(0);
shader->use();
shader->setAttribData("VertexPosition", vertices, sizeof(Lib3dsVector) * 3 * m_TotalFaces, GL_STATIC_DRAW);
shader->setAttribData("VertexNormal", normals, sizeof(Lib3dsVector) * 3 * m_TotalFaces, GL_STATIC_DRAW);
shader->setAttribData("VertexTexCoord", texels, sizeof(Lib3dsTexel) * 3 * m_TotalFaces, GL_STATIC_DRAW);
m_Shaders.push_back(shader);
}
}
}
void Model::ApplyTexture(int index, std::string textureFile, FREE_IMAGE_FORMAT type, GLenum texNum, int texId)
{
if(index < m_Shaders.size()) {
Util::load_texture(m_Shaders[index], textureFile, type, texNum, texId, "Tex1");
}
}
// Copy vertices and normals to the memory of the GPU
void Model::ReadData()
{
assert(m_model != NULL);
// Calculate the number of faces we have in total
GetFaces();
// Allocate memory for our vertices and normals
vertices = new Lib3dsVector[m_TotalFaces * 3];
normals = new Lib3dsVector[m_TotalFaces * 3];
texels = new Lib3dsVector[m_TotalFaces * 2];
Lib3dsMesh * mesh;
unsigned int FinishedFaces = 0;
// Loop through all the meshes
for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
{
lib3ds_mesh_calculate_normals(mesh, &normals[FinishedFaces*3]);
// Loop through every face
for(unsigned int cur_face = 0; cur_face < mesh->faces;cur_face++)
{
Lib3dsFace * face = &mesh->faceL[cur_face];
for(unsigned int i = 0;i < 3;i++)
{
float *pos = mesh->pointL[face->points[i]].pos;
/*vec4 pos_vec = vec4(pos[0], pos[1], pos[2], 1.0);
pos_vec = translate * pos_vec;
pos[0] = pos_vec.x;
pos[1] = pos_vec.y;
pos[2] = pos_vec.z;*/
memcpy(&vertices[FinishedFaces*3 + i], pos , sizeof(Lib3dsVector));
float *texel = mesh->texelL[face->points[i]];
if(texel) {
memcpy(&texels[FinishedFaces*2 + i], texel, sizeof(Lib3dsTexel));
}
bbox->AddPoint(vec3(pos[0], pos[1], pos[2]));
}
FinishedFaces++;
}
}
bbox->Calculate();
lib3ds_file_free(m_model);
m_model = NULL;
}
// Count the total number of faces this model has
void Model::GetFaces()
{
assert(m_model != NULL);
m_TotalFaces = 0;
Lib3dsMesh * mesh;
// Loop through every mesh
for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
{
// Add the number of faces this mesh has to the total faces
m_TotalFaces += mesh->faces;
}
}
// Render the model using Vertex Buffer Objects
void Model::Draw(int index, glm::mat4 modelViewMatrix, glm::mat4 projectionMatrix, glm::mat3 normalMatrix)
{
if(index < m_Shaders.size()) {
GLSLProgram *m_Shader = m_Shaders[index];
m_Shader->use();
m_Shader->setUniform("ModelViewMatrix", modelViewMatrix);
m_Shader->setUniform("NormalMatrix", normalMatrix);
m_Shader->setUniform("ProjectionMatrix", projectionMatrix);
m_Shader->setUniform("MVP", projectionMatrix * modelViewMatrix);
vec3 Kd = vec3(139/255.0f, 119/255.0f, 101/255.0f);
m_Shader->setUniform("Kd", Kd);
//program->setUniform("Ld", Kd);
vec3 Ka = vec3(139/255.0f, 119/255.0f, 101/255.0f);
m_Shader->setUniform("Ka", Ka);
vec3 Ks = vec3(1.0, 1.0, 1.0);
m_Shader->setUniform("Ks", Ks);
vec4 LightPosition = vec4(0.0f, 0.0f, 0.0f, 0.0f);
//LightPosition = projection * modelview * LightPosition;
m_Shader->setUniform("LightPosition", LightPosition);
vec3 LightIntensity = vec3(1.0f, 1.0f, 1.0f);
m_Shader->setUniform("LightIntensity", LightIntensity);
m_Shader->setUniform("Shininess", 3.0f);
m_Shader->setAttribData("VertexPosition", vertices, sizeof(Lib3dsVector) * 3 * m_TotalFaces, GL_STATIC_DRAW);
m_Shader->setAttribData("VertexNormal", normals, sizeof(Lib3dsVector) * 3 * m_TotalFaces, GL_STATIC_DRAW);
m_Shader->setAttribData("VertexTexCoord", texels, sizeof(Lib3dsTexel) * 2 * m_TotalFaces, GL_STATIC_DRAW);
//glBindVertexArray(m_vaoHandle);
glDrawArrays(GL_TRIANGLES, 0, m_TotalFaces * 3);
}
}
void Model::SetPosition(int index, vec3 newPosition)
{
if(m_Positions.size() > index) {
m_Positions[index] = vec4(newPosition, 1.0f);
}
}
vec4 Model::GetPosition(int index)
{
if(m_Positions.size() > index) {
return m_Positions[index];
}
return vec4();
}
void Model::SetAngle(int index, float angle)
{
if(m_Angles.size() > index) {
m_Angles[index] = angle;
}
}
float Model::GetAngle(int index)
{
if(m_Angles.size() > index) {
return m_Angles[index];
}
return 0;
}
void Model::SetScale(int index, float scale)
{
if(m_Scales.size() > index) {
m_Scales[index] = scale;
}
}
float Model::GetScale(int index)
{
if(m_Scales.size() > index) {
return m_Scales[index];
}
return 0;
}






