Hi, I’m trying to use shaders to draw an obj file and I don’t know why the object isn’t getting rendered to the screen. This is my first time trying to do something like this so sorry if this seems like a simple issue! I think it’s probably the way I’m binding the buffers or something. The code works when I do a simple triangle in this vertex buffer data:
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
but not when I try to parse through the vertices of my obj file. But when I just do glBegin(GL_LINES) on my 3d model (class used to store obj vertices), the object correctly renders to the screen so I know the file itself isn’t wrong. Maybe it’s also because I don’t exactly know what’s going on with the buffers and the entire process of using the shader program after compiling and linking. The last parameter of drawArrays also confuses me a little. I believe it’s the total amount of vertices that need to be drawn which is why mine is such a high number but I could be wrong. Any help would be appreciated, thanks!
---------------------MAIN CODE --------------------------
#include <GL\glew.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
#include <GL\freeglut.h>
#include <string>
#include "model.h"
using namespace std;
// Read our shaders into the appropriate buffers
GLuint useShaders(const char * vertex_file_path, const char * fragment_file_path,
model &m) {
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if (VertexShaderStream.is_open()) {
std::stringstream sstr;
sstr << VertexShaderStream.rdbuf();
VertexShaderCode = sstr.str();
VertexShaderStream.close();
}
else {
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !
", vertex_file_path);
getchar();
return 0;
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if (FragmentShaderStream.is_open()) {
std::stringstream sstr;
sstr << FragmentShaderStream.rdbuf();
FragmentShaderCode = sstr.str();
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s
", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
printf("%s
", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
printf("Compiling shader : %s
", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
printf("%s
", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking program
");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s
", &ProgramErrorMessage[0]);
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
glUseProgram(ProgramID);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
/* static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};*/
vector<double> g_vertex_buffer_data;
for (model::Vector3 f : m.faces) {
g_vertex_buffer_data.push_back(m.verts[f.x - 1].x);
g_vertex_buffer_data.push_back(m.verts[f.x - 1].y);
g_vertex_buffer_data.push_back(m.verts[f.x - 1].z);
g_vertex_buffer_data.push_back(m.verts[f.y - 1].x);
g_vertex_buffer_data.push_back(m.verts[f.y - 1].y);
g_vertex_buffer_data.push_back(m.verts[f.y - 1].z);
g_vertex_buffer_data.push_back(m.verts[f.z - 1].x);
g_vertex_buffer_data.push_back(m.verts[f.z - 1].y);
g_vertex_buffer_data.push_back(m.verts[f.z - 1].z);
}
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), &g_vertex_buffer_data[0], GL_STATIC_DRAW);
//glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// glBindVertexArray(vertexArray);
//glColor3f(1, 1, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 500000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 200.0);
glDrawArrays(GL_POINTS, 0, 18960); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
}
void readFile(const char* fileName, vector<vector<string>> &v) {
string line;
ifstream myFile(fileName);
if (myFile.is_open()) {
while (getline(myFile, line)) {
if (!line.empty()) {
istringstream buf(line);
istream_iterator<string> beg(buf), end;
vector<string> tokens(beg, end);
v.push_back(tokens);
}
}
}
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 500000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
vector<vector<string>> list;
readFile("teapot.obj", list);
model m(list);
//m.draw();
useShaders("vertexShader.txt", "fragmentShader.txt", m);
glutSwapBuffers();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("window");
glClearColor(0.0, 0.0, 0.0, 0.0);
glutDisplayFunc(display);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 200.0);
glMatrixMode(GL_MODELVIEW);
GLenum err = glewInit();
if (GLEW_OK != err) {
// cout << "error" << endl;
}
glutMainLoop();
return 0;
}
------------- MODEL CLASS -------------
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "model.h"
model::model() {
}
model::model(vector<vector<string>> &s) {
for (vector<vector<string>>::iterator it = s.begin(); it != s.end(); it++) {
double x;
double y;
double z;
vector<string> vs = *it;
x = atof(vs[1].c_str());
y = atof((*it)[2].c_str());
z = atof((*it)[3].c_str());
Vector3 v(x, y, z);
if ((*it)[0] == "v") {
verts.push_back(v);
}
if ((*it)[0] == "f") {
faces.push_back(v);
}
}
}
void model::draw() {
for (Vector3 f : faces) {
glBegin(GL_LINE_LOOP);
glVertex3f(verts[f.x - 1].x, verts[f.x - 1].y, verts[f.x - 1].z);
glVertex3f(verts[f.y - 1].x, verts[f.y - 1].y, verts[f.y - 1].z);
glVertex3f(verts[f.z - 1].x, verts[f.z - 1].y, verts[f.z - 1].z);
glEnd();
}
}
-------------MODEL H--------------------------
#ifndef H_model_H
#define H_model_H
#include <GL\glew.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <GL\freeglut.h>
using namespace std;
class model {
public:
struct Vector3 {
double x;
double y;
double z;
Vector3() {}
Vector3(double n, double n2, double n3) {
x = n;
y = n2;
z = n3;
}
};
Vector3 v3;
struct Color {
char r;
char g;
char b;
};
model();
model(vector<vector<string>> &s);
~model() {}
void draw();
vector<Vector3> verts;
vector<Vector3> faces;
vector<Color> color;
};
#endif