Skip to content
Snippets Groups Projects
Commit 0074e862 authored by Joakim Hunskaar's avatar Joakim Hunskaar
Browse files

More descriptive variable names and proper error handling for software rendering

parent d6ef6031
No related branches found
No related tags found
1 merge request!4Software render
......@@ -51,7 +51,7 @@ class AnimationWindow {
bool keepPreviousFrame = false;
bool closeRequested = false;
bool render=false;
bool isSoftwareRenderer = false;
std::vector<std::reference_wrapper<TDT4102::Widget>> widgets;
......@@ -60,7 +60,7 @@ class AnimationWindow {
// SDL related context
SDL_Window* windowHandle = nullptr;
SDL_Renderer* rendererHandle = nullptr;
SDL_Surface* surf;
SDL_Surface* screenshotSurface = nullptr;
// Nuklear related context
nk_context* context = nullptr;
......@@ -75,7 +75,7 @@ class AnimationWindow {
public:
explicit AnimationWindow(int x = 50, int y = 50, int width = 1024, int height = 768, const std::string& title = "Animation Window", bool softwareRender = false);
explicit AnimationWindow(int x = 50, int y = 50, int width = 1024, int height = 768, const std::string& title = "Animation Window", bool useSoftwareRenderer = false);
~AnimationWindow();
void screenshot(std::string name);
void simulateClickAtPoint(TDT4102::Point p);
......
......@@ -23,7 +23,7 @@
static bool sdlHasBeenInitialised = false;
TDT4102::AnimationWindow::AnimationWindow(int x, int y, int width, int height, const std::string& title, bool softwareRender) {
TDT4102::AnimationWindow::AnimationWindow(int x, int y, int width, int height, const std::string& title, bool useSoftwareRenderer) {
// Initialise SDL if it has not already been
if (!sdlHasBeenInitialised) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
......@@ -32,10 +32,14 @@ TDT4102::AnimationWindow::AnimationWindow(int x, int y, int width, int height, c
sdlHasBeenInitialised = true;
}
// Open a new window
if (softwareRender){
render=true;
surf = SDL_CreateRGBSurface(0, width, height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
rendererHandle = SDL_CreateSoftwareRenderer(surf);
if (useSoftwareRenderer) {
isSoftwareRenderer = true;
screenshotSurface = SDL_CreateRGBSurface(0, width, height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
if (screenshotSurface == nullptr) {
throw std::runtime_error("Failed to create an AnimationWindow: The SDL backend could not create a RGB Surface.\nError details: " + std::string(SDL_GetError()));
}
// Create a software renderer
rendererHandle = SDL_CreateSoftwareRenderer(screenshotSurface);
}
else{
windowHandle = SDL_CreateWindow(
......@@ -43,6 +47,7 @@ TDT4102::AnimationWindow::AnimationWindow(int x, int y, int width, int height, c
if (windowHandle == nullptr) {
throw std::runtime_error("Failed to create an AnimationWindow: The SDL backend could not open a new window.\nError details: " + std::string(SDL_GetError()));
}
// Create a window renderer
rendererHandle = SDL_CreateRenderer(windowHandle, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
}
......@@ -52,9 +57,6 @@ TDT4102::AnimationWindow::AnimationWindow(int x, int y, int width, int height, c
// Create a renderer
// Default window background colour
SDL_SetRenderDrawColor(rendererHandle, backgroundColour.redChannel, backgroundColour.greenChannel, backgroundColour.blueChannel, backgroundColour.alphaChannel);
SDL_RenderClear(rendererHandle);
......@@ -64,7 +66,7 @@ TDT4102::AnimationWindow::AnimationWindow(int x, int y, int width, int height, c
std::cout << "Created an SDL renderer with name: " << rendererInfo.name << std::endl;
context = nk_sdl_init(softwareRender ? nullptr:windowHandle, rendererHandle);
context = nk_sdl_init(isSoftwareRenderer ? nullptr : windowHandle, rendererHandle);
fontCache.initialise();
fontCache.setFont(context, Font::defaultFont, 18);
nk_clear(context);
......@@ -88,6 +90,10 @@ void TDT4102::AnimationWindow::destroy() {
nk_free(context);
context = nullptr;
}
if (screenshotSurface != nullptr) {
SDL_FreeSurface(screenshotSurface);
screenshotSurface = nullptr;
}
}
void TDT4102::AnimationWindow::show_frame() {
......@@ -153,16 +159,16 @@ void TDT4102::AnimationWindow::next_frame() {
void TDT4102::AnimationWindow::screenshot(std::string name){
if (!render){
std::cout << "screenshot only works in software render mode" << std::endl;
return;
if (!isSoftwareRenderer){
throw std::runtime_error("Screenshot utility only works in software render mode");
}
update_gui();
nk_sdl_render(NK_ANTI_ALIASING_ON);
std::cout<<"screenshot"<<std::endl;
TDT4102::Point windowDimensions = getWindowDimensions();
unsigned error = lodepng::encode("screenshot_"+name+".png", reinterpret_cast<const unsigned char*>(surf->pixels), static_cast<unsigned>(windowDimensions.x), static_cast<unsigned>(windowDimensions.y));
if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
unsigned int error = lodepng::encode("screenshot_"+name+".png", reinterpret_cast<const unsigned char*>(screenshotSurface->pixels), static_cast<unsigned int>(windowDimensions.x), static_cast<unsigned int>(windowDimensions.y));
if (error) {
throw std::runtime_error("Lodepng: Failed to encode, error code " + std::to_string(error) + ":\n" + std::string((lodepng_error_text(error))));
}
std::string content = "";
for (Widget& widget : widgets){
......@@ -183,15 +189,15 @@ void TDT4102::AnimationWindow::screenshot(std::string name){
}
void TDT4102::AnimationWindow::simulateClickAtPoint(TDT4102::Point p){
std::cout<<"pressPoint"<<std::endl;
int posx=p.x;
int posy=p.y;
int xPos = p.x;
int yPos = p.y;
SDL_Event event;
event.type = SDL_MOUSEBUTTONDOWN;
event.button.button = SDL_BUTTON_LEFT;
event.button.state = SDL_PRESSED;
event.button.x = posx;
event.button.y = posy;
event.button.x = xPos;
event.button.y = yPos;
SDL_PushEvent(&event);
next_frame();
event.type = SDL_MOUSEBUTTONUP;
......@@ -202,17 +208,15 @@ void TDT4102::AnimationWindow::simulateClickAtPoint(TDT4102::Point p){
}
void TDT4102::AnimationWindow::simulateClickOnWidget(int n){
std::cout<<"pressKey"<<std::endl;
int posx=widgets.at(n).get().position.x+20;
int posy=widgets.at(n).get().position.y+5;
int xPos = widgets.at(n).get().position.x+20;
int yPos = widgets.at(n).get().position.y+5;
SDL_Event event;
event.type = SDL_MOUSEBUTTONDOWN;
event.button.button = SDL_BUTTON_LEFT;
event.button.state = SDL_PRESSED;
event.button.x = posx;
event.button.y = posy;
event.button.x = xPos;
event.button.y = yPos;
SDL_PushEvent(&event);
next_frame();
event.type = SDL_MOUSEBUTTONUP;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment