I don't know what causing the error (C3074) - c++

It says "an array cannot be initialized with a parenthesized initializer", which I'm not quiet sure I understand... So, can someone explain what is causing it, why and how I fix it? Please?
(By the way, I'm sort of new to memory c++, so be gentle please?)
What I'm trying to accomplish is for a mesh to be generated by an obj file. And to be honest I'm not that great at it. So sorry!
Mesh.h --------------------------------------------------------------
#pragma once
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <vector>
#include "../Shader/Shader.h"
struct Vertex
{
float Position[3];
float Uv[2];
float Normal[3];
};
class Mesh
{
private:
unsigned int VAO, VBO; // Vertex Array Object ID
unsigned int TextureID; // Texture ID
unsigned int size;
const char* objFilePath;
const char* textureFilePath;
Shader& shader;
public:
Mesh(const char* objFilePath, const char* textureFilePath, Shader& shader);
void draw();
};
Mesh.cpp --------------------------------------------------------------
#include "Mesh.h"
void fillVerticesWithData(std::vector<float> data, std::vector<Vertex> info);
Mesh::Mesh(const char* objFilePath, const char* textureFilePath, Shader& shader)
: objFilePath(objFilePath), textureFilePath(textureFilePath), shader(shader)
{
{
// Load Vertices from File!
std::vector<Vertex> vertices;
{
std::vector<float[3]> filePos; // Position(s)
std::vector<float[2]> fileUV; // Uv(s)
std::vector<float[3]> fileNorm; // Normal(s)
std::ifstream file;
file.open(objFilePath);
std::string line;
while (std::getline(file, line))
{
std::string text;
std::istringstream iss(line);
iss >> text;
// Easy part!
if (text == "v")
{
float currectPos[3];
iss >> currectPos[0];
iss >> currectPos[1];
iss >> currectPos[2];
filePos.push_back(currectPos);
}
if (text == "vt")
{
float currectUV[2];
iss >> currectUV[0];
iss >> currectUV[1];
fileUV.push_back(currectUV);
}
if (text == "vn")
{
float currectNorm[3];
iss >> currectNorm[0];
iss >> currectNorm[1];
iss >> currectNorm[2];
fileNorm.push_back(currectNorm);
}
// Last part, hard part!
if (text == "f")
{
int x, y, z;
int x2, y2, z2;
int x3, y3, z3;
char e;
// First Vertex!
iss >> x;
iss >> e;
iss >> y;
iss >> e;
iss >> z;
iss >> x2;
iss >> e;
iss >> y2;
iss >> e;
iss >> z2;
iss >> x3;
iss >> e;
iss >> y3;
iss >> e;
iss >> z3;
Vertex temp_Vertex;
for (int i = 0; i < 3; i++)
{
temp_Vertex.Position[i] = filePos.at(x - 1)[i];
temp_Vertex.Normal[i] = fileNorm.at(y - 1)[i];
}
for (int i = 0; i < 2; i++)
{
temp_Vertex.Uv[i] = fileUV.at(z - 1)[i];
}
vertices.push_back(temp_Vertex);
std::cout << "Vertex 1 -----------" << std::endl;
std::cout << "Position: " << temp_Vertex.Position[0] << " " << temp_Vertex.Position[1] << " " << temp_Vertex.Position[2] << std::endl;
std::cout << "UV: " << temp_Vertex.Uv[0] << " " << temp_Vertex.Uv[1] << std::endl;
std::cout << "Normal: " << temp_Vertex.Normal[0] << " " << temp_Vertex.Normal[1] << temp_Vertex.Normal[2] << std::endl;
// Second Vertex!
Vertex temp_Vertex2;
for (int i = 0; i < 3; i++)
{
temp_Vertex2.Position[i] = filePos.at(x2 - 1)[i];
temp_Vertex2.Normal[i] = fileNorm.at(y2 - 1)[i];
}
for (int i = 0; i < 2; i++)
{
temp_Vertex2.Uv[i] = fileUV.at(z2 - 1)[i];
}
vertices.push_back(temp_Vertex2);
std::cout << "Vertex 1 -----------" << std::endl;
std::cout << "Position: " << temp_Vertex2.Position[0] << " " << temp_Vertex2.Position[1] << " " << temp_Vertex2.Position[2] << std::endl;
std::cout << "UV: " << temp_Vertex2.Uv[0] << " " << temp_Vertex2.Uv[1] << std::endl;
std::cout << "Normal: " << temp_Vertex2.Normal[0] << " " << temp_Vertex2.Normal[1] << temp_Vertex2.Normal[2] << std::endl;
// Third Vertex
Vertex temp_Vertex3;
for (int i = 0; i < 3; i++)
{
temp_Vertex3.Position[i] = filePos.at(x3 - 1)[i];
temp_Vertex3.Normal[i] = fileNorm.at(y3 - 1)[i];
}
for (int i = 0; i < 2; i++)
{
temp_Vertex3.Uv[i] = fileUV.at(z3 - 1)[i];
}
vertices.push_back(temp_Vertex3);
std::cout << "Vertex 1 -----------" << std::endl;
std::cout << "Position: " << temp_Vertex3.Position[0] << " " << temp_Vertex3.Position[1] << " " << temp_Vertex3.Position[2] << std::endl;
std::cout << "UV: " << temp_Vertex3.Uv[0] << " " << temp_Vertex3.Uv[1] << std::endl;
std::cout << "Normal: " << temp_Vertex3.Normal[0] << " " << temp_Vertex3.Normal[1] << temp_Vertex3.Normal[2] << std::endl;
// Face!!! :O
// This one here I am having trouble with
// How do I read it?
}
}
}
// Load Texture from File!
// Last step:
std::vector<float> vertexArray;
fillVerticesWithData(vertexArray, vertices);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexArray.size() * sizeof(float), &vertexArray[0], GL_STATIC_DRAW);
// Position Pointer:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)3);
glEnableVertexAttribArray(1);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)5);
glEnableVertexAttribArray(3);
// Unbinding everything:
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
size = vertexArray.size();
}
}
void Mesh::draw()
{
shader.use();
glBindVertexArray(VAO);
// glBindTexture(GL_TEXTURE_2D, TextureID);
// Later:
// Draw Elements
// For now:
glDrawArrays(GL_TRIANGLES, 0, size);
}
// data is the data we wanna fill with information!
// The info has the information we want to put into data!
void fillVerticesWithData(std::vector<float> data, std::vector<Vertex> info)
{
for (int i = 0; i < info.size(); i++)
{
// Position:
for (int posI = 0; posI < 3; posI++)
{
float temp[3];
temp[posI] = info.at(i).Position[posI];
data.push_back(temp[posI]);
}
// Uv:
for (int uvI = 0; uvI < 2; uvI++)
{
float temp[2];
temp[uvI] = info.at(i).Uv[uvI];
data.push_back(temp[uvI]);
}
// Normal:
for (int norI = 0; norI < 3; norI++)
{
float temp[3];
temp[norI] = info.at(i).Normal[norI];
data.push_back(temp[norI]);
}
}
}
Anyway, thanks for checking out this post/question, even if it just reading.
I appreciate any help I can get! (And I've been working on loading this mesh thing for a long time and I just want to be done with it)
I hope you're having a nice day! (Or night, lol) :)

The elements of a std::vector have to be copyable and assignable. Arrays are not copyable and assignable.
I recommend to use std::array:
std::vector<std::array<float, 3>> filePos; // Position(s)
std::vector<std::array<float, 2>> fileUV; // Uv(s)
std::vector<std::array<float, 3>> fileNorm; // Normal(s)
std::array<float, 3> currectPos;
std::array<float, 2> currectUV;
std::array<float, 3> currectNorm;
Furthermore, if a named buffer object is bound, then the last parameter of glVertexAttribPointer is treated as a byte offset into the buffer object's data store:
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)3);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(sizeof(float)*3));
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)5);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(sizeof(float)*5));

You can't use a native c array as the template argument for std::vector<>.
Use a std::array<3> instead
Like so: std::vector<std::array<float,3>>
You can also use a pointer to three float that's fine.

Related

GLSL uniform mat4 is always 0

I am trying to load a orthographic projection matrix into a shader, but when I go to run the code and I click around in the window I end up with all the points going to (0,0,0) which I'm guessing is being caused by the uniform matrix never being setup and as a result everything is being multiplied by 0. I am using Qt, OpenGL and GLM for this. Any ideas why this would be happening?
I have been debugging it a little and it seems to be having issues at the point where I'm loading the matrix into the shader in resizeGL and initializeGL, not sure of the cause though.
Thanks in advance!
My Class handling all of the OpenGL Stuff:
GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent), outline(false), drawMode(0) {
num_pts = 0;
drawMode = GL_POINTS;
next = 1;
ortho = glm::ortho(0.0f, 640.0f, 480.0f, 0.0f);
}
GLWidget::~GLWidget() {
}
void GLWidget::keyPressEvent(QKeyEvent *event) {
switch (event->key()) {
case Qt::Key_C:
cout << "Cleared all the points." << endl;
num_pts = 0;
pts.clear();
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW);
break;
case Qt::Key_W:
outline = !outline;
if (outline) {
cout << "Displaying outlines." << endl;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
else {
cout << "Displaying filled polygons." << endl;
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
break;
case Qt::Key_Space:
switch (next) {
case(0):
drawMode = GL_POINTS;
cout << "drawMode is GL_POINTS" << endl;
next = 1;
break;
case(1):
drawMode = GL_LINES;
cout << "drawMode is GL_LINES" << endl;
next = 2;
break;
case(2):
drawMode = GL_LINE_STRIP;
cout << "drawMode is GL_LINE_STRIP" << endl;
next = 3;
break;
case(3):
drawMode = GL_LINE_LOOP;
cout << "drawMode is GL_LINE_LOOP" << endl;
next = 4;
break;
case(4):
drawMode = GL_TRIANGLES;
cout << "drawMode is GL_TRIANGLES" << endl;
next = 5;
break;
case(5):
drawMode = GL_TRIANGLE_STRIP;
cout << "drawMode is GL_TRIANGLE_STRIP" << endl;
next = 6;
break;
case(6):
drawMode = GL_TRIANGLE_FAN;
cout << "drawMode is GL_TRIANGLE_FAN" << endl;
next = 0;
break;
}
break;
case Qt::Key_P:
cout << "Projection Location: " << projectionMatrixLoc << endl << endl;
cout << "Projection Matrix:" << endl << endl;
cout << "------------" << endl;
cout << ortho[0][0] << " ";
cout << ortho[1][0] << " ";
cout << ortho[2][0] << " ";
cout << ortho[3][0] << endl;
cout << "------------" << endl;
cout << ortho[0][1] << " ";
cout << ortho[1][1] << " ";
cout << ortho[2][1] << " ";
cout << ortho[3][1] << endl;
cout << "------------" << endl;
cout << ortho[0][2] << " ";
cout << ortho[1][2] << " ";
cout << ortho[2][2] << " ";
cout << ortho[3][2] << endl;
cout << "------------" << endl;
cout << ortho[0][3] << " ";
cout << ortho[1][3] << " ";
cout << ortho[2][3] << " ";
cout << ortho[3][3] << endl;
cout << "------------" << endl << endl << endl;
break;
}
update();
}
void GLWidget::mousePressEvent(QMouseEvent *event) {
glm::vec2 temp = glm::vec2(0.0);
temp.x = event->x();
temp.y = event->y();
pts.push_back(temp);
cout << "Added point (" << pts.back().x << ", " << pts.back().y << ") " << endl;
cout << "Number of points: " << pts.size() << endl;
num_pts++;
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, pts.size(), &pts, GL_DYNAMIC_DRAW);
update();
}
void GLWidget::initializeGL() {
initializeOpenGLFunctions();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glPointSize(4.0f);
// Create a new Vertex Array Object on the GPU which
// saves the attribute layout of our vertices.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a buffer on the GPU for position data
glGenBuffers(1, &positionBuffer);
// Upload the position data to the GPU, storing
// it in the buffer we just allocated.
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW);
// Load our vertex and fragment shaders into a program object
// on the GPU
program = loadShaders(":/vert.glsl", ":/frag.glsl");
// Bind the attribute "position" (defined in our vertex shader)
// to the currently bound buffer object, which contains our
// position data for a single triangle. This information
// is stored in our vertex array object.
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
GLint positionIndex = glGetAttribLocation(program, "position");
glEnableVertexAttribArray(positionIndex);
glVertexAttribPointer(positionIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
glUseProgram(program);
projectionMatrixLoc = glGetUniformLocation(program, "ProjectionMatrix");
glUniformMatrix4fv(projectionMatrixLoc, 1, GL_FALSE, glm::value_ptr(ortho));
}
void GLWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
ortho = glm::ortho(0.0f, (float)w, (float)h, 0.0f);
glUseProgram(program);
// problem area?
glUniformMatrix4fv(projectionMatrixLoc, 1, GL_FALSE, glm::value_ptr(ortho));
}
void GLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
// draw primitives based on the current draw mode
glDrawArrays(drawMode, 0, num_pts);
// draw points so we can always see them
// glPointSize adjusts the size of point
// primitives
glDrawArrays(GL_POINTS, 0, num_pts);
}
// Copied from LoadShaders.cpp in the the oglpg-8th-edition.zip
// file provided by the OpenGL Programming Guide, 8th edition.
const GLchar* GLWidget::readShader(const char* filename) {
#ifdef WIN32
FILE* infile;
fopen_s(&infile, filename, "rb");
#else
FILE* infile = fopen(filename, "rb");
#endif // WIN32
if (!infile) {
#ifdef _DEBUG
std::cerr << "Unable to open file '" << filename << "'" << std::endl;
#endif /* DEBUG */
return NULL;
}
fseek(infile, 0, SEEK_END);
int len = ftell(infile);
fseek(infile, 0, SEEK_SET);
GLchar* source = new GLchar[len + 1];
fread(source, 1, len, infile);
fclose(infile);
source[len] = 0;
return const_cast<const GLchar*>(source);
}
GLuint GLWidget::loadShaders(const char* vertf, const char* fragf) {
GLuint program = glCreateProgram();
// read vertex shader from Qt resource file
QFile vertFile(vertf);
vertFile.open(QFile::ReadOnly | QFile::Text);
QString vertString;
QTextStream vertStream(&vertFile);
vertString.append(vertStream.readAll());
std::string vertSTLString = vertString.toStdString();
const GLchar* vertSource = vertSTLString.c_str();
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertShader, 1, &vertSource, NULL);
glCompileShader(vertShader);
{
GLint compiled;
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLsizei len;
glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &len);
GLchar* log = new GLchar[len + 1];
glGetShaderInfoLog(vertShader, len, &len, log);
std::cout << "Shader compilation failed: " << log << std::endl;
delete[] log;
}
}
glAttachShader(program, vertShader);
// read fragment shader from Qt resource file
QFile fragFile(fragf);
fragFile.open(QFile::ReadOnly | QFile::Text);
QString fragString;
QTextStream fragStream(&fragFile);
fragString.append(fragStream.readAll());
std::string fragSTLString = fragString.toStdString();
const GLchar* fragSource = fragSTLString.c_str();
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragShader, 1, &fragSource, NULL);
glCompileShader(fragShader);
{
GLint compiled;
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLsizei len;
glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &len);
GLchar* log = new GLchar[len + 1];
glGetShaderInfoLog(fragShader, len, &len, log);
std::cerr << "Shader compilation failed: " << log << std::endl;
delete[] log;
}
}
glAttachShader(program, fragShader);
glLinkProgram(program);
{
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked) {
GLsizei len;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
GLchar* log = new GLchar[len + 1];
glGetProgramInfoLog(program, len, &len, log);
std::cout << "Shader linker failed: " << log << std::endl;
delete[] log;
}
}
return program;
}
The Header File:
#ifndef __GLWIDGET__INCLUDE__
#define __GLWIDGET__INCLUDE__
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QMouseEvent>
#include <glm/glm.hpp>
#include <vector>
// glm by default uses degrees, but that functionality
// is deprecated so GLM_FORCE_RADIANS turns off some
// glm warnings
#define GLM_FORCE_RADIANS
using glm::vec2;
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core {
Q_OBJECT
public:
GLWidget(QWidget *parent = 0);
~GLWidget();
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void mousePressEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
private:
GLuint loadShaders(const char* vertf, const char* fragf);
static const GLchar* readShader(const char* filename);
GLuint vao;
GLuint program;
GLuint positionBuffer;
GLint projectionMatrixLoc;
bool outline;
GLenum drawMode;
glm::mat4 ortho;
int next;
std::vector<vec2> pts;
int num_pts;
};
#endif
My Vertex Shader:
#version 330
in vec2 position;
uniform mat4 ProjectionMatrix;
void main() {
gl_Position = vec4(position.x, position.y, 0, 1)*ProjectionMatrix;
}
My Fragment Shader:
#version 330
out vec4 color_out;
void main() {
color_out = vec4(1.0,1.0,1.0,1.0);
}

Implementing Dijkstra's algorithm with vector of pointers

I'm working on a program involving Dijkstra's algorithm.
After searching long and far, I have only found help pertaining to Dijkstra's algorithm using Queues or Heaps, however, I am not using these. I have been tasked to used a vector of pointers to Vertex objects (a custom class I have defined).
I have attempted to convert the Queue pseudo code (from my textbook) to the best of my ability below:
void Dijkstra(vector<Vertex*> & V, int startNum)
{
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0);
insertionSort(sortedVertices);
while(sortedVertices.size() != 0)
{
sortedVertices[sortedVertices.size() - 1]->setKnown(true);
sortedVertices.pop_back();
insertionSort(sortedVertices);
Vertex * v = V[1]; // Will always bring the first element off the list
v->setKnown(true);
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
{
int dist = getAdjacentVertices()[m].getWeight();
if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
{
//WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
cout << "It works so far" << endl;
// BOOK has this, somehow need to change it: w.path = v
}
}
}
}
However, when I attempt to compile, I keep receiving the following errors:
Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'
I am trying to reduce the amount of Code in this post, but if need to be, my entire code is below:
Main.cpp:
#include "Vertex.h"
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
void shortestPath(vector<Vertex> & v);
template <typename Comparable>
void insertionSort(vector<Comparable> & a);
template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right );
///overload the less than operator in order to use the stl sort for vector
///print out the path for each vertex
int main()
{
/////READ ALL THE STUFF INTO THE GRAPH////
ifstream file;
file.open("graph.txt");
cout << "Opening file..." << endl;
if(!file)
{
cout << "System failed to open file.";
}
else
{
cout << "File successfully opened" << endl;
}
int numVertices;
int numEdges;
int num;
int adjacentVertex;
int weight;
file >> numVertices;
cout << "The number of vertices that are being read into the graph from the file: " << numVertices;
cout << endl;
vector<Vertex*> vertices;
//vector<Vertex> vertices(numVertices + 1);
Vertex * newVertex;
vertices.push_back(NULL);
cout << "SIZE: " << vertices.size() << endl;
cout << "NUM VERTICES: " << numVertices << endl;
for(int i=1;i < numVertices + 1; i++)
{
file >> numEdges;
cout << "At vertex " << i << " the number of edges is " << numEdges << endl;
newVertex = new Vertex();
//Using the i counter variable in the outer for loop to identify
//the what vertex what are currently looking at in order to read in the correct adjacent vertex and weight
cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
newVertex->setVertexNum(i);
//newVertex.setVertexNum(i);
for(int j=1;j<=numEdges;j++)
{
file >> adjacentVertex;
cout << "The adjacent vertex is: " << adjacentVertex << endl;
file >> weight;
cout << "The weight is: " << weight << endl;
cout << endl;
newVertex->setAdjacentVertex(adjacentVertex, weight);
}
//cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
vertices.push_back(newVertex);
}
file.close();
vector<Vertex*> sortedVertices = vertices;
insertionSort(sortedVertices);
cout << "SIZE: " << vertices.size() << endl;
for(int i=0;i<vertices.size();i++)
{
cout << "V" << i << ": ";
cout << endl;
if(vertices[i] != NULL)
{
cout << "DV Value: " << vertices[i]->getDV();
cout << endl;
cout << "Known Value: " << vertices[i]->getKnown();
cout << endl;
}
}
cout << "Sorted: " << endl;
for(int i=0;i<sortedVertices.size();i++)
{
cout << "V" << i << ": ";
cout << endl;
if(vertices[i] != NULL)
{
cout << "DV Value: " << sortedVertices[i]->getDV();
cout << endl;
cout << "Known Value: " << sortedVertices[i]->getKnown();
cout << endl;
}
}
//CALL THE SHORTEST PATH FUNCTION ON THE GRAPH/////
}
/*
const bool myFunction(const Vertex & x, const Vertex & y)
{
return (x.getDV() >= y.getDV());
}
*/
bool operator < (const Vertex & v1, const Vertex & v2)
{
return v1.getDV() > v2.getDV();
}
void Dijkstra(vector<Vertex*> & V, int startNum)
{
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0);
insertionSort(sortedVertices);
while(sortedVertices.size() != 0)
{
sortedVertices[sortedVertices.size() - 1]->setKnown(true);
sortedVertices.pop_back();
insertionSort(sortedVertices);
Vertex * v = V[1]; // Will always bring the first element off the list
v->setKnown(true);
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
{
int dist = getAdjacentVertices()[m].getWeight();
if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
{
//WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
cout << "It works so far" << endl;
// BOOK has this, somehow need to change it: w.path = v
}
}
}
}
////////INSERTION SORT////////////
template <typename Comparable>
void insertionSort( vector<Comparable> & a )
{
for( int p = 1; p < a.size( ); ++p )
{
Comparable tmp = std::move( a[ p ] );
int j;
for( j = p; j > 0 && tmp < a[ j - 1 ]; --j )
a[ j ] = std::move( a[ j - 1 ] );
a[ j ] = std::move( tmp );
}
}
template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right )
{
for( int p = left + 1; p <= right; ++p )
{
Comparable tmp = std::move( a[ p ] );
int j;
for( j = p; j > left && tmp < a[ j - 1 ]; --j )
a[ j ] = std::move( a[ j - 1 ] );
a[ j ] = std::move( tmp );
}
}
Vertex.h:
#include "Edge.h"
#include <vector>
#include <climits>
#include <fstream>
using namespace std;
class Vertex
{
private:
int vertexNum; //number of the vertex for identification purposes
int degree;
bool known;
vector<Edge> adjacentVertices; //vector of vertices that are adjacent to the vertex we are currently looking at
int dv; //distance
int pv; //previous vertex
Vertex *vertex;
public:
Vertex()
{
dv = INT_MAX;
known = false;
}
void setKnown(bool Known)
{
known = Known;
}
bool getKnown()
{
return known;
}
void setVertexNum(int VertexNum)
{
vertexNum = VertexNum;
}
void setDegree(int Degree)
{
degree = Degree;
}
vector<Edge> & getAdjacentVertices()
{
return adjacentVertices;
}
int getVertexNum()
{
return vertexNum;
}
int getDegree()
{
return degree;
}
int getDV() const
{
return dv;
}
int setDV(int Dv)
{
dv = Dv;
}
void setAdjacentVertex(int AdjacentVertex, int Weight)
{
Edge newEdge;
newEdge.setWeight(Weight);
newEdge.setAdjVertex(AdjacentVertex);
adjacentVertices.push_back(newEdge);
}
friend ostream & operator <<(ostream & outstream, Vertex *vertex)
{
outstream << vertex->getVertexNum() << endl;
outstream << vertex->getDegree() << endl;
outstream << vertex->getKnown() << endl;
vector<Edge> E = vertex->getAdjacentVertices();
for(int x=0;x<E.size();x++)
{
outstream << E[x].getAdjVertex() << endl;
outstream << E[x].getWeight() << endl;
}
return outstream;
}
friend bool operator < (const Vertex & v1, const Vertex & v2);
};
Edge.h:
#include <cstdlib>
class Edge
{
private:
int adjVertex; //represents the vertex that the edge leads to
int weight;
public:
Edge()
{
adjVertex = 0;
weight = 0;
}
void setWeight(int Weight)
{
weight = Weight;
}
void setAdjVertex(int adjacent)
{
adjVertex = adjacent;
}
int getAdjVertex()
{
return adjVertex;
}
int getWeight()
{
return weight;
}
};
From g++ to English:
Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'
Explanation:
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++) <- this is 154. sortedVertices is not a pointer. It is a std::vector of some pointers.
int dist = getAdjacentVertices()[m].getWeight(); <- 156. What is getAdjacentVertices?
sortedVertices[1].getDV() <- 157 sortedVertices[1] is a pointer. Look at operator[]
sortedVertices[m+1]->getAdjacentVertices() is a vector of Edge. Edge does not have a getDV() method defined.
Is this really your code?
As an author you should not have trouble understanding the error messages. Those are simple mistakes, that took 5 minutes for a stranger to understand. You need to put more effort in understanding what you write, and what compiler tells you. Or get some sleep to get some focus.
I would also suggest to spend some time working out what std::vector really is and how to understand std::vector<Vertex*> vector_of_vertices; object.
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0)
Here you create variable of type vector<Vertex*> on the stack. This is not a pointer. This is a container containing pointers of type Vertex* and that's completely different. You use -> operator which is only used on pointers.

Can't resolve Segmentation Fault core dump error

I am writing a program that implements Dijkstra algorithm for graphs and I ran into this:
Segmentation fault (core dump). I have narrowed down the line (I have marked the line where the error is occurring) that is causing me the error, and then I used both GDB and Valgrind on my program, but all those told me was what line the error was occurring on, something I already new. Any help that y'all can give would me awesome! Thanks in advance!
////HERE'S MY MAIN/////
#include "Vertex.h"
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
void Dijkstra(vector<Vertex> & V);
///overload the less than operator in order to use the stl sort for vector
///print out the path for each vertex
int main()
{
/////READ ALL THE STUFF INTO THE GRAPH////
ifstream file;
file.open("graph.txt");
cout << "Opening file..." << endl;
if(!file)
{
cout << "System failed to open file.";
}
else
{
cout << "File successfully opened" << endl;
}
int numVertices;
int numEdges;
int adjacentVertex;
int weight;
file >> numVertices;
cout << "The number of vertices that are being read into the graph from the file: " << numVertices;
cout << endl;
vector<Vertex*> vertices;
//vector<Vertex> vertices(numVertices + 1);
for(int i=1;i<=numVertices;i++)
{
file >> numEdges;
cout << "At vertex " << i << " the number of edges is " << numEdges << endl;
cout << "Hello" << endl;
vertices[i] = new Vertex(); ////THIS IS WHERE THE ERROR IS
cout << "World" << endl;
//Vertex newVertex;
//Using the i counter variable in the outer for loop to identify
//the what vertex what are currently looking at in order to read in the correct adjacent vertex and weight
vertices[i] -> setVertexNum(i);
//newVertex.setVertexNum(i);
for(int j=1;j<=numEdges;j++)
{
file >> adjacentVertex;
cout << "The adjacent vertex is: " << adjacentVertex << endl;
file >> weight;
cout << "The weight is: " << weight << endl;
cout << endl;
vertices[i]->setAdjacentVertex(adjacentVertex, weight);
}
vertices.push_back(vertices[i]);
}
file.close();
/*
for(int i=0;i<vertices.size();i++)
{
cout << "V" << i <<": ";
cout << endl;
for(int j=0;j<vertices[i].getAdjacentVertices().size();j++)
{
cout << "V" << vertices[i].getAdjacentVertices()[j].getAdjVertex() << " " << vertices[i].getAdjacentVertices()[j].getWeight() << endl;
}
}
*/
//CALL THE SHORTEST PATH FUNCTION ON THE GRAPH/////
}
////HERE'S MY VERTEX CLASS/////
#include "Edge.h"
#include <vector>
#include <climits>
#include <fstream>
using namespace std;
class Vertex
{
private:
int vertexNum; //number of the vertex for identification purposes
int degree;
bool known;
vector<Edge> adjacentVertices; //vector of vertices that are adjacent to the vertex we are currently looking at
int dv; //distance
int pv; //previous vertex
Vertex *vertex;
public:
Vertex()
{
dv = INT_MAX;
known = false;
}
void setKnown(bool Known)
{
known = Known;
}
bool getKnown()
{
return known;
}
void setVertexNum(int VertexNum)
{
vertexNum = VertexNum;
}
void setDegree(int Degree)
{
degree = Degree;
}
vector<Edge> & getAdjacentVertices()
{
return adjacentVertices;
}
int getVertexNum()
{
return vertexNum;
}
int getDegree()
{
return degree;
}
int getDV() const
{
return dv;
}
void setAdjacentVertex(int AdjacentVertex, int Weight)
{
Edge newEdge;
newEdge.setWeight(Weight);
newEdge.setAdjVertex(AdjacentVertex);
adjacentVertices.push_back(newEdge);
}
friend ostream & operator <<(ostream & outstream, Vertex & vertex)
{
outstream << vertex.vertexNum << endl;
outstream << vertex.degree << endl;
outstream << vertex.known << endl;
vector<Edge> E = vertex.getAdjacentVertices();
for(int x=0;x<E.size();x++)
{
outstream << E[x].getAdjVertex() << endl;
outstream << E[x].getWeight() << endl;
}
return outstream;
}
friend bool operator < (const Vertex & v1, const Vertex & v2);
void printVertex()
{
}
};
When initializing elements of a vector, you should use the push_back method.
So change:
vertices[i] = new Vertex();
to:
vertices.push_back( new Vertex() );
Of course, there are still other problems in your code. One hint I can give you is to iterate your for loops starting with 0 and using < instead of <= in the predicate.
So you must replace the line
vector <Vertex*> vertices;
By
vector<Vertex*> vertices(numVertices);

.OBJLoader, weird indices numbers

I've been messing with OpenGL and c++ lately (with FreeGLUT and GLEW) and started to try and import .obj files from 3DS Max 2014. Everything is fine if i manual type the vertices and indices but, when trying to get them from a file i get strange numbers.
when getting the indices instead of 1 there was 1000 and instead of 3 there was 3965 and when there was a 12 is was 1212 (there are ones and threes etc but sometimes they are random)
Here is the code I use to import: http://pastebin.com/1ds6fgj9
or
std::vector<std::string> Object::split(std::string str, char splitter){
char charText[1000];
int number = 0;
int numberOfWords = 0;
char current[10][100];
std::vector<std::string> tokens;
strcpy(charText, str.c_str());
int size = sizeof(charText) / sizeof(*charText);
//std::cout << size << " size\n";
for (int i = 0; i < splitter; i++){
if (charText[i] == splitter){
tokens.push_back(current[numberOfWords]);
numberOfWords++;
number = 0;
}
else{
current[numberOfWords][number] = charText[i];
number++;
}
}
return tokens;
}
Object::Object(std::string fileName, Vector3f pos, Vector3f rot, float Size, Vector3f color){
Position = pos;
Rotation = rot;
size = Size;
colors = color;
std::string data;
std::ifstream file(fileName);
std::string line;
Vector3f _verts[1024];
int noVerts = 0;
unsigned int _inds[1024];
int noIndices = 0;
while (getline(file, line)) // same as: while (getline( myfile, line ).good())
{
char charText[1024];
strcpy(charText, line.c_str());
if (charText[0] == 'v' && charText[1] != 'n' && charText[1] != 't'){
std::vector<std::string> splitLine = split(line, ' ');
_verts[noVerts] = Vector3f(atoi(splitLine[1].c_str()), atoi(splitLine[2].c_str()), atoi(splitLine[3].c_str()));
//std::cout << "Vertices Number:" << noVerts << " x:" << _verts[noVerts].getX() << " y:" << _verts[noVerts].getY() << " z:" << _verts[noVerts].getZ() << "\n";
noVerts++;
}
if (charText[0] == 'f'){
std::vector<std::string> splitLine = split(line, ' ');
for (int i = 0; i < 3; i++){
std::vector<std::string> ssl = split(splitLine[i+1], '/');
//std::cout << atoi(splitLine[i].c_str()) << "\n";
std::cout << i << ": " << atoi(ssl[0].c_str()) << " " << atoi(ssl[1].c_str()) << " " << atoi(ssl[2].c_str()) << "\n";
_inds[noIndices] = atoi(ssl[0].c_str());
noIndices++;
_inds[noIndices] = atoi(ssl[1].c_str());
noIndices++;
_inds[noIndices] = atoi(ssl[2].c_str());
noIndices++;
//std::cout << "number of indices:" << noIndices<< "\n";
}
}
}
verts = _verts;
inds = _inds;
SizeV = sizeof(verts);
SizeI = sizeof(inds);
noPoints = SizeI / sizeof(*inds);
length = SizeV / sizeof(*verts);
Matrix4f posM, rotM, sizeM;
sizeM.InitScaleTransform(size, size, size);
rotM.InitRotateTransform(rot.getX(), rot.getY(), rot.getZ());
posM.InitTranslationTransform(pos.getX(), pos.getY(), pos.getZ());
M = posM * rotM * sizeM;
for (unsigned int i = 0; i < length; i++){
verts[i] = _verts[i];
}
}
I think it is an error in my code when reading the file but if not just ask to see my other code.
[EDIT]
It does this for all obj files (not tried exporting with a different program and the obj files I have tried have very few faces).

Obj Loader not displaying properly

so this is an obj loader in c++ using opengl
it seem displays the cube i input as a flat it seems to position them correctly but all objects i have tried come out as a plane (see pictures)
https://docs.google.com/file/d/0B8AdFl9H3IJVRG9FbFo1UnpWaUE/edit?usp=sharing
i have tried other 3d objects and they all seem to come out as this plane (may difer in size)
what i have tried
going over other obj loaders online
slowly running through the debug
checking the vectors load properly
checking to see if the reading in is corect
List item
typedef.h
#pragma
typedef struct {
float x,y,z;
} points;
typedef struct {
float vn[3]; // store the ve3rtex normals
} normal;
typedef struct {
float vt[3]; // store the texture coordinates
} coordinate;
typedef struct {
int shaders;
points p[3];
normal norm[3];
coordinate coord[3];
} face;
loader.h
#pragma once
#include <string>
#include <vector>
#include <fstream>
#include <GL/freeglut.h>
#include<iostream> // this is just for testing, you can remove this with all the cout's
#include "typedef.h"
class Loader
{
public:
Loader(std::string input);
~Loader(void);
void draw(); // this function takes the obj file and draws it
private:
std::ifstream m_inFile;
// the list of vectors that i will be using
std::vector<points> m_points;
std::vector<normal> m_normals;
std::vector<coordinate> m_coords;
std::vector<face> m_faces;
void process(std::string input);
void inputPoints(points temp);
void inputNormals(normal temp);
void inputCoordinates(coordinate temp);
void createFaces(face temp);
};
loader.cpp
#include "Loader.h"
Loader::Loader(std::string input)
{
process(input);
}
Loader::~Loader(void)
{
}
void Loader::process(std::string input)
{
std::string identifier; //used to identify where the input should go
points temppoint;
normal tempnormal;
coordinate tempcoord;
face tempface;
std::string read; // used to read the curent line
int readNum; // this is the number that has just been read in
char skip; // a char to skip thr /
int i;
int count= 1;
m_inFile.open(input);
/* // check to see if it read
if(!m_inFile)
std::cout << "did not read";
else
std::cout << "file read";
*/
//creation of the reading loop
//while(!m_inFile.eof())
m_inFile >> identifier;
do {
// check to see what the opening is
if (identifier =="#")
{
getline(m_inFile,read); // use this to read the whole line
}
else if(identifier == "v")
{
m_inFile >> temppoint.x >> temppoint.y >> temppoint.z;
inputPoints(temppoint);
}
else if(identifier == "vn")
{
m_inFile >> tempnormal.vn[0] >> tempnormal.vn[1] >> tempnormal.vn[2];
inputNormals(tempnormal);
}
else if (identifier == "vt")
{
m_inFile >> tempcoord.vt[0] >> tempcoord.vt[1] >> tempcoord.vt[2];
inputCoordinates(tempcoord);
}
else if(identifier == "f")
{
for( i =0; i < 3; i++)
{
//std::cout << "loops: " << count << std::endl;
count++;
//if(read == "Material.001")
// std::cout << std::endl;
//std::cout << "Iteration: " << i << std::endl;
m_inFile >> readNum;
if(readNum == 0)
break;
readNum--;
tempface.p[i].x = m_points[readNum].x;
tempface.p[i].y = m_points[readNum].x;
tempface.p[i].z = m_points[readNum].z;
m_inFile >> skip >> readNum;
readNum--;
tempface.coord[i].vt[0] = m_coords[readNum].vt[0];
tempface.coord[i].vt[1] = m_coords[readNum].vt[1];
tempface.coord[i].vt[2] = m_coords[readNum].vt[2];
m_inFile >> skip >> readNum;
readNum--;
tempface.norm[i].vn[0] = m_normals[readNum].vn[0];
tempface.norm[i].vn[1] = m_normals[readNum].vn[1];
tempface.norm[i].vn[2] = m_normals[readNum].vn[2];
}
createFaces(tempface);
}
else
{
getline(m_inFile,read);
std::cout << "Not Processed " << identifier << " " << read <<std::endl;
}
m_inFile >> identifier;
} while (!m_inFile.eof());
}
void Loader::inputPoints(points temp)
{
m_points.push_back(temp);
}
void Loader::inputNormals(normal temp)
{
m_normals.push_back(temp);
}
void Loader::inputCoordinates(coordinate temp)
{
m_coords.push_back(temp);
}
void Loader::createFaces(face temp)
{
m_faces.push_back(temp);
}
void Loader::draw()
{
int i;
int j;
glBegin(GL_TRIANGLES);
for (i=0; i < m_faces.size();i++)
{
//std::cout<<"glBegin" <<std::endl;
for(j = 0 ; j < 3; j++)
{
//std::cout << "Vn1: "<< m_faces[i].norm[j].vn[0] << "Vn2: " << m_faces[i].norm[j].vn[1] <<"Vn3: "<< m_faces[i].norm[j].vn[2] << std::endl;
//std::cout << "X: " << m_faces[i].p[j].x << "Y: " << m_faces[i].p[j].y << "Z: " << m_faces[i].p[j].z << std::endl;
//glNormal3f(m_faces[i].norm[j].vn[0],m_faces[i].norm[j].vn[1],m_faces[i].norm[j].vn[2]);
glVertex3f(m_faces[i].p[j].x,m_faces[i].p[j].y,m_faces[i].p[j].z);
}
//glEnd();
//std::cout << "glEnd()" << std::endl <<std::endl;
}
glEnd();
}
inside main i call a function called banner
void Banner()
{
glTranslatef(15000.0,11000.0,25000.0);
glScalef(100,100,100);
lod.draw();
}
which is badly created as a global