Skip to content

Screen.h and .cpp

Hannupekka Sormunen edited this page Dec 11, 2018 · 12 revisions

Screen.h

//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 */

Constructor

	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_];
	}

ReadConfig

//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;
	}

Init()

//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;
	}

Clone this wiki locally