Advertisement

SDL_FillRect doing nothing in Mac OS X environment

Started by November 28, 2017 01:38 AM
1 comment, last by aganm 6 years, 11 months ago

SDL isn't drawing any rectangles to the window in a Mac OS X environment, and I have no idea why. I've tried in both a Windows and an Ubuntu environment, and the rectangles are being drawn in those environments. I'm using SDL by using frameworks. This is what I write into the terminal:

g++ example.cpp -I/Library/Frameworks/SDL2.framework/Headers -F/Library/Frameworks -framework SDL2

This is the actual code of the program:


	#include <SDL2/SDL.h>
#include <iostream>
#include <stdio.h>
	const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int PLAYER_WIDTH = 20;
const int PLAYER_HEIGHT = 20;
SDL_Window* w = NULL;
SDL_Surface* s = NULL;
SDL_Renderer* r = NULL;
SDL_Rect BG = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
	 
	bool init() {
	    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Couldn't initialize. error: %s\n", SDL_GetError() );
        return false;
    } else {
	        w = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
	
        if(w == NULL) {
            printf("Couldn't make window. error:%s\n", SDL_GetError() );
            return false;
        } else {
            s = SDL_GetWindowSurface(w);
            r = SDL_CreateRenderer(w,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
            SDL_SetRenderDrawColor(r,0,0,0,0);
            return true;
        }
	    }
	}
	void close() {
    SDL_FreeSurface(s);
    SDL_DestroyWindow(w);
    SDL_DestroyRenderer(r);
    SDL_Quit();
	}
	class Player {
	    private:
        int x;
        int y;
        int xvel;
        int yvel;
        int acceleration;
        SDL_Rect collider;
	
    public:
	        bool landed;
	        Player() {
            x = 0;
            y = SCREEN_HEIGHT - PLAYER_HEIGHT;
            xvel = 0;
            yvel = 0;
            acceleration = -1;
            collider.x = x;
            collider.y = y;
            collider.w = PLAYER_WIDTH;
            collider.h = PLAYER_HEIGHT;            
            landed = true;
        }
	        int getx() {
            return x;
        }
	        int gety() {
            return y;
        }
	        void setx(int num) {
            x = num;
        }
	        void sety(int num) {
            y = num;
        }
	        void setyvel(int num) {
            yvel += num;
        }
	        void setxvel(int num) {
            xvel += num;
        }
	        void move() {
            x += xvel;
	            if( (y + PLAYER_HEIGHT) > SCREEN_HEIGHT) {
                
                y = SCREEN_HEIGHT - PLAYER_HEIGHT;
                yvel = 0;
                landed = true;
	            } else {
                if(landed != true) { //so sorry for the bad code, this was the only idea i had to debug "bouncing" of the player
                    y += yvel;
                    yvel = yvel - acceleration;
                }
                
            }
	            
            collider.x = x;
            collider.y = y;
        }
	        void render() {
            SDL_SetRenderDrawColor(r,255,255,255,255);
            SDL_RenderFillRect(r,&collider);
            SDL_SetRenderDrawColor(r,0,0,0,255);
        }
};
	
int main(int argc, char *argv[]) {
	bool quit = false;
SDL_Event e; //event for event polling
Player p;
int count = 0;
	    if(init() == false) {
	        printf("Init failed: %s\n", SDL_GetError());
	    } else {
        while(quit == false ) {
            while( SDL_PollEvent(&e) != 0) {
	                if(e.type == SDL_QUIT) {
                    quit = true;
                }
	
                
                if(e.type == SDL_KEYDOWN) {
	                    switch(e.key.keysym.sym) {
	                        case SDLK_LEFT: if(e.key.repeat == 0) { p.setxvel(-10); }
                        break;
	                        case SDLK_RIGHT: if(e.key.repeat == 0) { p.setxvel(10); }
                        break;
	                        case SDLK_UP:
	                        if(count < 5) {
                            p.setyvel(-3);
                            ++count;
                            }
                            p.landed = false;
                        
                        break;
	                    }
	                }
	                
	                if(e.type == SDL_KEYUP && e.key.repeat == 0) {
	                    switch(e.key.keysym.sym) {
	                        case SDLK_LEFT: p.setxvel(10);
                        break;
	                        case SDLK_RIGHT: p.setxvel(-10);
                        break;
	                        case SDLK_UP: count = 0;
                        break;
	                    }
	                }
	                
	            }
	            SDL_RenderClear(r);
            SDL_RenderFillRect(r,&BG);
            p.move();
            p.render();
            
	            SDL_RenderPresent(r);
        }
    }
	    close();

Please help me to get it working, I have no idea what's going on. I have SDL 2.0.7 and my Mac is OS X 10.10.3.

The problem is caused by a line in the init function. Remove the following line and it will work.


s = SDL_GetWindowSurface(w);

This happens because this function initialises the window to be used in blit mode. The documentation states that you can either use Blit mode or the SDL renderer, you can't use both.

Quote

A new surface will be created with the optimal format for the window, if necessary. [...] You may not combine this (the blit mode) with 3D or the rendering API on this window. (https://wiki.libsdl.org/SDL_GetWindowSurface)

You missed the error because you did not check the return value of the next line.


r = SDL_CreateRenderer(w,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

If you call SDL_GetError, you get:


Renderer already associated with window

This means that the window already has a renderer and you cannot create another one for it. This is because the blit mode creates his own renderer internally. The blit mode is deprecated, still available for backwards compatibility.

This topic is closed to new replies.

Advertisement