I want to use OpenGL 3.1.
I'm using a Macbook Pro with 2 graphic cards: NVIDIA GeForce GT 650M 1024 MB, and Intel HD Graphics 4000 1536 MB. They both support up to OpenGL 4.1.
Previously i was able to draw a triangle however, my program was using version 2.1. Therefore I added: SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);. However, now the triangle is no longer drawn.
#include <string>
#include <iostream>
#include <SDL2/SDL.h>
#define GL3_PROTOTYPES 1
#include "../include/GL3/gl3.h"
int main(int argc, const char *argv[]) {
// Initialize the SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "Failed to initialize the SDL: " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Configure the SDL to use OpenGL 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
// ======= HERE =======
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// ====================
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_Window* window = SDL_CreateWindow("Triangle Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
if (window == 0) {
std::cout << "Error when creating the window: " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Create the OpenGL context
SDL_GLContext contextOpenGL = SDL_GL_CreateContext(window);
// Initialization may fail
if (contextOpenGL == 0) {
std::cout << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return -1;
}
SDL_Event events;
bool end = false;
// Define the vertices of our triangle
static const GLfloat vertices[] = {0.0, 1.0, // left point
-0.5, 0.0, // right point
0.5, 0.0}; // upper point
const int TRIANGLE_IDX = 0;
while(!end) {
SDL_WaitEvent(&events);
if(events.window.event == SDL_WINDOWEVENT_CLOSE) {
end = true;
}
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT);
// Send vertices to OpenGL
glVertexAttribPointer(TRIANGLE_IDX, 2, GL_FLOAT, GL_FALSE, 0, vertices);
// Activate our vertex array
glEnableVertexAttribArray(TRIANGLE_IDX);
// Draw the points passed previously
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(TRIANGLE_IDX);
// Refresh the screen
SDL_GL_SwapWindow(window);
}
return 0;
}
I tried to first use glGenBuffers, glBindBuffer and glBufferData but i could not manage to make it work.
The Fixed Function Pipeline has been removed from core OpenGL 3.1 and above.
You will have to use shaders instead. This site has a nice example of how to use them.
Related
I've tried to set the window icon from the scripts within the stackoverflow questions below, but nothing did work to my solution
GLFW SetWindowIcon
https://learn.microsoft.com/en-us/windows/win32/menurc/using-icons
My entire main.cpp from my solution:
#include "imgui/imgui.h"
#include "imgui/imgui_impl_glfw.h"
#include "imgui/imgui_impl_opengl3.h"
#include <string>
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <Windows.h>
#include <WinUser.h>
#include <WinNls32.h>
int main()
{
// Create a custom icon at run time.
// 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(1200, 700, "Dessor 0.1.0c", 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, 1200, 700);
// Initialize ImGUI
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
// Variables to be changed in the ImGUI window
bool drawCube = false;
float size = 1.0f;
float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
// Main while loop
while (!glfwWindowShouldClose(window))
{
// Specify the color of the background
glClearColor(0.11f, 0.11f, 0.11f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Clean the back buffer and assign the new color to it
// Tell OpenGL a new frame is about to begin
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
if (drawCube)
glClearColor(0.01f, 0.01f, 0.01f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// ImGUI window creation
// Particular widget styling
static int i2 = 3;
static int ifov = 60;
static float size = 3.0;
static char name[128] = "5";
static const ImVec4 edge_color = ImVec4(0.25f, 0.25f, 0.90f, 1.00f);
static const ImVec4 inside_color = ImVec4(0.55f, 0.55f, 0.90f, 1.00f);
const ImVec2 size2 = ImVec2(250, 200);
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255));
ImGui::Begin("Drawing HyperCube Options", NULL, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::PopStyleColor();
ImGui::Checkbox("Draw Shape", &drawCube);
ImGui::SliderInt("D", &i2, 0, atoi(name), "%d-dimensional hypercube");
ImGui::InputText("", name, 7, ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::SameLine();
ImGui::TextColored(ImVec4(255, 0, 255, 255), name);
ImGui::NewLine();
ImGui::SliderFloat("SIZE", &size, 1.0, 10.0);
ImGui::SliderInt("FOV", &ifov, 30, 120, "%d");
ImGui::NewLine();
ImGui::Button("Render", ImVec2(250, 60));
ImGui::BeginChild("Inside color", size2);
ImGui::TextColored(inside_color, "INSIDE COLOR");
ImGui::ColorPicker3("", (float*)&inside_color);
ImGui::TextColored(edge_color, "EDGE COLOR");
ImGui::ColorEdit3("", (float*)&edge_color);
ImGui::EndChild();
ImGui::NewLine();
ImGui::End();
// Checkbox that appears in the window
// Renders the ImGUI elements
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Swap the back buffer with the front buffer
glfwSwapBuffers(window);
// Take care of all GLFW events
glfwPollEvents();
}
// Deletes all ImGUI instances
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
// Delete window before ending the program
glfwDestroyWindow(window);
// Terminate GLFW before ending the program
glfwTerminate();
return 0;
}
How can I use the glfwSetWindowIcon() or there's another way for change window icon in native c++?
I'm trying to use all 3 libraries or whatnot but i'm quite confused by the sample code and I can't quite follow the documentation. This is the code and ill explain my confusions below:
#include <iostream>
#include <string>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <imgui/imgui.h>
#include <imgui/imgui_stdlib.h>
#include <imgui/imgui_impl_sdl.h>
#include <imgui/imgui_impl_opengl3.h>
// Main code
int main(int argc, char* argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
std::cout << SDL_GetError() << std::endl;
return -1;
}
// GL 3.0 + GLSL 130
const char* glsl_version = "#version 130";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
// Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(0); // Disable vsync
if (glewInit() != GLEW_OK) {
std::cout << "Error initializing glew\n";
}
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer backends
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init(glsl_version);
ImFont* font = io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\Arial.ttf", 30.0f);
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop
bool running = false;
SDL_Event event;
while (!running)
{
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_QUIT)
running = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
running = true;
}
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame(window);
ImGui::NewFrame();
{
static std::string buf = "";
ImGui::PushFont(font);
ImGui::Begin("Window");
ImGui::InputText("Hello", &buf);
//std::cout << io.Fonts->Fonts.size() << std::endl;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::End();
ImGui::PopFont();
}
// Rendering
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);
}
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
There are a few confusions I have here, starting with there being no SDL_Renderer anywhere within the code. I notice that the display draw color is handled by OpenGL, but the rendering is called via glClear(GL_COLOR_BUFFER_BIT); (I THINK). I'm unsure, though, how I could actually then call any SDL2 functions such as SDL_RenderFillRect() with no SDL_Renderer ? My best hint is this line:
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);
where its SDL_GL_SwapWindow() but this I believe just also renders for the OpenGL? I'm not really sure what line out of all the rending actually does what. I mean I would have thought ImGui::Render() would render all ImGui things, but then theres an ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); and then I'm not sure how the SDL_GL_SwapWindow ties in since i've already called glClear(). Additionally, why is there a function called ImGui::EndFrame() but not called in the sample code at the end of a frame and then there is ImGui::NewFrame() for each loop and same for ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplSDL2_NewFrame(window); Can someone please explain some of these things its very confusing.
SDL_Renderer is something you need if you want to use the SDL API for drawing tasks, but it is not required if you just create the OpenGL context with SDL and do all the drawing directly with OpenGL.
but the rendering is called via glClear(GL_COLOR_BUFFER_BIT);
No, glClearclearse part of the current render buffer, in this case, the color (What is the purpose of GL_COLOR_BUFFER_BIT and GL_DEPTH_BUFFER_BIT?
)
SDL_GL_SwapWindow(window); brings the contents of the current render buffer (the rendering) to the window SDL_GL_SwapWindow
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); invokes he drawing of the ImGUI components.
#include "list.h"
int main()
{
//INIT GLFW
glfwInit();
//CREATE WINDOW
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480;
int framebufferWidth = 0;
int framebufferHight = 0;
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH,WINDOW_HEIGHT,"Title", NULL, NULL);
glfwGetFramebufferSize(window, &framebufferWidth, &framebufferHight);
glViewport(0, 0, framebufferWidth, framebufferHight);
glfwMakeContextCurrent(window);//IMPORTIANT!!
//INIT GLEW (NEEDS WINDOW AND OPENGL CONTEXT)
glewExperimental = GL_TRUE;
>//Error
if (glewInit() != GLEW_OK)
{
std::cout << "ERROR::MAIN.CPP::GLEW_INIT_FAILED" << "\n";
glfwTerminate();
}
//MAIN LOOP
while (glfwWindowShouldClose(window))
{
//UPDATE INPUT ---
//UPDATE ---
//DRAW ---
//Clear
//Draw
//End Draw
}
//END OF PROGAM
glfwTerminate();
return 0;
}
glViewport(0, 0, framebufferWidth, framebufferHight); is giving me
Unhandled exception at >0x00007FF704D6E7D9 in OpenzGL4.exe: 0xC0000005: Access violation reading >location >0x0000000000000348.
when I run it.
For any OpenGL instruction is required a valid and current OpenGL Context. Hence glfwMakeContextCurrent hast to be invoked before any OpneGL instruction:
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH,WINDOW_HEIGHT,"Title", NULL, NULL);
glfwMakeContextCurrent(window); // <----- ADD
glfwGetFramebufferSize(window, &framebufferWidth, &framebufferHight);
glViewport(0, 0, framebufferWidth, framebufferHight);
glfwMakeContextCurrent(window); // <----- DELETE
In addition to what Rabbid76 already wrote in his answer, there is another problem in your code:
glViewport(0, 0, framebufferWidth, framebufferHight);
glfwMakeContextCurrent(window);//IMPORTIANT!!
//INIT GLEW (NEEDS WINDOW AND OPENGL CONTEXT)
glewExperimental = GL_TRUE;
>//Error
if (glewInit() != GLEW_OK) {
std::cout << "ERROR::MAIN.CPP::GLEW_INIT_FAILED" << "\n";
glfwTerminate(); }
Since you use the GLEW OpenGL loader, every gl...() Function name is actually remapped as a preprocessor macro to a function pointer, and glewInit will query all those function pointers (and that needs an active OpenGL context, so it can't be done before the glfwMakeContextCurrent). So it is not enough to move the glViewport after the glfwMakeContextCurrent, you must also move it after glewInit.
And there is a second issue with this code: the glewExperimental = GL_TRUE is an evil hack for a bug in GLEW 1.x with OpenGL core profiles, and it's use can't be discouraged enough. Just update to GLEW 2.x or another loader which is compatible with OpenGL core profile contexts.
This code is supposedly the code to draw a triangle however all I get is a black screen. Why am I not getting anything drawn?
Secondly, in my array of vertices, if I put an 'f' after my coordinates like I always see in tutorials I get an error about an invalid digit in an octal. Why can everyone else use 'f' after their numbers and not me?
I am using openGL 4.1 on OSX Yosemite.
#include <iostream>
//Using SDL and standard IO
#include <SDL2/SDL.h>
//#define GL_GLEXT_PROTOTYPES 1
//#include <SDL2/SDL_opengl.h>
#include <GLUT/glut.h>
#include <stdio.h>
#include <OpenGL/gl3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string.h>
using namespace std;
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
bool SetOpenGLAttributes()
{
// Set our OpenGL version.
// SDL_GL_CONTEXT_CORE gives us only the newer version, deprecated functions are disabled
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
return true;
}
int main( int argc, char* args[] )
{
//The window we'll be rendering to
SDL_Window* window = NULL;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
}
else
{
SetOpenGLAttributes();
//Create window
window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL );
if( window == NULL )
{
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
}
else
{
//creating new context
SDL_GL_CreateContext(window);
GLuint vertexArrayID;
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
printf("%s", "This is your version");
printf("%s\n", glGetString(GL_VERSION));
printf("%s", glGetString(GL_RENDERER));
SDL_GL_SetSwapInterval(1);
glEnable(GL_DEPTH_TEST);
float r = 0.5;
static const GLfloat cubeV[] = {
-.5, 0, 0,
.5, 0, 0,
0, .5, 0
};
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeV), cubeV, GL_STATIC_DRAW);
SDL_GL_SwapWindow(window);
bool running = true;
while(running){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
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
);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glFlush();
SDL_GL_SwapWindow(window);
SDL_Delay(17);
}
}
}
//Destroy window
//SDL_DestroyWindow( window );
//Quit SDL subsystems
//SDL_Quit();
return 0;
}
I'm learning OpenGL so I was experimenting with drawing 2D images.
I first put everything in the main function of my C++ program. It worked fine (2 triangles were drawn).
I decided to make the program clearer by making separate classes, ...
But now it isn't working anymore. When I want to make the OpenGL Context, it fails. When I display the error I get :
Failed creating OpenGL context at version requested
In the tutorial I am reading they said this error is most likely due to the fact that the version of OpenGL isn't supported by your graphics card, but if this was the case, it shouldn't work when I put all the code in the main procedure.
This is the part where it goes wrong (context creation) :
bool OpenGL_Scene::initializeWindow() {
// Initialize the SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
cout << "Error while initializing the SDL : " << SDL_GetError() << endl;
SDL_Quit();
return false;
}
// Configure OpenGL
// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1
// Double buffering
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // Buffer has a depth of 24 bits
// Make the window
this->window = SDL_CreateWindow(this->windowTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->windowWidth, this->windowHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); // SDL_WINDOW_OPENGL necessary to specify that the window will have an OpenGL context attached to it.
if(this->window == 0) // Initialization failed
{
cout << "Error while creating the window : " << SDL_GetError() << endl;
SDL_Quit();
return false;
}
// Make the OpenGL context given the SDL window
this->OpenGL_Context = SDL_GL_CreateContext(this->window);
// Make sure the creation of the context succeeded. If not the problem is probably that the version of OpenGL isn't supported by the graphics card.
if(this->OpenGL_Context == 0)
{
cout << "Could not create the OpenGL context : " << SDL_GetError() << endl;
SDL_DestroyWindow(window);
SDL_Quit();
return false;
}
return true;
};
In the last few lines the error get displayed so the program results in :
Could not create the OpenGL context : Failed creating OpenGL context at version requested
I searched a lot to find a solution and found this :
SO topic
So in the above code I tried :
// Configure OpenGL
// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1
// Double buffering
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); // ADDING THIS AVOIDS THAT THE CONTEXT COULD NOT BE CREATED BUT THEN WHEN WE DRAW SOMETHING WE DON'T SEE ANYTHING
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // Buffer has a depth of 24 bits
Now when I run the program with this extra line, the context is created (without errors so OpenGL_Context != 0) but nothing is drawn. I omitted the part of the code where I am drawing, because it worked before and I didn't changed anything.
Does someone has an idea what could be the problem?
PS : I'm working on a Macbook Pro (OS X Yosemite (10.10.4)) and my graphics card is an NVIDIA GeForce GT 650M 1024 MB
EDIT : I tried debugging the code that draws the triangles but I really don't see the error (mainly because I'm really really new to OpenGL). Underneath you can find the drawing code. Notice that I don't initialize GLEW anymore as it isn't necessary (according to the comments).
void OpenGL_Scene::mainLoop() {
bool end = false;
// Make vertices (punten) in a table
// !!! WARNING : Use 1 table for ALL vertices !!! Don't use a separate table for each of the forms, this would slow down the program because you have to send each of the tables to OpenGL !!!
float vertices[] = {-0.5, -0.5, 0.0, 0.5, 0.5, -0.5, // 3 Points for first triangle --> (-0.5, -0.5) , (0.0, 0.5) and (0.5, -0.5) (All in (x, y) --> 2D)
-0.8, -0.8, -0.3, -0.8, -0.8, -0.3}; // 3 Points for second triangle
// Before we start drawing, clear the screen
glClear(GL_COLOR_BUFFER_BIT);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0); // Activate the table we passed to OpenGL using the identifier (index) passed to OpenGL (in this case 0)
// Now that OpenGL knows which vertices it has to display we are going to specify what it has to do with these vertices
glDrawArrays(GL_TRIANGLES, 0, 6); // Draw both triangles
glDisableVertexAttribArray(0); // Because it isn't necessary anymore
SDL_GL_SwapWindow(this->window); // Refresh the screen
while(!end) {
// Listen to events and play with them
SDL_WaitEvent(&this->events); // Will wait for an event and assign it to "events" variable
if(this->events.window.event == SDL_WINDOWEVENT_HIDDEN)
cout << "The user has hidden the window !" << endl;
else if(this->events.window.event == SDL_WINDOWEVENT_CLOSE) {
cout << "The user closed the window !" << endl;
glClear(GL_COLOR_BUFFER_BIT); // Clear the screen
SDL_GL_SwapWindow(this->window); // Refresh the window
end = true;
}
}
// Quitting the SDL and OpenGL properly is done by the destructor
}
So now when I execute the project, first I make the window (this is succesfull) and then I call the mainLoop procedure (from above).
I stepped trough the drawing code using the debugger, all the procedures were called (glClear, ...) but nothing appears in the window (it stays black).
I found the error. I was initializing OpenGL after initializing the SDL, this is why the context could not be created without forcing to go into "Core Profile".
The correct order in "initializeWindow" is :
// Configure OpenGL
// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1
// Double buffering
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // Buffer has a depth of 24 bits
// Initialize the SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
cout << "Error while initializing the SDL : " << SDL_GetError() << endl;
SDL_Quit();
return false;
}
Doing so the context is created successfully.