Artifact of the black line in the client area - opengl

I have a black line artifact in the client area that disappears when the window is resized:
I called glViewport:
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <glad/glad.h>
#include <iostream>
SDL_Window *window;
const float maxFPS = 5.f;
void fatalError(const std::string &message)
{
std::cout << message << std::endl;
if (window)
{
SDL_DestroyWindow(window);
}
SDL_Quit();
exit(-1);
}
int main()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fatalError("Failed to initialize");
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
const int winW = 300;
const int winH = 300;
window = SDL_CreateWindow("OpenGL, SDL2, C++",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
winW,
winH,
SDL_WINDOW_OPENGL);
if (!window)
{
fatalError("Failed to create the SDL window");
}
SDL_SetWindowResizable(window, SDL_TRUE);
SDL_GLContext glContext = SDL_GL_CreateContext(window);
if (!glContext)
{
fatalError("Failed to create the SDL_GL context");
}
if (!gladLoadGL())
{
fatalError("Failed to initialize the GLAD library");
}
glViewport(0, 0, winW, winH);
glClearColor(0.5f, 0.5f, 1.f, 1.f);
SDL_Event event;
bool running = true;
while (running)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_WINDOWEVENT:
switch (event.window.event)
{
case SDL_WINDOWEVENT_RESIZED:
glViewport(0, 0, event.window.data1, event.window.data2);
break;
}
break;
}
}
float startTicks = SDL_GetTicks();
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
// Limit FPS to the max FPS
float frameTicks = SDL_GetTicks() - startTicks;
if (1000.f / maxFPS > frameTicks)
{
SDL_Delay(1000.f / maxFPS - frameTicks);
}
}
SDL_GL_DeleteContext(glContext);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
makefile
# build command: mingw32-make
# -mwindows - a key to hide the console
INC = -I"E:\Libs\SDL2-2.24.0-mingw-64bit\include" \
-I"E:\Libs\glad-0.1.36-mingw-64bit\include"
LIB = -L"E:\Libs\SDL2-2.24.0-mingw-64bit\lib" \
-L"E:\Libs\glad-0.1.36-mingw-64bit\lib"
all: main.o
g++ main.o $(LIB) -lSDL2.dll -lglad -o app.exe
main.o: main.cpp
g++ -c $(INC) main.cpp
The same topic on the official SDL2 forum: https://discourse.libsdl.org/t/artifact-of-the-black-line-in-the-client-area/39110
Not sure if it matters but the
docs says you should
call SDL_GL_SetAttribute before creating the window.
#Peter87 I tried it but everything the same:
int main()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fatalError("Failed to initialize");
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
const int winW = 300;
const int winH = 300;
window = SDL_CreateWindow("OpenGL, SDL2, C++",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
winW,
winH,
SDL_WINDOW_OPENGL);
if (!window)
{
fatalError("Failed to create the SDL window");
}
SDL_SetWindowResizable(window, SDL_TRUE);
SDL_GLContext glContext = SDL_GL_CreateContext(window);
if (!glContext)
{
fatalError("Failed to create the SDL_GL context");
}

It appears to be a SDL bug, though for me the effect was different (the window wasn't resizable at all).
Instead of calling SDL_SetWindowResizable(window, SDL_TRUE);, pass SDL_WINDOW_RESIZABLE when creating the window.

Related

SDL_DrawRect() does not draw a proper rect

When I try to draw a rectangle, the bottom line always is one pixel up on the right side:
The problem also persists when I change the size and position.
Below I have a minimal working solution that should reproduce the problem, if it's not my computer going crazy:
#include "SDL.h"
#include <iostream>
int main(int args, char **argv) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
printf("error initializing SDL: %s\n", SDL_GetError());
}
SDL_Window *window = SDL_CreateWindow("Testing", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, 0);
Uint32 renderFlags = SDL_RENDERER_ACCELERATED;
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, renderFlags);
if (renderer == nullptr) {
std::cout << "Error initializing _renderer: " << SDL_GetError() << std::endl;
}
int close = 0;
SDL_Event event;
while (!close) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
close = 1;
break;
}
}
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_Rect rect = {100, 100, 100, 100};
SDL_RenderDrawRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderPresent(renderer);
SDL_Delay(1000 / 240);
}
SDL_Quit();
return 0;
}
I am using Fedora 36 Linux and the Gnome 42 desktop.
I also tried starting it with x11 instead of wayland with SDL_VIDEODRIVER=x11, but that doesn't change anything.
What could be the problem here?
It seems like I solved the problem by changing from the Flatpak version of CLion to the native one installed from the JetBrains toolbox.
The problem only occurs when I run the compiled executable from inside CLion, so I think it's a CLion problem. I reported the problem to JetBrains here.

SDL2 textures don't work with pixel format ARGB2101010

I am trying to use a texture with the SDL_PIXELFORMAT_ARGB2101010 color format but I only get a black texture. The same program works when using the SDL_PIXELFORMAT_ARG88888 format.
None of SDL's variables are null. This is my code:
#include <SDL2/SDL.h>
int main(int argc, const char * argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *win = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowWidth, windowHeight, 0);
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
SDL_Texture *tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB2101010, SDL_TEXTUREACCESS_STREAMING, bufferWidth, bufferHeight);
uint32_t* buffer = new uint32_t[bufferWidth * bufferHeight];
for(int bufferIdx = 0; bufferIdx < bufferWidth * bufferHeight; bufferIdx++) {
buffer[bufferIdx] = 0xc0ffffff;
}
SDL_Event event;
while(running) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT)
running = false;
}
SDL_UpdateTexture(tex, nullptr, buffer, bufferWidth * 4);
SDL_RenderCopy(ren, tex, nullptr, nullptr);
SDL_RenderPresent(ren);
}
}
This is some of my hardware and software:
AMD Radeon Pro 5500M GPU
SDL Version 2.0.14
MacOS 11.1
C++14
Compiled with default Xcode 12.3 settings

SDL_Texture from IMG_Load() fails to draw?

The only thing I see is the RenderDrawColor.
Also the "circle.png" is in the right folder (where the main.cpp is).
#include <SDL.h>
#include <SDL_Image.h>
int main(int argc,char* args[]) {
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG);
SDL_Window* window = SDL_CreateWindow("_", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(render,0, 255, 255, 255);
SDL_Surface* img = IMG_Load("circle.png");
SDL_Texture* texture = SDL_CreateTextureFromSurface(render, img);
SDL_FreeSurface(img);
SDL_Event event;
while (1) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
return 0;
}
}
SDL_RenderClear(render);
SDL_RenderCopy(render, texture, NULL, NULL);
SDL_RenderPresent(render);
}
system("PAUSE");
return 0;
}
Had to include zlib1.dll and libpng16-16.dll to the same folder as the cpp.
libpng16-16.dll depends on zlib1.dll.

Rendering Sprites with SDL2

I am extremely new to game development. I am attempting to move sprites on a window with SDL. I was using http://gamedevgeek.com/tutorials/moving-sprites-with-sdl/ as a reference for this to help me get a feel for SDL. However, this method of blit doesn't work with SDL2. I researched and found that I must convert surfaces to textures and render those, but I am running into some frustrating difficulties. When ran, the background image seems to render fine, but the sprite only appears in the corner of the window, and when moved, it seems to be overwritten by the background. Here is the code:
#include <iostream>
#include "stdafx.h"
#include <SDL.h>
#include <SDL_image.h>
const int WIDTH = 900;
const int HEIGHT = 360;
const int SPRITE_SIZE = 256;
int main(int argc, char *argv[])
{
SDL_Surface *imageSurface = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Surface *temp = NULL;
SDL_Surface *sprite = NULL;
SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface);
SDL_Rect rcSprite;
SDL_Rect gdSprite;
SDL_Event windowEvent;
SDL_Event event;
SDL_Renderer *renderer = NULL;
SDL_Texture *texture;
SDL_Texture *spriteTexture;
const Uint8 *keystate;
int colorkey;
int count;
int xPosition = 0;
int yPosition = 0;
int gameover = 0;
SDL_Window *window = SDL_CreateWindow("ABDUCTO", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_ALLOW_HIGHDPI);
windowSurface = SDL_GetWindowSurface(window);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
imageSurface = IMG_Load("farm.png");
sprite= IMG_Load("sprite6.png");
texture = SDL_CreateTextureFromSurface(renderer, imageSurface);
spriteTexture = SDL_CreateTextureFromSurface(renderer, sprite);
SDL_FreeSurface(sprite);
SDL_FreeSurface(imageSurface);
//rcSprite used as source rectangle, gdSprite as destination rectangle. Initialize them to the same position
rcSprite.x = xPosition;
rcSprite.y = yPosition;
rcSprite.w = SPRITE_SIZE;
rcSprite.h = SPRITE_SIZE;
gdSprite.x = xPosition;
gdSprite.y = yPosition;
gdSprite.w = SPRITE_SIZE;
gdSprite.h = SPRITE_SIZE;
while (!gameover)
{
if (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
gameover = 1;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
case SDLK_q:
gameover = 1;
break;
}
break;
}
}
keystate = SDL_GetKeyboardState(NULL);
// When key pressed, update the destination rectangle
if (keystate[SDL_SCANCODE_LEFT]) {
gdSprite.x -= 2;
}
if (keystate[SDL_SCANCODE_RIGHT]) {
gdSprite.x += 2;
}
if (keystate[SDL_SCANCODE_UP]) {
gdSprite.y -= 2;
}
if (keystate[SDL_SCANCODE_DOWN]) {
gdSprite.y += 2;
}
if (gdSprite.x < 0) {
gdSprite.x = 0;
}
else if (gdSprite.x > WIDTH - SPRITE_SIZE) {
gdSprite.x = WIDTH - SPRITE_SIZE;
}
if(gdSprite.y < 0) {
gdSprite.y = 0;
}
else if (gdSprite.y > HEIGHT - SPRITE_SIZE) {
gdSprite.y = HEIGHT - SPRITE_SIZE;
}
//Render the window
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderCopy(renderer, spriteTexture, &rcSprite, &gdSprite);
SDL_RenderPresent(renderer);
//SDL_BlitSurface(imageSurface, NULL, windowSurface, NULL);
//SDL_BlitSurface(sprite, NULL, imageSurface, &rcSprite);
//SDL_UpdateWindowSurface(window);
//update the source rectangle to move with the sprite??
rcSprite.x = gdSprite.x;
rcSprite.y = gdSprite.y;
}
SDL_DestroyTexture(spriteTexture);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
return 0;
SDL_Quit();
}
Any input is appreciated. Thank you.
probably has to do something with the path of your images, or copying the files into the resources on compilation.
are you on windows, osx or linux?
What IDE are you using?
But i noticed two things:
1)
Before the SDL_CreateWindow you should initialize SDL:
SDL_Init(SDL_INIT_EVERYTHING);
2)
SDL_Quit(); will never be called because one line above you quit the main function with return 0;
=> you should swap the lines!
noticed some more:
3) DON'T update the source rectangle to move with the sprite
just render the whole sprite to the gdSprite loction:
SDL_RenderCopy(renderer, sTexture, NULL, &gdSprite);

From SMFL to SDL 2.0

Here is some code in SMFL
RenderWindow window(VideoMode(320, 480), "The Game!");
Texture t1,t2,t3;
t1.loadFromFile("images/tiles.png");
t2.loadFromFile("images/background.png");
t3.loadFromFile("images/frame.png");
Sprite s(t1), background(t2), frame(t3);
Does SDL 2.0 has functions like this and how to convert them to SDL 2.0
yes, all is there:
https://programmersranch.blogspot.kr/2014/03/sdl2-animations-with-sprite-sheets.html
#include <SDL.h>
#include <SDL_image.h>
int main(int argc, char ** argv)
{
bool quit = false;
SDL_Event event;
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_PNG);
SDL_Window * window = SDL_CreateWindow("SDL2 Sprite Sheets",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640,
480, 0);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface * image = IMG_Load("spritesheet.png");
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,
image);
while (!quit)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
}
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(texture);
SDL_FreeSurface(image);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return 0;
}