This commit is contained in:
Ben Kyd
2020-01-14 16:57:08 +00:00
parent e8c82af202
commit ed5e264b0c
13 changed files with 1993 additions and 66 deletions

View File

@@ -1,19 +0,0 @@
#pragma once
//#include <glad/glad.hpp>
class FrameBuffer
{
public:
FrameBuffer();
// Renders with OpenGL as a texture
void Render();
uint32_t data;
};

72
src/framebuffer.cpp Normal file
View File

@@ -0,0 +1,72 @@
#include "framebuffer.hpp"
#include <memory>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "thirdparty/stb_image_write.h"
FrameBuffer::FrameBuffer( int width, int height )
: mWidth(width)
, mHeight(height)
{
size_t size = sizeof( uint32_t ) * mWidth * mHeight;
Data = (uint32_t*)malloc( size );
// Initialise the framebuffer
if ( Data != nullptr )
memset( Data, 0xFFFFFFFF, size );
}
void FrameBuffer::SetPixel( int x, int y, glm::vec3 p )
{
int i = y * mWidth + x;
const static float gamma = 1.0f / 2.2f;
uint8_t r = (uint8_t)( pow( p.r, gamma ) * 255.0f );
uint8_t g = (uint8_t)( pow( p.g, gamma ) * 255.0f );
uint8_t b = (uint8_t)( pow( p.b, gamma ) * 255.0f );
uint32_t col = 0xFF000000 | r << 16 | g << 8 | b;
Data[i] = col;
}
void FrameBuffer::Resize( int width, int height )
{
mWidth = width; mHeight = height;
size_t size = sizeof( uint32_t ) * mWidth * mHeight;
realloc( Data, size );
memset( Data, 0xFFFFFFFF, size );
}
void FrameBuffer::DumpToFile( std::string file )
{
// int stbi_write_png(char const* filename, int w, int h, int comp, const void* data, int stride_in_bytes);
struct P {
unsigned char r, g, b, a;
};
P* imageData = (P*)malloc( ( (int)mWidth * (int)mHeight ) * sizeof( P ) );
for ( int x = 0; x < mWidth; x++ )
for ( int y = 0; y < mHeight; y++ ) {
// Red and Blue channels need to be swapped, no clue why
// saving the framebuffer just doesnt work
uint32_t pixel = Data[y * mWidth + x];
uint8_t er = ( pixel & 0x000000FF );
uint8_t eg = ( pixel & 0x0000FF00 ) >> 8;
uint8_t eb = ( pixel & 0x00FF0000 ) >> 16;
uint8_t ea = ( pixel & 0xFF000000 ) >> 24;
imageData[y * mWidth + x] = P{ (unsigned char)eb, (unsigned char)eg, (unsigned char)er, (unsigned char)ea };
}
stbi_write_png( file.c_str(), mWidth, mHeight, sizeof( P ), imageData, sizeof( P ) * mWidth );
free( imageData );
}
FrameBuffer::~FrameBuffer()
{
free( Data );
}

27
src/framebuffer.hpp Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#include <string>
#include <glm/glm.hpp>
class FrameBuffer
{
public:
FrameBuffer( int width, int height );
void SetPixel( int x, int y, glm::vec3 col );
// Will clear the framebuffers current state
void Resize( int width, int height );
void DumpToFile( std::string file );
uint32_t* Data;
~FrameBuffer();
private:
int mWidth, mHeight;
};

View File

@@ -9,90 +9,105 @@
#include <SDL2/SDL.h>
#endif
void doInput(SDL_Event* e, bool& isWindowOpen);
#include "renderer.hpp"
#include "framebuffer.hpp"
void doInput( SDL_Event* e, bool& isWindowOpen );
struct Game
{
int Width, Height;
SDL_Window* Window = nullptr;
SDL_GLContext GlContext = nullptr;
int Width, Height;
SDL_Window* Window = nullptr;
SDL_GLContext GlContext = nullptr;
};
int main()
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Init( SDL_INIT_VIDEO );
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE, 32 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
Game game;
game.Width = 1000; game.Height = 1000;
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 4 );
game.Window = SDL_CreateWindow("2D Global Illumination",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
game.Width, game.Height,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
Game game;
game.Width = 700; game.Height = 700;
game.GlContext = SDL_GL_CreateContext(game.Window);
game.Window = SDL_CreateWindow( "2D Global Illumination",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
game.Width, game.Height,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
// Vsync
SDL_GL_SetSwapInterval(1);
game.GlContext = SDL_GL_CreateContext( game.Window );
// Time to actually load OpenGL
gladLoadGLLoader(SDL_GL_GetProcAddress);
if ( !game.GlContext )
{
std::cout << SDL_GetError() << std::endl;
exit( 0 );
}
// Vsync
SDL_GL_SetSwapInterval( 1 );
SDL_Event e;
const float clearColour[] = { 186.0f / 255.0f, 214.0f / 255.0f, 254.0f / 255.0f };
// Time to actually load OpenGL
gladLoadGLLoader( SDL_GL_GetProcAddress );
bool IsWindowOpen = true;
while (IsWindowOpen)
{
Renderer renderer;
renderer.LoadShader();
doInput(&e, IsWindowOpen);
FrameBuffer framebuffer{ game.Width, game.Height };
framebuffer.SetPixel( 1, 1, { 1.0, 0.0, 0.0 } );
framebuffer.DumpToFile( "image.png" );
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearBufferfv(GL_COLOR, 0, clearColour);
SDL_Event e;
const float clearColour[] = { 186.0f / 255.0f, 214.0f / 255.0f, 254.0f / 255.0f };
SDL_GL_SwapWindow(game.Window);
bool IsWindowOpen = true;
while ( IsWindowOpen )
{
}
doInput( &e, IsWindowOpen );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClearBufferfv( GL_COLOR, 0, clearColour );
SDL_GL_SwapWindow( game.Window );
}
return 0;
}
void doInput(SDL_Event* e, bool& isWindowOpen)
void doInput( SDL_Event* e, bool& isWindowOpen )
{
Uint8* state = (Uint8*)SDL_GetKeyboardState(NULL);
Uint8* state = (Uint8*)SDL_GetKeyboardState( NULL );
static bool IsMouseActive = false;
static bool IsMouseActive = false;
while (SDL_PollEvent(e)) {
while ( SDL_PollEvent( e ) ) {
switch (e->type) {
switch ( e->type ) {
case SDL_KEYDOWN:
{
if (e->key.keysym.sym == SDLK_ESCAPE) {
if ( e->key.keysym.sym == SDLK_ESCAPE ) {
IsMouseActive = !IsMouseActive;
if (IsMouseActive)
SDL_SetRelativeMouseMode(SDL_TRUE);
if ( IsMouseActive )
SDL_SetRelativeMouseMode( SDL_TRUE );
else
SDL_SetRelativeMouseMode(SDL_FALSE);
SDL_SetRelativeMouseMode( SDL_FALSE );
}
@@ -100,7 +115,7 @@ void doInput(SDL_Event* e, bool& isWindowOpen)
}
case SDL_QUIT:
case SDL_QUIT:
{
isWindowOpen = false;

90
src/renderer.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include "renderer.hpp"
#include <iostream>
Renderer::Renderer()
: mFileReader()
{
}
bool checkShader( GLuint uid ) {
GLint status = GL_TRUE;
glGetShaderiv( uid, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE ) {
char buf[512];
glGetShaderInfoLog( uid, 512, NULL, buf );
std::cout << "ERROR: " << buf << std::endl;
delete buf;
return false;
}
return true;
}
void Renderer::LoadShader()
{
std::string path = std::string( RESOURCES ) + "/2d";
GLuint vert, frag;
auto Load = [&]( std::string path, GLenum type )
{
GLuint activeShader = 0;
if ( type == GL_VERTEX_SHADER )
vert = activeShader = glCreateShader( type );
if ( type == GL_FRAGMENT_SHADER )
frag = activeShader = glCreateShader( type );
std::string loadedShaderSource = mFileReader.LoadTextFromFile( path );
const char* shaderSource = loadedShaderSource.c_str();
int shaderSourceLength = loadedShaderSource.length();
glShaderSource( activeShader, 1, &shaderSource, &shaderSourceLength );
};
std::string vertexLocation = path + ".vert";
Load( vertexLocation, GL_VERTEX_SHADER );
std::cout << "Vertex shader at '" << vertexLocation << "' loaded..." << std::endl;
std::string fragmentLocation = path + ".frag";
Load( fragmentLocation, GL_FRAGMENT_SHADER );
std::cout << "Fragment shader at '" << fragmentLocation << "' loaded..." << std::endl;
if ( vert == 0 || frag == 0 ) {
std::cout << "Failed to link programs: Both programs not present" << std::endl;
return;
}
glCompileShader( vert );
if ( checkShader( vert ) ) {
std::cout << "Vertex shader '" << vert << "' compiled..." << std::endl;
}
glCompileShader( frag );
if ( checkShader( frag ) ) {
std::cout << "Fragment shader '" << frag << "' compiled..." << std::endl;
}
mShaderProgram = glCreateProgram();
glAttachShader( mShaderProgram, vert );
glAttachShader( mShaderProgram, frag );
glLinkProgram( mShaderProgram );
glDeleteShader( vert );
glDeleteShader( frag );
glUseProgram( mShaderProgram );
}

33
src/renderer.hpp Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#include <glad/glad.h>
#include <vector>
#include "util/filereader.hpp"
class FrameBuffer;
struct FrameBufferRenderable
{
FrameBuffer* Buffer;
GLuint TextureID;
int Layer;
};
class Renderer
{
public:
Renderer();
void LoadShader();
void RegisterBuffer( FrameBuffer* buffer, int layer );
private:
FileReader mFileReader;
GLuint mShaderProgram;
};

1636
src/thirdparty/stb_image_write.h vendored Normal file

File diff suppressed because it is too large Load Diff

16
src/util/filereader.cpp Normal file
View File

@@ -0,0 +1,16 @@
#include "filereader.hpp"
#include <fstream>
FileReader::FileReader()
{
}
std::string FileReader::LoadTextFromFile( std::string path )
{
std::ifstream t( path );
std::string text( ( std::istreambuf_iterator<char>( t ) ),
std::istreambuf_iterator<char>() );
return text;
}

12
src/util/filereader.hpp Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <string>
class FileReader
{
public:
FileReader();
std::string LoadTextFromFile( std::string path );
};