In the begining, I’m working on loading an OBJ file to display on my screen.
But after several trying, it didn’t show up anything.
So I simplify the code to below ones…(if you want to see the original one work, just uncomment #define OBJ_MODE and it will switch to read OBJ file mode)
Is there anything wrong in VAO VBO EBO creating and buffering data?
Or is there the other problem i didn’t notice?
After several days trying debuging,I’m almost want to give up…:dejection:
Below are the code.
VertexObject.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <SOIL/SOIL.h>
//#define OBJ_MODE
using namespace std;
GLuint LocModelMatrix; // Object Translate, Rotate, Scale Matrix
GLuint LocViewMatrix; // Camera Look At Matrix
GLuint LocProjectionMatrix; // Orthogonal, Perspective Matrix
bool glLoadShaderFile(const char * szFile, GLuint shader);
void CameraMovement();
void KeyCallback(GLFWwindow * window, int key, int scancode, int action, int mode);
void MouseCallback(GLFWwindow * window, double xpos, double ypos);
void ScrollCallback(GLFWwindow * window, double xOffset, double yOffset);
int LoadOBJfile(const char * szfile);
void LoadTGAfile(const char * szfile, GLenum min, GLenum mag, GLenum wrap);
void error_callback(int error, const char * description);
bool key_press[1024];
glm::vec3 CameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 CameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 CameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
GLfloat LastFrame = 0.0f;
GLfloat DeltaTime = 0.0f;
GLfloat yaw = -90.0f;// Since 0 will set to right side
GLfloat pitch = 0.0f;
GLfloat FoV = 45.0f;
int model_count = 0;
GLfloat TestVertices[] = {
// Positions
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f // Top Left
};
GLuint TestIndices[] = { // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
vector<unsigned int> VAO_model;
vector<unsigned int> VBO_model;
vector<unsigned int> EBO_model;
GLuint Shader;
vector<size_t> indice_count;
GLfloat vLightPosition[4] = {100.0f, 100.0f, 100.0f, 1.0f};
void error_callback(int error, const char * description)
{
fprintf(stderr, "%d %s
", error, description);
}
int main(int argc,char ** argv)
{
glfwSetErrorCallback(error_callback);
if(glfwInit() == GLFW_FALSE)
fprintf(stderr, "GLFW Initialize Error
");
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow * window = glfwCreateWindow(800, 600, "OpenGL VertexObject", nullptr, nullptr);
glfwMakeContextCurrent(window);
// glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetKeyCallback(window, KeyCallback);
glfwSetCursorPosCallback(window, MouseCallback);
glfwSetScrollCallback(window, ScrollCallback);
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
GLenum Error = glewInit();
if(GLEW_OK != Error)
{
fprintf(stderr, "GLEW Error : %s
", glewGetErrorString(Error));
return 0;
}
//Shader Setup
GLuint VertexShader = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
if(glLoadShaderFile("VertexShader.vs", VertexShader) == false)
{
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
fprintf(stderr, "Shader \"VertexShader.vs\" Not Found
");
}
if(glLoadShaderFile("FragmentShader.fs", FragmentShader) == false)
{
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
fprintf(stderr, "Shader \"FragmentShader.fs\" Not Found
");
}
glCompileShader(VertexShader);
glCompileShader(FragmentShader);
GLint TestValue;
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &TestValue);
if(TestValue == GL_FALSE)
{
char Info[1024];
glGetShaderInfoLog(VertexShader, 1024, NULL, Info);
fprintf(stderr, "Shader \"VertexShader.vs\" can't compile because %s
", Info);
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
}
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &TestValue);
if(TestValue == GL_FALSE)
{
char Info[1024];
glGetShaderInfoLog(FragmentShader, 1024, NULL, Info);
fprintf(stderr, "Shader \"FragmentShader.fs\" can't compile because %s
", Info);
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
}
Shader = glCreateProgram();
glAttachShader(Shader, VertexShader);
glAttachShader(Shader, FragmentShader);
// glBindAttribLocation(Shader, 0, "Position");
glLinkProgram(Shader);
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
glGetProgramiv(Shader, GL_LINK_STATUS, &TestValue);
if(TestValue == GL_FALSE)
{
char Info[1024];
glGetProgramInfoLog(Shader, 1024, NULL, Info);
fprintf(stderr, "Shader Program Link Error : %s
", Info);
glDeleteProgram(Shader);
}
LocModelMatrix = glGetUniformLocation(Shader, "ModelMatrix");
LocViewMatrix = glGetUniformLocation(Shader, "ViewMatrix");
LocProjectionMatrix = glGetUniformLocation(Shader, "ProjectionMatrix");
#ifdef OBJ_MODE
LoadOBJfile("box.obj");
#else
VAO_model.push_back(0);
glGenVertexArrays(1, &VAO_model[0]);
VBO_model.push_back(0);
glGenBuffers(1, &VBO_model[0]);
EBO_model.push_back(0);
glGenBuffers(1, &EBO_model[0]);
glBindVertexArray(VAO_model[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO_model[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(TestVertices), TestVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_model[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(TestIndices), TestIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void *)0);
glBindVertexArray(0);
#endif
while(!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 ViewMatrix = glm::lookAt(CameraPos, CameraPos + CameraFront, CameraUp);
glm::mat4 Projection = glm::perspective(FoV, (float)width / (float)height, 0.1f, 100.0f);
GLfloat CurrentFrame = glfwGetTime();
DeltaTime = CurrentFrame - LastFrame;
LastFrame = CurrentFrame;
glfwPollEvents();
CameraMovement();
glUseProgram(Shader);
glm::mat4 ModelMatrix = glm::translate(ModelMatrix, glm::vec3(1.0f, 0.0f, 0.0f));
glUniformMatrix4fv(LocModelMatrix, 1, GL_FALSE, value_ptr(ModelMatrix));
glUniformMatrix4fv(LocViewMatrix, 1, GL_FALSE, value_ptr(ViewMatrix));
glUniformMatrix4fv(LocProjectionMatrix, 1, GL_FALSE, value_ptr(Projection));
#ifdef OBJ_MODE
for(int i = 0;i < model_count;i++)
{
glBindVertexArray(VAO_model[i]);
glDrawElements(GL_TRIANGLES, indice_count[i] * 3, GL_UNSIGNED_INT, (GLvoid *) 0);
}
#else
glBindVertexArray(VAO_model[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (GLvoid *) 0);
#endif
glfwSwapBuffers(window);
}
glDeleteProgram(Shader);
for(int i = 0;i < model_count;i++)
{
glDeleteVertexArrays(1, &VAO_model[i]);
glDeleteBuffers(1, &VBO_model[i]);
glDeleteBuffers(1, &EBO_model[i]);
}
glfwTerminate();
return 0;
}
void CameraMovement()
{
GLfloat CameraSpeed = 5.0f * DeltaTime;
if(key_press[GLFW_KEY_W])
CameraPos += CameraSpeed * CameraFront;
if(key_press[GLFW_KEY_S])
CameraPos -= CameraSpeed * CameraFront;
if(key_press[GLFW_KEY_A])
CameraPos -= glm::normalize(glm::cross(CameraFront, CameraUp)) * CameraSpeed;
if(key_press[GLFW_KEY_D])
CameraPos += glm::normalize(glm::cross(CameraFront, CameraUp)) * CameraSpeed;
}
void KeyCallback(GLFWwindow * window, int key, int scancode, int action, int mode)
{
if(key >= 0 && key < 1024)
{
if(action == GLFW_PRESS)
key_press[key] = true;
if(action == GLFW_RELEASE)
key_press[key] = false;
}
}
void MouseCallback(GLFWwindow * window, double xpos, double ypos)
{
//mouse support
float Sensitive = 0.05f;
float xOffset, yOffset;
xOffset = xpos - 400.0f;
yOffset = 300.0f - ypos;
glfwSetCursorPos(window, 400, 300);
xOffset *= Sensitive;
yOffset *= Sensitive;
yaw += xOffset;
pitch += yOffset;
if(pitch > 89.0f)
pitch = 89.0f;
if(pitch < -89.0f)
pitch = -89.0f;
glm::vec3 front;
front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
front.y = sin(glm::radians(pitch));
front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
CameraFront = glm::normalize(front);
}
void ScrollCallback(GLFWwindow * window, double xOffset, double yOffset)
{
if(FoV >= 1.0f && FoV <= 45.0f)
FoV -= yOffset;
if(FoV <= 1.0f)
FoV = 1.0f;
if(FoV >= 45.0f)
FoV = 45.0f;
}
void LoadTGAfile(const char * szfile,GLenum min, GLenum mag, GLenum wrap)
{
unsigned char * pBits;
int Width, Height;
pBits = SOIL_load_image(szfile, &Width, &Height, 0, SOIL_LOAD_RGB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, pBits);
SOIL_free_image_data(pBits);
if(min == GL_LINEAR_MIPMAP_LINEAR ||
min == GL_LINEAR_MIPMAP_NEAREST ||
min == GL_NEAREST_MIPMAP_LINEAR ||
min == GL_NEAREST_MIPMAP_NEAREST)
glGenerateMipmap(GL_TEXTURE_2D);
}
/*
int LoadOBJfile(const string szfile)
{
fstream OBJFile;
OBJFile.open(szfile, ios::in);
}
*/
int LoadOBJfile(const char * szfile)
{
FILE * OBJFile;
OBJFile = fopen(szfile, "r");
if(OBJFile == NULL)
{
fprintf(stderr, "In function LoadOBJfile : Open File Failed
");
return 0;
}
char Buffer[100];
while(fscanf(OBJFile, "%s", Buffer) == 1)
{
if(strcmp(Buffer, "g") == 0)
{
model_count++;
}
}
rewind(OBJFile);
vector<size_t> vertex_count;
bool g_sign = 0;
for(int i = 0;i < model_count;i++)
{
vertex_count.push_back(0);
indice_count.push_back(0);
while(fscanf(OBJFile, "%s", Buffer) == 1)
{
if(strcmp(Buffer, "v") == 0)
{
if(g_sign)
{
g_sign = 0;
fseek(OBJFile, -sizeof(char), SEEK_CUR);
break;
}
vertex_count[i] += 1;
}
if(strcmp(Buffer, "#") == 0)
{
fscanf(OBJFile, "%*[^
]");
continue;
}
if(strcmp(Buffer, "f") == 0)
indice_count[i] += 1;
if(strcmp(Buffer, "g") == 0)
{
fscanf(OBJFile, "%*[^
]");
g_sign = 1;
continue;
}
}
}
rewind(OBJFile);
if(model_count == 0)
model_count = 1;
size_t current_vertex, current_indice;
vector<float> Position;
vector<unsigned int> indice;
for(int i = 0;i < model_count;i++)
{
VAO_model.push_back(0);
VBO_model.push_back(0);
EBO_model.push_back(0);
glGenVertexArrays(1, &VAO_model[i]);
glGenBuffers(1, &VBO_model[i]);
glGenBuffers(1, &EBO_model[i]);
}
for(int i = 0;i < model_count;i++)
{
current_vertex = 0;
current_indice = 0;
while(fscanf(OBJFile, "%s", Buffer) == 1)
{
if(strcmp(Buffer, "v") == 0)
{
float temp[3];
fscanf(OBJFile, "%f %f %f
", &temp[0], &temp[1], &temp[2]);
Position.push_back(temp[0]);
Position.push_back(temp[1]);
Position.push_back(temp[2]);
current_vertex++;
}
if(strcmp(Buffer, "f") == 0)
{
unsigned int temp[3];
fscanf(OBJFile, "%u/%*u/%*u %u/%*u/%*u %u/%*u/%*u
", &temp[0], &temp[1], &temp[2]);
indice.push_back(temp[0] - 1);
indice.push_back(temp[1] - 1);
indice.push_back(temp[2] - 1);
current_indice++;//texture coordination indice deal
if(current_indice == indice_count[i])
{
break;
}
}
if(strcmp(Buffer, "s") == 0)
{
}
if(strcmp(Buffer, "#") == 0)
{
fscanf(OBJFile, "%*[^
]");
continue;
}
if(strcmp(Buffer, "g") == 0)
{
}
}
glBindVertexArray(VAO_model[i]);
glBindBuffer(GL_ARRAY_BUFFER, VBO_model[i]);
glBufferData(GL_ARRAY_BUFFER, Position.size() * sizeof(float), &Position[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_model[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indice.size() * sizeof(unsigned int), &indice[0], GL_STATIC_DRAW);
//Vertex Position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid * ) 0);
glEnableVertexAttribArray(0);
fprintf(stdout, "Position:%d, indice:%d
", Position.size(), indice.size());
Position.clear();
indice.clear();
}
glBindVertexArray(0);
fprintf(stdout, "model_count: %d
", model_count);
}
bool glLoadShaderFile(const char * szFile, GLuint Shader)
{
ifstream ShaderFile;
ShaderFile.open(szFile);
stringstream ss;
ss << ShaderFile.rdbuf();
ShaderFile.close();
string s = ss.str();
const char * ShaderSource = s.c_str();
glShaderSource(Shader, 1, &ShaderSource, NULL);
return true;
}
VertexShader.vs
#version 130
in vec3 Position;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
void main()
{
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.0);
}
FragmentShader.fs
#version 130
out vec4 Color;
void main()
{
Color = vec4(1.0,1.0,1.0,1.0);
}