In my following code.
class RenderOpengl
{
private:
GLFWwindow* window = NULL;
public:
RenderOpengl() { InitGLFW(); }
void InitGLFW()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(1920, 1080, "Test", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
// return -1;
}
else
std::cout << "Window Created";
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
GLenum GlewInitResult;
glewExperimental = GL_TRUE;
GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult) // Check if glew is initialized properly
{
std::cout << "Not able to initialize glew";
// return -1;
}
}
void Render()
{
while (!glfwWindowShouldClose(window)) {
std::cout << "I am function number 555" << std::endl;
glfwMakeContextCurrent(window);
std::cout << glGetError() << std::endl;
glfwSwapBuffers(window);
glfwPollEvents();
}
}
};
class ThreadClass
{
public:
explicit ThreadClass(RenderOpengl* _gl) { gl = _gl; };
RenderOpengl* gl;
void RenderGL()
{
gl->Render();
}
};
int main()
{
RenderOpengl renderGL;
std::thread t(&ThreadClass::RenderGL, ThreadClass(&renderGL));
t.join();
// renderGL.Render();
std::cout << "Hello World!\n";
}
The rendering call in the Main function does not give any error.(renderGL.Render())
But if I comment this line and call the same function in a separate thread it gives error 1282 , despite calling the glfwMakeContextCurrent(window).
Related
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 am trying to set up an SDL project, however I am getting from following error message:
Renderer already associated with window
from the following function:
void Game::render()
{
renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL)
std::cout << "Failed to create a renderer" << '\n' << "Error: " << SDL_GetError() << std::endl;
}
I have only made a window and a renderer once, and they are separate, so I have no idea why this could happen. I found another question on SO with the same error, but apparently he was having problems because SDL_GetWindowSurface() was being called but I am not calling that function. The following is my code. Thanks for helping.
game.h:
#pragma once
#include <iostream>
#include "SDL.h"
class Game
{
public:
bool init();
bool constructWindow
(
const char* windowName,
unsigned int xWindowPos,
unsigned int yWindowPos,
unsigned int windowWidth,
unsigned int windowHeight,
bool fullScreen = false
);
void render();
void update();
SDL_Window* getWindow();
bool handleEvents();
protected:
private:
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Event event;
bool quit = false;
};
game.cpp:
#include "game.h"
bool Game::init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return true;
else
std::cout << "Could not initialise SDL" << '\n' << "Error: " << SDL_GetError() << std::endl;
}
bool Game::constructWindow(const char* windowName, uint16_t xWindowPos, uint16_t yWindowPos
, uint16_t windowWidth, uint16_t windowHeight, bool fullScreen)
{
window = SDL_CreateWindow(windowName, xWindowPos, yWindowPos, windowWidth, windowHeight, fullScreen);
if (!window)
std::cout << "Could not create window" << '\n' << "Error: " << SDL_GetError() << std::endl;
return window;
}
void Game::render()
{
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer)
std::cout << "Failed to create a renderer" << '\n' << "Error: " << SDL_GetError() << std::endl;
}
void Game::update()
{
SDL_RenderPresent(renderer);
}
SDL_Window* Game::getWindow()
{
return window;
}
bool Game::handleEvents()
{
while (SDL_PollEvent(&event))
if (event.type == SDL_QUIT)
quit = true;
return quit;
}
main.cpp
#include "game.h"
int main(int argc, char* argv[])
{
Game app;
if (app.init())
if (app.constructWindow("3D Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1200, 600))
while (!app.handleEvents())
{
app.render();
app.update();
}
SDL_DestroyWindow(app.getWindow());
SDL_Quit();
return EXIT_SUCCESS;
}
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
I'm learning OpenGL via http://learnopengl.com/ however I am crashing when I am trying to bind the buffers in the 'hello triangle' part of the tutorial. I have prior coding experience in C++ but I can't work out what is wrong.
My Code:
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/glfw3.h>
#include <GL/gl.h>
using namespace std;
const GLuint WIDTH = 800, HEIGHT = 600;
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
int initializeWindow(GLFWwindow* window);
int main() {
GLFWwindow* window;
cout << "Creating Triangles" << endl;
GLfloat triangles[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f
};
cout << "Initialising GLFW" << endl;
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);
cout << "Initialising Window..." << endl;
window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
cout << "Setting Callback Functions..." << endl;
glfwSetKeyCallback(window, key_callback);
cout << "Binding Buffers" << endl;
GLuint VBO;
glGenBuffers(1, &VBO); // <--- Crashing here
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangles), triangles, GL_STATIC_DRAW);
if (initializeWindow(window) == -1) {
return -1;
}
while(!glfwWindowShouldClose(window)) {
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
}
cout << "Terminating..." << endl;
glfwTerminate();
return 0;
}
int initializeWindow(GLFWwindow* window) {
if (window == NULL) {
cout << "Failed to create GLFW window... exiting" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK) {
cout << "Failed to initialize GLEW... exiting" << endl;
return -1;
}
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
I am getting just a generic 'not responding' crash, no errors in the console. Any help will be greatly appreciated, thanks.
You need to call initializeWindow just after the window creation and before any call to gl functions. This is necessary in order to make current windows active and initialize glew (these operations are done inside initializewindow)
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, ¤t);
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 ?