I've recently switch from SDL 1.0 to 2.0 for some program necessity. I've successfully managed to make it work as well as SDL_image that I use. However, for some reason, SDL_ttf 2.0 does not work on my program. I have paid attention to use the function of the 2.0 and not the 1.0 and tested the ttf with programs that weren't my owns, nothing worked. Usually, the program runs until it has to print text then it closes and send "process returned -1073741819" which is for what I know an error message in a program for it should return 0. I tried both x64 and x86 but none worked though the x86 seemed to give better results.
#include <stdlib.h>
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
int main()
{
SDL_Surface *logo = NULL, *Wreed, *Reminder, *ecran = NULL;
SDL_Window *window = NULL;
SDL_Texture *textureLogo = NULL, *textureWreed = NULL, *textureReminder = NULL;
SDL_Rect positionLogo = {1100/2 - 600/2, 700/2 - 600/2, 600, 600}, /*positionWreed,*/ positionReminder;
TTF_Font *police = NULL;
SDL_Color couleur = {0,0,0};
SDL_Renderer* renderer;
police = TTF_OpenFont("arial.ttf", 40);
window = SDL_CreateWindow("Wreed Reminder", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1100, 700, SDL_WINDOW_OPENGL);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
ecran = SDL_GetWindowSurface(window);
SDL_RenderClear(renderer);
Wreed = TTF_RenderText_Blended(police, "Wreed", couleur);
textureWreed = SDL_CreateTextureFromSurface(renderer, Wreed);
SDL_Rect positionWreed = {10, 10, 10, 10};
SDL_RenderCopy(renderer, textureWreed, NULL, &positionWreed);
SDL_RenderPresent(renderer);
SDL_Delay(5000);
}
If anyone knows how to fix this, please help.
Well, I don't know quite what happened but I reinstalled the latest version of the ttf and set the x86 but it didn't work, so I tried x64, just in case. Didn't work either. Then, I reset the x86 and, surprise, it is working.
Related
I have the following code:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define GLFW_INCLUDE_NONE
#include <stdio.h>
#include <stdlib.h>
static void error_callback(int error, const char *description)
{
printf("Error: %s\n", description);
}
int main()
{
glfwInit();
glfwSetErrorCallback(error_callback);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
GLFWwindow *window = glfwCreateWindow(800, 600, "Learn OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
printf("Failed to initialize GLAD. Fatal error.\n");
return -1;
}
glfwSwapInterval(1);
while (!glfwWindowShouldClose(window))
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
When the code is set the way it is above, with GLFW_CONTEXT_VERSION set to 2.0, it works pretty well. When I resize the window, as soon as I stop resizing, it renders the new portion. However, when I set the version to 3.3 (which is the version I want to use) it lags a bit in spreading the blue across the whole window (even after I have stopped resizing it), as can be seen here: (I'm running Windows by the way)
This does not happen when the version is 2.0. Why is this, and how can I get it so it renders in 3.3 as well as it does in 2.0?
When I set GLFW_OPENGL_PROFILE to GLFW_OPENGL_COMPAT_PROFILE it works in 3.3 just like in 2.0 but on GLFW_OPENGL_CORE_PROFILE (which is what I want to use) it doesn't. How do I fix it so it works in CORE_PROFILE?
(I suspect GLFW is using some sort of deprecated function... I don't know. I'm using glfw3, so shouldn't it not have any deprecated functions though?)
Here is what worked for me. I have an Intel UHD Graphics 620 GPU, and I updated my driver, and now it works.
Old driver version was 24.something, new driver version is 30.0.101.1660.
I have a somewhat basic rendering loop which blits a scaled image to the screen as fast as I can process the event loop. I created a minimal example that recreates the flickering on pastebin here.
If I don't use "SDL_CreateRenderer", and instead leave renderer to NULL, it works. I just can't clear the screen first. If I set the renderer, I get this crazy fast flickering.
// if I comment this out in my init_sdl(), no flickering...
renderer = SDL_CreateRenderer(window, -1, 0);
assert(renderer != NULL);
my draw function happens at the end of the event loop:
void draw()
{
SDL_SetRenderDrawColor(renderer, 255, 0, 128, 255);
SDL_RenderClear(renderer);
SDL_Rect dstrect = {
.x = 50,
.y = 50,
.h = 100,
.w = 100,
};
SDL_BlitScaled(img, NULL, screen, &dstrect);
SDL_UpdateWindowSurface(window);
SDL_RenderPresent(renderer);
}
I've seen this potential duplicate question, but the problem was that they had their RenderPresent in the wrong place. You can see I'm calling SDL_RenderPresent at the end of all drawing operations, which was my takeaway from that. It is still happening.
I'm using msys2 (mingw_x64), gcc, windows 10, SDL2.
I am trying to get a simple demo of OpenGL working with SDL2. I am using MacOS Big Sur 11.3.1, my SDL version is 2.0.16, and my attempted OpenGL version is 3.1.
Everything seems to work fine at first, given that SDL is initialized successfully, the SDL window is not null, and the OpenGL context is not null either. But when trying to print out the vendor name, renderer name, and version name of OpenGL, all of the strings are null:
vendor = (null)
renderer = (null)
version = (null)
This also explains why nothing appears on the window. I have followed plenty of tutorials that go over using SDL2 with OpenGL, but none of them have worked for me.
I am compiling like this: clang -O3 -lSDL2 -lGL gl_sdl.c.
If anyone knows what is going on, please let me know; I am very confused. My code is below.
#include <SDL2/SDL.h>
#include <GL/gl.h>
enum {w = 800, h = 600};
#define FAIL(msg) {fprintf(stderr, "Could not " msg "\n"); return 1;}
// https://www.khronos.org/opengl/wiki/Tutorial1:_Creating_a_Cross_Platform_OpenGL_3.2_Context_in_SDL_(C_/_SDL)
// clang -O3 -lSDL2 -lGL gl_sdl.c && ./a.out
int main(void) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) FAIL("initialize SDL");
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, 1);
// Turn on double buffering with a 24bit Z buffer. You may need to change this to 16 or 32 for your system
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_Window* const window = SDL_CreateWindow("gl_sdl", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_OPENGL);
if (window == NULL) FAIL("create a window");
SDL_GLContext context = SDL_GL_CreateContext(window);
if (context == NULL) FAIL("create a context");
// This makes our buffer swap syncronized with the monitor's vertical refresh
SDL_GL_SetSwapInterval(1);
printf("vendor = %s\nrenderer = %s\nversion = %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION));
SDL_Event event;
while (1) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
}
// Blue
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
SDL_Delay(20);
}
}
MacOS uses a different library flag for OpenGL than Linux and Windows. Instead of -lGL, use -framework OpenGL. E.g.
clang -O3 gl_sdl.c -lSDL2 -framework OpenGL
On a side note, the program requests a context for OpenGL 3.1, but does not use an OpenGL Loading Library (or loads any functions manually). As is, this happens to cause no problems, only because no functions from OpenGL >1.1 are used.
I have a problem when I run my prog : "prog.exe just stopped working".
#include <SDL.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
SDL_Surface *screen; // even with SDL2, we can still bring ancient code back
SDL_Window *window;
SDL_Surface *image;
SDL_Init(SDL_INIT_VIDEO); // init video
// create the window like normal
window = SDL_CreateWindow("SDL2 Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
// but instead of creating a renderer, we can draw directly to the screen
screen = SDL_GetWindowSurface(window);
// let's just show some classic code for reference
SDL_FillRect(image, NULL, SDL_MapRGB(image->format, 0, 255, 0));
SDL_BlitSurface(image, NULL, screen, NULL); // blit it to the screen
SDL_FreeSurface(image);
// this works just like SDL_Flip() in SDL 1.2
SDL_UpdateWindowSurface(window);
// show image for 2 seconds
SDL_Delay(2000);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
// gcc src/main.c -o bin/prog -I include -L lib -lmingw32 -lSDL2main -lSDL2
As Eugene Sh. pointed out your surface isn't initialized
You need to create the surface someway, either by loading an IMG or using SDL_CreateRGBSurface. Add this before calling SDL_FillRect and now your code shows a green screen.
image = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
When I run the following code on my machine, it doesn't behave deterministically. The triangle it should draw only appears sometimes:
#include <SDL/SDL.h>
#include <SDL/SDL_gfxPrimitives.h>
int main(int argc, char* args[])
{
int xres = 250;
int yres = 250;
SDL_Surface* screen = SDL_SetVideoMode(xres, yres,
0, SDL_SWSURFACE | SDL_DOUBLEBUF | SDL_NOFRAME);
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
filledTrigonRGBA(screen, 10, 10, 170, 170, 75, 100, 255, 0, 255, 255);
//SDL_Delay(1); // this fixes some race condition?
SDL_Flip(screen);
SDL_Delay(1000);
SDL_Quit();
return 0;
}
But if I uncomment the first SDL_Delay() call, the triangle always appears. I have also observed this when using SDL 2.
Is there a race condition in one of the libraries here, or is something wrong with my computer?
There are many things involved, especially if you have compositing window manager. Like if you flip your resulting image but window wasn't visible at that moment. With compositing it is even worse since it implements its own double buffering.
Just repeatedly draw it a loop, like every single example does. If you absolutely have to, you can redraw only on window events (mostly 'exposed' one).