This is just a training excersize to get myself working with SDL, ignore the lack of functions, warnings and that everything is in main. I keep getting a segmentation fault, it is certainly what i've done with the section under the //Initialise TTF, create font pointer, set font and colour then render. section, as the code without that works fine.
#include <SDL2/SDL.h>
#include <SDL/SDL_ttf.h>
#include <stdio.h>
const int SCREEN_WIDTH = 1000;
const int SCREEN_HEIGHT = 1000;
int main(int argc, char* args[])
{
// Set up window, surface, image and font pointers
SDL_Window* gWindow = NULL;
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* gImage1 = NULL;
SDL_Surface* gImage2 = NULL;
SDL_Surface* text = NULL;
// Get a window surface, load images
gWindow = SDL_CreateWindow( "Image in a window, and some text", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
gScreenSurface = SDL_GetWindowSurface(gWindow);
gImage1 = SDL_GetWindowSurface(gWindow);
gImage2 = SDL_GetWindowSurface(gWindow);
gImage1 = SDL_LoadBMP("./Image1.bmp");
gImage2 = SDL_LoadBMP("./Image2.bmp");
------------------------------------------------------
//Initialise TTF, create font pointer, set font and colour then render.
TTF_Init();
TTF_Font* font;
font = TTF_OpenFont("./LucidaBrightDemiBold.ttf", 24);
SDL_Color text_color = {255, 255, 255, 255};
text = TTF_RenderText_Solid(font, "Using TTF to write stuff", text_color);
-------------------------------------------------------
// Apply the image, update the surface with the image
SDL_BlitSurface(gImage1, NULL, gScreenSurface, NULL);
SDL_BlitSurface(gImage2, NULL, gScreenSurface, NULL);
SDL_BlitSurface(text, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface( gWindow );
SDL_Delay(5000);
// Free surfaces
SDL_FreeSurface(gImage1);
SDL_FreeSurface(gImage2);
SDL_FreeSurface(text);
// Nullify surfaces
gImage1 = NULL;
gImage2 = NULL;
text = NULL;
//Close and nullify window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit images
TTF_Quit();
SDL_Quit();
return 0;
}
I think the problem lies between the -------'s.
Related
I am trying to get an SDL_Rect to appear on screen with a texture from a bitmap. I run this program and the screen is simply white, with no image.
#include "SDL.h"
int main(int argc, char** args) {
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = NULL;
window = SDL_CreateWindow("window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface* surface = SDL_LoadBMP("car.bmp");
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = 1280;
rect.h = 720;
SDL_RenderCopy(renderer, texture, NULL, &rect);
SDL_Delay(2000);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I got it working, I simply had to add SDL_RenderPresent().
I'm new to SDL & I'm trying to render a simple image & this is my code:
#include <SDL.h>
#include<SDL_image.h>
#include <stdio.h>
#include <string>
using namespace std;
int main(int argc, char* args[])
{
SDL_Window* window = NULL;
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* gHelloWorld = NULL;
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL Tutorial", 100, 50, 500, 500, SDL_WINDOW_SHOWN);
gScreenSurface = SDL_GetWindowSurface(window);
IMG_Init(IMG_INIT_PNG);
SDL_Surface* optimizedSurface = SDL_ConvertSurface(IMG_Load("glow.png"), gScreenSurface->format, 0);
SDL_BlitSurface(optimizedSurface, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(5000);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
but when I run it, I'm getting this type of output
and here's how the image really looks like
I can't understand what I'm doing wrong
I am trying to create an SDL window which is by itself fully transparent, but when an image is rendered onto it, the image is fully opaque and the alpha channel of the image is conserved (so the transparent pixels of the image remain transparent). So the result would be just an image on the screen, with no container around it (Imagine sticking a real-life sticker on your screen)
So here is the simplified code for that:
#include <stdio.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_syswm.h>
#include <iostream>
#include <Windows.h>
#include <string>
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Texture* image;
int imageWidth = 0;
int imageHeight = 0;
bool init()
{
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
return false;
}
//Set texture filtering to linear
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
{
printf("Warning: Linear texture filtering not enabled!");
}
//Create window
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 500, 300, SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS);
if (window == NULL)
{
printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
return false;
}
//Create renderer for window
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL)
{
printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError());
return false;
}
//Initialize renderer color
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError());
return false;
}
return true;
}
bool loadImage(const std::string& path)
{
//The final texture
SDL_Texture* newImage = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (!loadedSurface)
{
printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError());
return false;
}
//Create texture from surface pixels
newImage = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (!newImage)
{
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
return false;
}
imageWidth = loadedSurface->w;
imageHeight = loadedSurface->h;
//Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
image = newImage;
return true;
}
void displayImage()
{
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_RenderClear(renderer);
SDL_SetWindowSize(window, imageWidth, imageHeight);
SDL_Rect renderQuad = { 0, 0, imageWidth, imageHeight };
SDL_RenderCopy(renderer, image, NULL, &renderQuad);
SDL_RenderPresent(renderer);
}
// Makes a window transparent by setting a transparency color.
bool windowColorKey(SDL_Window* window, COLORREF colorKey) {
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version); // Initialize wmInfo
SDL_GetWindowWMInfo(window, &wmInfo);
HWND hWnd = wmInfo.info.win.window;
// Change window type to layered
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// Set transparency color
return SetLayeredWindowAttributes(hWnd, colorKey, 0, LWA_COLORKEY);
}
int main(int argc, char* args[]) {
// Initialize SDL: Create a window and renderer
init();
// Load the image
loadImage("example.png");
// Color key the background of the window (magenta)
windowColorKey(window, RGB(255, 0, 255));
// Render the image on the widnow with magenta for backround color
displayImage();
// Check for events
bool windowActive = true;
SDL_Event event;
while (windowActive)
{
while (SDL_PollEvent(&event) != 0)
{
if (event.type == SDL_QUIT || event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { windowActive = false; }
}
}
return 0;
}
Using SDL_SetWindowOpacity() won't work because all the elements of the window transparent too.
For now the only way I know to achieve this goal is using color keying, but unfortunately it doesn't work that well, since some of the images will contain the color you use for color keying, and additionally the images will have a small border of the color you used for color keying all around the image. It's thin but annoying.
I am thinking of using the features of a layered window in some other way but cannot find or understand how to.
So, the question is how to make the window itself fully transparent, while having full control over the transparency of the elements of the window?
I need to build an interface where on the left side of the screen shows part of one streaming video and the right side the other part. Something like this https://www.youtube.com/watch?v=fSPXpdVzamo
The video streaming is saved on a memory buffer that is being loaded on a texture. My question is how to render just the half of the texture, I've bee trying using SDL_Rect but nothing happens.
This is the relevant part of my code:
SDL_UpdateTexture(texture, NULL, buffer_start, fmt.fmt.pix.width * 2);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
If I try something like this, it doesn't work:
SDL_UpdateTexture(texture, NULL, buffer_start, fmt.fmt.pix.width * 2);
SDL_Rect someRect;
someRect.x = 0;
someRect.y = 0;
someRect.w = 1500;
someRect.h = 3000;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, &someRect);
SDL_RenderPresent(renderer);
Any advice would be great!
Without you posting a MCVE is hard to know where you went wrong. My guess is your x position is wrong. Here is an example where I show how to draw 2 images in the fashion of your video.
Green image: https://i.imgur.com/yaOG8Ng.png
Red image: https://i.imgur.com/faKKShU.png
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
#define HEIGHT 600
#define WIDTH 800
using namespace std;
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("Red Green", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
SDL_Renderer *renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
bool quit = false;
SDL_Event event;
SDL_Texture *green_part = IMG_LoadTexture(renderer, "Green400x600.png");
SDL_Texture *red_part = IMG_LoadTexture(renderer, "Red400x600.png");
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
SDL_RenderClear(renderer);
SDL_Rect copy_rect{0, 0, 400, 600};
SDL_RenderCopy(renderer, green_part, nullptr, ©_rect);
// We now draw from half the screen onward x position = WIDTH / 2.
copy_rect.x = 400;
SDL_RenderCopy(renderer, red_part, nullptr, ©_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
I am using SDL2 in windowed mode on Windows 7 64bit to create a small game.
I get tearing at the same height of the window despite having VSYNC active. The weird thing is that the movement in itself is fluid, but there is this line, about 50px from the bottom, where tearing is noticeable. It always stays there, without moving or anything.
The weird thing is that if I crate a smaller window, I get tearing at exactly the same height from the bottom.
I tried taking screens of it but it doesn't show the tearing.
I have no idea if this is a problem of SDL2, a problem with Windows, a problem with my pc or a problem in my source file. I have tried looking online for a solution but I could not find anything like this problem.
It is a first for me since I have been playing with a lot of SDL games in the past in windowed mode and none had this problem.
Here is a snippet of the source I have been using:
#include <stdio.h>
#include <SDL.h>
#include <SDL_image.h>
const int SCREEN_WIDTH = 400;
const int SCREEN_HEIGHT = 300;
bool init( SDL_Window** window, SDL_Renderer** renderer ) {
SDL_Init(SDL_INIT_VIDEO);
*window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
*renderer = SDL_CreateRenderer(*window, 0, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
int flags = IMG_INIT_PNG;
IMG_Init(flags);
return true;
}
void close( SDL_Texture** image, SDL_Window** window ) {
SDL_DestroyTexture( *image );
*image = NULL;
SDL_DestroyWindow( *window );
*window = NULL;
SDL_Quit();
}
int main(int argc, char* argv[]) {
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Texture* image = NULL;
const SDL_Rect rect = { 0, 0, SCREEN_WIDTH, 200 };
SDL_Rect rectImage, rectImageOriginal;
int w, h;
SDL_QueryTexture(image, NULL, NULL, &w, &h);
rectImage = { 0, 0, w, h };
rectImageOriginal = rectImage;
init( window, renderer );
image = IMG_LoadTexture( renderer, path );
while (running) {
[... here I move rectImage ...]
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 200, 0, 0, 255);
SDL_RenderFillRect(renderer, NULL);
SDL_RenderCopy(renderer, image, &rectImageOriginal, &rectImage);
SDL_RenderPresent(renderer);
}
close(&image, &window);
}