SDL_RenderCopy not rendering (Isn't NULL, none SDL/IMG Error too)












1















I'm trying to make a simple Snake game. The self collision and a lot of things aren't ready. The problem is: Even with no errors, running just fine, changing "close()" to "endGame()" and reverting, rebuilding the entire program, i could not render anything with SDL_RenderCopy. You will see many unnecessary things in my code and some Brazilian-Portuguese comments, prepare yourself.



The image is a 16x16 png spritesheet, using the color #ff00ff as ColorKey. There are only 4 sprites in this spritesheet, respectively: Apple, Snake's Body, Snake's Head and Snake's Tail (still unused).



Whole code:



#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

using namespace std;

const int CELL_SIZE = 16;
const int CELL_WIDTH = 16;
const int CELL_HEIGHT = 16;
const int SCREEN_WIDTH = CELL_SIZE * (CELL_WIDTH-1);
const int SCREEN_HEIGHT = CELL_SIZE * (CELL_HEIGHT-1);

SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;

void loadTexture(string path);

SDL_Texture* spriteSheet = NULL;

void loadMedia();
void init();


class Snake {
int initialLength = 3; //from body (head incluse)
int length = initialLength;
int facing = DIR_UP;

//Head position in CELLS (multiplied for CELL_SIZE when drawed)
int x = 5;
int y = 5;

//UNUSED TEMPORARY COLORS - IGNORE
Uint8 color[3] = {0x22,0x88,0x44}; //Snake Color, em RGB
Uint8 headColor[3] = {0x11,0x44,0x44}; //Color for the Head of the Snek

int stepDelay = 60; //time in frames that the Snakes waits till move
int stepFramesRemaining = stepDelay;
int stepDelayReduction = 1; //reduces stepDelay every time the Snakes eats the apple
const int minStepDelay = 15; //the minimum delay

//For clipping the image (its an 16x16 png image)
const SDL_Rect clipHead = {0,8,8,8};
const SDL_Rect clipBody = {8,0,8,8};
const SDL_Rect clipTail = {8,8,8,8};

public:
enum direction { //direções nas quais a cobra pode se mover
DIR_UP,
DIR_RIGHT,
DIR_DOWN,
DIR_LEFT
};

/* The following var stores the entire Snake's body in an 2D Array. The number stored means how much "steps" it will survive.
When the value is zero, it means that there is no body in the place. The bodypart with value equivalent to "length" is the Head.
*/
int body[CELL_WIDTH][CELL_HEIGHT];

void init(); //initializes some vars
void tick(); //tick function
void stepFoward(); //moves Snake foward
void faceTo(int dir); //alters which direction Snake is faced
void eat(); //eats the apple
void draw(); //renders (or at least tries) to render the snake

int getLength(){
return length;
};

int getFacing(){
return facing;
};
} Snake;

class Food {
Uint8 color[3] = {0x85,0x22,0x10}; //RGB color of the Apple
bool visible = true;

public:
int x = 2;
int y = 2;

void respawn();
void destroy();
void draw();
} Food;

void Food::respawn(){
//teleports the apple to a random spot
x = rand() % (CELL_WIDTH-2);
y = rand() % (CELL_HEIGHT-2);
visible = true;
}

void Food::destroy(){
//Reset values
x = 0;
y = 0;
visible = false;

//resets
respawn();
}

void Food::draw(){
if(visible){
SDL_Rect rect = {x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_RenderFillRect(gRenderer, &rect);
}
}

void Snake::init(){
//Spawns in a vertical line
for(int i=0; i<length; i++){
body[x][y+i] = length-i;
}
}

void Snake::tick(){
if(stepFramesRemaining > 0){
stepFramesRemaining--;
} else {
//when 0, moves the snake
stepFramesRemaining = stepDelay;

stepFoward();
}
}

void Snake::eat(){

//increases the body size by 1
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
body[j][i]++;
}
}
}
length++;

if(stepDelay > minStepDelay){
stepDelay -= stepDelayReduction;
}

Food.destroy();
}

void Snake::draw(){
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_Rect rect = {0,0,0,0}; //for later use

//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}

void Snake::stepFoward(){
int headMoved = 0; //informs if the head already moved

//decreases the "body" lifespan and moves head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
//Verifica se é a cabeça, para movê-la logo em seguida
if(body[j][i] == length && headMoved < 2){
//moves head position, looping if needed
switch(facing){
case DIR_UP:
if(y == 0){
body[x][CELL_HEIGHT-1] = length;
y = CELL_HEIGHT-1;
} else {
body[x][y-1] = length;
y--;
}
break;
case DIR_DOWN:
if(y == CELL_HEIGHT-2){
body[x][0] = length+1; //(+1 to avoid being subtracted twice)
y = 0;
} else {
body[x][y+1] = length+1;
y++;
}
break;
case DIR_LEFT:
if(x == 0){
body[CELL_WIDTH-1][y] = length;
x = CELL_WIDTH-1;
} else {
body[x-1][y] = length;
x--;
}
break;
case DIR_RIGHT:
if(x == CELL_WIDTH-2){
body[0][y] = length+1; //avoiding again the "-2" subtraction.
x = 0;
} else {
body[x+1][y] = length+1;
x++;
}
break;
}

headMoved++;
}
body[j][i]--; //decreases the "body" lifespan
}
}
}

//verifies if can eat (head in the same position as the apple)
if(x == Food.x && y == Food.y){
eat();
}
}

void Snake::faceTo(int dir){
facing = dir;
}

void init();

void close();

void init(){ //Initializes the game
gWindow = SDL_CreateWindow("· Snake ·", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if( gRenderer == NULL ){
printf( "Renderer could not be created! SDL Error: %sn", SDL_GetError() );
}

int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
cout << "IMG INIT error!" << endl;
}

loadMedia();
Snake.init();
}

void close(){ //Closes the program
SDL_DestroyTexture(spriteSheet);
spriteSheet = NULL;
SDL_DestroyRenderer(gRenderer);
gRenderer = NULL;

IMG_Quit();
SDL_Quit();
}

void loadTexture(string path){ //Almost the same function from LazyFoo tutorial
//The final texture
SDL_Texture* newTexture = NULL;

//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError() );
}
else
{
//Color key image
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0xff, 0x00, 0xff));

//Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface);
if( newTexture == NULL ){
printf( "Unable to create texture from %s! SDL Error: %sn", path.c_str(), SDL_GetError() );
}

//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}

spriteSheet = newTexture;
}

void loadMedia(){ //loads everything (it will load sound too, when i make the sounds of course)
loadTexture("spritesheet.png");
if(spriteSheet == NULL){
cout << "ERRO" << endl;
}
}

void tick(){
Snake.tick();
}

void draw(){ //Render Function
//Background
SDL_SetRenderDrawColor(gRenderer, 0xee, 0xf2, 0xf0, 0xff);
SDL_RenderClear(gRenderer);

Snake.draw();
Food.draw();

//Aplica as alterações
SDL_RenderPresent(gRenderer);
}

int main(){
srand (time (NULL));
init();

bool quit = false;
SDL_Event e; //Event Handling
while(!quit){
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
} else if(e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_UP:
Snake.faceTo(Snake.DIR_UP);
break;
case SDLK_DOWN:
Snake.faceTo(Snake.DIR_DOWN);
break;
case SDLK_LEFT:
Snake.faceTo(Snake.DIR_LEFT);
break;
case SDLK_RIGHT:
Snake.faceTo(Snake.DIR_RIGHT);
break;
}
}
}

//Tick function
tick();

//Renders everything
draw();

SDL_RenderCopy(gRenderer, spriteSheet, NULL, NULL);

//Slows down the program just a bit (its not a time based frame system... yet)
SDL_Delay(3);
}

close(); //ends
return 0;
}


The portion of code who should be working, but isn't:



//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}









share|improve this question


















  • 2





    In second if branch you RenderCopy and then immediately FillRect to the same rectangle, overwriting image result with fixed colour. And then doing that again outside of branch.

    – keltar
    Nov 28 '18 at 5:02











  • Thanks! It partially worked.

    – Bruno Peres
    Nov 29 '18 at 19:27
















1















I'm trying to make a simple Snake game. The self collision and a lot of things aren't ready. The problem is: Even with no errors, running just fine, changing "close()" to "endGame()" and reverting, rebuilding the entire program, i could not render anything with SDL_RenderCopy. You will see many unnecessary things in my code and some Brazilian-Portuguese comments, prepare yourself.



The image is a 16x16 png spritesheet, using the color #ff00ff as ColorKey. There are only 4 sprites in this spritesheet, respectively: Apple, Snake's Body, Snake's Head and Snake's Tail (still unused).



Whole code:



#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

using namespace std;

const int CELL_SIZE = 16;
const int CELL_WIDTH = 16;
const int CELL_HEIGHT = 16;
const int SCREEN_WIDTH = CELL_SIZE * (CELL_WIDTH-1);
const int SCREEN_HEIGHT = CELL_SIZE * (CELL_HEIGHT-1);

SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;

void loadTexture(string path);

SDL_Texture* spriteSheet = NULL;

void loadMedia();
void init();


class Snake {
int initialLength = 3; //from body (head incluse)
int length = initialLength;
int facing = DIR_UP;

//Head position in CELLS (multiplied for CELL_SIZE when drawed)
int x = 5;
int y = 5;

//UNUSED TEMPORARY COLORS - IGNORE
Uint8 color[3] = {0x22,0x88,0x44}; //Snake Color, em RGB
Uint8 headColor[3] = {0x11,0x44,0x44}; //Color for the Head of the Snek

int stepDelay = 60; //time in frames that the Snakes waits till move
int stepFramesRemaining = stepDelay;
int stepDelayReduction = 1; //reduces stepDelay every time the Snakes eats the apple
const int minStepDelay = 15; //the minimum delay

//For clipping the image (its an 16x16 png image)
const SDL_Rect clipHead = {0,8,8,8};
const SDL_Rect clipBody = {8,0,8,8};
const SDL_Rect clipTail = {8,8,8,8};

public:
enum direction { //direções nas quais a cobra pode se mover
DIR_UP,
DIR_RIGHT,
DIR_DOWN,
DIR_LEFT
};

/* The following var stores the entire Snake's body in an 2D Array. The number stored means how much "steps" it will survive.
When the value is zero, it means that there is no body in the place. The bodypart with value equivalent to "length" is the Head.
*/
int body[CELL_WIDTH][CELL_HEIGHT];

void init(); //initializes some vars
void tick(); //tick function
void stepFoward(); //moves Snake foward
void faceTo(int dir); //alters which direction Snake is faced
void eat(); //eats the apple
void draw(); //renders (or at least tries) to render the snake

int getLength(){
return length;
};

int getFacing(){
return facing;
};
} Snake;

class Food {
Uint8 color[3] = {0x85,0x22,0x10}; //RGB color of the Apple
bool visible = true;

public:
int x = 2;
int y = 2;

void respawn();
void destroy();
void draw();
} Food;

void Food::respawn(){
//teleports the apple to a random spot
x = rand() % (CELL_WIDTH-2);
y = rand() % (CELL_HEIGHT-2);
visible = true;
}

void Food::destroy(){
//Reset values
x = 0;
y = 0;
visible = false;

//resets
respawn();
}

void Food::draw(){
if(visible){
SDL_Rect rect = {x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_RenderFillRect(gRenderer, &rect);
}
}

void Snake::init(){
//Spawns in a vertical line
for(int i=0; i<length; i++){
body[x][y+i] = length-i;
}
}

void Snake::tick(){
if(stepFramesRemaining > 0){
stepFramesRemaining--;
} else {
//when 0, moves the snake
stepFramesRemaining = stepDelay;

stepFoward();
}
}

void Snake::eat(){

//increases the body size by 1
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
body[j][i]++;
}
}
}
length++;

if(stepDelay > minStepDelay){
stepDelay -= stepDelayReduction;
}

Food.destroy();
}

void Snake::draw(){
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_Rect rect = {0,0,0,0}; //for later use

//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}

void Snake::stepFoward(){
int headMoved = 0; //informs if the head already moved

//decreases the "body" lifespan and moves head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
//Verifica se é a cabeça, para movê-la logo em seguida
if(body[j][i] == length && headMoved < 2){
//moves head position, looping if needed
switch(facing){
case DIR_UP:
if(y == 0){
body[x][CELL_HEIGHT-1] = length;
y = CELL_HEIGHT-1;
} else {
body[x][y-1] = length;
y--;
}
break;
case DIR_DOWN:
if(y == CELL_HEIGHT-2){
body[x][0] = length+1; //(+1 to avoid being subtracted twice)
y = 0;
} else {
body[x][y+1] = length+1;
y++;
}
break;
case DIR_LEFT:
if(x == 0){
body[CELL_WIDTH-1][y] = length;
x = CELL_WIDTH-1;
} else {
body[x-1][y] = length;
x--;
}
break;
case DIR_RIGHT:
if(x == CELL_WIDTH-2){
body[0][y] = length+1; //avoiding again the "-2" subtraction.
x = 0;
} else {
body[x+1][y] = length+1;
x++;
}
break;
}

headMoved++;
}
body[j][i]--; //decreases the "body" lifespan
}
}
}

//verifies if can eat (head in the same position as the apple)
if(x == Food.x && y == Food.y){
eat();
}
}

void Snake::faceTo(int dir){
facing = dir;
}

void init();

void close();

void init(){ //Initializes the game
gWindow = SDL_CreateWindow("· Snake ·", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if( gRenderer == NULL ){
printf( "Renderer could not be created! SDL Error: %sn", SDL_GetError() );
}

int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
cout << "IMG INIT error!" << endl;
}

loadMedia();
Snake.init();
}

void close(){ //Closes the program
SDL_DestroyTexture(spriteSheet);
spriteSheet = NULL;
SDL_DestroyRenderer(gRenderer);
gRenderer = NULL;

IMG_Quit();
SDL_Quit();
}

void loadTexture(string path){ //Almost the same function from LazyFoo tutorial
//The final texture
SDL_Texture* newTexture = NULL;

//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError() );
}
else
{
//Color key image
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0xff, 0x00, 0xff));

//Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface);
if( newTexture == NULL ){
printf( "Unable to create texture from %s! SDL Error: %sn", path.c_str(), SDL_GetError() );
}

//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}

spriteSheet = newTexture;
}

void loadMedia(){ //loads everything (it will load sound too, when i make the sounds of course)
loadTexture("spritesheet.png");
if(spriteSheet == NULL){
cout << "ERRO" << endl;
}
}

void tick(){
Snake.tick();
}

void draw(){ //Render Function
//Background
SDL_SetRenderDrawColor(gRenderer, 0xee, 0xf2, 0xf0, 0xff);
SDL_RenderClear(gRenderer);

Snake.draw();
Food.draw();

//Aplica as alterações
SDL_RenderPresent(gRenderer);
}

int main(){
srand (time (NULL));
init();

bool quit = false;
SDL_Event e; //Event Handling
while(!quit){
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
} else if(e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_UP:
Snake.faceTo(Snake.DIR_UP);
break;
case SDLK_DOWN:
Snake.faceTo(Snake.DIR_DOWN);
break;
case SDLK_LEFT:
Snake.faceTo(Snake.DIR_LEFT);
break;
case SDLK_RIGHT:
Snake.faceTo(Snake.DIR_RIGHT);
break;
}
}
}

//Tick function
tick();

//Renders everything
draw();

SDL_RenderCopy(gRenderer, spriteSheet, NULL, NULL);

//Slows down the program just a bit (its not a time based frame system... yet)
SDL_Delay(3);
}

close(); //ends
return 0;
}


The portion of code who should be working, but isn't:



//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}









share|improve this question


















  • 2





    In second if branch you RenderCopy and then immediately FillRect to the same rectangle, overwriting image result with fixed colour. And then doing that again outside of branch.

    – keltar
    Nov 28 '18 at 5:02











  • Thanks! It partially worked.

    – Bruno Peres
    Nov 29 '18 at 19:27














1












1








1








I'm trying to make a simple Snake game. The self collision and a lot of things aren't ready. The problem is: Even with no errors, running just fine, changing "close()" to "endGame()" and reverting, rebuilding the entire program, i could not render anything with SDL_RenderCopy. You will see many unnecessary things in my code and some Brazilian-Portuguese comments, prepare yourself.



The image is a 16x16 png spritesheet, using the color #ff00ff as ColorKey. There are only 4 sprites in this spritesheet, respectively: Apple, Snake's Body, Snake's Head and Snake's Tail (still unused).



Whole code:



#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

using namespace std;

const int CELL_SIZE = 16;
const int CELL_WIDTH = 16;
const int CELL_HEIGHT = 16;
const int SCREEN_WIDTH = CELL_SIZE * (CELL_WIDTH-1);
const int SCREEN_HEIGHT = CELL_SIZE * (CELL_HEIGHT-1);

SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;

void loadTexture(string path);

SDL_Texture* spriteSheet = NULL;

void loadMedia();
void init();


class Snake {
int initialLength = 3; //from body (head incluse)
int length = initialLength;
int facing = DIR_UP;

//Head position in CELLS (multiplied for CELL_SIZE when drawed)
int x = 5;
int y = 5;

//UNUSED TEMPORARY COLORS - IGNORE
Uint8 color[3] = {0x22,0x88,0x44}; //Snake Color, em RGB
Uint8 headColor[3] = {0x11,0x44,0x44}; //Color for the Head of the Snek

int stepDelay = 60; //time in frames that the Snakes waits till move
int stepFramesRemaining = stepDelay;
int stepDelayReduction = 1; //reduces stepDelay every time the Snakes eats the apple
const int minStepDelay = 15; //the minimum delay

//For clipping the image (its an 16x16 png image)
const SDL_Rect clipHead = {0,8,8,8};
const SDL_Rect clipBody = {8,0,8,8};
const SDL_Rect clipTail = {8,8,8,8};

public:
enum direction { //direções nas quais a cobra pode se mover
DIR_UP,
DIR_RIGHT,
DIR_DOWN,
DIR_LEFT
};

/* The following var stores the entire Snake's body in an 2D Array. The number stored means how much "steps" it will survive.
When the value is zero, it means that there is no body in the place. The bodypart with value equivalent to "length" is the Head.
*/
int body[CELL_WIDTH][CELL_HEIGHT];

void init(); //initializes some vars
void tick(); //tick function
void stepFoward(); //moves Snake foward
void faceTo(int dir); //alters which direction Snake is faced
void eat(); //eats the apple
void draw(); //renders (or at least tries) to render the snake

int getLength(){
return length;
};

int getFacing(){
return facing;
};
} Snake;

class Food {
Uint8 color[3] = {0x85,0x22,0x10}; //RGB color of the Apple
bool visible = true;

public:
int x = 2;
int y = 2;

void respawn();
void destroy();
void draw();
} Food;

void Food::respawn(){
//teleports the apple to a random spot
x = rand() % (CELL_WIDTH-2);
y = rand() % (CELL_HEIGHT-2);
visible = true;
}

void Food::destroy(){
//Reset values
x = 0;
y = 0;
visible = false;

//resets
respawn();
}

void Food::draw(){
if(visible){
SDL_Rect rect = {x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_RenderFillRect(gRenderer, &rect);
}
}

void Snake::init(){
//Spawns in a vertical line
for(int i=0; i<length; i++){
body[x][y+i] = length-i;
}
}

void Snake::tick(){
if(stepFramesRemaining > 0){
stepFramesRemaining--;
} else {
//when 0, moves the snake
stepFramesRemaining = stepDelay;

stepFoward();
}
}

void Snake::eat(){

//increases the body size by 1
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
body[j][i]++;
}
}
}
length++;

if(stepDelay > minStepDelay){
stepDelay -= stepDelayReduction;
}

Food.destroy();
}

void Snake::draw(){
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_Rect rect = {0,0,0,0}; //for later use

//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}

void Snake::stepFoward(){
int headMoved = 0; //informs if the head already moved

//decreases the "body" lifespan and moves head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
//Verifica se é a cabeça, para movê-la logo em seguida
if(body[j][i] == length && headMoved < 2){
//moves head position, looping if needed
switch(facing){
case DIR_UP:
if(y == 0){
body[x][CELL_HEIGHT-1] = length;
y = CELL_HEIGHT-1;
} else {
body[x][y-1] = length;
y--;
}
break;
case DIR_DOWN:
if(y == CELL_HEIGHT-2){
body[x][0] = length+1; //(+1 to avoid being subtracted twice)
y = 0;
} else {
body[x][y+1] = length+1;
y++;
}
break;
case DIR_LEFT:
if(x == 0){
body[CELL_WIDTH-1][y] = length;
x = CELL_WIDTH-1;
} else {
body[x-1][y] = length;
x--;
}
break;
case DIR_RIGHT:
if(x == CELL_WIDTH-2){
body[0][y] = length+1; //avoiding again the "-2" subtraction.
x = 0;
} else {
body[x+1][y] = length+1;
x++;
}
break;
}

headMoved++;
}
body[j][i]--; //decreases the "body" lifespan
}
}
}

//verifies if can eat (head in the same position as the apple)
if(x == Food.x && y == Food.y){
eat();
}
}

void Snake::faceTo(int dir){
facing = dir;
}

void init();

void close();

void init(){ //Initializes the game
gWindow = SDL_CreateWindow("· Snake ·", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if( gRenderer == NULL ){
printf( "Renderer could not be created! SDL Error: %sn", SDL_GetError() );
}

int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
cout << "IMG INIT error!" << endl;
}

loadMedia();
Snake.init();
}

void close(){ //Closes the program
SDL_DestroyTexture(spriteSheet);
spriteSheet = NULL;
SDL_DestroyRenderer(gRenderer);
gRenderer = NULL;

IMG_Quit();
SDL_Quit();
}

void loadTexture(string path){ //Almost the same function from LazyFoo tutorial
//The final texture
SDL_Texture* newTexture = NULL;

//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError() );
}
else
{
//Color key image
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0xff, 0x00, 0xff));

//Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface);
if( newTexture == NULL ){
printf( "Unable to create texture from %s! SDL Error: %sn", path.c_str(), SDL_GetError() );
}

//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}

spriteSheet = newTexture;
}

void loadMedia(){ //loads everything (it will load sound too, when i make the sounds of course)
loadTexture("spritesheet.png");
if(spriteSheet == NULL){
cout << "ERRO" << endl;
}
}

void tick(){
Snake.tick();
}

void draw(){ //Render Function
//Background
SDL_SetRenderDrawColor(gRenderer, 0xee, 0xf2, 0xf0, 0xff);
SDL_RenderClear(gRenderer);

Snake.draw();
Food.draw();

//Aplica as alterações
SDL_RenderPresent(gRenderer);
}

int main(){
srand (time (NULL));
init();

bool quit = false;
SDL_Event e; //Event Handling
while(!quit){
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
} else if(e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_UP:
Snake.faceTo(Snake.DIR_UP);
break;
case SDLK_DOWN:
Snake.faceTo(Snake.DIR_DOWN);
break;
case SDLK_LEFT:
Snake.faceTo(Snake.DIR_LEFT);
break;
case SDLK_RIGHT:
Snake.faceTo(Snake.DIR_RIGHT);
break;
}
}
}

//Tick function
tick();

//Renders everything
draw();

SDL_RenderCopy(gRenderer, spriteSheet, NULL, NULL);

//Slows down the program just a bit (its not a time based frame system... yet)
SDL_Delay(3);
}

close(); //ends
return 0;
}


The portion of code who should be working, but isn't:



//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}









share|improve this question














I'm trying to make a simple Snake game. The self collision and a lot of things aren't ready. The problem is: Even with no errors, running just fine, changing "close()" to "endGame()" and reverting, rebuilding the entire program, i could not render anything with SDL_RenderCopy. You will see many unnecessary things in my code and some Brazilian-Portuguese comments, prepare yourself.



The image is a 16x16 png spritesheet, using the color #ff00ff as ColorKey. There are only 4 sprites in this spritesheet, respectively: Apple, Snake's Body, Snake's Head and Snake's Tail (still unused).



Whole code:



#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

using namespace std;

const int CELL_SIZE = 16;
const int CELL_WIDTH = 16;
const int CELL_HEIGHT = 16;
const int SCREEN_WIDTH = CELL_SIZE * (CELL_WIDTH-1);
const int SCREEN_HEIGHT = CELL_SIZE * (CELL_HEIGHT-1);

SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;

void loadTexture(string path);

SDL_Texture* spriteSheet = NULL;

void loadMedia();
void init();


class Snake {
int initialLength = 3; //from body (head incluse)
int length = initialLength;
int facing = DIR_UP;

//Head position in CELLS (multiplied for CELL_SIZE when drawed)
int x = 5;
int y = 5;

//UNUSED TEMPORARY COLORS - IGNORE
Uint8 color[3] = {0x22,0x88,0x44}; //Snake Color, em RGB
Uint8 headColor[3] = {0x11,0x44,0x44}; //Color for the Head of the Snek

int stepDelay = 60; //time in frames that the Snakes waits till move
int stepFramesRemaining = stepDelay;
int stepDelayReduction = 1; //reduces stepDelay every time the Snakes eats the apple
const int minStepDelay = 15; //the minimum delay

//For clipping the image (its an 16x16 png image)
const SDL_Rect clipHead = {0,8,8,8};
const SDL_Rect clipBody = {8,0,8,8};
const SDL_Rect clipTail = {8,8,8,8};

public:
enum direction { //direções nas quais a cobra pode se mover
DIR_UP,
DIR_RIGHT,
DIR_DOWN,
DIR_LEFT
};

/* The following var stores the entire Snake's body in an 2D Array. The number stored means how much "steps" it will survive.
When the value is zero, it means that there is no body in the place. The bodypart with value equivalent to "length" is the Head.
*/
int body[CELL_WIDTH][CELL_HEIGHT];

void init(); //initializes some vars
void tick(); //tick function
void stepFoward(); //moves Snake foward
void faceTo(int dir); //alters which direction Snake is faced
void eat(); //eats the apple
void draw(); //renders (or at least tries) to render the snake

int getLength(){
return length;
};

int getFacing(){
return facing;
};
} Snake;

class Food {
Uint8 color[3] = {0x85,0x22,0x10}; //RGB color of the Apple
bool visible = true;

public:
int x = 2;
int y = 2;

void respawn();
void destroy();
void draw();
} Food;

void Food::respawn(){
//teleports the apple to a random spot
x = rand() % (CELL_WIDTH-2);
y = rand() % (CELL_HEIGHT-2);
visible = true;
}

void Food::destroy(){
//Reset values
x = 0;
y = 0;
visible = false;

//resets
respawn();
}

void Food::draw(){
if(visible){
SDL_Rect rect = {x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_RenderFillRect(gRenderer, &rect);
}
}

void Snake::init(){
//Spawns in a vertical line
for(int i=0; i<length; i++){
body[x][y+i] = length-i;
}
}

void Snake::tick(){
if(stepFramesRemaining > 0){
stepFramesRemaining--;
} else {
//when 0, moves the snake
stepFramesRemaining = stepDelay;

stepFoward();
}
}

void Snake::eat(){

//increases the body size by 1
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
body[j][i]++;
}
}
}
length++;

if(stepDelay > minStepDelay){
stepDelay -= stepDelayReduction;
}

Food.destroy();
}

void Snake::draw(){
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_Rect rect = {0,0,0,0}; //for later use

//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}

void Snake::stepFoward(){
int headMoved = 0; //informs if the head already moved

//decreases the "body" lifespan and moves head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
//Verifica se é a cabeça, para movê-la logo em seguida
if(body[j][i] == length && headMoved < 2){
//moves head position, looping if needed
switch(facing){
case DIR_UP:
if(y == 0){
body[x][CELL_HEIGHT-1] = length;
y = CELL_HEIGHT-1;
} else {
body[x][y-1] = length;
y--;
}
break;
case DIR_DOWN:
if(y == CELL_HEIGHT-2){
body[x][0] = length+1; //(+1 to avoid being subtracted twice)
y = 0;
} else {
body[x][y+1] = length+1;
y++;
}
break;
case DIR_LEFT:
if(x == 0){
body[CELL_WIDTH-1][y] = length;
x = CELL_WIDTH-1;
} else {
body[x-1][y] = length;
x--;
}
break;
case DIR_RIGHT:
if(x == CELL_WIDTH-2){
body[0][y] = length+1; //avoiding again the "-2" subtraction.
x = 0;
} else {
body[x+1][y] = length+1;
x++;
}
break;
}

headMoved++;
}
body[j][i]--; //decreases the "body" lifespan
}
}
}

//verifies if can eat (head in the same position as the apple)
if(x == Food.x && y == Food.y){
eat();
}
}

void Snake::faceTo(int dir){
facing = dir;
}

void init();

void close();

void init(){ //Initializes the game
gWindow = SDL_CreateWindow("· Snake ·", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if( gRenderer == NULL ){
printf( "Renderer could not be created! SDL Error: %sn", SDL_GetError() );
}

int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
cout << "IMG INIT error!" << endl;
}

loadMedia();
Snake.init();
}

void close(){ //Closes the program
SDL_DestroyTexture(spriteSheet);
spriteSheet = NULL;
SDL_DestroyRenderer(gRenderer);
gRenderer = NULL;

IMG_Quit();
SDL_Quit();
}

void loadTexture(string path){ //Almost the same function from LazyFoo tutorial
//The final texture
SDL_Texture* newTexture = NULL;

//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError() );
}
else
{
//Color key image
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0xff, 0x00, 0xff));

//Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface);
if( newTexture == NULL ){
printf( "Unable to create texture from %s! SDL Error: %sn", path.c_str(), SDL_GetError() );
}

//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}

spriteSheet = newTexture;
}

void loadMedia(){ //loads everything (it will load sound too, when i make the sounds of course)
loadTexture("spritesheet.png");
if(spriteSheet == NULL){
cout << "ERRO" << endl;
}
}

void tick(){
Snake.tick();
}

void draw(){ //Render Function
//Background
SDL_SetRenderDrawColor(gRenderer, 0xee, 0xf2, 0xf0, 0xff);
SDL_RenderClear(gRenderer);

Snake.draw();
Food.draw();

//Aplica as alterações
SDL_RenderPresent(gRenderer);
}

int main(){
srand (time (NULL));
init();

bool quit = false;
SDL_Event e; //Event Handling
while(!quit){
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
} else if(e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_UP:
Snake.faceTo(Snake.DIR_UP);
break;
case SDLK_DOWN:
Snake.faceTo(Snake.DIR_DOWN);
break;
case SDLK_LEFT:
Snake.faceTo(Snake.DIR_LEFT);
break;
case SDLK_RIGHT:
Snake.faceTo(Snake.DIR_RIGHT);
break;
}
}
}

//Tick function
tick();

//Renders everything
draw();

SDL_RenderCopy(gRenderer, spriteSheet, NULL, NULL);

//Slows down the program just a bit (its not a time based frame system... yet)
SDL_Delay(3);
}

close(); //ends
return 0;
}


The portion of code who should be working, but isn't:



//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};

SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);

SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);

} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);

SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);

SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}

SDL_RenderFillRect(gRenderer,&rect);
}
}

//SDL_RenderFillRect(gRenderer,&rect);
}






c++ textures sdl-2 renderer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 28 '18 at 2:29









Bruno PeresBruno Peres

61




61








  • 2





    In second if branch you RenderCopy and then immediately FillRect to the same rectangle, overwriting image result with fixed colour. And then doing that again outside of branch.

    – keltar
    Nov 28 '18 at 5:02











  • Thanks! It partially worked.

    – Bruno Peres
    Nov 29 '18 at 19:27














  • 2





    In second if branch you RenderCopy and then immediately FillRect to the same rectangle, overwriting image result with fixed colour. And then doing that again outside of branch.

    – keltar
    Nov 28 '18 at 5:02











  • Thanks! It partially worked.

    – Bruno Peres
    Nov 29 '18 at 19:27








2




2





In second if branch you RenderCopy and then immediately FillRect to the same rectangle, overwriting image result with fixed colour. And then doing that again outside of branch.

– keltar
Nov 28 '18 at 5:02





In second if branch you RenderCopy and then immediately FillRect to the same rectangle, overwriting image result with fixed colour. And then doing that again outside of branch.

– keltar
Nov 28 '18 at 5:02













Thanks! It partially worked.

– Bruno Peres
Nov 29 '18 at 19:27





Thanks! It partially worked.

– Bruno Peres
Nov 29 '18 at 19:27












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53511230%2fsdl-rendercopy-not-rendering-isnt-null-none-sdl-img-error-too%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53511230%2fsdl-rendercopy-not-rendering-isnt-null-none-sdl-img-error-too%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)