-
Notifications
You must be signed in to change notification settings - Fork 2
Screen.h and .cpp
Hannupekka Sormunen edited this page Dec 11, 2018
·
12 revisions
//Header guards for SCREEN_H_
#ifndef SCREEN_H_
#define SCREEN_H
//Include C++ system libraries
#include <fstream>
#include <sstream>
#include <string>
//Include other libraries
#include <SDL.h>
//Create a namespace for this the use of this class
namespace particlefire {
//Create a class Screen inside namespace ParticleFire.
class Screen {
//Private data members of a Screen-class:
private:
SDL_Window *m_window;
SDL_Renderer *m_renderer;
SDL_Texture *m_texture;
Uint32 *m_buffer;
//Protected data members of a Screen-class:
protected:
static int screen_width_;
static int screen_height_;
static unsigned int target_fps_;
//Public data members of a Screen-class:
public:
//Constructors and destructor of a Screen-class:
public:
Screen();//Constructor for Screen-class
~Screen();//Destructor is used to deallocate processes and variables stored in to heap
//Private data methods of a Screen-class:
private:
bool ReadConfig();//Method for getting settings from a file
//Public data methods of a Screen-class:
public:
bool Init();//Method for initializing SDL-library. Returns true(1) if init was successful, else false(0)
void UpdateScreen();//Method for updating the window
void SetPixel(int x, int y, Uint8 red, Uint8 green, Uint8 blue);//Method for setting pixel value on the screen
void ApplyBoxBlur();//Method for blurring the particles
bool ProcessEvents();//Method for event processing
void LimitFPS(int elapsed);//Method for limiting frames per second(FPS)
};
} /* end of namespace ParticleFire */
#endif /* SCREEN_H */ Screen::Screen() :m_window(NULL), m_renderer(NULL), m_texture(NULL), m_buffer(NULL) {
//Constructor initializition list is used to set data members to NULL, otherwise SDL can't inform of failure or success when SDL instances are called.
//Call ReadConfig data method to get settings from the config.cfg-file
ReadConfig();
//Allocate pixel buffer arrays in to heap-memory so that they can be accessed throught the program
m_buffer = new Uint32[screen_width_*screen_height_];
}//Method for getting settings from a file
bool Screen::ReadConfig() {
//Access the file "config.cfg" and store it's position to variable file
std::ifstream file("config.cfg");
//Variable where to save each line of the file
std::string line;
//Variables for storing the values from file
int screen_width(0);
int screen_height(0);
int target_fps(0);
//Loop that goes throught the file line by line
while (std::getline(file, line)) {
std::istringstream sin(line.substr(line.find("=") + 1));
//If any of the following text snippets are found from the file these if-else statements are true and values are saved to variables
if (line.find("#") != -1) {
//do nothing, since lines starting with #-character are ignored
}
else if (line.find("SCREEN_WIDTH") != -1) {
sin >> screen_width;
}
else if (line.find("SCREEN_HEIGHT") != -1) {
sin >> screen_height;
}
else if (line.find("TARGET_FPS") != -1) {
sin >> target_fps;
}
}
//Check that the values from the file are greater than zero
if (screen_width > 0 && screen_height > 0 && target_fps > 0) {
//Save values to data members
screen_width_ = screen_width;
screen_height_ = screen_height;
target_fps_ = target_fps;
//Close the file "config.cfg"
file.close();
}
//If values are negative or zero file is closed and function returns false.
else {
//Close the file "config.cfg"
file.close();
return false;
}
return true;
}//Method for initializing SDL-library. Returns true(1) if init was successful, else false(0)
bool Screen::Init() {
//Checks if SDL video initialization works, which returns value zero if everything is ok. Otherwise prints out error message from SDL_GetError() and returns false
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
return false;
}
//This function is used to create a window with the specified position, dimensions, and flags. It is using predefined pointer m_window of Screen-class
m_window = SDL_CreateWindow(
"The Particle Fire Simulation", //Title of the window
SDL_WINDOWPOS_CENTERED, //The position of the window on x-axis
SDL_WINDOWPOS_CENTERED, //The position of the window on y-axis
screen_width_, // the width of the window in pixels
screen_height_, // the height of the window in pixels
//Both height and width are defined in class as constant static data members
SDL_WINDOW_SHOWN); //The final argument is for flags see SDL wiki for more info.
//Checks if SDL window initialization works, which returns value NULL if there was an error and prints out error message from SDL_GetError(). Returns false before shutting down the SDL-process
if (m_window == NULL) {
SDL_Log("Unable to initialize SDL window: %s", SDL_GetError());
SDL_Quit();
return false;
}
//This function is used to create a 2D rendering context for a window
m_renderer = SDL_CreateRenderer(
m_window, //the window where rendering is displayed, in this case pointer called m_window.
-1, //the index of the rendering driver to initialize, or -1 to initialize the first one supporting the requested flags
SDL_RENDERER_ACCELERATED); //flags see SDL wiki for more info. Basically makes the program use hardware graphics rendering instead of software
//Checks if SDL renderer initialization works, which returns value NULL if there was an error and prints out error message from SDL_GetError(). Returns false before shutting down SDL-process.
if (m_renderer == NULL) {
SDL_Log("Unable to initialize SDL renderer: %s", SDL_GetError());
SDL_DestroyWindow(m_window);
SDL_Quit();
return false;
}
//This function is used to create a texture for a rendering context.
m_texture = SDL_CreateTexture(
m_renderer,//renderer, The rendering context, where the texture is added on, meaning this case m_renderer-pointer,
SDL_PIXELFORMAT_RGB888,//format, one of the enumerated values in SDL_PixelFormatEnum; see Remarks for details. This uses one byte (255 in decimal) for each pixel
SDL_TEXTUREACCESS_STREAMING,//access, one of the enumerated values in SDL_TextureAccess; see Remarks for details in the SDL wiki
screen_width_,//the width of the texture in pixels
screen_height_);//the height of the texture in pixels
//Checks if SDL texture initialization works, which returns value NULL if there was an error and prints out error message from SDL_GetError().
//Returns false after shutting down SDL-processes.
if (m_texture == NULL) {
SDL_Log("Unable to initialize SDL texture: %s", SDL_GetError());
SDL_DestroyWindow(m_window);
SDL_DestroyRenderer(m_renderer);
SDL_Quit();
return false;
}
//If everything was initialized correctly return 1
return true;
} //Method for setting pixel value on the screen
void Screen::SetPixel(int x, int y, Uint8 red, Uint8 green, Uint8 blue) {
//Check if pixels that is about the be set is out of range of resolution
if (x < 1 || x >= screen_width_ - 1 || y < 1 || y >= screen_height_ - 1) {
return;
}
//Initialize the 8 byte integer variable with zero value
Uint32 color(0);
//Setting up the red channel with value and shifting two bytes forward in variable to access different color
color += red;
color <<= 8;
//Setting up the green channel with value and shifting two bytes forward in variable to access different color
color += green;
color <<= 8;
//Setting up the blue channel with value, no need to shift bits anymore
color += blue;
//Setting value in the buffer, to get to right pixel y must be multiplied with SCREEN_WIDTH so that the y-axis moves down to correct row
//and then add x (column value) how far right we have to go from the left.
//With resolution 800x600 On the first run the value is 0 + 0 so the top leftmost pixel. After 800 runs value is 0 + 800 so the to rightmost pixel.
//Then the second row starts updating.
m_buffer[(y * screen_width_) + x] = color;
}