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

@@ -44,6 +44,7 @@ include_directories(${exe}
file(GLOB src
${src}/*
${src}/util/*
${src}/thirdparty/*
)

21
LICENSE.md Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Benjamin Kyd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

9
resources/2d.frag Normal file
View File

@@ -0,0 +1,9 @@
#version 450 core
out vec4 outColour;
void main() {
outColour = vec4(.9, .9, .9, 1);
}

14
resources/2d.vert Normal file
View File

@@ -0,0 +1,14 @@
#version 450 core
layout (location = 0) in vec3 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
void main() {
gl_Position = proj * view * model * vec4(position, 1.0);
}

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