PDA

View Full Version : A segmentation error when I get size of the std::vector



8Observer8
3rd December 2014, 15:00
Hello!

I have a segmentation error on the this string: size_t size = meshes.size();


void meshLoader::draw(unsigned int programId)
{
size_t size = meshes.size();

for( unsigned int i = 0;i < meshes.size(); ++i )
meshes[i].draw( programId );
}

Please, run my application if you use Assimp. Or just see code

anda_skoa
3rd December 2014, 16:01
That usually means that "this" is not a valid instance.

Check the creation of the meshLoader instance and if you call its method and not on some invalid pointer

Cheers,
_

8Observer8
3rd December 2014, 17:35
I don't understand why it occur. I have a global variable "globalGLFunctions":


#include <QOpenGLFunctions_2_1>

// ...

QOpenGLFunctions_2_1 *globalGLFunctions;

// ...

Scene::Scene( QWidget *parent ) :
QGLWidget( parent )
{
makeCurrent();
globalGLFunctions = new QOpenGLFunctions_2_1;
globalGLFunctions->initializeOpenGLFunctions();
}

void mesh::draw(unsigned int programId)
{
//attribute vec3 vertex
int vertex = globalGLFunctions->glGetAttribLocation(programId,"vertex"); //0
int normal = globalGLFunctions->glGetAttribLocation(programId,"normal"); //1
int tangent = globalGLFunctions->glGetAttribLocation(programId,"tangent"); //2
int color = globalGLFunctions->glGetAttribLocation(programId,"color"); //3
int UV = globalGLFunctions->glGetAttribLocation(programId,"UV"); //4

//texture0
//texture1...
std::string str="texture";
for( size_t i=0;i<textures.size();i++)
{
globalGLFunctions->glActiveTexture(GL_TEXTURE0+i);
globalGLFunctions->glBindTexture(GL_TEXTURE_2D,textures[i].id);
globalGLFunctions->glUniform1i(globalGLFunctions->glGetUniformLocation(programId,(str+(char)(i+'0')) .c_str()),i);
}

globalGLFunctions->glBindBuffer(GL_ARRAY_BUFFER,VBO);
globalGLFunctions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IND);

globalGLFunctions->glEnableVertexAttribArray(vertex);
globalGLFunctions->glVertexAttribPointer(vertex,3,GL_FLOAT,GL_FALSE,s izeof(vertexData),0);

globalGLFunctions->glEnableVertexAttribArray(normal);
globalGLFunctions->glVertexAttribPointer(normal,3,GL_FLOAT,GL_FALSE,s izeof(vertexData),(void*)(3*sizeof(float)));

globalGLFunctions->glEnableVertexAttribArray(tangent);
globalGLFunctions->glVertexAttribPointer(tangent,3,GL_FLOAT,GL_FALSE, sizeof(vertexData),(void*)(6*sizeof(float)));

globalGLFunctions->glEnableVertexAttribArray(color);
globalGLFunctions->glVertexAttribPointer(color,3,GL_FLOAT,GL_FALSE,si zeof(vertexData),(void*)(9*sizeof(float)));

globalGLFunctions->glEnableVertexAttribArray(UV);
globalGLFunctions->glVertexAttribPointer(UV,2,GL_FLOAT,GL_FALSE,sizeo f(vertexData),(void*)(12*sizeof(float)));

globalGLFunctions->glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSI GNED_INT,0);

globalGLFunctions->glDisableVertexAttribArray(vertex);
globalGLFunctions->glDisableVertexAttribArray(normal);
globalGLFunctions->glDisableVertexAttribArray(tangent);
globalGLFunctions->glDisableVertexAttribArray(color);
globalGLFunctions->glDisableVertexAttribArray(UV);
globalGLFunctions->glBindBuffer(GL_ARRAY_BUFFER,0);
globalGLFunctions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}

8Observer8
4th December 2014, 05:53
That usually means that "this" is not a valid instance.

Check the creation of the meshLoader instance and if you call its method and not on some invalid pointer

Cheers,
_

Please, look at my "meshLoader instance" and say me where is my mistake:


#include <QOpenGLFunctions_2_1>
#include <QDir>
#include <QFile>
#include <vector>
#include <iostream>
#include "Scene.h"
#include "MeshData.h"
//#include "ObjLoader.h"
#include <GL/glu.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

QOpenGLFunctions_2_1 *globalGLFunctions;

class mesh
{
std::vector<vertexData> data;
std::vector<textureData> textures;
std::vector<unsigned int> indices;
unsigned int VBO;
unsigned int IND;
public:
mesh(std::vector<vertexData>* vd,std::vector<unsigned int>* id,std::vector<textureData>* td=NULL);
~mesh();
void draw(unsigned int programId);
};

mesh::mesh(std::vector<vertexData>* vd,std::vector<unsigned int>* id,std::vector<textureData>* td)
{
data=*vd;
indices=*id;
if(td)
textures=*td;

globalGLFunctions->glGenBuffers(1,&VBO);
globalGLFunctions->glBindBuffer(GL_ARRAY_BUFFER,VBO);
globalGLFunctions->glBufferData(GL_ARRAY_BUFFER,data.size()*sizeof(ve rtexData),
&data[0],GL_STATIC_DRAW);


globalGLFunctions->glGenBuffers(1,&IND);
globalGLFunctions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IND);
globalGLFunctions->glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.size( )*sizeof(unsigned int),&indices[0],GL_STATIC_DRAW);

globalGLFunctions->glBindBuffer(GL_ARRAY_BUFFER,0);
globalGLFunctions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}

mesh::~mesh()
{
// glDeleteBuffers(1,&VBO);
// glDeleteBuffers(1,&IND);
}

void mesh::draw(unsigned int programId)
{
//attribute vec3 vertex
int vertex = globalGLFunctions->glGetAttribLocation(programId,"vertex"); //0
int normal = globalGLFunctions->glGetAttribLocation(programId,"normal"); //1
int tangent = globalGLFunctions->glGetAttribLocation(programId,"tangent"); //2
int color = globalGLFunctions->glGetAttribLocation(programId,"color"); //3
int UV = globalGLFunctions->glGetAttribLocation(programId,"UV"); //4

//texture0
//texture1...
std::string str="texture";
for( size_t i=0;i<textures.size();i++)
{
globalGLFunctions->glActiveTexture(GL_TEXTURE0+i);
globalGLFunctions->glBindTexture(GL_TEXTURE_2D,textures[i].id);
globalGLFunctions->glUniform1i(globalGLFunctions->glGetUniformLocation(programId,(str+(char)(i+'0')) .c_str()),i);
}

globalGLFunctions->glBindBuffer(GL_ARRAY_BUFFER,VBO);
globalGLFunctions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IND);

globalGLFunctions->glEnableVertexAttribArray(vertex);
globalGLFunctions->glVertexAttribPointer(vertex,3,GL_FLOAT,GL_FALSE,s izeof(vertexData),0);

globalGLFunctions->glEnableVertexAttribArray(normal);
globalGLFunctions->glVertexAttribPointer(normal,3,GL_FLOAT,GL_FALSE,s izeof(vertexData),(void*)(3*sizeof(float)));

globalGLFunctions->glEnableVertexAttribArray(tangent);
globalGLFunctions->glVertexAttribPointer(tangent,3,GL_FLOAT,GL_FALSE, sizeof(vertexData),(void*)(6*sizeof(float)));

globalGLFunctions->glEnableVertexAttribArray(color);
globalGLFunctions->glVertexAttribPointer(color,3,GL_FLOAT,GL_FALSE,si zeof(vertexData),(void*)(9*sizeof(float)));

globalGLFunctions->glEnableVertexAttribArray(UV);
globalGLFunctions->glVertexAttribPointer(UV,2,GL_FLOAT,GL_FALSE,sizeo f(vertexData),(void*)(12*sizeof(float)));

globalGLFunctions->glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSI GNED_INT,0);

globalGLFunctions->glDisableVertexAttribArray(vertex);
globalGLFunctions->glDisableVertexAttribArray(normal);
globalGLFunctions->glDisableVertexAttribArray(tangent);
globalGLFunctions->glDisableVertexAttribArray(color);
globalGLFunctions->glDisableVertexAttribArray(UV);
globalGLFunctions->glBindBuffer(GL_ARRAY_BUFFER,0);
globalGLFunctions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}

class meshLoader
{
//std::vector<mesh*> meshes;
std::vector<mesh> meshes;
void recursiveProcess(aiNode* node,const aiScene* scene);
void processMesh(aiMesh* mesh,const aiScene* scene);
unsigned int loadTexture(const char* filename);
public:
meshLoader(const char* filename);
~meshLoader();
void draw(unsigned int programId);
std::vector<mesh*>& getMeshes();
};

void meshLoader::recursiveProcess(aiNode* node,const aiScene* scene)
{
//process
for( unsigned int i=0;i<node->mNumMeshes;i++)
{
aiMesh* mesh=scene->mMeshes[node->mMeshes[i]];
processMesh(mesh,scene);
}



//recursion
for( unsigned int i=0;i<node->mNumChildren;i++)
{
recursiveProcess(node->mChildren[i],scene);
}
}

void meshLoader::processMesh(aiMesh* mesh,const aiScene* scene)
{
std::vector<vertexData> data;
std::vector<unsigned int> indices;
std::vector<textureData> textures;

aiColor4D col;
aiMaterial* mat=scene->mMaterials[mesh->mMaterialIndex];
aiGetMaterialColor(mat,AI_MATKEY_COLOR_DIFFUSE,&col);
vector3d defaultColor(col.r,col.g,col.b);

for( unsigned int i=0;i<mesh->mNumVertices;i++)
{
vertexData tmp;
vector3d tmpVec;

//position
tmpVec.x=mesh->mVertices[i].x;
tmpVec.y=mesh->mVertices[i].y;
tmpVec.z=mesh->mVertices[i].z;
tmp.position=tmpVec;

//normals
tmpVec.x=mesh->mNormals[i].x;
tmpVec.y=mesh->mNormals[i].y;
tmpVec.z=mesh->mNormals[i].z;
tmp.normal=tmpVec;


//tangent
if(mesh->mTangents)
{
tmpVec.x=mesh->mTangents[i].x;
tmpVec.y=mesh->mTangents[i].y;
tmpVec.z=mesh->mTangents[i].z;
}else{
tmpVec.x=1.0;
tmpVec.y=tmpVec.z=0;
}
tmp.tangent=tmpVec;


//colors
if(mesh->mColors[0])
{
//!= material color
tmpVec.x=mesh->mColors[0][i].r;
tmpVec.y=mesh->mColors[0][i].g;
tmpVec.z=mesh->mColors[0][i].b;
}else{
tmpVec=defaultColor;
}
tmp.color=tmpVec;

//color
if(mesh->mTextureCoords[0])
{
tmpVec.x=mesh->mTextureCoords[0][i].x;
tmpVec.y=mesh->mTextureCoords[0][i].y;
}else{
tmpVec.x=tmpVec.y=tmpVec.z=0.0;
}
tmp.U=tmpVec.x;
tmp.V=tmpVec.y;
data.push_back(tmp);
}

for( unsigned int i=0;i<mesh->mNumFaces;i++)
{
aiFace face=mesh->mFaces[i];
for( unsigned int j=0;j<face.mNumIndices;j++) //0..2
{
indices.push_back(face.mIndices[j]);
}
}


for( unsigned int i=0;i<mat->GetTextureCount(aiTextureType_DIFFUSE);i++)
{
aiString str;
mat->GetTexture(aiTextureType_DIFFUSE,i,&str);
textureData tmp;
tmp.id=loadTexture(str.C_Str());
tmp.type=0;
textures.push_back(tmp);
}
//meshes.push_back( new ::mesh(&data,&indices,&textures) );
meshes.push_back( ::mesh(&data,&indices,&textures) );
}




unsigned int meshLoader::loadTexture(const char* filename)
{
unsigned int num = 0;
// glGenTextures(1,&num);
// SDL_Surface* img=IMG_Load(filename);
// if(img==NULL)
// {
// //std::cout << "img was not loaded" << std::endl;
// return -1;
// }
// SDL_PixelFormat form={NULL,32,4,0,0,0,0,0,0,0,0,0xff000000,0x00ff0 000,0x0000ff00,0x000000ff,0,255};
// SDL_Surface* img2=SDL_ConvertSurface(img,&form,SDL_SWSURFACE);
// if(img2==NULL)
// {
// //std::cout << "img2 was not loaded" << std::endl;
// return -1;
// }
// glBindTexture(GL_TEXTURE_2D,num);

// glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
// glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,img2->w,img2->h,0,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8,img2->pixels);
// SDL_FreeSurface(img);
// SDL_FreeSurface(img2);
return num;
}


meshLoader::meshLoader(const char* filename)
{
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile( filename, aiProcess_GenSmoothNormals | aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_FlipUVs );
if(scene->mFlags==AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{
std::cout << "The file wasn't successfuly opened " << filename << std::endl;
return;
}

recursiveProcess(scene->mRootNode,scene);
}

meshLoader::~meshLoader()
{
//for( unsigned int i=0;i<meshes.size();i++)
//delete meshes[i];
}

void meshLoader::draw(unsigned int programId)
{
size_t size = meshes.size();

for( unsigned int i = 0;i < meshes.size(); ++i )
meshes[i].draw( programId );
}

//std::vector<mesh*>& meshLoader::getMeshes()
//{
// return meshes;
//}

meshLoader* scene;

Scene::Scene( QWidget *parent ) :
QGLWidget( parent )/*,
m_objId( 0 ),
m_angle( 0 )*/
{
makeCurrent();
globalGLFunctions = new QOpenGLFunctions_2_1;

globalGLFunctions->initializeOpenGLFunctions();


// connect( &m_timer, SIGNAL( timeout( ) ),
// this, SLOT( slotUpdate( ) ) );
// m_timer.start( 50 );
}

Scene::~Scene()
{
globalGLFunctions->glDetachShader( m_program, m_vs );
globalGLFunctions->glDetachShader( m_program, m_fs );
globalGLFunctions->glDeleteShader( m_vs );
globalGLFunctions->glDeleteShader( m_fs );
globalGLFunctions->glDeleteProgram( m_program );
}

//void Scene::slotUpdate( )
//{
// ++m_angle;
// if ( m_angle >= 360 )
// {
// m_angle = 0;
// }
// updateGL( );
//}

void Scene::slotLoadObject( const QString &fileName )
{
scene = new meshLoader( fileName.toStdString( ).c_str( ) );
}

void Scene::initializeGL( )
{
glClearColor(0,0,0,1);
glMatrixMode(GL_PROJECTION);
{
glLoadIdentity();
gluPerspective(50,640.0/480.0,1,1000);
}
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);

// Load Shaders
initShader( ":/vshader.glsl", ":/fshader.glsl" );

// Remove comment for to enable lighting
// glEnable( GL_LIGHTING ); // we enable lighting, to make the 3D object to 3D
// glEnable( GL_LIGHT0 );
// float col[] = { 1.0, 1.0, 1.0, 1.0 }; //light color is white
// glLightfv( GL_LIGHT0, GL_DIFFUSE, col );

// Remove comment for to enable fog
// glEnable( GL_FOG ); // we enable fog
// glFogi( GL_FOG_MODE, GL_LINEAR );
// glFogf( GL_FOG_START, 1.0 );
// glFogf( GL_FOG_END, 5.0 );
// float fogColor[] = { 0.5, 0.5, 0.5, 1.0 };
// glFogfv( GL_FOG_COLOR, fogColor );
}

void Scene::paintGL( )
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//glRotatef(angle,0.0,1.0,0.0);
//globalGLFunctions->glUniform3f( globalGLFunctions->glGetUniformLocation(m_program,"lightPos"),0,1,2);
//glUniform3f(glGetUniformLocation(m_program,"cameraPosition"),cam.getLocation().x,cam.getLocation().y,cam.getL ocation().z);
glTranslatef( 0.0, 0.0, -5.0 );
scene->draw( m_program );

// float pos[] = { 0.0, 0.0, 5.0, 1.0 }; //set the position
// glLightfv( GL_LIGHT0, GL_POSITION, pos );
// glTranslatef( 0.0, 0.0, -5.0 );
// glRotatef( m_angle, 1.0, 1.0, 1.0 );
// if ( m_objId != 0 ) {
// glCallList( m_objId ); //draw the 3D mesh
// }
}

void Scene::resizeGL( int w, int h )
{
// Prevent a divide by zero
if ( h == 0 )
h = 1;

// Set Viewport to window dimensions
glViewport( 0, 0, w, h );

// Reset coordinate system
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );

// Produce the perspective projection
gluPerspective( 45, 640.0 / 480.0, 1.0, 500.0 );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
}

void Scene::initShader( const QString &vname, const QString &fname )
{
// Create vertex shader
std::string source;
loadFile( vname, source );
m_vs = loadShader( source, GL_VERTEX_SHADER );

// Create fragment shader
source = "";
loadFile( fname, source );
m_fs = loadShader( source, GL_FRAGMENT_SHADER );

// Create a program
m_program = globalGLFunctions->glCreateProgram();
globalGLFunctions->glAttachShader( m_program, m_vs );
globalGLFunctions->glAttachShader( m_program, m_fs );

globalGLFunctions->glLinkProgram( m_program );
globalGLFunctions->glUseProgram( m_program );
}

void Scene::loadFile( const QString &fileName, std::string &str )
{
QFile in( fileName );
if ( !in.open( QIODevice::ReadOnly ) ) {
std::cerr << "The file " << fileName.toStdString() << " cannot be opened.\n";
return;
}

while ( !in.atEnd() ) {
QByteArray data = in.readLine();
QString qstr( data );
str += qstr.toStdString();
}
}

unsigned int Scene::loadShader( std::string &source, unsigned int mode )
{
unsigned int id = 0;
id = globalGLFunctions->glCreateShader( mode );

const char *csource = source.c_str();
globalGLFunctions->glShaderSource( id, 1, &csource, NULL );
globalGLFunctions->glCompileShader( id );
char error[1000];
globalGLFunctions->glGetShaderInfoLog( id, 1000, NULL, error );
std::cout << error;

return id;
}

anda_skoa
4th December 2014, 07:25
So, have you checked the instance like I suggested?

Cheers,
_

8Observer8
4th December 2014, 14:15
So, have you checked the instance like I suggested?

Cheers,
_

Thank you very much! Yes, I checked the instance and I found the mistake! I called the method draw() when the instance of "meshLoader" object was not created


meshLoader* scene;

//...

void Scene::slotLoadObject( const QString &fileName )
{
scene = new meshLoader( fileName.toStdString( ).c_str( ) );
}


I solved it like this:


void Scene::slotLoadObject( const QString &fileName )
{
isLoaded = true;
scene = new meshLoader( fileName.toStdString( ).c_str( ) );
}

// ...

void Scene::paintGL( )
{
// ...

if ( isLoaded )
scene->draw( m_program );
}

anda_skoa
4th December 2014, 15:05
If you properly initialize the pointer to 0, you can check the variable itself instead of needing the boolean flag.

Cheers,
_