My first question here. In my program depth testing works properly on some computers, but it doesn't work on others, objects that are located farther away cover those which are located closer. I called glEnable(GL_DEPTH_TEST); and tried to call glDepthFunc(GL_LESS); and as I said, everything works properly on some computers, but the same program doesn't work properly on other computers. How can it be fixed?
Edit: Problem solved. Added these lines before calling
al_create_display(); and everything works
al_set_new_display_option( ALLEGRO_COLOR_SIZE, 32, ALLEGRO_REQUIRE);
al_set_new_display_option( ALLEGRO_DEPTH_SIZE, 24, ALLEGRO_REQUIRE);
al_set_new_display_option( ALLEGRO_STENCIL_SIZE, 8, ALLEGRO_REQUIRE);
al_set_new_display_option( ALLEGRO_AUX_BUFFERS, 0, ALLEGRO_REQUIRE);
al_set_new_display_option( ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);
In addition to activating the Depth Test (glEnable(GL_DEPTH_TEST)), it is important that the current framebuffer has a depth buffer.
The default framebuffer is created at the time the OpenGL Context is constructed. The creation of the OpenGL context depends on the OS and windowing library (e.g. GLFW, SDL, SFML). Whether a depth buffer is created by default often depends on the system. In general, window libraries provide additional options for explicitly specifying a depth buffer when generating the OpenGL window:
For instance:
GLFW - Framebuffer related hints
glfwWindowHint(GLFW_DEPTH_BITS, 24);
// [...]
GLFWwindow *wnd = glfwCreateWindow(800, 600, "OpenGL window", nullptr, nullptr);
SDL - Using OpenGL With SDL
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// [...]
SDL_SetVideoMode(800, 600, bpp, flags);
SFML - Using OpenGL in a SFML window
sf::ContextSettings settings;
settings.depthBits = 24;
// [...]
sf::Window window(sf::VideoMode(800, 600), "OpenGL window", sf::Style::Default, settings);
GLUT - glutInitDisplayMode
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowSize(800, 600);
Related
I'm new to Mac, so I'm not very conversant with the get arounds with this OS.
I wrote a simple Open GL program in Xcode and it ran without issues. However, when I checked the versions using the following code
cout<<glGetString(GL_VENDOR)<<endl;
cout<<glGetString(GL_RENDERER)<<endl;
cout<<glGetString(GL_VERSION)<<endl;
cout<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<endl;
Initialization Code
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutCreateWindow("First Test");
initRendering();
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutMainLoop();
I get the following output
ATI Technologies Inc.
AMD Radeon Pro 5300M OpenGL Engine
2.1 ATI-3.10.15
1.20
From forums elsewhere I have read that Mac OS 10.15 supports Open GL version 4.1 and the Graphics card here can certainly support higher versions too.
So my questions are as follows:
Why is it showing 2.1 on my machine
How to fix this? Is there a code that I can type into fix the issue or more software needs to be installed?
Any direction would be great.
Thanks
GLUT is ancient and doesn't support common macOS features such as HiDPI or mouse scrolling. You probably want to look into using the GLFW library instead (see here for what you need to do for a 4.1 context).
However if you really want to use GLUT, you need to add
glutInitContextVersion(4, 1);
glutInitContextProfile(GLUT_CORE_PROFILE);
after glutInit.
Edit: the answer was posted before I know he's using glut, also I recommend GLFW for Modern OpenGL 4.1+
I think you should define the version and create the context first, using some libraries like GLFW and set the OpenGL profile intended to use. also use GLEW/GLAD libraries for GL extensions management.
In case you are using GLFW and GLEW you can add this code to define a version and create a context and a window. then check the version again.
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
using namespace std;
int main()
{
// Initialize GLFW
glfwInit();
// Define version and compatibility settings
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //ver
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // for MAC ONLY
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create OpenGL window and context
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
// Check for window creation failure
if (!window)
{
// Terminate GLFW
glfwTerminate();
return 0;
}
// Initialize GLEW
glewExperimental = GL_TRUE; glewInit();
// your code
cout<<glGetString(GL_VENDOR)<<endl;
cout<<glGetString(GL_RENDERER)<<endl;
cout<<glGetString(GL_VERSION)<<endl;
cout<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<endl;
// Event loop
while(!glfwWindowShouldClose(window))
{
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
// Terminate GLFW
glfwTerminate(); return 0;
}
If you don't have GLFW and GLEW already installed, you can check this tutorial to install them for MacOS : https://riptutorial.com/opengl/example/21105/setup-modern-opengl-4-1-on-macos--xcode--glfw-and-glew- or check this one: https://giovanni.codes/opengl-setup-in-macos/
in case it does not work and still showing 2.1 try to go to the "Energy Saver" in the system settings and deselect the "Automatic graphics switching".
I have been learning about SDL 2D programming for a while and now I wanted to create a program using SDL and OpenGL combined. I set it up like this:
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL and OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
context = SDL_GL_CreateContext(window);
The program is for now just a black window with a white line displayed using OpenGl. Here is the code for the rendering:
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2d(1, 0);
glVertex2d(-1, 0);
glEnd();
SDL_GL_SwapWindow(window);
So the thing is, I would like to render textures additionally using pure SDL and a SDL_Renderer object, as I did before without OpenGL. I tried that out but it didn't work. Is it even possible to do that and how? What I did is creating a SDL_Renderer and then after drawing OpenGL stuff doing this:
SDL_Rect fillRect;
fillRect.w = 50;
fillRect.h = 50;
fillRect.x = 0;
fillRect.y = 0;
SDL_SetRenderDrawColor(renderer, 100, 200, 100, 0);
SDL_RenderFillRect(renderer, &fillRect);
SDL_RenderPresent(renderer);
But this does not work. The rectangle is not shown, although for some milliseconds it appears slightly. I feel like the OpenGL rendering is overwriting it.
SDL uses OpenGL (or in some cases Direct3D) and OpenGL has internal state which affects the GL calls in your program. The current version of SDL does not clearly indicate which states it changes or depends upon for any call and it does not include functions to reset to a known state. That means you should not mix SDL_Renderer with OpenGL yet.
However, if you really want this functionality now, you can try SDL_gpu (note: I'm the author). It does support mixing with OpenGL calls and custom shaders. You would want to specify which version of the OpenGL API you need (e.g. with GPU_InitRenderer(GPU_RENDERER_OPENGL_1, ...)) and reset the GL state that SDL_gpu uses each frame (GPU_ResetRendererState()). Check out the 3d demo in the SDL_gpu source repository for more.
https://github.com/grimfang4/sdl-gpu/blob/master/demos/3d/main.c
You can render to an SDL_Surface with SDL, and then convert it to a texture & upload it to the GPU using OpenGL.
Example code: http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture
I have been learning about SDL 2D programming for a while and now I wanted to create a program using SDL and OpenGL combined. I set it up like this:
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL and OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
context = SDL_GL_CreateContext(window);
The program is for now just a black window with a white line displayed using OpenGl. Here is the code for the rendering:
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2d(1, 0);
glVertex2d(-1, 0);
glEnd();
SDL_GL_SwapWindow(window);
So the thing is, I would like to render textures additionally using pure SDL and a SDL_Renderer object, as I did before without OpenGL. I tried that out but it didn't work. Is it even possible to do that and how? What I did is creating a SDL_Renderer and then after drawing OpenGL stuff doing this:
SDL_Rect fillRect;
fillRect.w = 50;
fillRect.h = 50;
fillRect.x = 0;
fillRect.y = 0;
SDL_SetRenderDrawColor(renderer, 100, 200, 100, 0);
SDL_RenderFillRect(renderer, &fillRect);
SDL_RenderPresent(renderer);
But this does not work. The rectangle is not shown, although for some milliseconds it appears slightly. I feel like the OpenGL rendering is overwriting it.
SDL uses OpenGL (or in some cases Direct3D) and OpenGL has internal state which affects the GL calls in your program. The current version of SDL does not clearly indicate which states it changes or depends upon for any call and it does not include functions to reset to a known state. That means you should not mix SDL_Renderer with OpenGL yet.
However, if you really want this functionality now, you can try SDL_gpu (note: I'm the author). It does support mixing with OpenGL calls and custom shaders. You would want to specify which version of the OpenGL API you need (e.g. with GPU_InitRenderer(GPU_RENDERER_OPENGL_1, ...)) and reset the GL state that SDL_gpu uses each frame (GPU_ResetRendererState()). Check out the 3d demo in the SDL_gpu source repository for more.
https://github.com/grimfang4/sdl-gpu/blob/master/demos/3d/main.c
You can render to an SDL_Surface with SDL, and then convert it to a texture & upload it to the GPU using OpenGL.
Example code: http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture
My program starts with a loading window while it is compiling shaders, loading textures etc. I then want to be able to launch a fullscreen application and use these resources. My understanding is that the openGL context must be the same before and after. I tried two methods for this: first of all I tried making a second window which was fullscreen, and used the SDL_GL_makecurrent command on this window to 'transfer' the context across (couldn't find where I read about this method), and secondly tried just fullscreening the loading window. Both of these methods resulted in the loading screen being moved to the top left corner of the screen. However opengl commands no longer ran properly in fullscreen, including clearing buffers which meant that the window contained the contents of my desktop/background applications.
Is there a proper way of doing this? Or is this a strange bug in sdl/opengl drivers?
Code to fullscreen original window:
//opengl commands work fine up to here
//now to fullscreen
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_SetWindowSize(window, 1366, 768); //tried this on either side of line above and without either line
glViewport(0, 0, 1366, 768); //update viewport
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
//window should be whited, other draw commands tried and all fail or distort
SDL_GL_SwapWindow(window);
Creating a new window and using previous context:
//Fine up to here
window2 = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1366, 768, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_SHOWN);
SDL_GL_MakeCurrent(window2, glContext); //created with SDL_GL_CreateContext(oldwindow);
//draw commands dont work
PS: running ubuntu
Update: In the second code, reusing the context in a new window, it returns an error saying 'invalid window' when it fails, which is most of the time but not always. When it fails, the screen ends up completely corrupted(black with weird white squares and patterns), ending the program will not clear the screen of this (although screenshots are perfectly fine?), but it can be restored by ctrl+f1 to terminal then ctrl+f7 back
I dont really know if its a bug. I experienced the same issue with sdl2 and opengl.
Create an regular window
attach to opengl context.
fullscreen
BOOM. black screen and crashed window.
I only noticed that issue in ubuntu.
Trought some tests i found a quick way to fix it:
Uint32 flags = 0;
flags |= SDL_WINDOW_RESIZABLE;
//bla bla bla your tags
flags |= SDL_WINDOW_OPENGL;
m_window = SDL_CreateWindow( "hello gl", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_screen.x, m_screen.y,flags);
m_glContext = SDL_GL_CreateContext(m_window);
//Set right the way the screen to fullscrene false
SDL_SetWindowFullscreen(m_window, SDL_FALSE);
Now the fullscreen seems to work without problem.
I have reinstalled devcpp 4.9.9.2 on windows xp virtualbox and installed glut and glew.
My original program just used glut, and shows some spheres bouncing around a room. My problem is that once I add in the line
glGenFramebuffers(1, &myBuffer);
my program fails to run. It compiles just fine. But when I run it says "Ass1.exe has encountered a problem and needs to close. We are sorry for the inconvenience.".
If I comment out this line then it works just fine, with balls bouncing around. The glGenFramebuffers is at the bottom of my setup method.
Here is a link to my code. https://dl.dropboxusercontent.com/u/13330596/Exercise1.cpp
This is the code just before I now call glewInit();
// Initialize GLUT.
glutInit(&argc, argv);
// Set display mode with an RGB colour buffer, double buffering and a depth buffer..
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
// Set OpenGL window size
glutInitWindowSize(1000, 1000);
// Set position of OpenGL window upper-left corner
glutInitWindowPosition(100, 100);
// Create OpenGL window with title
glutCreateWindow("Dissertation");
glewInit();
You must call glewInit(); before you can use extended functionality. Probably you didn't so the functions pointers are still null pointer. glewInit must be called after a context has been created and bound. In the case of using GLUT this is right after glutCreateWindow(…);