this is my first post in this forum for last 4 days i had been struggling with this issue spent like 30 hrs and still struck!
my code is
// assimp include files. These three are usually needed.
#include <Assimp/assimp.hpp>
#include <Assimp/aiPostProcess.h>
#include <Assimp/aiScene.h>
// include GLEW to access OpenGL 3.3 functions
#include <GL/glew.h>
#include <GL/wglew.h>
// GLUT is the toolkit to interface with the OS
#include <GL/freeglut.h>
//GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform2.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <cstring>
using namespace std;
using namespace glm;
#define BUFFER_OFFSET(offset) ((GLvoid *) offset)
std::vector<unsigned int> faceCounts;
std::vector<GLuint> vertexBuffers;
std::vector<GLuint> elementArrayBuffers;
std::vector<GLuint> arrayBuffers;
struct MyMesh{
GLuint vao;
GLuint texIndex;
GLuint uniformBlockIndex;
int numFaces;
};
std::vector<struct MyMesh> myMeshes;
// Create an instance of the Importer class
Assimp::Importer importer;
// For push and pop matrix
std::vector<float *> matrixStack;
// Vertex Attribute Locations
GLuint vertexLoc=0, normalLoc=1, texCoordLoc=2;
// Uniform Bindings Points
GLuint matricesUniLoc = 1, materialUniLoc = 2;
enum ElementFormat {VERTEX, VERTEX_TEXCOORD, VERTEX_NORMAL, VERTEX_TEXCOORD_NORMAL};
enum TransformationType {TRANSLATION, ROTATION, SCALING, NONE};
enum TransformationAxis {AXISX, AXISY, AXISZ, FREE};
enum ViewTypes {FRONT, BACK, LEFT, RIGHT, TOP, BOTTOM, FREE_VIEW};
GLuint vertexArrayBufferID = 0;
GLuint elementArrayBufferID = 0;
GLuint program; // shader program ID
GLuint buffer;
GLuint vPos; // vertex attribute: position
const aiScene* scene = NULL;// the global Assimp scene object
GLuint mvpMatrixID; // uniform attribute: model, view, projection matrix
mat4 projMatrix; // projection matrix
mat4 viewMatrix; // view matrix
GLuint matricesUniBuffer;
#define MatricesUniBufferSize sizeof(float) * 16 * 3
int windowWidth = 0;
int windowHeight = 0;
TransformationType transformationType = TRANSLATION;
TransformationAxis transformationAxis = FREE;
bool inTransformation = false;
float transformMouseMotionFactor = 0.003f;
float rotationMouseMotionFactor = 1.0f;
float scalingMouseMotionFactor = 0.002f;
float translateX = 0;
float translateY = 0;
float translateZ = 0;
float rotateX = 0;
float rotateY = 0;
float rotateZ = 0;
float scaleX = 0.5f;
float scaleY = 0.5f;
float scaleZ = 0.5f;
int mouseCenterX = 0;
int mouseCenterY = 0;
float oldTranslationX = 0;
float oldTranslationY = 0;
float oldTranslationZ = 0;
float oldRotationX = 0;
float oldRotationY = 0;
float oldRotationZ = 0;
float oldScaleX = 0;
float oldScaleY = 0;
float oldScaleZ = 0;
float zoomFactor = 0.5f;
float zoomStep = 0.1f;
ViewTypes viewPoint = FREE_VIEW;
string titleString;
string statusString;
string axisString;
// ----------------------------------------------------------------------------
#define aisgl_min(x,y) (x<y?x:y)
#define aisgl_max(x,y) (y>x?y:x)
void get_bounding_box_for_node (const struct aiNode* nd,
struct aiVector3D* min,
struct aiVector3D* max)
{
struct aiMatrix4x4 prev;
unsigned int n = 0, t;
for (; n < nd->mNumMeshes; ++n) {
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
for (t = 0; t < mesh->mNumVertices; ++t) {
struct aiVector3D tmp = mesh->mVertices[t];
min->x = aisgl_min(min->x,tmp.x);
min->y = aisgl_min(min->y,tmp.y);
min->z = aisgl_min(min->z,tmp.z);
max->x = aisgl_max(max->x,tmp.x);
max->y = aisgl_max(max->y,tmp.y);
max->z = aisgl_max(max->z,tmp.z);
}
}
for (n = 0; n < nd->mNumChildren; ++n) {
get_bounding_box_for_node(nd->mChildren[n],min,max);
}
}
void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
{
min->x = min->y = min->z = 1e10f;
max->x = max->y = max->z = -1e10f;
get_bounding_box_for_node(scene->mRootNode,min,max);
}
bool Import3DFromFile( const std::string& pFile)
{
//check if file exists
std::ifstream fin(pFile.c_str());
if(!fin.fail()) {
fin.close();
}
else{
printf("Couldn't open file: %s\n", pFile);
printf("%s\n", importer.GetErrorString());
return false;
}
scene = importer.ReadFile( pFile, aiProcessPreset_TargetRealtime_Quality);
// If the import failed, report it
if( !scene)
{
printf("%s\n", importer.GetErrorString());
return false;
}
// Now we can access the file's contents.
printf("Import of scene %s succeeded.",pFile.c_str());
struct aiVector3D scene_min, scene_max, scene_center;
get_bounding_box(&scene_min, &scene_max);
float tmp;
tmp = scene_max.x-scene_min.x;
tmp = scene_max.y - scene_min.y > tmp?scene_max.y - scene_min.y:tmp;
tmp = scene_max.z - scene_min.z > tmp?scene_max.z - scene_min.z:tmp;
// We're done. Everything will be cleaned up by the importer destructor
return true;
}
void genVAOsAndUniformBuffer(const struct aiScene *sc) {
struct MyMesh aMesh;
GLuint buffer;
// For each mesh
for (unsigned int n = 0; n < sc->mNumMeshes; ++n)
{
const struct aiMesh* mesh = sc->mMeshes[n];
// create array with faces
// have to convert from Assimp format to array
unsigned int *faceArray;
faceArray = (unsigned int *)malloc(sizeof(unsigned int) * mesh->mNumFaces * 3);
unsigned int faceIndex = 0;
for (unsigned int t = 0; t < mesh->mNumFaces; ++t) {
const struct aiFace* face = &mesh->mFaces[t];
memcpy(&faceArray[faceIndex], face->mIndices,3 * sizeof(float));
faceIndex += 3;
}
aMesh.numFaces = sc->mMeshes[n]->mNumFaces;
// generate Vertex Array for mesh
glGenVertexArrays(1,&(aMesh.vao));
glBindVertexArray(aMesh.vao);
// buffer for faces
glGenBuffers(1, &buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * mesh->mNumFaces * 3, faceArray, GL_STATIC_DRAW);
// buffer for vertex positions
if (mesh->HasPositions()) {
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(vertexLoc);
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
}
// buffer for vertex normals
if (mesh->HasNormals()) {
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mNormals, GL_STATIC_DRAW);
glEnableVertexAttribArray(normalLoc);
glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
}
// unbind buffers
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glGenBuffers(1,&(aMesh.uniformBlockIndex));
glBindBuffer(GL_UNIFORM_BUFFER,aMesh.uniformBlockIndex);
myMeshes.push_back(aMesh);
}
}
// Read shader files
const char *readShaderFile(const char * filename) {
ifstream vShaderFile (filename);
if (!vShaderFile.is_open()) {
cerr << "Cannot open the vertex shader" << endl;
return NULL;
}
string line;
// Must created a new string, otherwise the returned pointer
// will be invalid
string *shaderSourceStr = new string();
while (getline(vShaderFile, line)) {
// lines with preprossors must end with \n
*shaderSourceStr += line + '\n';
}
const char *vSource = shaderSourceStr->c_str();
vShaderFile.close();
return vSource;
}
// Print out the output of the shader compiler
void printLog(GLuint obj)
{
int infologLength = 0;
char infoLog[1024];
if (glIsShader(obj)) {
glGetShaderInfoLog(obj, 1024, &infologLength, infoLog);
} else {
glGetProgramInfoLog(obj, 1024, &infologLength, infoLog);
}
if (infologLength > 0) {
cout << infoLog;
}
}
// Create a shader program from the given shader files
void createShaders(char *vShaderFilename, char *fShaderFilename) {
const char* vSource = readShaderFile(vShaderFilename);
// OpenGL fragment shader source code
const char* fSource = readShaderFile(fShaderFilename);
// Declare shader IDs
GLuint vShader, fShader;
// Create empty shader objects
vShader = glCreateShader(GL_VERTEX_SHADER);
fShader = glCreateShader(GL_FRAGMENT_SHADER);
// Attach shader source code the shader objects
glShaderSource(vShader, 1, &vSource, NULL);
glShaderSource(fShader, 1, &fSource, NULL);
// Compile shader objects
glCompileShader(vShader);
// printLog(vShader);
glCompileShader(fShader);
// printLog(fShader);
// Create an empty shader program object
program = glCreateProgram();
// Attach vertex and fragment shaders to the shader program
glAttachShader(program, vShader);
glAttachShader(program, fShader);
// Link the shader program
glLinkProgram(program);
printLog(program);
}
// Initialize data arrays and shaders
int init(char *objFilename, char *vShaderFilename, char *fShaderFilename)
{
if (!Import3DFromFile(objFilename))
return 0;
// Create the shader program from the given shader files
createShaders(vShaderFilename, fShaderFilename);
// Retrieve the ID of a vertex attribute, i.e. position
vPos = glGetAttribLocation(program, "vPos");
mvpMatrixID = glGetUniformLocation(program, "mvp_matrix");
// Specify the background color
glClearColor(1, 1, 1, 1);
// Draw in wireframe mode, the default if GL_FILL
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
return true;
}
// Handles the reshape event
void reshape(int width, int height)
{
if (height < 1) {
height = 1;
}
windowWidth = width;
windowHeight = height;
// Specify the width and height of the picture within the window
glViewport(0, 0, width, height);
#ifdef _DEBUG
fprintf(stderr, "reshape called.\n");
#endif
return;
}
// Recursive Render
void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
{
for (unsigned int n=0; n < nd->mNumMeshes; ++n){
glVertexAttribPointer(vPos, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(vPos);
glBindVertexArray(myMeshes[nd->mMeshes[n]].vao);
glDrawElements(GL_TRIANGLES,myMeshes[nd->mMeshes[n]].numFaces*3,GL_UNSIGNED_INT,BUFFER_OFFSET(0));
}
// draw all children
for (unsigned int n=0; n < nd->mNumChildren; ++n){
if (nd->mChildren[n] == NULL) {
continue;
}
recursive_render(sc, nd->mChildren[n]);
}
}
// Handles the display event
void display()
{
// Clear the window with the background color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Activate the shader program
glUseProgram(program);
projMatrix = perspective(60.0f * zoomFactor,
(float)windowWidth /(float)windowHeight, 0.1f, 1000.0f);
switch (viewPoint) {
case FRONT:
viewMatrix = lookAt(vec3(0.0f, 0.0f, 3.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
break;
case BACK:
viewMatrix = lookAt(vec3(0.0f, 0.0f, -3.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
break;
case RIGHT:
viewMatrix = lookAt(vec3(3.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
break;
case LEFT:
viewMatrix = lookAt(vec3(-3.0f, 0.0f, -3.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
break;
case TOP:
viewMatrix = lookAt(vec3(0.0f, 3.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(-1.0f, 0.0f, 0.0f));
break;
case BOTTOM:
viewMatrix = lookAt(vec3(0.0f, -3.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(1.0f, 0.0f, 0.0f));
break;
default:
viewMatrix = lookAt(vec3(0.0f, 3.0f, 3.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 3.0f, -3.0f));
break;
}
//scale the 3D model by half
mat4 scaleMatrix = scale(mat4(1.0f), vec3(scaleX, scaleY, scaleZ));
mat4 translateMatrix = translate(mat4(1.0f), vec3(translateX, translateY, translateZ));
mat4 rotationXMatrix = rotate(mat4(1.0f), rotateX, vec3(1.0f, 0.0f, 0.0f));
mat4 rotationYMatrix = rotate(mat4(1.0f), rotateY, vec3(0.0f, 1.0f, 0.0f));
mat4 rotationZMatrix = rotate(mat4(1.0f), rotateZ, vec3(0.0f, 0.0f, 1.0f));
mat4 modelMatrix =
translateMatrix * rotationZMatrix * rotationYMatrix * rotationXMatrix * scaleMatrix;
mat4 mvpMatrix = projMatrix * viewMatrix * modelMatrix;
glUniformMatrix4fv(mvpMatrixID, 1, GL_FALSE, glm::value_ptr(mvpMatrix));
glBindBuffer(GL_ARRAY_BUFFER, vertexArrayBufferID);
glVertexAttribPointer(vPos, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(vPos);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
// use our shader
glUseProgram(program);
// Clearing the buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
recursive_render(scene, scene->mRootNode);
// Refresh the window
glutSwapBuffers();
return;
}
// Read mouse motion data and convert them to translations or
// rotation angles.
void passiveMotion(int x, int y) {
if (!inTransformation) {
return;
}
x = x - mouseCenterX;
y = mouseCenterY - y;
switch (transformationType) {
case TRANSLATION: {
float scaledX = x * transformMouseMotionFactor;
float scaledY = y * transformMouseMotionFactor;
switch (transformationAxis) {
case FREE:
translateX = oldTranslationX + scaledX;
translateY = oldTranslationY + scaledY;
break;
case AXISX:
translateX = oldTranslationX + scaledX;
break;
case AXISY:
translateY = oldTranslationY + scaledY;
break;
case AXISZ:
translateZ = oldTranslationZ + scaledX;
break;
default: break;
}
}
break;
case ROTATION: {
float scaledX = x * rotationMouseMotionFactor;
float scaledY = y * rotationMouseMotionFactor;
switch (transformationAxis) {
case FREE:
rotateX = oldRotationX - scaledY;
rotateY = oldRotationY + scaledX;
break;
case AXISX:
rotateX = oldRotationX - scaledY;
break;
case AXISY:
rotateY = oldRotationY + scaledX;
break;
case AXISZ:
rotateZ = oldRotationZ - scaledX;
break;
default: break;
}
}
break;
case SCALING: {
float scaledX = x * scalingMouseMotionFactor;
float scaledY = y * scalingMouseMotionFactor;
switch (transformationAxis) {
case FREE:
scaleX = oldScaleX + scaledX;
scaleY = oldScaleY + scaledX;
scaleZ = oldScaleZ + scaledX;
break;
case AXISX:
scaleX = oldScaleX + scaledX;
break;
case AXISY:
scaleY = oldScaleY + scaledY;
break;
case AXISZ:
scaleZ = oldScaleZ + scaledX;
break;
default: break;
}
float minScale = 0.0001f;
if (scaleX <= minScale) {
scaleX = minScale;
}
if (scaleY <= minScale) {
scaleY = minScale;
}
if (scaleZ <= minScale) {
scaleZ = minScale;
}
}
break;
default:
break;
}
// Generate a dislay event to force refreshing the window.
glutPostRedisplay();
}
void recordMousePosition(int x, int y) {
mouseCenterX = x;
mouseCenterY = y;
}
void recordObjPositionRotationScaling() {
oldTranslationX = translateX;
oldTranslationY = translateY;
oldTranslationZ = translateZ;
oldRotationX = rotateX;
oldRotationY = rotateY;
oldRotationZ = rotateZ;
oldScaleX = scaleX;
oldScaleY = scaleY;
oldScaleZ = scaleZ;
}
// Read keyboard inputs
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 't':
case 'T':
inTransformation = true;
transformationType = TRANSLATION;
transformationAxis = FREE;
statusString = "Translation";
axisString = "Free";
break;
case 'r':
case 'R':
inTransformation = true;
transformationType = ROTATION;
transformationAxis = FREE;
statusString = "Rotation";
axisString = "Free";
break;
case 's':
case 'S':
inTransformation = true;
transformationType = SCALING;
transformationAxis = FREE;
statusString = "Scaling";
axisString = "Free";
break;
case '+': // zoom in
zoomFactor -= zoomStep;
break;
case '-': // zoom out
zoomFactor += zoomStep;
break;
case '1':
viewPoint = FRONT;
break;
case '2':
viewPoint = BACK;
break;
case '3':
viewPoint = LEFT;
break;
case '4':
viewPoint = RIGHT;
break;
case '5':
viewPoint = TOP;
break;
case '6':
viewPoint = BOTTOM;
break;
default:
break;
}
if (inTransformation) {
switch(key) {
case 'x':
case 'X':
// Only translate or rotate around the X axis
transformationAxis = AXISX;
axisString = "X axis";
break;
case 'y':
case 'Y':
// Only translate or rotate around the Y axis
transformationAxis = AXISY;
axisString = "Y axis";
break;
case 'z':
case 'Z':
// Only translate or rotate around the Z axis
transformationAxis = AXISZ;
axisString = "Z axis";
break;
default:
break;
}
}
// Remember where the mouse cursor position when the
// key is pressed. This is for calculating the
// relative motion of the subsequent transformations.
recordMousePosition(x, y);
recordObjPositionRotationScaling();
// Display the current transformation status and the current
// axis of transformation
string newTitleString = titleString + ": " + statusString + ": "
+ axisString;
glutSetWindowTitle(newTitleString.c_str());
glutPostRedisplay();
}
// mouse button callback function
void mouse(int button, int state, int x, int y) {
if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN)) {
// Stop the transformation when the user presses the
// left mouse button.
if (inTransformation) {
inTransformation = false;
transformationType = NONE;
statusString = "";
axisString = "";
}
}
glutSetWindowTitle(titleString.c_str());
glutPostRedisplay();
}
void main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
titleString = "Transformation Demo";
glutCreateWindow(titleString.c_str());
// needed for this code
GLenum glewInitErr = glewInit();
if (glewInitErr != GLEW_OK) {
exit(1);
}
if (! glewIsSupported("GL_VERSION_3_3")) {
exit(2);
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glutReshapeWindow(800, 800);
glewInit();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);;
if (argc > 3) {
init(argv[1], argv[2], argv[3]);
} else {
cout << "Please enter object filename, vertex shader file name, and fragment shader file name" << endl;
}
// Register the display callback function
glutDisplayFunc(display);
// Register the reshape callback function
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutPassiveMotionFunc(passiveMotion);
// Start the event loop
glutMainLoop();
}
and my shaders are
#version 130
in vec4 vPos;
uniform mat4 mvp_matrix;
void main() {
gl_Position = mvp_matrix *vPos;
}
#version 130
out vec4 fragColor;
void main() {
fragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
I get the error vector subscript out of range
Any help will be highly appreciated











