As an attempt to learn SDL on C, I decided to try and create a simple Pong program using it. My problem now is that of the textures I've given it, two paddles and a ball, only the ball is rendered. It fails to render anything else even if it is the only thing I give. I have no idea why this happens. I've spend more than an hour trying to fix this, scanning each line of code line by line multiple times. I even went as far as renaming a paddle image to ball, and only then did it render. I think there is a deep and most likely stupid flaw to how I implemented it, so I attached some of the code below:
texRacquet1 = SDL_CreateTextureFromSurface(rend, racquet1);
SDL_FreeSurface(racquet1);
texRacquet2 = SDL_CreateTextureFromSurface(rend, racquet2);
SDL_FreeSurface(racquet2);
texBall = SDL_CreateTextureFromSurface(rend, ball);
SDL_FreeSurface(ball);
This creates textures from the images and sets them to the pointers I defined.
SDL_Rect sracquet1;
SDL_Rect sracquet2;
SDL_Rect sball;
//Gets scale and dimensions of textures
SDL_QueryTexture(texRacquet1, NULL, NULL, &sracquet1.w, &sracquet1.h);
sracquet1.w * 6;
sracquet1.h * 6;
SDL_QueryTexture(texRacquet2, NULL, NULL, &sracquet2.w, &sracquet2.h);
sracquet2.w * 6;
sracquet2.h * 6;
SDL_QueryTexture(texBall, NULL, NULL, &sball.w, &sball.h);
sball.w * 6;
sball.h * 6;
This queries the textures and finds the dimensions of the shape, adding them to their respective structure members from the rectangle structures set for each texture. It also dilates it by 6 so it can be seen.
//Copies textures to buffer and presents them to screen
SDL_RenderCopy(rend, texRacquet1, NULL, &sracquet1);
SDL_RenderCopy(rend, texRacquet2, NULL, &sracquet2);
SDL_RenderCopy(rend, texBall, NULL, &sball);
SDL_RenderPresent(rend);
Finally, this draws the textures and presents them to the screen. Or it should. It only renders the ball, and if I remove that line, it just does nothing.
Full code:
//Speed of ball in pixels per second
const int SPEED = 300;
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480;
int main(int argc, char* argv[])
{
//Creates pointers to various game elements
const char *window1_title = "Pong";
Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
SDL_Window *window1 = NULL;
SDL_Renderer*rend = NULL;
SDL_Surface *racquet1 = NULL;
SDL_Surface *racquet2 = NULL;
SDL_Surface *ball = NULL;
SDL_Texture *texRacquet1 = NULL;
SDL_Texture *texRacquet2 = NULL;
SDL_Texture *texBall = NULL;
int request_quit = 0;
//Initializes SDL
SDL_Init(SDL_INIT_EVERYTHING);
//Prints error message if SDL fails to initalize
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
printf("Failed to initialize SDL: %s\n", SDL_GetError());
//Quits SDL
SDL_Quit();
return 1;
}
/*
Creates centered window with the window title pointer, width, height, and
no flags
*/
window1 = SDL_CreateWindow(window1_title, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
WINDOW_WIDTH, WINDOW_HEIGHT, 0);
//Prints error message if SDL failed to create window1
if(!window1)
{
printf("Failed to initalize window: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
//Initializes renderer
rend = SDL_CreateRenderer(window1, -1, render_flags);
if(!rend)
{
printf("Failed to initialize renderer: %s\n", SDL_GetError());
//Destroys window
SDL_DestroyWindow(window1);
SDL_Quit();
return 1;
}
SDL_SetRenderDrawColor(rend, 255, 255, 255, 255);
//Loads images
racquet1 = IMG_Load("resources/raquet1.png");
racquet2 = IMG_Load("resources/raquet2.png");
ball = IMG_Load("resources/ball.png");
//Tests if an image didn't load
if(!racquet1 && !racquet2 && !ball)
{
printf("Failed to load images\n");
//Destroys initalized components and quits
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window1);
SDL_Quit();
return 1;
}
//Texturizes loaded images
texRacquet1 = SDL_CreateTextureFromSurface(rend, racquet1);
SDL_FreeSurface(racquet1);
texRacquet2 = SDL_CreateTextureFromSurface(rend, racquet2);
SDL_FreeSurface(racquet2);
texBall = SDL_CreateTextureFromSurface(rend, ball);
SDL_FreeSurface(ball);
// Errors if sprites fail to texturize
if(!texRacquet1 && !texRacquet2 && !texBall)
{
printf("Failed to texturize images\n");
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window1);
SDL_Quit();
return 1;
}
// Structs to hold coordinate positions
SDL_Rect xracquet1 = {0, 0, 0, 0};
SDL_Rect xracquet2 = {0, 0, 0, 0};
SDL_Rect xball = {0, 0, 0, 0};
//Gets scale and dimensions of textures
SDL_QueryTexture(texRacquet1, NULL, NULL, &xracquet1.w, &xracquet1.h);
SDL_QueryTexture(texRacquet2, NULL, NULL, &xracquet2.w, &xracquet2.h);
SDL_QueryTexture(texBall, NULL, NULL, &xball.w, &xball.h);
// Set ball to the middle of the window
xball.x = (WINDOW_WIDTH - xball.w) / 2;
xball.y = (WINDOW_HEIGHT - xball.h) / 2;
// Set racquet 1 to the left side of the window
xracquet1.x = 0;
xracquet1.y = (WINDOW_HEIGHT - xracquet1.h) / 2;
// Set racquet 2 to the right side of the window
xracquet2.x = (WINDOW_WIDTH - xracquet2.w);
xracquet2.y = (WINDOW_HEIGHT - xracquet2.h) / 2;
//Initializes game loop
while(!request_quit)
{
//Processes events
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
request_quit = 1;
break;
}
}
//Clears screen for renderer
SDL_RenderClear(rend);
//Copies textures to buffer and presents them to screen
SDL_RenderCopy(rend, texRacquet1, NULL, &xracquet1);
SDL_RenderCopy(rend, texRacquet2, NULL, &xracquet2);
SDL_RenderCopy(rend, texBall, NULL, &xball);
SDL_RenderPresent(rend);
//Waits 1/60th of a second for a 60 fps lock
SDL_Delay(1000 / 60);
}
SDL_DestroyTexture(texRacquet1);
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window1);
SDL_Quit();
return 0;
}