here is my c++ code:
#include <SDL2/SDL.h>
SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_VIDEO );
gWindow = SDL_CreateWindow( "test", 0,0,640,480, SDL_WINDOW_SHOWN );
gRenderer = SDL_CreateRenderer(gWindow,-1,SDL_RENDERER_ACCELERATED);
SDL_Surface* x = SDL_CreateRGBSurface(0,50,50,32,0xFF,0xFF00,0xFF0000,0XFF000000);
SDL_Surface* y = SDL_CreateRGBSurface(0,640,480,32,0xFF,0xFF00,0xFF0000,0XFF000000);
SDL_Rect a = {0,0,50,50};
SDL_RenderClear(gRenderer);
SDL_FillRect(x,&a,SDL_MapRGBA(x->format,255,255,0,255));
SDL_Rect dest = {0,0,100,100};
SDL_BlitScaled( x, &a, y, &dest ); //Does nothing
dest.x = 200;
SDL_BlitSurface( x, &a, y, &dest );
SDL_Texture* t;
t = SDL_CreateTextureFromSurface(gRenderer,y);
SDL_RenderCopy(gRenderer,t,NULL,NULL);
SDL_RenderPresent(gRenderer);
SDL_Delay(2000);
return 0;
}
well,when you compile this code,you will see there is ONLY ONE rect on the screen.The function SDL_BlitScaled does nothing.
I'm working with Archlinux,gcc 4.8.2,SDL 2.0.1
According to Retired Ninja's answer,I changed my code:
#include <SDL2/SDL.h>
SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_VIDEO );
gWindow = SDL_CreateWindow( "test", 0,0,640,480, SDL_WINDOW_SHOWN );
gRenderer = SDL_CreateRenderer(gWindow,-1,SDL_RENDERER_ACCELERATED);
SDL_Surface* x = SDL_CreateRGBSurface(0,50,50,32,0xFF,0xFF00,0xFF0000,0XFF000000);
SDL_Surface* y = SDL_CreateRGBSurface(0,640,480,32,0xFF,0xFF00,0xFF0000,0XFF000000);
SDL_SetRenderDrawColor(gRenderer,255,255,255,255);
SDL_RenderClear(gRenderer);
SDL_Rect a = {0,0,25,25};
SDL_FillRect(x,&a,SDL_MapRGBA(x->format,255,255,0,255));
a.x = 25;a.y = 25;
SDL_FillRect(x,&a,SDL_MapRGBA(x->format,255,0,0,255));
SDL_FillRect(y,&y->clip_rect,SDL_MapRGBA(y->format,255,0,255,128));
SDL_Rect dest = {0,0,100,100};
SDL_Rect x_rect = {0,0,50,50};
SDL_SetSurfaceBlendMode(x,SDL_BLENDMODE_NONE);
SDL_BlitScaled( x, &x_rect, y, &dest );
SDL_Texture* t;
t = SDL_CreateTextureFromSurface(gRenderer,y);
SDL_RenderCopy(gRenderer,t,NULL,NULL);
SDL_RenderPresent(gRenderer);
SDL_Delay(2000);
return 0;
}
there is another problem appeared.I try to copy x into y,The x covered y entirely,even through there are transparent area in x.But if I don't use SDL_BLENDMODE_NONE,the alpha of the area copied into y will be set into 128,which is not my purpose.
Filling y with a color makes it work.
I added:
SDL_FillRect(y, &y->clip_rect, SDL_MapRGBA(x->format, 255, 0, 0, 255));
after the SDL_FillRect for x and it worked.
Some further experimentation of just filling a portion of y with alpha leads me to believe that SDL_BlitScaled isn't copying the alpha from the source surface so unless the dest surface has alpha where the destination rect is you won't see the result.
Some more experimentation shows that the default blend mode for a surface is SDL_BLENDMODE_BLEND and changing the mode for y to SDL_BLENDMODE_NONE also makes it work.
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().
Here is a minimal SDL-1.2 text output example (stripped from the lazyfoo tutorial for ttf):
#include <SDL.h>
#include <SDL_ttf.h>
#include <string>
SDL_Surface *message = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;
TTF_Font *font = NULL;
SDL_Color color = { 255, 255, 255 };
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_EVERYTHING );
screen = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
TTF_Init();
SDL_WM_SetCaption( "Test message", NULL );
font = TTF_OpenFont( "anyttffont.ttf", 20 );
message = TTF_RenderText_Solid(
font, "My test message", color );
SDL_Rect offset;
offset.x = 0;
offset.y = 150;
SDL_BlitSurface( message, NULL, screen, &offset );
SDL_Flip( screen );
bool quit = false;
while( quit == false )
while( SDL_PollEvent( &event ) )
if( event.type == SDL_QUIT )
quit = true;
SDL_FreeSurface( message );
TTF_CloseFont( font );
TTF_Quit();
SDL_Quit();
return 0;
}
The resulting executable redraws the window automatically after re-exposing it (after minimizing or obscuring).
Is it possible to do something like this in SDL-2?
I tried the equivalent tutorial from lazyfoo for SDL-2, but this has code to constantly re-render the text in the event loop. It stops re-drawing when the render code is moved in front of the loop. I also tried rewriting it using the window surface directly and then using SDL_UpdateWindowSurface(gWindow);, but this behaves the same way.
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.
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);
}
I'm writing a function in C++ with the SDL2 library, and I'm stuck with a small problem. The function deals with everything related to the graphics. I want to use it once to create the window, surface and so on ( graphics(0,0) ), and that everytime I use it after that it just updates the value of x and y, and updates the window surface. How can I do it? I've tried everything I could think of, but in order to update the window surface I need to create the window again. Thanks in advance.
void graficos(int var1,int var2){
int x = 0, y = 0; //declare the variables that will determine position of rectangle
x += var1; y += var2; //declare the variables that will modify x & y
//delcare graphics and load them
SDL_Window * window = SDL_CreateWindow("window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Surface * surface = SDL_GetWindowSurface(window);
SDL_Surface * texture = SDL_LoadBMP("texture.bmp");
SDL_Rect rectangle = { x, y, 50, 50 };
//render graphics
SDL_BlitSurface(texture, NULL, surface, &rectangle);
//update window
SDL_UpdateWindowSurface(window);
}
First. You can break your function into two: init and graficos like this:
void init( SDL_Window * &window, SDL_Surface * &texture ) {
window = SDL_CreateWindow("window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
0
);
texture = SDL_LoadBMP("texture.bmp");
}
void graficos( SDL_Window * window, SDL_Surface * texture, int var1, int var2 ) {
// You can delete these lines and use var1 and var2 directly
/* int x = 0, y = 0; //declare the variables that will determine position of rectangle
x += var1; y += var2; //declare the variables that will modify x & y
*/
SDL_Surface * surface = SDL_GetWindowSurface(window);
SDL_Rect rectangle = { var1, var2, 50, 50 };
//render graphics
SDL_BlitSurface(texture, NULL, surface, &rectangle);
//update window
SDL_UpdateWindowSurface(window);
}
And here is the usage:
// somewhere in global place
SDL_Window * window;
SDL_Surface * texture;
// somewhere in initialization of programm
init( window, texture ); // call it only ones
...
graficos( window, texture, newX, newY ); // call it every time you need
Second. You can make window and texture as static like this:
void graficos(int var1,int var2){
/* int x = 0, y = 0; //declare the variables that will determine position of rectangle
x += var1; y += var2; //declare the variables that will modify x & y
*/
//delcare graphics and load them
// ---v---
static SDL_Window * window = SDL_CreateWindow("window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
// ---^---
SDL_Surface * surface = SDL_GetWindowSurface(window);
// ---v---
static SDL_Surface * texture = SDL_LoadBMP("texture.bmp");
// ---^---
SDL_Rect rectangle = { x, y, 50, 50 };
//render graphics
SDL_BlitSurface(texture, NULL, surface, &rectangle);
//update window
SDL_UpdateWindowSurface(window);
}
If there will be a voiting, then my voice would be for first :)