Move image on screen - c++

I have an image which I want to be moveable. My problem is that the image isn't really moving, it's just dublicated and a new image loads on the new place while the old position still contain the image.
void draw_surface(int srcX, int srcY, int dstX, int dstY, int width, int height, SDL_Surface *source, SDL_Surface *destination)
{
SDL_Rect src;
src.x = srcX;
src.y = srcY;
src.w = width;
src.h = height;
SDL_Rect dst;
dst.x = dstX;
dst.y = dstY;
dst.w = width;
dst.h = height;
SDL_BlitSurface(source, &src, destination, &dst);
}
in the main function:
while (gameRunning)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_DOWN)
{
dstY += 10; //new position
}
}
//apply
apply_surface(0, 10, background, screen);
draw_surface(srcX, srcY, dstX, dstY, width, heigth, background, screen);
}
//update screen
SDL_Flip(screen);
}
What's wrong with this code?

You should use a while loop to poll for events
Moving the drawing outside of the event loop block is a good idea
You need to clear your screen before drawing to it or else the old back buffer data will still be on it
Uint32 black = SDL_MapRGB(screen->format, 0, 0, 0);
while (gameRunning) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
gameRunning = false;
}
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.sym == SDLK_DOWN) {
dstY += 10; //new position
}
}
}
// Clear screen
SDL_FillRect(screen, NULL, black);
//apply
apply_surface(0, 10, background, screen);
draw_surface(srcX, srcY, dstX, dstY, width, heigth, background, screen);
//update screen
SDL_Flip(screen);
}

Related

Texture not displaying SDL2 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 months ago.
Improve this question
I'm trying to make a game in C++ with SDL2, and I can't even get a texture displaying. SDL_GetError() returns nothing.
I'm on a windows 10 pro using Visual Studio.
Here are my 3 files:
main.cpp
#include "Classes.h"
int MouseX = 0;
int MouseY = 0;
int PlayerX = 0;
int PlayerY = 0;
SDL_Renderer* renderer;
Tile tile = Tile({10, 10, TileTypes::Tile_Grass}, renderer);
EventReturns HandleEvent(SDL_Event* event) {
switch (event->type) {
case SDL_QUIT:
return EventReturns::Event_QUIT;
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
return EventReturns::Event_TryQuit;
default:
return EventReturns::Event_None;
}
default:
return EventReturns::Event_None;
}
}
int mainLoop(EventReturns eventReturn) {
SDL_GetMouseState(&MouseX, &MouseY);
if (eventReturn == EventReturns::Event_QUIT || eventReturn == EventReturns::Event_TryQuit) {
return 1;
}
return 0;
}
void render() {
SDL_SetRenderDrawColor(renderer, 100, 200, 200, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
tile.SetPos(0, 0);
if (tile.Draw(renderer) != 0) {
SDL_ShowSimpleMessageBox(0, "ERROR", "ERROR: Rect in tile has 0x0 size, Please close this with the task manager", NULL);
}
SDL_RenderPresent(renderer);
}
int main(int argc, char* argv[]) {
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 2880, 1600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
bool running = true;
EventReturns eventReturn = EventReturns::Event_None;
SDL_Event event;
int quit = 0;
while (running) {
while (SDL_PollEvent(&event)) {
eventReturn = HandleEvent(&event);
}
quit = mainLoop(eventReturn);
render();
if (quit == 1) {
running = false;
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Classes.h
#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
#define SpriteSizeMult 1
enum class EventReturns {
Event_QUIT,
Event_None,
Event_TryQuit
};
enum class TileTypes {
Tile_Grass
};
struct TileStruct {
int x;
int y;
TileTypes type;
};
class Tile {
public:
Tile(int x, int y, char* TexturePath, SDL_Renderer* renderer);
Tile(TileStruct structure, SDL_Renderer* renderer);
Tile();
int Draw(SDL_Renderer* renderer);
void SetPos(int x, int y);
private:
int x = 0;
int y = 0;
int TextureWidth = 0;
int TextureHeight = 0;
SDL_Texture* texture;
SDL_Rect rect;
};
SDL_Point getsize(SDL_Texture* texture);
Classes.cpp
#include "Classes.h"
SDL_Point getsize(SDL_Texture* texture) {
SDL_Point size;
SDL_QueryTexture(texture, NULL, NULL, &size.x, &size.y);
return size;
}
Tile::Tile(int x, int y, char* TexturePath, SDL_Renderer* renderer)
{
this->x = x;
this->y = y;
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load(TexturePath));
if (this->texture == nullptr) {
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
std::cout << IMG_GetError();
}
SDL_Point point = getsize(this->texture);
this->TextureHeight = point.y;
this->TextureWidth = point.x;
this->rect = {this->x - ((this->TextureWidth * SpriteSizeMult) / 2), this->y - ((this->TextureHeight * SpriteSizeMult) / 2), this->TextureWidth * SpriteSizeMult, this->TextureHeight * SpriteSizeMult};
}
Tile::Tile(TileStruct structure, SDL_Renderer* renderer)
{
this->x = structure.x;
this->y = structure.y;
switch (structure.type) {
case TileTypes::Tile_Grass:
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/Tiles/Grass.png"));
default:
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
}
if (this->texture == NULL) {
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
if (this->texture == NULL) {
SDL_ShowSimpleMessageBox(0, "ERROR", "Failed to load texture", NULL);
SDL_ShowSimpleMessageBox(0, "ERROR", IMG_GetError(), NULL);
}
}
SDL_Point point = getsize(this->texture);
this->TextureHeight = point.y;
this->TextureWidth = point.x;
this->rect = { this->x - ((this->TextureWidth * SpriteSizeMult) / 2), this->y - ((this->TextureHeight * SpriteSizeMult) / 2), this->TextureWidth * SpriteSizeMult, this->TextureHeight * SpriteSizeMult };
}
Tile::Tile()
{
}
int Tile::Draw(SDL_Renderer* renderer)
{
if (rect.w == 0 || rect.h == 0) {
return -1;
}
this->rect.x = 0;
this->rect.y = 0;
SDL_RenderCopy(renderer, this->texture, NULL, &rect);
return 0;
}
void Tile::SetPos(int x, int y)
{
this->x = x;
this->y = y;
}
I'm sorry for the sheer amount of code that is, but I'd really appreciate the help. If there's any more info I need to put here, just let me know.
I'm fully aware that I should make a Minimal Reproducible Example, but as far as I'm aware, all the code listed here is necessary.
Finally, in case I've been unclear, when running the code the Missing Texture image that should appear isn't showing up.
I can't see SDL_INIT function in your code.
You should add this in the beginning of your main function.
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return 1;
You are initialising tile before creating a renderer so the constructor is trying to create a texture without a renderer.
SDL_Renderer* renderer;
Tile tile = Tile({10, 10, TileTypes::Tile_Grass}, renderer);
You should do something like this
#include "Classes.h"
int MouseX = 0;
int MouseY = 0;
int PlayerX = 0;
int PlayerY = 0;
SDL_Renderer* renderer;
EventReturns HandleEvent(SDL_Event* event) {
switch (event->type) {
case SDL_QUIT:
return EventReturns::Event_QUIT;
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
return EventReturns::Event_TryQuit;
default:
return EventReturns::Event_None;
}
default:
return EventReturns::Event_None;
}
}
int mainLoop(EventReturns eventReturn) {
SDL_GetMouseState(&MouseX, &MouseY);
if (eventReturn == EventReturns::Event_QUIT || eventReturn == EventReturns::Event_TryQuit) {
return 1;
}
return 0;
}
void render(Tile tile) {
SDL_SetRenderDrawColor(renderer, 100, 200, 200, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
tile.SetPos(0, 0);
if (tile.Draw(renderer) != 0) {
SDL_ShowSimpleMessageBox(0, "ERROR", "ERROR: Rect in tile has 0x0 size, Please close this with the task manager", NULL);
}
SDL_RenderPresent(renderer);
}
int main(int argc, char* argv[]) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return 1;
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 2880, 1600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
Tile tile = Tile({ 10, 10, TileTypes::Tile_Grass }, renderer);
bool running = true;
EventReturns eventReturn = EventReturns::Event_None;
SDL_Event event;
int quit = 0;
while (running) {
while (SDL_PollEvent(&event)) {
eventReturn = HandleEvent(&event);
}
quit = mainLoop(eventReturn);
render(tile);
if (quit == 1) {
running = false;
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

SDL window shows incorrectly. On linux terminal

This is basically my code here, very simple just to load an image to display. But the first thing I open a window surface, the surface has characters like 'X','S' out of nowhere:
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_VIDEO );
SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 0,
SDL_HWSURFACE | SDL_DOUBLEBUF );
SDL_WM_SetCaption( WINDOW_TITLE, 0 );
SDL_Surface* bitmap = SDL_LoadBMP("bat.bmp");
// Part of the bitmap that we want to draw
SDL_Rect source;
source.x = 24;
source.y = 63;
source.w = 65;
source.h = 44;
// Part of the screen we want to draw the sprite to
SDL_Rect destination;
destination.x = 100;
destination.y = 100;
destination.w = 65;
destination.h = 44;
SDL_Event event;
bool gameRunning = true;
int i=1000;
while (i)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
}
SDL_BlitSurface(bitmap, &source, screen, &destination);
SDL_Flip(screen);
i--;
}
SDL_FreeSurface(bitmap);
SDL_Quit();
return 0;
}

Collision with more than 1 Object SDL 2.0-C++

I'am new there. I've been learning classes and tried to make a very simple platform game. But I have problem now. I've wanted to set Class "Player" to collide with 2 objects of Class "Block" But Collision do not work for one of them.
Here is my code:
#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#undef main
class Block
{
private:
SDL_Texture *BlockTexture;
public:
Block(SDL_Renderer *renderTarget, std::string filePath, int xPos, int yPos, int Width, int Height);
~Block();
void Draw(SDL_Renderer *renderTarget);
SDL_Rect BlockPos;
};
Block::Block(SDL_Renderer *renderTarget, std::string filePath, int xPos, int yPos, int Width, int Height)
{
SDL_Surface *surface = IMG_Load(filePath.c_str());
{
BlockTexture = SDL_CreateTextureFromSurface(renderTarget, surface);
}
SDL_FreeSurface(surface);
BlockPos.x = xPos;
BlockPos.y = yPos;
BlockPos.w = Width;
BlockPos.h = Height;
}
Block::~Block()
{
SDL_DestroyTexture(BlockTexture);
}
void Block::Draw(SDL_Renderer *renderTarget)
{
SDL_RenderCopy(renderTarget, BlockTexture, NULL, &BlockPos);
}
class Player
{
private:
SDL_Texture *Texture;
float moveSpeed;
float jumpSpeed;
int falling = 0;
SDL_Scancode keys [3];
public:
SDL_Rect PlayerPos;
Player(SDL_Renderer *renderTarget, std::string filePath, int PosX, int PosY, int Width, int Height);
~Player();
void Update(float delta, const Uint8 *Keystate);
void Draw(SDL_Renderer *renderTarget);
bool Collision(Block &p);
};
Player::Player(SDL_Renderer *renderTarget, std::string filePath, int PosX, int PosY, int Width, int Height)
{
SDL_Surface *surface = IMG_Load(filePath.c_str());
{
Texture = SDL_CreateTextureFromSurface(renderTarget, surface);
}
SDL_FreeSurface(surface);
PlayerPos.x = PosX;
PlayerPos.y = PosY;
PlayerPos.w = Width;
PlayerPos.h = Height;
keys[0] = SDL_SCANCODE_UP;
keys[1] = SDL_SCANCODE_LEFT;
keys[2] = SDL_SCANCODE_RIGHT;
moveSpeed = 200.f;
jumpSpeed = 100.f;
}
Player::~Player()
{
SDL_DestroyTexture(Texture);
}
void Player::Update(float delta, const Uint8 *KeyState)
{
if(KeyState[keys[0]])
{
PlayerPos.y -= moveSpeed * delta;
}
if(KeyState[keys[1]])
{
PlayerPos.x -= (moveSpeed / 2) * delta;
}
if(KeyState[keys[2]])
{
PlayerPos.x += moveSpeed * delta;
}
if(falling == 0)
{
PlayerPos.y += jumpSpeed * delta;
}
}
void Player::Draw(SDL_Renderer *renderTarget)
{
SDL_RenderCopy(renderTarget, Texture, NULL, &PlayerPos);
}
bool Player::Collision(Block &p)
{
if(PlayerPos.x + PlayerPos.w <= p.BlockPos.x || PlayerPos.x >= p.BlockPos.x + p.BlockPos.w ||
PlayerPos.y + PlayerPos.h <= p.BlockPos.y || PlayerPos.y >= p.BlockPos.y + p.BlockPos.h)
{
falling = 0;
return true;
}
else
falling = 1;
return false;
}
SDL_Texture *LoadTexture(std::string filePath, SDL_Renderer *Renderer)
{
SDL_Texture *texture = NULL;
SDL_Surface *surface = IMG_Load(filePath.c_str());
{
texture = SDL_CreateTextureFromSurface(Renderer, surface);
}
SDL_FreeSurface(surface);
return texture;
}
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = SDL_CreateWindow("Platform", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
SDL_Renderer *renderTarget = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
int imgFlags = IMG_INIT_PNG;
int currentTime = 0;
int previousTime = 0;
float delta = 0;
const Uint8 *Keystate;
Player Player(renderTarget, "BlockP.png", 100, 100, 50, 50);
Block Block1(renderTarget, "Block.png", 0, 500, 800, 100);
Block Block2(renderTarget, "Block.png", 100, 300, 300, 50);
bool isRunning = true;
SDL_Event ev;
while(isRunning)
{
Keystate = SDL_GetKeyboardState(NULL);
Player.Collision(Block1);
Player.Collision(Block2);
previousTime = currentTime;
currentTime = SDL_GetTicks();
delta = (currentTime - previousTime) / 1000.0f;
Player.Update(delta, Keystate);
while(SDL_PollEvent(&ev) != 0)
{
if(ev.type == SDL_QUIT)
isRunning = false;
}
SDL_RenderClear(renderTarget);
Player.Draw(renderTarget);
Block1.Draw(renderTarget);
Block2.Draw(renderTarget);
SDL_RenderPresent(renderTarget);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderTarget);
window = NULL;
renderTarget = NULL;
SDL_Quit();
return 0;
}
The problem with your code is that each call to Player.Collision overwrites the "falling" variable.
Player.Collision(Block1); //this call calculates a falling value
Player.Collision(Block2); //...then this call overwrites falling with a new value
So effectively your code is only testing if the player is colliding with Block2, so collisions with Block1 are ignored.
Currently your Collision function is:
bool Player::Collision(Block &p)
{
if(PlayerPos.x + PlayerPos.w <= p.BlockPos.x || PlayerPos.x >= p.BlockPos.x + p.BlockPos.w ||
PlayerPos.y + PlayerPos.h <= p.BlockPos.y || PlayerPos.y >= p.BlockPos.y + p.BlockPos.h)
{
falling = 0;
return true;
}
else
falling = 1;
return false;
}
Firstly, your "return false;" is not actually part of the else, as you don't have {}. In this particular case it makes no difference as the else is exited and then the return happens but your indentation would suggest you expect the "return false;" line to be executed as part of the else block so you should put:
else
{
falling = 1;
return false;
}
Next you want to say if you have already detected a collision (eg, with Block1) then don't set falling to 1, to do this add an if statement.
else
{
if(falling != 0) //if we haven't already detected a collision this frame
{
falling = 1;
}
return false;
}
You will however need to set falling back to 1 at the start of each frame, otherwise if a collision is detected on one frame then the player will never fall on subsequent frames, even if they are not colliding with a block.
As a side note, your Player.Update code modifies the player's y position if falling == 0, this seems counter intuitive as usually 0 is false and 1 is true, hence you seem to be saying if not falling then update y, where as it should be if falling update y. Personally I would use a bool rather than an int to hold the value of falling, and then say if(falling) update y, this would make your code clearer.

C++ SDL2, moving too fast

I'm currently having a problem with my pong game. I'm trying to smooth out the player movement (so it wont stutter so much when is moves, and no delay after first keypress)
This is my code so far, problem is while I've got the movement smoother the _paddle move too fast! and I don't now how to make it move slower!
Is there a way i can make the _paddle move slower or did i write the code wrong?
maingame.h
#pragma once
#include <iostream>
#include <SDL/SDL.h>
#include <string>
#include "maingame.h"
class maingame
{
public:
maingame();
~maingame();
//loads pictures
bool loadMedia(std::string path);
//init the system
void init();
//runs the game
void run();
//THE EPIC GAMELOOP
void gameloop();
//draw the screen
void draw();
void UserInput();
private:
//window
SDL_Window* _window;
//redenderer
SDL_Renderer* _rend;
//the screens surface
SDL_Surface* _screensurface;
//player, ai and the ball
SDL_Rect _paddle;
SDL_Rect _ai;
SDL_Rect _ball;
//checks if you pressed down the W or S button
bool keydown_w = false;
bool keydown_s = false;
//Event for the pall stuff
SDL_Event e;
};
maingame.c
#include "maingame.h"
/*
PONG V0.2
Black background - CHECK
paddle appear on screen - CHECK
other paddle appear on screen - CHECK
ball appear on screen - CHECK
move player paddle - CHECK
impossible to move outside of map - CHECK
movement smoother -
make ball go around -
collison with paddles -
keep scores -
show scores -
make a 2nd player chooseable -
*/
//screen width and height
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
maingame::maingame()
{
_window = nullptr;
_rend = nullptr;
}
maingame::~maingame()
{
}
void maingame::init()
{
SDL_Init(SDL_INIT_EVERYTHING);
}
void maingame::run()
{
init();
//creating a windows
_window = SDL_CreateWindow("PONG", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
//create the render
_rend = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
//set out the player
_paddle.x = 100;
_paddle.y = (SCREEN_HEIGHT / 2) - 100;
_paddle.w = 20;
_paddle.h = 200;
//set out the ai
_ai.x = SCREEN_WIDTH - 100;
_ai.y = (SCREEN_HEIGHT / 2) - 100;
_ai.w = 20;
_ai.h = 200;
//set out the ball
_ball.x = SCREEN_WIDTH / 2 - 20;
_ball.y = (SCREEN_HEIGHT / 2) - 20;
_ball.w = 20;
_ball.h = 20;
draw();
gameloop();
}
void maingame::draw()
{
//make the render be black
SDL_SetRenderDrawColor(_rend, 0, 0, 0, 0);
//Clear the render with the color we set with SDL_SetRenderDrawColor, in this case black
SDL_RenderClear(_rend);
//make the next things we will render white
SDL_SetRenderDrawColor(_rend, 255, 255, 255, 0);
//make the paddle, ai and ball the color of SDL_SetRenderDrawColor, which is whites in this case
SDL_RenderFillRect(_rend, &_paddle);
SDL_RenderFillRect(_rend, &_ai);
SDL_RenderFillRect(_rend, &_ball);
//SDL_RenderDrawRect(_rend, &_paddle);
//Present the render, draw it to the screen
SDL_RenderPresent(_rend);
}
bool maingame::loadMedia(std::string path)
{
//Loading success flag
bool success = true;
SDL_Surface* pic;
//Load splash image
pic = SDL_LoadBMP(path.c_str());
if (pic == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}
void maingame::gameloop()
{
const Uint8 *keys = SDL_GetKeyboardState(NULL);
bool keydown_w = false;
bool keydown_s = false;
while (true)
{
while (SDL_PollEvent(&e) != 0)
{
//pressed the X, quit the program
if (e.type == SDL_QUIT)
{
exit(1);
}
UserInput();
}
UserInput();
draw();
}
}
void maingame::UserInput()
{
float lol = 0;
//Pressed a key!
if (e.type == SDL_KEYDOWN)
{
//pressed W, move the player
if (e.key.keysym.sym == SDLK_w)
{
keydown_w = true;
}
//pressed S, move the player
else if (e.key.keysym.sym == SDLK_s)
{
keydown_s = true;
}
}
if (e.type == SDL_KEYUP)
{
std::cout << keydown_w << std::endl;
if (e.key.keysym.sym == SDLK_w)
keydown_w = false;
if (e.key.keysym.sym == SDLK_s)
keydown_s = false;
}
if (keydown_w)
{
if (_paddle.y > 1)
{
_paddle.y -= 1;
}
std::cout << keydown_w << std::endl;
}
if (keydown_s)
{
if (_paddle.y < SCREEN_HEIGHT - _paddle.h)
{
_paddle.y += 1;
}
}
}
It maybe bad programming practice to do so but the only way I would see getting around your problem is to add an SDL_Delay() in your gameloop function. I would suggest you use it as a temporary fix until you find an alternative solution. Hope this helps.

Preserving alpha when blitting

How can I preserve alpha values when blitting? I want to blit multiple black squares with various alpha values onto a surface and then blit that surface onto the screen. Everything I try just blits a solid opaque black surface.
Edit:
What I want is this:
What I'm getting is this:
The code
#include <SDL.h>
void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel){
Uint32 *pixels = (Uint32*)surface->pixels;
pixels[(y * surface->w) + x] = pixel;
}
void FillAlpha(SDL_Surface* Surface){
Uint32 Pixel;
Uint8 RGBA[4] = {0, 0, 0, 100};
Pixel = RGBA[3]<<24 | RGBA[2]<<16 | RGBA[1]<<8 | RGBA[0];
for(int x=0; x<32; x++){
for(int y=0; y<32; y++){
putPixel(Surface, x, y, Pixel);
}
}
RGBA[3] = 150;
Pixel = RGBA[3]<<24 | RGBA[2]<<16 | RGBA[1]<<8 | RGBA[0];
for(int x=32; x<64; x++){
for(int y=0; y<32; y++){
putPixel(Surface, x, y, Pixel);
}
}
}
int main(int argc, char* args[])
{
SDL_Window* Window = NULL;
SDL_Surface* Screen = NULL;
SDL_Surface* Alpha = NULL;
SDL_Event Event;
bool Quit = false;
Window = SDL_CreateWindow("Alpha test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 128, 128, SDL_WINDOW_SHOWN);
if(Window == NULL) return 1;
Screen = SDL_GetWindowSurface(Window);
if(Screen == NULL) return 2;
Alpha = SDL_CreateRGBSurface(NULL, 64, 32, 32,
Screen->format->Rmask, Screen->format->Gmask,
Screen->format->Bmask, Screen->format->Amask);
if(Alpha == NULL) return 3;
SDL_SetSurfaceBlendMode(Alpha, SDL_BLENDMODE_BLEND);
FillAlpha(Alpha);
while(!Quit){
while(SDL_PollEvent(&Event)){
if(Event.type == SDL_KEYDOWN){
if(Event.key.keysym.sym == SDLK_ESCAPE){
Quit = true;
}
}else if(Event.type == SDL_QUIT){
Quit = true;
}
}
SDL_FillRect(Screen, NULL, SDL_MapRGB(Screen->format, 255, 255, 255));
SDL_BlitSurface(Alpha, NULL, Screen, NULL);
SDL_UpdateWindowSurface(Window);
}
SDL_Quit();
return 0;
}