Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Question about glBufferData


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 metsfan   Members   -  Reputation: 460

Like
0Likes
Like

Posted 01 April 2012 - 01:38 PM

Hey all, I had a question about glBufferData which is probably simple to answer, but I can't seem to figure it out. I have several 3d models in my application that I use over and over. I had the idea to create a Model class, which reads in the mesh, then creates instances of a class called GLSLProgram, which is basically a level of abstraction on top of a GLSL shader program. I want to set it up so that when I create an instance of the model, it will initialize a new shader, and populate the shader program with the vertex, normal, and texel data, then when I draw the model, just update the modelview and projection matrices, and lighting information, so that OpenGL doesn't need to load the same vertex mesh data over and over. This method doesn't seem to be working, however if I re-populate the vertex buffer every time I draw the model, everything works fine. I know people are going to ask for code, so I'll include the Model class.

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;
}


Sponsor:

#2 metsfan   Members   -  Reputation: 460

Like
0Likes
Like

Posted 01 April 2012 - 02:14 PM

Nevermind, solved the issue, the issue was the way I was using Vertex Array Objects, having each model have its own VAO solved this issue.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS