SDL_GL_SetAttribute causes some opengl functions to be null - c++

Setting values higher, for example 32 for SDL_GL_DEPTH_SIZE causes glCreateShader to be null.
I don't know what is causing this behavior, because I don't get any errors while setting attributes and creating context. Here's a minimalistic example.
#include <iostream>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <SDL2/SDL_opengl.h>
const int WIDTH = 800;
const int HEIGHT = 600;
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
int response;
response = SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE);
response = SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
response = SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
response = SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
if (response < 0) {
std::cout << "Setting Attribute: DEPTH_SIZE Failed\n";
return 0;
}
SDL_Window *window = SDL_CreateWindow("TestApp", WIDTH >> 1, HEIGHT >> 1, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
if (window == nullptr) {
std::cout << "window not setup\n";
return 0;
}
SDL_GLContext context = SDL_GL_CreateContext(window);
if (context == nullptr) {
std::cout << "context failed\n";
return 0;
}
glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit()) {
std::cout << "Failed to initialize glew\n";
return 0;
}
glViewport(0, 0, WIDTH, HEIGHT);
int value;
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
std::cout << "Querying Depth size: " << value << "\n";
std::cout << "glEnable: " << (glEnable ? "Available" : "NULL") << "\n";
std::cout << "glCreateShader: " << (glCreateShader ? "Available" : "NULL") << "\n";
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
output for DEPTH_SIZE = 24 bits
Querying Depth size: 24
glEnable: Available
glCreateShader: Available
output for DEPTH_SIZE = 32 bits
Querying Depth size: 32
glEnable: Available
glCreateShader: NULL

Related

SDL2_image not showing up, getting instead a black screen

I am doing a game using SDL.
The problem is that instead of getting image I see a black screen without any errors. And the most interesting thing that I've made another test project to see if I'll get an image and this one works excellent. In test project I have only main.cpp which does the same (not sure as i am getting black screen in my main project) and not using headers and this stuff.
Here is my code:
main.cpp(game project)
#include <SDL2\SDL.h>
#include <SDL2\SDL_image.h>
#include <iostream>
#include <stdio.h>
#include "RenderWindow.hpp"
int main(int argc, char** argv){
if (SDL_Init(SDL_INIT_VIDEO) > 0)
std::cout << "SDL_init has crushed" << SDL_GetError() << std::endl; // ініціалізація сдл
if (!(IMG_Init(IMG_INIT_PNG)))
std::cout << "IMG_init has failed. Error: " << IMG_GetError() << std::endl;
RenderWindow window("Game",640,480);
SDL_Texture* grassTexture = window.loadTexture("images/ground_grass_1.png");
bool gameRunning = true;
SDL_Event event;
while(gameRunning)
{
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
gameRunning = false;
}
window.clear();
window.render(grassTexture);
window.display();
}
window.cleanUp();
IMG_Quit();
SDL_Quit();
return 0;
}
RenderWindow.hpp
#pragma once
#include <SDL2\SDL.h>
#include <SDL2\SDL_image.h>
class RenderWindow
{
public:
RenderWindow(const char* p_title, int p_w, int p_h);
SDL_Texture* loadTexture(const char* p_filePath);
void cleanUp();
void clear();
void render(SDL_Texture* p_text);
void display();
private:
SDL_Window* window;
SDL_Renderer* renderer;
};
renderwindow.cpp
#include <SDL2\SDL.h>
#include <SDL2\SDL_image.h>
#include <iostream>
#include "RenderWindow.hpp"
RenderWindow::RenderWindow(const char* p_title, int p_w, int p_h)
:window(NULL), renderer(NULL) // присвоювання нульових поінтеров
{
window = SDL_CreateWindow(p_title,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,p_w,p_h,SDL_WINDOW_SHOWN); // ініціалізація вікна
if(window == NULL)
std::cout << "Window failed to init" << SDL_GetError() << std::endl;
renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED); // ініціалізація рендера
if(renderer == NULL)
std::cout << "Renderer failed to init" << SDL_GetError() << std::endl;
}
SDL_Texture* RenderWindow::loadTexture(const char* p_filePath)
{
SDL_Texture* texture = NULL;
texture = IMG_LoadTexture(renderer,p_filePath);
if(texture = NULL)
std::cout << "Failed to load texture. Error: " << SDL_GetError() << std::endl;
return texture;
}
void RenderWindow::cleanUp()
{
SDL_DestroyWindow(window);
}
void RenderWindow::clear()
{
SDL_RenderClear(renderer);
}
void RenderWindow::render(SDL_Texture* p_tex)
{
SDL_RenderCopy(renderer,p_tex,NULL,NULL);
}
void RenderWindow::display()
{
SDL_RenderPresent(renderer);
}
and main.cpp(test project)
#include <SDL2/SDL.h> // include the SDL library
#include <SDL2/SDL_image.h> // include the SDL_image library for loading image files
#include <iostream>
int main(int argc, char* argv[]) {
// initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "SDL initialization failed: " << SDL_GetError() << std::endl;
return 1;
}
// create the window
SDL_Window* window = SDL_CreateWindow("My Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
if (window == NULL) {
std::cout << "Failed to create window: " << SDL_GetError() << std::endl;
return 1;
}
// create the renderer
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
std::cout << "Failed to create renderer: " << SDL_GetError() << std::endl;
return 1;
}
// load the image file
SDL_Texture* texture = IMG_LoadTexture(renderer, "ground_grass_1.png");
if (texture == NULL) {
std::cout << "Failed to load image: " << SDL_GetError() << std::endl;
return 1;
}
// render the image
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
// wait for 5 seconds
SDL_Delay(5000);
// clean up
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

I have an error when I'm trying to copy a texture with SDL_RenderCopy, in C++

This is my .cpp file:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
bool runningOnEmpty = false;
const char* title;
int xpos, ypos, width, height;
bool fullscreen = false;
SDL_Window *window;
SDL_Renderer *renderer;
void init(){
int flags = 0;
if(fullscreen){
flags = SDL_WINDOW_FULLSCREEN;
}
if(!SDL_Init(SDL_INIT_EVERYTHING)){
std::cout << "Sdl initialised!!\n";
window = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
if(window){
std::cout << "window created!!\n";
}
renderer = SDL_CreateRenderer(window, -1, 0);
if(renderer){
std::cout << "renderer created!!\n";
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
}
runningOnEmpty = true;
} else {
runningOnEmpty = false;
}
if(TTF_Init()==-1) {
std::cout << "cannot init TTF: " << TTF_GetError() << "\n";
} else {
std::cout << "TTF initialized!" << "\n";
}
}
void render(){
SDL_RenderClear(renderer);
TTF_Font* rFont = TTF_OpenFont("./fonts/roboto.ttf", 20);
if(!rFont){
std::cout << "Cannot open font: " << TTF_GetError() << "\n";
}
SDL_Color White = {0, 0, 0};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(rFont, "Score: ", White);
if(surfaceMessage == NULL)
std::cout << "Cannot make surface!" << SDL_GetError() << "\n";
SDL_Texture* Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage);
SDL_Rect mr;
mr.x = 50, mr.y = 50, mr.w = 100, mr.h = 100;
if(Message = NULL)
std::cout << "Cannot make texture!" << SDL_GetError() << "\n";
if(SDL_RenderCopy(renderer, Message, NULL, &mr))
std::cout << "Cannot render text!" << SDL_GetError() << "\n";
SDL_FreeSurface(surfaceMessage);
SDL_RenderPresent(renderer);
}
void clean(){
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
std::cout << "Game cleaned!\n";
}
void handleEvents(){
SDL_Event event;
SDL_PollEvent(&event);
switch(event.type){
case SDL_QUIT:
runningOnEmpty = false;
break;
default:
break;
}
}
int main(){
title = "Test";
xpos = SDL_WINDOWPOS_CENTERED;
ypos = SDL_WINDOWPOS_CENTERED;
width = 800, height = 900;
fullscreen = false;
init();
render();
while(runningOnEmpty){
handleEvents();
}
clean();
return 0;
}
It compiles without error, and when I run the executable it renders a white window, with no text on it(even if it should have some text).
The error comes when I try to use SDL_RenderCopy, and as I acknowledged using SDL_Error(), apparently the texture is invalid, even if I check it before using it.
This is the exact thing that I get in the console when running the code:
Sdl initialised!!
window created!!
renderer created!!
TTF initialized!
Cannot render text!Invalid texture
Game cleaned!
if(Message = NULL) is an assignment, not comparison, so your previous value of Message is lost and it is NULL after that, and that result is used as logic value (NULL == 0 == false, for that matter). Enabling compiler warnings should produce a message pinpointhing this specific problem, e.g. -Wall for gcc gives
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
if(Message = NULL)
To compare values, use == operator.
Also your texture goes out of scope without DestroyTexture, which is clearly a resource leak.

Migration from GLFW + AntTweakBar to SDL2 + ImGui performance issues

I just migrated it an single animation app (just one model) from GLFW+AntTweakBar to SDL2+ImGui .
OpenGL code is the same but i am seem to experiencing more than half of FPS drop
with SDL2+ImGui .
While on GLFW i have an average fps of 100 and on SDL2 i have an average of 30-40.
SDL/GL init code is below :
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
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_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_DisplayMode current;
SDL_GetCurrentDisplayMode(0, &current);
gWindow = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowWidth, windowHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (gWindow == NULL)
{
std::cout << "Window could not be created! SDL Error: " << SDL_GetError() << std::endl;
success = false;
}
else
{
std::cout << std::endl << "Yay! Created window sucessfully!" << std::endl << std::endl;
//Create context
gContext = SDL_GL_CreateContext(gWindow);
if (gContext == NULL)
{
std::cout << "OpenGL context could not be created! SDL Error: " << SDL_GetError() << std::endl;
success = false;
}
else
{
//Initialize GLEW
glewExperimental = GL_TRUE;
GLenum glewError = glewInit();
if (glewError != GLEW_OK)
{
std::cout << "Error initializing GLEW! " << glewGetErrorString(glewError) << std::endl;
}
//Use Vsync
if (SDL_GL_SetSwapInterval(1) < 0)
{
std::cout << "Warning: Unable to set Vsync! SDL Error: " << SDL_GetError << std::endl;
}
If i try setting SDL_GL_SetSwapInterval(0) for immediate update i get an average of 60FPS but it still doesn't look smooth and there is small tearing on the model.
I tried removing the ImGui code and it's a better as it ought to be but still much worse performance .
Is this normal ?

SDL2 Hello World tutorial closes with error

I'm developing in VS2013 on a Windows 8.1 machine. The window flashes briefly on the screen (despite having a 2 second delay in the code).
Here is all the code:
#include <SDL.h>
#include <iostream>
int main(int argc, char **argv)
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 4;
}
//open a window
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if (win == nullptr){
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
return 3;
}
//renderer
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr){
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
return 2;
}
//load bitmap
SDL_Surface *bmp = SDL_LoadBMP("helloworld.jpg");
if (bmp == nullptr){
std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
return 6;
}
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_FreeSurface(bmp);
if (tex == nullptr){
std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
return 5;
}
SDL_RenderClear(ren);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
SDL_Delay(2000);
return 0;
}
It exits with a code 6. I was thinking it couldn't find the helloworld.jpg file. But, its there. I moved it from location to location hoping I was just an idiot. No luck. Its currently in the same directory as the .exe file.
SDL_LoadBMP will only load BMP formatted pictures, and guessing by the extension you have chosen you look to be using a JPEG formatted image, and your program is refusing to load it.
see SDL_Image for one possible solution.

SDL2 CreateRenderer throwing Invalid Window Error

My current code is as follows:
#include <iostream>
#include "SDL.h"
#include "SDL_image.h"
int main(int argc, char **argv) {
if (SDL_Init(SDL_INIT_EVERYTHING != 0)) {
std::cout << "SDL_Init() Error: " << SDL_GetError() << std::endl;
std::cin.get();
return 1;
}
SDL_Window *win = SDL_CreateWindow("RandomSDL2", 100, 100, 1280, 720, SDL_WINDOW_SHOWN);
if (win = nullptr) {
std::cout << "SDL_CreateWindow() Error: " << SDL_GetError() << std::endl;
std::cin.get();
return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr) {
std::cout << "SDL_CreateRenderer() Error: " << SDL_GetError() << std::endl;
std::cin.get();
return 1;
}
SDL_Surface *img = IMG_Load("res/test.png");
if (img == nullptr) {
std::cout << "IMG_Load() Error: " << IMG_GetError() << std::endl;
std::cin.get();
return 1;
}
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, img);
SDL_FreeSurface(img);
if (tex == nullptr) {
std::cout << "SDL_CreateTextureFromSurface() Error: " << SDL_GetError << std::endl;
std::cin.get();
}
SDL_RenderClear(ren);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
SDL_Delay(2000);
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
It seems that the CreateRenderer function throws the error Invalid Window, I'm unsure as to why, I'm currently following this tutorial, I've copied the code down to a T besides the resolution and the use of SDL_image, SDL_image shouldn't really effect the creation of the renderer at this stage, I've also tried the resolution specified in the tutorial and it seems to still throw the same error.
Does anyone have any insight on this issue?
if (win = nullptr) {
^ assignment, probably wanted ==
Don't set win to nullptr and it probably won't be nullptr.