Jump to content


lib3ds and texture mapping help

opengl

1 reply to this topic

#1 Adam Burton

    New Member

  • Members
  • Pip
  • 1 posts

Posted 09 April 2012 - 11:49 AM

hi there



i have fixed up a few problems on my 3ds loader using lib3ds, my only problem now is that i have no idea how to load a texture map onto the loaded model. do i have to use lib3ds Material or something like that?



3ds.h



#include "main.h"
#include "lib3ds/file.h"
#include "lib3ds/mesh.h"
#include "lib3ds/material.h"

class Object
{
public:
Object(const char* filename);
virtual ~Object();
virtual void Draw() const;
virtual void CreateVBO();
void applyTexture(const char*texfilename);

protected:
void GetFaces();
unsigned int m_TotalFaces;
Lib3dsFile * m_model;

Lib3dsMesh* Mesh;
GLuint textureObject;
GLuint m_VertexVBO, m_NormalVBO, m_TexCoordVBO;
};



3dsloader.cpp

#include "3dsloader.h"
#include "shader.h"[/size][/color][/font][/left]
[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]Object::Object(const char* filename)
{
m_TotalFaces = 0;
m_model = lib3ds_file_load(filename);
// If loading the model failed, we throw an exception
if(!m_model)
{
  cout << ("Unable to load ", filename);
}
Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(m_model,"filename");[/size][/color][/font]

[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]}
Object::~Object()
{
if(m_model) // if the file isn't freed yet
  lib3ds_file_free(m_model); //free up memory
}[/size][/color][/font]
[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]void Object::GetFaces()
{
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 number of faces.
  m_TotalFaces += mesh->faces;
}  
}
void Object::CreateVBO()
{
  assert(m_model != NULL);
  // Calculate the number of faces we have in total
  GetFaces();
  // Allocate memory for our vertices and normals
  Lib3dsVector * vertices = new Lib3dsVector[m_TotalFaces * 3];
  Lib3dsVector * normals = new Lib3dsVector[m_TotalFaces * 3];
  Lib3dsTexel* texCoords = new Lib3dsTexel[m_TotalFaces * 3];

  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++)
    {
	   
		 if(mesh->texels)
		 {
		  memcpy(&texCoords[FinishedFaces*2 + i], mesh->texelL[face->points[ i ]], sizeof(Lib3dsTexel));
		 }  
		 memcpy(&vertices[FinishedFaces*3 + i], mesh->pointL[face->points[ i ]].pos, sizeof(Lib3dsVector));
  
    }
  
    FinishedFaces++;
   }

  }[/size][/color][/font]
[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]  // Generate a Vertex Buffer Object and store it with our vertices
  glGenBuffers(1, &m_VertexVBO);
  glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, vertices, GL_STATIC_DRAW);
  // Generate another Vertex Buffer Object and store the normals in it
  glGenBuffers(1, &m_NormalVBO);
  glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, normals, GL_STATIC_DRAW);
  // Generate a third VBO and store the texture coordinates in it.
  glGenBuffers(1, &m_TexCoordVBO);
  glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsTexel) * 3 * m_TotalFaces, texCoords, GL_STATIC_DRAW);[/size][/color][/font]
[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]  // Clean up our allocated memory
  delete vertices;
  delete normals;
  delete texCoords;

  // We no longer need lib3ds
  lib3ds_file_free(m_model);
  m_model = NULL;
}
void Object::applyTexture(const char*texfilename)
{

  textureObject = SOIL_load_OGL_texture(texfilename,SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID,SOIL_FLAG_MIPMAPS);
		 
    glBindTexture(GL_TEXTURE_2D,textureObject);// use our newest texture
}[/size][/color][/font]
[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]void Object::Draw() const
{[/size][/color][/font]

[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]// Enable vertex, normal and texture-coordinate arrays.
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); [/size][/color][/font]

[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]// Bind the VBO with the normals.
glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
// The pointer for the normals is NULL which means that OpenGL will use the currently bound VBO.
glNormalPointer(GL_FLOAT, 0, NULL);[/size][/color][/font]
[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);  
glTexCoordPointer(2, GL_FLOAT, 0,(char *) NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
glVertexPointer(3, GL_FLOAT, 0, NULL);
// Render the triangles.
glDrawArrays(GL_TRIANGLES, 0, m_TotalFaces * 3);[/size][/color][/font]

[font="helvetica, arial, verdana, tahoma, sans-serif"][color="#282828"][size=3]glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);  
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}


Posted Image

[left]the output should actually be a perfectly mapped pyramid with no black parts



#2 Vilem Otte

    Valued Member

  • Members
  • PipPipPipPip
  • 345 posts

Posted 10 April 2012 - 12:13 AM

Your code seems wrong.

You once create 3 * sizeof(Lib3dsTexel) - at
Lib3dsTexel* texCoords = new Lib3dsTexel[m_TotalFaces * 3];

Then you copy just 2 * sizeof(Lib3dsTexel) - at
memcpy(&texCoords[FinishedFaces*2 + i], mesh->texelL[face->points[ i ]], sizeof(Lib3dsTexel));

Then you load 3 * sizeof(Lib3dsTexel) to VRAM - definitely should be 2 * sizeof(Lib3dsTexel) - after you copy that array in the way thats shortening it of third dimension - at
glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsTexel) * 3 * m_TotalFaces, texCoords, GL_STATIC_DRAW);[/

And then at this 3 * sizeof(Lib3dsTexel) you're reading 2 coordinates - at
glTexCoordPointer(2, GL_FLOAT, 0,(char *) NULL);

I hope this hint is enough to point you in right way ;) - if you still don't understand it, I can write further info on this (commenting your code - what it actually does now and what should it do imo) :)
My blog about game development (and not just game development) - http://gameprogramme...y.blogspot.com/

If you don't know how to speed up application, go "roarrrrrr!", hit the compiler with the club and use -O3 :D





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users