I have some trouble to get my glew to work. When I initialize glew I get an error: Missing GL version. I can't create a context aswell: OpenGL not initialized.
This is my code:
#include <GL\glew.h>
#include <GL\GLU.h>
#include <SDL2\SDL.h>
#include <SDL2\SDL_opengl.h>
#include <iostream>
#undef main
SDL_GLContext context;
SDL_Renderer * renderer;
SDL_Window * window;
int main(int argc, char *argv[]) {
//init SDL
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
fprintf(stderr, "\n> Unable to initialize SDL: %s\n", SDL_GetError());
}
window = SDL_CreateWindow("Cri Engine 3D", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
if (window == nullptr)
{
printf("> Window could not be created! SDL Error: %s\n", SDL_GetError());
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, context);
if (context == NULL) {
printf("> OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
}
//Glew
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "> Error: %s\n", glewGetErrorString(err));
}
fprintf(stdout, "> Using GLEW %s\n", glewGetString(GLEW_VERSION));
glViewport(0, 0, 800, 600);
SDL_Quit();
return 0;
}
These are the linker settings I use(in this order): glew32.lib, glu32.lib, opengl32.lib, SDL2.lib, SDL2main.lib.
I'm sure that the libaries are correctly included.
PS: this is my first post, if I am missing some information tell me!
You're missing SDL_WINDOW_OPENGL flag for SDL_CreateWindow().
Also, you must remove #undef main.
Otherwise you would need to do some low-level initialization yourself, which you don't do.
Another thing: You must switch to compatibility profile from core profile (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);) because GLEW has a tendency to crash when you ask it to initialize a core profile context on Windows.
Also, many parts of your core are redundant:
SDL_WINDOW_SHOWN - It is already used by default.
SDL_GL_MakeCurrent(window, context); - Not needed when there is only one context.
glViewport(0, 0, 800, 600); - When you create a context, it automatically sets up a correct viewport for you.
SDL_Quit(); - You don't need to call anything when your program ends. It does nothing but makes your program close slower. (At least this is how it works on Windows. On Linux it is sometimes necessary, as #keltar has pointed out. Also, it prevents leak detectors like valgring from yelling at you about SDL internal structures.)
#include <SDL2\SDL_opengl.h> - It's a replacement for <GL/gl.h>, which you don't need because you already have <GL\glew.h>.
Try adding SDL_WINDOW_OPENGL to window creation flags.
Related
There is something strange happening with gl3w's isSupported function. When I call isSupported(4, 0) it returns false, meaning OpenGL 4.0 isn't supported. However, when I call glGetString(GL_VERSION) it says OpenGL version 4.0.
Does this mean I can use OpenGL 4.0 functions?
I'm using gl3w in C++ and Visual Studio 2017
#include <GL/gl3w.h>
#include <GLFW/glfw3.h>
int main(int argc, char** argv){
if(!glfwInit()) {
FATAL_ERROR("Failed to initialise GLFW");
}
glfwSetErrorCallback(glfwErrorCallback);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL", nullptr, nullptr);
//If i put glfwMakeContextCurrent here gl3wInit fails
//glfwMakeContextCurrent(window);
if (!window) {
glfwTerminate();
FATAL_ERROR("Window creation failed");
}
if(!gl3wInit()) {} // handle that
glfwMakeContextCurrent(window);
bool support = gl3wIsSupported(4, 0); // returns false
const char* version = glGetString(GL_VERSION); // return "4.0.0"
}
You have to make a GL context current before you call gl3wInit() or regular OpenGL functions otherwise they won't do anything useful.
In the OpenGL wiki you can read:
The GL3W library focuses on the core profile of OpenGL 3 and 4. It
only loads the core entrypoints for these OpenGL versions. It supports
Windows, Mac OS X, Linux, and FreeBSD.
Note: GL3W loads core OpenGL
only by default. All OpenGL extensions will be loaded if the --ext
flag is specified to gl3w_gen.py.
And this is confirmed looking inside the code:
int gl3wIsSupported(int major, int minor)
{
if (major < 3) // <<<<=========== SEE THIS
return 0;
if (version.major == major)
return version.minor >= minor;
return version.major >= major;
}
You are asking with glfwWindowHint for an old 2.0 version. Thus, gl3wIsSupported will return false and gl3wInit will return GL3W_ERROR_OPENGL_VERSION.
For glGetString(GL_VERSION) returning "4.0" means that, yes, you can use that 4.0 version. Ask for it with glfwWindowHint.
I fixed it by switching over to glad instead
if (!glfwInit()) {
FATAL_ERROR("Failed to initialise GLFW");
}
glfwSetErrorCallback(glfwErrorCallback);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL", nullptr, nullptr);
if (!window) {
glfwTerminate();
FATAL_ERROR("Window creation failed");
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
glfwDestroyWindow(window);
glfwTerminate();
FATAL_ERROR("Failed to initialise OpenGL context");
}
PRINT("OpenGL Version: " << GLVersion.major << "." << GLVersion.minor);
I am a SDL beginner.
I would like to draw a black background and a filled blue circle on it with SDL2. As there is no way to draw a circle with SDL2, I use SDL2_gfx. I have no problem to draw a black background, but I do not arrive to draw a circle with the function filledCircleRGBA.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL2_gfxPrimitives.h>
#define DEFAULT_WINDOW_WIDTH 800
#define DEFAULT_WINDOW_HEIGHT 600
void
print_SDL_error()
{
fputs("SDL_Error: ", stderr);
fputs(SDL_GetError(), stderr);
fputc('\n', stderr);
}
bool
initSDL()
{
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "SDL could not initialize!\n");
print_SDL_error();
return false;
}
return true;
}
SDL_Window*
initMainWindow()
{
SDL_Window* window;
window = SDL_CreateWindow("SDL2 test",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT,
SDL_WINDOW_SHOWN);
if(window == NULL)
{
fprintf(stderr, "SDL could not create a window!\n");
print_SDL_error();
}
return window;
}
SDL_Window*
initSDLAndMainWindow(SDL_Window* * window)
{
return initSDL() ? initMainWindow() : NULL;
}
void
quit(SDL_Window* main_window)
{
SDL_DestroyWindow(main_window);
SDL_Quit();
}
int
main(int argc, char* argv[])
{
SDL_Window* main_window;
main_window = initMainWindow();
if(main_window == NULL)
{
quit(NULL);
return EXIT_FAILURE;
}
SDL_Renderer* main_window_renderer;
main_window_renderer = SDL_CreateRenderer(main_window, -1, SDL_RENDERER_ACCELERATED);
if(main_window_renderer == NULL)
{
fprintf(stderr, "Renderer could not be created!\n");
print_SDL_error();
quit(main_window);
return EXIT_FAILURE;
}
SDL_SetRenderDrawColor(main_window_renderer, 0, 0, 0, 0);
SDL_RenderClear(main_window_renderer);
SDL_RenderPresent(main_window_renderer);
SDL_Delay(2000);
if(filledCircleRGBA(main_window_renderer,
150, 150, 75,
0, 0, 255, 0) != 0)
{
fprintf(stderr, "A circle was not rendered!\n");
print_SDL_error();
SDL_DestroyRenderer(main_window_renderer);
quit(main_window);
return EXIT_FAILURE;
}
SDL_RenderPresent(main_window_renderer);
SDL_Delay(2000);
SDL_DestroyRenderer(main_window_renderer);
quit(main_window);
return EXIT_SUCCESS;
}
I am running under Debian GNU/Linux 8 "Jessie", and I use libsdl2-dev and libsdl2-gfx-dev of my distribution.
To compile, I use gcc -O0 -g sdl2-test.c `sdl2-config --cflags --libs` -lSDL2_gfx.
Moreover, valgrind notifies me that there are 21 errors from 21 contexts. 3 errors come from SDL2 calls, and 19 from nouveau_dri.so that I suppose to be the shared library used by nouveau driver (a free/libre driver for nVidia GPU) so this ones may not be my fault.
Thanks.
You are calling filledCircleRGBA with an alpha value of 0. Your circle is completely transparent.
For the errors reported by Valgrind, I just noticed you are not actually calling SDL_Init. This is causing some leaks, but not all of them. The others aren't caused by your code.
I also see some Conditional jump or move depends on uninitialised value(s). Valgrind can reports where the uninitialised value was created with the --track-origins=yes option, that way you can see if you passed an uninitialised value to a library function or if the error is in the function.
You can create a suppression file for Valgrind to hide the leaks that aren't yours. It is best to have the debug symbols for the libraries if you want to create rules specific enought to avoid hiding cases where you create something with an SDL function and don't destroy it.
The program following, is one that creates a window which does nothing except close when you press esc. When I compile it with cygwin, there are no errors. The GLEW I use is from Cygwin Ports, and the SDL2 is version 2.0.3, from their website's SDL2-devel-2.0.3-mingw.tar.gz download. I have SDL2.dll in the directory of the compiled executable.
Links with: -lSDL2 -lSDL2main -lGLEW -lGLU -lGL -lSDL2 -lSDL2main -lGLEW -lGLU -lGL, twice to ensure everything is linked.
Also compiled with: -std=c++11
On my computer, the following program prints out:
OpenGL Vendor: (null)
OpenGL Renderer: (null)
OpenGL Shading Language Version: (null)
OpenGL Extensions: (null)
Error initializing GLEW! Missing GL version
The program appears to work otherwise. The main problem is that if I try to call, for example glGenVertexArrays, the program will crash with STATUS_ACCESS_VIOLATION. (See the crashing code here. I think this has something to do with GLEW's error Missing GL version.
#include <cstdio>
#include <chrono>
#include <thread>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <SDL2/SDL_opengl.h>
#include <GL/glu.h>
const int width = 1000;
const int height = 500;
bool Running = true;
#undef main
int main (int argc, char *argv[]) {
FILE* cdebug = fopen("cdebug.txt", "w");
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(cdebug, "SDL could not initialize! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
#define setAttr(attr, value) \
if (SDL_GL_SetAttribute(attr, value) < 0) { \
fprintf(cdebug, "SDL failed to set %s to %s, SDL Error: %s\n", #attr, #value, SDL_GetError()); fflush(cdebug);\
}
setAttr(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
setAttr(SDL_GL_CONTEXT_MINOR_VERSION, 3);
setAttr(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
setAttr(SDL_GL_RED_SIZE, 8);
setAttr(SDL_GL_GREEN_SIZE, 8);
setAttr(SDL_GL_BLUE_SIZE, 8);
setAttr(SDL_GL_DEPTH_SIZE, 24);
setAttr(SDL_GL_DOUBLEBUFFER, 1);
#undef setAttr
/*
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
*/
SDL_Window *window = SDL_CreateWindow(
"test",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
if (window == NULL) {
fprintf(cdebug, "Window could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
SDL_GLContext GLContext = SDL_GL_CreateContext(window);
if (GLContext == NULL) {
fprintf(cdebug, "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
if (SDL_GL_MakeCurrent(window, GLContext) < 0) {
fprintf(cdebug, "OpenGL context could not be made current! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
fprintf(cdebug, "OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
fprintf(cdebug, "OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
fprintf(cdebug, "OpenGL Shading Language Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
fprintf(cdebug, "OpenGL Extensions: %s\n", glGetString(GL_EXTENSIONS));
fflush(cdebug);
glewExperimental = GL_TRUE;
{
GLenum glewError = glewInit();
if (glewError != GLEW_OK) {
fprintf(cdebug, "Error initializing GLEW! %s\n", glewGetErrorString(glewError)); fflush(cdebug);
}
}
SDL_Event event;
while (Running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYUP: {
switch (event.key.keysym.scancode) {
case SDL_SCANCODE_ESCAPE:
Running = false;
break;
}
break;
}
}
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
SDL_GL_DeleteContext(GLContext);
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
return 0;
}
You are mixing cygwin and mingw in ways in which you shouldn't.
If you use cygwin's toolchain and -lGL and so on, you link against cygwin's OpenGL - which is not the native OpenGL lib on windows, but the one provided by cygwin's X server, implementing the GLX protocol.
The mingw version of SDL will use the native GL lib (opengl32.dll) on windows, using the wgl API. So SDL might even create a context for you, but the GL functions your programm are calling belong to a completely different GL implementation - for which your program never created a GL context.
The solution is to stick with one or the other: Completely use cygwin, and a cygwin version of SDL, and a cygwin X server. However, that is not the path I would recommend. I don't know if that would even get you some HW acceleration at all.
The more useful solution would be to not use cygwin, but mingw, for the whole project, with a mingw version of GLEW. That will result in a completely native windows binrary which will use the native OpenGL library with all features provided by the driver and not require cygwin's dlls and especially not cygwin's X server.
I managed to get things working in a weird way.
I am using a self compiled version of SDL2 but the SDL2-devel-2.0.3-mingw.tar.gz provided by the SDL website seems to work as well and using a combination of them (such as mingw version's libs and self-compiled .dll) seem to work as well.
For GLEW, I am using my own compiled version. To compile this, I used their website's source glew-1.11.0.zip and extracted this. Then I edited glew-1.11.0/Makefile and edited line 24 to SYSTEM = cygming. Then in glew-1.11.0/config/Makefile.cygming on line's 7 and 8, I removed the -mno-cygwin flag (so the line's are CC := gcc and LD := gcc) and added -D_WIN32 to line 10 (so the line becomes CFLAGS.SO = -DGLEW_BUILD -D_WIN32). Then in glew-1.11.0, I ran make all and let it compile. After that, I copied glew-1.11.0/include/GL to my includes directory. Next, I copied glew-1.11.0/lib/libglew32.dll.a to my libs folder. I also copied glew-1.11.0/lib/glew32.dll to my .exe's folder. Then to get it to not produce a linker error, I had to place a #define _WIN32 before my #include <GL/glew.h>.
To link everything, I managed to compile it with a minimum of -lSDL2 -lSDL2main -lglew32.dll -lopengl32.
I have an SDL2 application in which I want to create an OpenGL 3.2 context. I googled a bit and started following this tutorial: http://open.gl/context#SDL
Everything seems to work except for the last step. When I had to implement this piece of code:
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
printf("%u\n", vertexBuffer);
My application doesn't seem to have a reference to the functor that should be there. I know there are some people here who had the same problem but I didn't find a solution there. When I output the GL_VERSION it says it's 1.1.0 although I say it should be 3.2.0. Here's my code:
// START SDL
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
logSDLError(std::cout, "SDL_Init");
return 1;
}
// SETUP OPENGL SETTINGS
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, 2);
// OPENING WINDOW
m_pWindow = SDL_CreateWindow("SDL/OpenGL Game Client - With Networking Library", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL);
if (m_pWindow == nullptr)
{
logSDLError(std::cout, "CreateWindow");
return 2;
}
// CREATE AN OPENGL CONTEXT ASSOCIATED WITH THE WINDOW.
m_GlContext = SDL_GL_CreateContext(m_pWindow);
if( m_GlContext == NULL )
{
printf( "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError() );
}
//Initialize GLEW
glewExperimental = GL_TRUE;
GLenum glewError = glewInit();
if( glewError != GLEW_OK )
{
printf( "Error initializing GLEW! %s\n", glewGetErrorString( glewError ) );
}
printf((char*)glGetString(GL_VERSION));
I have a FirePro graphics card that should be able to run OpenGL 4.0. I checked my driver updates and everything should be fine + I get no compile warnings saying that something might be wrong with OpenGL or Glew or SDL.
One thing I had to do to make glGetString() working was to include GL\freeglut.h. I don't really know why that is because it doesn't say so in the tutorial I followed.
I found the problem. I forgot to mention that I'm using MSTSC to remote from my desktop to my laptop (which is easier to work) and apparently this changes the graphics device.
I tried opening my application from the actual laptop and suddenly it worked, giving the right OpenGL version and everything.
Stupid mistake, I should've found this earlier.
I'm on Linux Mint 13 XFCE. My problem is that when I run in terminal the command:
glxinfo | grep "OpenGL version"
I get the following output:
OpenGL version string: 3.3.0 NVIDIA 295.40
But when I run the glGetString(GL_VERSION) in my application then the result is null. Why doesn't this code get the gl_version?
#include <stdio.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GL/glext.h>
int main(int argc, char **argv) {
glutInit(&argc, argv);
glewInit();
printf("OpenGL version supported by this platform (%s): \n",
glGetString(GL_VERSION));
}
glutInit() doesn't create a GL context or make one current. You need a current GL context for glewInit() and glGetString() to work.
Try this:
#include <GL/glew.h>
#include <GL/glut.h>
#include <cstdio>
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutCreateWindow("GLUT");
glewInit();
printf("OpenGL version supported by this platform (%s): \n", glGetString(GL_VERSION));
}
You can also use glfw in order to create GL context and then query the version:
Include this files:
#include "GL/glew.h"
#include "GLFW/glfw3.h"
And then you can do:
// Initialise GLFW
glewExperimental = true; // Needed for core profile
if (!glfwInit())
{
return "";
}
// We are rendering off-screen, but a window is still needed for the context
// creation. There are hints that this is no longer needed in GL 3.3, but that
// windows still wants it. So just in case.
glfwWindowHint(GLFW_VISIBLE, GL_FALSE); //dont show the window
// Open a window and create its OpenGL context
GLFWwindow* window;
window = glfwCreateWindow(100, 100, "Dummy window", NULL, NULL);
if (window == NULL) {
return "";
}
glfwMakeContextCurrent(window); // Initialize GLEW
if (glewInit() != GLEW_OK)
{
return "";
}
std::string versionString = std::string((const char*)glGetString(GL_VERSION));