Trying to draw a rectangle with inherited class


#1

I am trying to draw a rectangle in an inherited class. If I try to do it inside my Screen class, it works flawlessly. But as soon as I put the code in my Gamefield class, it does not draw the rectangle anymore. What is the problem with my code?

Test.cpp

#include "SDL.h"
#include <iostream>
#include "Screen.h"
#include "Gamefield.h"

int main(int argc, char* argv[]){
  
  Screen screen;
  if(!screen.init("Das ist ein Fenster", 1024, 768)){
    return 1;
  }

  SDL_Event e;
  Gamefield field;
  while(true){
    field.drawGamefield();
    if(SDL_PollEvent(&e)){
      if(e.type == SDL_QUIT){
        break;
      }
    }
    screen.clear();
  }
  screen.close();
  return 0;
}

Screen.h

#pragma once

#include "SDL.h"
#include <iostream>

class Screen{
public:
  Screen(){};
  ~Screen(){};
  bool init(std::string name, int width, int height);
  void update();  
  void close();
  void clear();

private:
  SDL_Window*   m_pWindow   = nullptr;

  
protected:
  SDL_Renderer* m_pRenderer = nullptr;

  int m_screen_width;
  int m_screen_height;
  int m_pixel_size{16};
};

Screen.cpp

#include "Screen.h"
#include <iostream>

bool Screen::init(std::string name, int width, int height){
  if(SDL_Init(SDL_INIT_VIDEO) < 0){
    std::cout << "Can't init SDL\n";
    return false;
  }

  m_pWindow = SDL_CreateWindow(name.c_str(),
                               SDL_WINDOWPOS_UNDEFINED,
                               SDL_WINDOWPOS_UNDEFINED,
                               width,
                               height,
                               0);
  if(m_pWindow == nullptr){
    std::cout << "Can't create Window\n";
    SDL_Quit();
    return false;
  }

  m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
  if(m_pRenderer == nullptr){
    std::cout << "Can't create Renderer\n";
    SDL_DestroyWindow(m_pWindow);
    SDL_Quit();
    return false;
  }
  m_screen_width  = width;
  m_screen_height = height;

  return true;
}

void Screen::clear(){

  SDL_Rect rect = {100,100, 500, 500};

  SDL_SetRenderDrawColor(m_pRenderer, 0xFF, 0x00, 0x00, 0xFF);
  SDL_RenderDrawRect(m_pRenderer, &rect);
  
  SDL_RenderPresent(m_pRenderer);
  SDL_SetRenderDrawColor(m_pRenderer, 0,0,0,255);
  SDL_RenderClear(m_pRenderer);
}

void Screen::close(){
  SDL_DestroyWindow(m_pWindow);
  SDL_DestroyRenderer(m_pRenderer);
}

Gamefield.h

#pragma once

#include "Screen.h"

class Gamefield : Screen{

public:
void drawGamefield();

};

Gamefield.cpp

#include "Gamefield.h"

void Gamefield::drawGamefield(){
  SDL_Rect rect = {200,200, 500, 500};

  SDL_SetRenderDrawColor(m_pRenderer, 0xFF, 0x00, 0x00, 0xFF);
  SDL_RenderDrawRect(m_pRenderer, &rect);
  
  SDL_RenderPresent(m_pRenderer);
  SDL_SetRenderDrawColor(m_pRenderer, 0,0,0,255);
  SDL_RenderClear(m_pRenderer);
}

#2

Screen and GameField Screen are two seperate objects.

You will need to call all the functions such as init etc from gamefield and not screen.


#3

The SDL_Renderer pointer that the Gamefield class is inheriting from the Screen class is nullptr, which means that whenever any SDL_* specific function is called in Gamefield::drawGamefield(), nothing is called and nothing is rendered. If you were to do some error checking inside that function, after each function call, you would actually get an error message (from SDL_GetError()) saying “Invalid renderer”.
The Screen class is initializing/creating its own SDL_Renderer* instance, which is initialized/created inside the init() function.
There’s clearly some design issues in your code, since the two classes has their own SDL_Renderer* instances and I’m not really sure why the Gamefield class are even inheriting from the Screen class. The best choice to get around the renderer problem is probably to let the Screen class handle the rendering. By this, I mean that, whenever the Gamefield class is gonna call any SDL_* specific function, the Gamefied is calling, for example, Screen::clear() to clear the window, Screen::DrawRect() to render the quad and then finally Screen::present() to update the screen, effectively rendering the quad to the window. The Screen class are then calling all the SDL_* specific functions, with its own SDL_Renderer* instance, basically working like an SDL wrapper class.