Framebuffer rendering not workin but all the code is there, need to fix KHR for debug output

This commit is contained in:
Ben Kyd
2020-01-15 16:05:04 +00:00
parent b7c6f69ff9
commit 083c93926f
8 changed files with 218 additions and 54 deletions

View File

@@ -1,9 +1,13 @@
#version 450 core
#version 430
out vec4 outColour;
out vec4 FragColour;
in vec2 fTextCoord;
void main() {
uniform sampler2D iTexture;
outColour = vec4(.9, .9, .9, 1);
}
void main()
{
FragColour = texture(iTexture, fTextCoord);
// FragColour = vec4( 1.0, .0, .0, 1.0); // texture(iTexture, fTextCoord);
}

View File

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

View File

@@ -66,6 +66,16 @@ void FrameBuffer::DumpToFile( std::string file )
free( imageData );
}
int FrameBuffer::GetWidth()
{
return mWidth;
}
int FrameBuffer::GetHeight()
{
return mHeight;
}
FrameBuffer::~FrameBuffer()
{
free( Data );

View File

@@ -16,6 +16,9 @@ public:
void DumpToFile( std::string file );
int GetWidth();
int GetHeight();
uint32_t* Data;
~FrameBuffer();

View File

@@ -21,6 +21,21 @@ struct Game
SDL_GLContext GlContext = nullptr;
};
void GLAPIENTRY
MessageCallback( GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam )
{
std::cout << "GL CALLBACK: type = " << type
<< ", severity = " << severity
<< ", message = " << message << std::endl;
}
int main()
{
@@ -59,12 +74,20 @@ int main()
// Time to actually load OpenGL
gladLoadGLLoader( SDL_GL_GetProcAddress );
glEnable( GL_DEBUG_OUTPUT );
glDebugMessageCallback( MessageCallback, 0 );
Renderer renderer;
renderer.LoadShader();
FrameBuffer framebuffer{ game.Width, game.Height };
framebuffer.SetPixel( 1, 1, { 1.0, 0.0, 0.0 } );
framebuffer.DumpToFile( "image.png" );
framebuffer.SetPixel( 2, 1, { 1.0, 0.0, 0.0 } );
framebuffer.SetPixel( 3, 1, { 1.0, 0.0, 0.0 } );
framebuffer.SetPixel( 4, 1, { 1.0, 0.0, 0.0 } );
framebuffer.SetPixel( 5, 1, { 1.0, 0.0, 0.0 } );
renderer.RegisterBuffer( &framebuffer, 0 );
SDL_Event e;
const float clearColour[] = { 186.0f / 255.0f, 214.0f / 255.0f, 254.0f / 255.0f };
@@ -78,6 +101,8 @@ int main()
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClearBufferfv( GL_COLOR, 0, clearColour );
renderer.Render();
SDL_GL_SwapWindow( game.Window );
}

View File

@@ -1,10 +1,21 @@
#include "renderer.hpp"
#include "framebuffer.hpp"
#include <iostream>
Renderer::Renderer()
: mFileReader()
{
// So DrawElements works, EBO can be lost as it should remain bound
GLuint indices[] = {
0, 1, 3, 1, 2, 3
};
glGenBuffers( 1, &mEBO );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mEBO );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mEBO );
}
@@ -18,12 +29,13 @@ bool checkShader( GLuint uid ) {
char buf[512];
glGetShaderInfoLog( uid, 512, NULL, buf );
std::cout << "ERROR: " << buf << std::endl;
delete buf;
// buf gets leaked here but it was crashing
// the program so i removed the delete
return false;
}
return true;
}
}
void Renderer::LoadShader()
@@ -31,60 +43,143 @@ 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 );
mLoad( vertexLocation, GL_VERTEX_SHADER );
std::cout << "Vertex shader at '" << vertexLocation << "' loaded..." << std::endl;
std::string fragmentLocation = path + ".frag";
Load( fragmentLocation, GL_FRAGMENT_SHADER );
mLoad( fragmentLocation, GL_FRAGMENT_SHADER );
std::cout << "Fragment shader at '" << fragmentLocation << "' loaded..." << std::endl;
if ( vert == 0 || frag == 0 ) {
if ( mVert == 0 || mFrag == 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( mVert );
if ( checkShader( mVert ) ) {
std::cout << "Vertex shader '" << mVert << "' compiled..." << std::endl;
}
glCompileShader( frag );
if ( checkShader( frag ) ) {
std::cout << "Fragment shader '" << frag << "' compiled..." << std::endl;
glCompileShader( mFrag );
if ( checkShader( mFrag ) ) {
std::cout << "Fragment shader '" << mFrag << "' compiled..." << std::endl;
}
mShaderProgram = glCreateProgram();
glAttachShader( mShaderProgram, vert );
glAttachShader( mShaderProgram, frag );
glAttachShader( mShaderProgram, mVert );
glAttachShader( mShaderProgram, mFrag );
glLinkProgram( mShaderProgram );
glDeleteShader( vert );
glDeleteShader( frag );
glDeleteShader( mVert );
glDeleteShader( mFrag );
glUseProgram( mShaderProgram );
}
void Renderer::mLoad( std::string path, GLenum type )
{
GLuint activeShader = 0;
if ( type == GL_VERTEX_SHADER )
mVert = activeShader = glCreateShader( type );
if ( type == GL_FRAGMENT_SHADER )
mFrag = activeShader = glCreateShader( type );
std::string loadedShaderSource = mFileReader.LoadTextFromFile( path );
const char* shaderSource = loadedShaderSource.c_str();
GLint shaderSourceLength = loadedShaderSource.length();
glShaderSource( activeShader, 1, &shaderSource, &shaderSourceLength );
}
int8_t Renderer::RegisterBuffer( FrameBuffer* buffer, int layer )
{
if ( buffer == nullptr )
return -1;
// Load buffer as a texture into OpenGL
GLuint texture;
glGenTextures( 1, &texture );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, buffer->GetWidth(), buffer->GetHeight(), 0, GL_RGB, GL_RGBA32UI, buffer->Data );
FrameBufferRenderable fb =
{
buffer,
texture,
layer,
{
// positions // texture coords
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
}
};
glGenVertexArrays( 1, &fb.VAO );
glBindVertexArray( fb.VAO );
glGenBuffers( 1, &fb.VBO );
glBindBuffer( GL_ARRAY_BUFFER, fb.VBO );
glBufferData( GL_ARRAY_BUFFER, 20 * sizeof( float ), &fb.QuadVerts, GL_STATIC_DRAW );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), (void*)( 0 * sizeof( float ) ) );
glEnableVertexAttribArray( 1 );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), (void*)( 3 * sizeof( float ) ) );
glBindVertexArray( 0 );
mRenderQueue.push_back( fb );
return mRenderQueue.size();
}
FrameBuffer* Renderer::GetBuffer( int8_t id )
{
return mRenderQueue[id].Buffer;
}
void Renderer::UpdateBuffer( int8_t id )
{
if ( id > mRenderQueue.size() )
return;
FrameBuffer* buffer = mRenderQueue[id].Buffer;
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, buffer->GetWidth(), buffer->GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, buffer->Data );
}
void Renderer::Render()
{
glUseProgram( mShaderProgram );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mEBO );
for ( size_t i = 0; i < mRenderQueue.size(); i++ )
{
FrameBufferRenderable* fb = &mRenderQueue[i];
glBindTexture( GL_TEXTURE_2D, fb->TextureID );
glBindVertexArray( fb->VAO );
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );
}
}
Renderer::~Renderer()
{
glDeleteProgram( mShaderProgram );
glDeleteShader( mVert );
glDeleteShader( mFrag );
}

View File

@@ -7,11 +7,17 @@
class FrameBuffer;
// 3 * 4 each corner vert
// 2 * 4 each corner text
#define FRAMEBUFFER_VERTS 20
struct FrameBufferRenderable
{
FrameBuffer* Buffer;
GLuint TextureID;
int Layer;
float QuadVerts[20];
GLuint VAO; GLuint VBO;
};
class Renderer
@@ -21,13 +27,34 @@ public:
void LoadShader();
void RegisterBuffer( FrameBuffer* buffer, int layer );
// Callee retains ownership of framebuffer
// Returns buffer ID
int8_t RegisterBuffer( FrameBuffer* buffer, int layer );
FrameBuffer* GetBuffer( int8_t ID );
// Re-uploads buffer to GPU
void UpdateBuffer( int8_t ID );
void Render();
~Renderer();
private:
// On insertion is sorted by layer
// TODO: Render by layers
// reverse referenced lists might be useful
// to retain ID but update render queues position
std::vector<FrameBufferRenderable> mRenderQueue;
FileReader mFileReader;
// GL Shaders
void mLoad( std::string path, GLenum type );
// Used once, are invalid after LoadShader call
GLuint mVert, mFrag;
GLuint mShaderProgram;
GLuint mEBO;
};

View File

@@ -1,5 +1,6 @@
#include "filereader.hpp"
#include <iostream>
#include <fstream>
FileReader::FileReader()
@@ -12,5 +13,6 @@ std::string FileReader::LoadTextFromFile( std::string path )
std::ifstream t( path );
std::string text( ( std::istreambuf_iterator<char>( t ) ),
std::istreambuf_iterator<char>() );
text += "\0";
return text;
}