From 3804b57d27bd67ab1b7d1a6e5b4ce0b75ba97bcb Mon Sep 17 00:00:00 2001 From: Benedict Gaster <benedict.gaster@gmail.com> Date: Fri, 27 Nov 2020 22:42:37 +0000 Subject: [PATCH] added beginnings of context --- .gitignore | 1 + include/graphics.hpp | 38 +++++++++++++ src/graphics.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 .gitignore create mode 100644 include/graphics.hpp create mode 100644 src/graphics.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f8305e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +a.out \ No newline at end of file diff --git a/include/graphics.hpp b/include/graphics.hpp new file mode 100644 index 0000000..de445fa --- /dev/null +++ b/include/graphics.hpp @@ -0,0 +1,38 @@ +/** + * + * \author Benedict R. Gaster + */ +#pragma once + +#include <vector> + +#include <SDL2/SDL.h> + +namespace uwe { + class Context { + public: + /** \brief Create a context + * \param width an integer setting the window width + * \param height an integer setting the window height + */ + Context(int width, int height); + ~Context(); + + /// Output details of GPU backend and texture formats + void dump_renderer_info(); + + /// run the control loop, returns only when user exits + void run(); + private: + int height_; ///< window height + int width_; ///< window width + int tex_width_; ///< texture width + int tex_height_; ///< texture height + SDL_Window* window_; ///< window handle + SDL_Renderer* renderer_; ///< graphics backend handle + SDL_Texture* texture_; ///< pixel buffer texture handle + + std::vector< uint8_t > pixels_; ///< pixels representing framebuffer + }; +} + diff --git a/src/graphics.cpp b/src/graphics.cpp new file mode 100644 index 0000000..e4501d1 --- /dev/null +++ b/src/graphics.cpp @@ -0,0 +1,133 @@ +#include <iostream> + +#include <graphics.hpp> +#include <iomanip> +#include <cstring> + +namespace uwe { + + Context::Context(int width, int height) : + width_{width}, + height_{height}, + tex_width_{width}, + tex_height_{height}, + pixels_(tex_width_ * tex_height_ * 4, 0) { + SDL_Init( SDL_INIT_EVERYTHING ); + + window_ = SDL_CreateWindow( + "SDL2", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width_, height_, + SDL_WINDOW_SHOWN); + + renderer_ = SDL_CreateRenderer( + window_, + -1, + SDL_RENDERER_ACCELERATED); + + texture_ = SDL_CreateTexture( + renderer_, + SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + tex_width_, + tex_height_); + } + + Context::~Context() { + SDL_DestroyRenderer( renderer_ ); + SDL_DestroyWindow( window_ ); + SDL_Quit(); + } + + void Context::run() { + SDL_Event event; + bool running = true; + bool useLocktexture = false; + + unsigned int frames = 0; + Uint64 start = SDL_GetPerformanceCounter(); + + while( running ) + { + + SDL_SetRenderDrawColor( renderer_, 0, 0, 0, SDL_ALPHA_OPAQUE ); + SDL_RenderClear( renderer_ ); + + while( SDL_PollEvent( &event ) ) { + if( ( SDL_QUIT == event.type ) || + ( SDL_KEYDOWN == event.type && SDL_SCANCODE_ESCAPE == event.key.keysym.scancode ) ) + { + running = false; + break; + } + if( SDL_KEYDOWN == event.type && SDL_SCANCODE_L == event.key.keysym.scancode ) + { + useLocktexture = !useLocktexture; + std::cout << "Using " << ( useLocktexture ? "SDL_LockTexture() + memcpy()" : "SDL_UpdateTexture()" ) << std::endl; + } + } + + // splat down some random pixels + for( unsigned int i = 0; i < 1000; i++ ) { + const unsigned int x = rand() % tex_width_; + const unsigned int y = rand() % tex_height_; + + const unsigned int offset = ( tex_width_ * 4 * y ) + x * 4; + pixels_[ offset + 0 ] = rand() % 256; // b + pixels_[ offset + 1 ] = rand() % 256; // g + pixels_[ offset + 2 ] = rand() % 256; // r + pixels_[ offset + 3 ] = SDL_ALPHA_OPAQUE; // a + } + + if( useLocktexture ) { + unsigned char* lockedPixels = nullptr; + int pitch = 0; + SDL_LockTexture( + texture_, + NULL, + reinterpret_cast< void** >( &lockedPixels ), + &pitch + ); + std::memcpy( lockedPixels, pixels_.data(), pixels_.size() ); + SDL_UnlockTexture( texture_ ); + } + else { + SDL_UpdateTexture( + texture_, + NULL, + pixels_.data(), + tex_width_ * 4); + } + + SDL_RenderCopy( renderer_, texture_, NULL, NULL ); + SDL_RenderPresent( renderer_ ); + + frames++; + const uint64_t end = SDL_GetPerformanceCounter(); + const static uint64_t freq = SDL_GetPerformanceFrequency(); + const double seconds = ( end - start ) / static_cast< double >( freq ); + if( seconds > 2.0 ) + { + std::cout + << frames << " frames in " + << std::setprecision(1) << std::fixed << seconds << " seconds = " + << std::setprecision(1) << std::fixed << frames / seconds << " FPS (" + << std::setprecision(3) << std::fixed << ( seconds * 1000.0 ) / frames << " ms/frame)" + << std::endl; + start = end; + frames = 0; + } + } + + } + + void Context::dump_renderer_info() { + SDL_RendererInfo info; + SDL_GetRendererInfo( renderer_, &info ); + std::cout << "Renderer name: " << info.name << std::endl; + std::cout << "Texture formats: " << std::endl; + for( uint32_t i = 0; i < info.num_texture_formats; i++ ) { + std::cout << SDL_GetPixelFormatName( info.texture_formats[i] ) << std::endl; + } + } +} \ No newline at end of file -- GitLab