incorporating "tinyobjloader" in my OpenGL project - opengl

So that i can load OBJ files and have them rendered in my openGL window. So far i've managed to:
create an OpenGL context and window using glfw3
created an executable (of test.cc, and its associated libraries and headers) which just outputs OBJ vertices as text in the terminal
I would like to visually render these vertices in my openGL window, so i guess this involves combining the two, but how is the question? I assuming my openGL context assimilates the obj importer, not the other way round, but where in the code would it go:
#include <GLFW/glfw3.h>
#include <GLUT/glut.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
/* clearing */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
or do I have to link to it externally?

between glfwMakeContextCurrent and the while loop you should read the obj and put the values into VBOs.
It would be of the form
std::string err = tinyobj::LoadObj(shapes, materials, objStream, matSSReader);
if (!err.empty()) {
glfwTerminate();
return 1;
}
then for each mesh in each shape create a VAO and VBO put in the data, setup the vertexAttributePointers and keep how many vertices are in the mesh.
Then during rendering you bind the VAO and bind the correct material and draw.

Related

Why is OpenGL telling me that terminate called after throwing an instance of 'int' after running it?

So I tried to make an OpenGL project with GLFW and glad in visual studio code, but it would throw and error when I would compile and run the program.
I tried to make 3 triangles in a window, it worked so I tried organizing the VBO, VAO, EBO, shaderProgram, vertexShaderSource, and fragmentShaderSource into individual files, and compiled and ran it, I expected the usual result but would give me a window that is not responding, then it would terminate and give out an error. I'm not sure witch of the files are causing this, but my guess is the main.cpp file:
#include"header/shaderClass.h"
#include"header/VAO.h"
#include"header/VBO.h"
#include"header/EBO.h"
//some vertex and indices arrays here
int main()
{
// Initialize GLFW
glfwInit();
// Tell GLFW what version of OpenGL we are using
// In this case we are using OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Tell GLFW we are using the CORE profile
// So that means we only have the modern functions
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create a GLFWwindow object of 800 by 800 pixels, naming it "YoutubeOpenGL"
GLFWwindow* window = glfwCreateWindow(800, 800, "YoutubeOpenGL", NULL, NULL);
// Error check if the window fails to create
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Introduce the window into the current context
glfwMakeContextCurrent(window);
//Load GLAD so it configures OpenGL
gladLoadGL();
// Specify the viewport of OpenGL in the Window
// In this case the viewport goes from x = 0, y = 0, to x = 800, y = 800
glViewport(0, 0, 800, 800);
// Generates Shader object using shaders defualt.vert and default.frag
Shader shaderProgram("default.vert", "default.frag");
// Generates Vertex Array Object and binds it
VAO VAO1;
VAO1.Bind();
// Generates Vertex Buffer Object and links it to vertices
VBO VBO1(vertices, sizeof(vertices));
// Generates Element Buffer Object and links it to indices
EBO EBO1(indices, sizeof(indices));
// Links VBO to VAO
VAO1.LinkVBO(VBO1, 0);
// Unbind all to prevent accidentally modifying them
VAO1.Unbind();
VBO1.Unbind();
EBO1.Unbind();
// Main while loop
while (!glfwWindowShouldClose(window))
{
// Specify the color of the background
glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
// Clean the back buffer and assign the new color to it
glClear(GL_COLOR_BUFFER_BIT);
// Tell OpenGL which Shader Program we want to use
shaderProgram.Activate();
// Bind the VAO so OpenGL knows to use it
VAO1.Bind();
// Draw primitives, number of indices, datatype of indices, index of indices
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);
// Swap the back buffer with the front buffer
glfwSwapBuffers(window);
// Take care of all GLFW events
glfwPollEvents();
}
// Delete all the objects we've created
VAO1.Delete();
VBO1.Delete();
EBO1.Delete();
shaderProgram.Delete();
// Delete window before ending the program
glfwDestroyWindow(window);
// Terminate GLFW before ending the program
glfwTerminate();
return 0;
}

glClear() crashes GLFW when including GLAD

When I started I used the GLFW example code:
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
When running this it gives me a black screen titled "Hello world" which is exactly what I want. But by simply adding GLAD:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
...and giving window hints:
//Specify the OpenGL versions we're using
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
Suddenly it tells me the window failed to initialize.
But by simply adding this:
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
...it allows the window to initialize but crashes when glClear(GL_COLOR_BUFFER_BIT) is called and it gives me the error
'./Voxel\ Game' terminated by signal SIGSEGV (Address boundary error)
I know this because when I remove that line it works, it just doesn't clear the screen.
This is the full code I have now in case the error is somewhere else in there:
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define SCREEN_WIDTH 640
#define SCREEN_HIEGHT 480
int main()
{
GLFWwindow* window;
//Initialize the library
if (!glfwInit())
{
std::cout << "Failed to initalize GLFW" << std::endl;
return -1;
}
//Specify the OpenGL versions we're using
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
//Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HIEGHT, "Voxel Game", NULL, NULL);
if (!window)
{
std::cout << "Failed create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
//Make the window's context current
glfwMakeContextCurrent(window);
//Loop until the user closes the window
while (!glfwWindowShouldClose(window))
{
//Render here
//glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//Swap front and back buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return 0;
}
You are not initializing glad, add gladLoadGL(glfwGetProcAddress); after glfwMakeContextCurrent() and check it returns OK.
In general, there is no OpenGL library apart from some old OpenGL1.1 stuff (in Windows at least), all those GL calls are implemented in the graphics drivers directly, GLAD library just defines a lot of function pointers and wraps them in nicer macros. Then during initialization, it will dynamically load the functions from the drivers present on the machine. Hence the need to generate GLAD for specific OpenGL version.
So if you get segfaults on some GL calls, a good guess is some of those functions were not found, maybe because they are not supported on the HW or because you did not setup GLAD/GLFW correctly.

OpenGL glClearColor always make a black screen

I'm trying to run my first opengl program in C++, which opens a window, sets a background color, and gives a title, from Terminal on Mac OS X.
The code compiles and links fine. When I run the program the window and title open fine but the background color is always black.
It is my understanding that the function glClearColor sets the background color. However, no matter what parameters I pass to the function, the background color of the window is always black.
If anyone can explain to me what errors I'm making, I would very much appreciate it. Thanks and below is the code:
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const GLint WIDTH = 800, HEIGHT = 600;
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Learn OpenGL", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
if(nullptr == window)
{
std::cout << "Failed to create GLFW window" << '\n';
glfwTerminate();
return -1;
}
glewExperimental = GL_TRUE;
GLenum err=glewInit();
if(err != glewInit())
{
std::cout << "Failed to initialize GLEW" << '\n';
return -1;
}
glViewport(0, 0, screenWidth, screenHeight);
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.2f, 0.9f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
glClearColor, like all OpenGL functions, works on the current OpenGL context.
You're not setting your window's context as current for your calling thread, so your call to glClearColor does nothing here. Add:
glfwMakeContextCurrent(window);
before your loop.
From glfwMakeContextCurrent docs:
This function makes the OpenGL or OpenGL ES context of the specified window current on the calling thread. A context can only be made current on a single thread at a time and each thread can have only a single current context at a time.
For those of you crazy enough to use pure WIN32 programming:
If your PIXELFORMATDESCRIPTOR has the flag:
PFD_DOUBLEBUFFER
Then all draw calls target the back buffer.
You need to use the windows GDI32 call "SwapBuffers( HDC )" to show the results of your OpenGL calls.
wlgMakeCurrent()
glClearColor( R, G, B, 1.0 ); //: <--Make sure alpha isn't transparent.
glClear( GL_COLOR_BUFFER_BIT )
SwapBuffers( your_window_HDC ); //: from GDI32.dll
To get access to SwapBuffers I use LoadLibrary and GetProcAddress and
put the function pointer in my Win32 functions library.
Also notworthy:
Call SwapBuffers on the same thread as your OpenGL calls.
One more thing. I used multiple threads. So this might be helpful to know:
My window was created in thread "B"
My Context was created in thread "A" using HDC from thread "B"
My openGL draw calls are in thread "A".
I mention this because before I found out about SwapBuffers I thought the problem was because of my multi threading. OpenGL wasn't giving me any errors though, so I had to guess around and experiment and read.

Unusual output when trying to Create a blank window in open GL

I am trying to create a Blank Window in OpenGL with help of GLFW. below is my code
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
using namespace glm;
int main( void )
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(800,600,"learnopengl",NULL,NULL);
if (window == NULL)
{
fprintf(stderr,"there is a problem with window creation\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
fprintf(stderr,"Failed to initialize GLEW\n");
return -1;
}
int width, height;
glfwGetFramebufferSize(window,&width,&height);
glViewport(0,0,width,height);
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
}
but when i try to run the above code instead of a black blank it shows an instance of my current screen in newly created window.
Why do you expect this code to result in a blank window?
As per the spec, the back buffer contents become undefined after you swap the buffers (and initially, they are of course undefined too). As a result, the output you should get is also undefined and basically anything might show up.
Add a glClear(GL_COLOR_BUFFER_BIT) to your render loop if you want some defined output.
I know the answer is late but may concern other people and help them, I ran this code and it's working pretty well, but the problem is not in your code, it is your video card driver, so what is happening ?
OpenGL has what is called "The Default Framebuffer", it is the Framebuffer (the buffer contains what you will see) that OpenGL is created with. It is created along with the OpenGL Context. Like Framebuffer Objects, the default framebuffer is a series of images. Unlike FBOs, one of these images usually represents what you actually see on some part of your screen. in other words the default framebuffer is the buffer used by the operating system to render your desktop and other application's windows, so your application is using the default framebuffer as the framebuffer is not edited by your app, so you may need to clear the framebuffer with some other values, let's say colors. this is your code edited with buffer clearing using colors.
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
using namespace glm;
int main( void )
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(800,600,"learnopengl",NULL,NULL);
if (window == NULL)
{
fprintf(stderr,"there is a problem with window creation\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
fprintf(stderr,"Failed to initialize GLEW\n");
return -1;
}
int width, height;
glfwGetFramebufferSize(window,&width,&height);
glViewport(0,0,width,height);
//this is an added line
glClearColor(1, 1, 1, 1); //the RGBA color we will clear with
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
//this is an added line
glClear(GL_COLOR_BUFFER_BIT); //the buffer used to clear with
glfwSwapBuffers(window);
}
glfwTerminate();
}
Hope this answer and this code help other people who may have this situation.
for further information about the framebuffer check this link : https://learnopengl.com/Advanced-OpenGL/Framebuffers

OpenGL glfw black window

I have a small problem with glfw.
My code is really simple, I juste want to create an empty window.
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main(void) {
// initialise the windows
GLFWwindow *window;
if (!glfwInit()) {
return -1;
}
// create a windows
window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
if (!window) {
fprintf(stderr, "Failed to initialize GLFW\n");
glfwTerminate();
return -1;
}
// make the window's current context
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// loop until the window close
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// swap back and front buffers
glfwSwapBuffers(window);
// poll the events
glfwPollEvents();
}
std::cout << "finished ";
glfwTerminate();
return 0;
}
This code compile but when I run it, I only have a white window. The title of the window is correct but everything inside is white...
I try to use glClearColor like that
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1, 1, 0, 0);
but my window still white....
I use visual studio 2015.
How to get a black window ?
Edit :
I forgot to add this:
glfwMakeContextCurrent(window);
For future visitors I'm posting the edit as a formal answer.
The thing missing here is to set the newly created window as the current OpenGL context by calling glfwMakeContextCurrent(window);
Interestingly the comments in the code say you are doing this
// make the window's current context
But then you do not call the method above but instead set the background colour immediately after. If you add the above method call after this comment and before you set the background colour then when I run your code it works fine.