|
|
|
@ -29,6 +29,10 @@ namespace lunarium
|
|
|
|
void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id,
|
|
|
|
void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id,
|
|
|
|
GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
|
|
|
|
GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
if (type == GL_DEBUG_TYPE_ERROR)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR, "OPENGL ERROR");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::OGL_DEBUG,
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::OGL_DEBUG,
|
|
|
|
"%s (type: %s, source: %s, severity: %s), message: %s",
|
|
|
|
"%s (type: %s, source: %s, severity: %s), message: %s",
|
|
|
|
@ -60,7 +64,6 @@ namespace lunarium
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mpWindow = pWindow;
|
|
|
|
mpWindow = pWindow;
|
|
|
|
mpFBTexture = new Image;
|
|
|
|
|
|
|
|
ResizeCanvas(); // Also calls InitTextureFrameBuffer
|
|
|
|
ResizeCanvas(); // Also calls InitTextureFrameBuffer
|
|
|
|
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
@ -100,41 +103,41 @@ namespace lunarium
|
|
|
|
|
|
|
|
|
|
|
|
void OglGraphics::Shutdown()
|
|
|
|
void OglGraphics::Shutdown()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Nothing to clean up at this point
|
|
|
|
// TODO: Clean up frame buffers
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OglGraphics::ResizeCanvas()
|
|
|
|
void OglGraphics::ResizeCanvas()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Get viewport size from glfw window
|
|
|
|
// NOTE: METHOD IS NO LONGER NEEDED
|
|
|
|
glfwGetFramebufferSize(mpWindow->GetWindow(), &mFBWidth, &mFBHeight);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glViewport(0, 0, mFBWidth, mFBHeight);
|
|
|
|
|
|
|
|
mProjection = glm::ortho(0.0f, (GLfloat)mFBWidth, (GLfloat)mFBHeight, 0.0f, -1.0f, 1.0f);
|
|
|
|
|
|
|
|
// mProjection = glm::ortho(0.0f, (GLfloat)mFBWidth, 0.0f, (GLfloat)mFBHeight, -1.0f, 1.0f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO_VERBOSE,
|
|
|
|
|
|
|
|
"glViewport set to %d, %d", mFBWidth, mFBHeight);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InitTextureFrameBuffer();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OglGraphics::BeginDraw(RenderTarget rt)
|
|
|
|
void OglGraphics::BeginDraw(int framebuffer)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
mActiveFrameBuffer = framebuffer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mActiveFrameBuffer > -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mRT = rt;
|
|
|
|
mFBWidth = mFrameBuffers[mActiveFrameBuffer]->Texture.GetWidth();
|
|
|
|
|
|
|
|
mFBHeight = mFrameBuffers[mActiveFrameBuffer]->Texture.GetHeight();
|
|
|
|
|
|
|
|
glViewport(0, 0, mFBWidth, mFBHeight);
|
|
|
|
|
|
|
|
mProjection = glm::ortho(0.0f, (GLfloat)mFBWidth, (GLfloat)mFBHeight, 0.0f, -1.0f, 1.0f);
|
|
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBuffers[mActiveFrameBuffer]->FBO);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
int width = 0, height = 0;
|
|
|
|
int width = 0, height = 0;
|
|
|
|
mpWindow->GetFramebufferSize(&width, &height);
|
|
|
|
mpWindow->GetFramebufferSize(&width, &height);
|
|
|
|
|
|
|
|
|
|
|
|
if (mFBWidth != width || mFBHeight != height)
|
|
|
|
if (mFBWidth != width || mFBHeight != height)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ResizeCanvas();
|
|
|
|
mFBWidth = width;
|
|
|
|
|
|
|
|
mFBHeight = height;
|
|
|
|
|
|
|
|
glViewport(0, 0, mFBWidth, mFBHeight);
|
|
|
|
|
|
|
|
mProjection = glm::ortho(0.0f, (GLfloat)mFBWidth, (GLfloat)mFBHeight, 0.0f, -1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (mRT == RenderTarget::RT_IMAGE)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
@ -142,27 +145,26 @@ namespace lunarium
|
|
|
|
|
|
|
|
|
|
|
|
Image* OglGraphics::EndDraw()
|
|
|
|
Image* OglGraphics::EndDraw()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (mRT == RenderTarget::RT_IMAGE)
|
|
|
|
if (mActiveFrameBuffer > -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
FrameBuffer* fb = mFrameBuffers[mActiveFrameBuffer];
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mpFBTexture->GetGLTextureID());
|
|
|
|
glBindTexture(GL_TEXTURE_2D, fb->Texture.GetGLTextureID());
|
|
|
|
|
|
|
|
|
|
|
|
// Buffer width and height (in pixels) is the same as the screen size
|
|
|
|
if (fb->Texture.GetFormat() == ImageFormat::RGBA)
|
|
|
|
// Need to multiply these by the number bytes per pixel
|
|
|
|
{
|
|
|
|
int bufferSize = mFBWidth * mFBHeight * 4; // NOTE: Assuming 4 channels for now
|
|
|
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)fb->Buffer);
|
|
|
|
// TODO: Preallocate the buffer so we don't call new every frame!
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO, "RGBA ID: %d", mActiveFrameBuffer);
|
|
|
|
unsigned char* buffer = new unsigned char[bufferSize];
|
|
|
|
}
|
|
|
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)buffer);
|
|
|
|
else if (fb->Texture.GetFormat() == ImageFormat::RGB)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)fb->Buffer);
|
|
|
|
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO, "RGB ID: %d", mActiveFrameBuffer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FlipImageVertically(buffer, mFBWidth, mFBHeight, 1);
|
|
|
|
fb->Texture.SetData(fb->Buffer);
|
|
|
|
// mpFBTexture->FreeRawData();
|
|
|
|
|
|
|
|
mpFBTexture->SetData(buffer);
|
|
|
|
|
|
|
|
mpFBTexture->SetWidth(mFBWidth);
|
|
|
|
|
|
|
|
mpFBTexture->SetHeight(mFBHeight);
|
|
|
|
|
|
|
|
mpFBTexture->SetFormat(ImageFormat::RGBA);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return a copy of the image
|
|
|
|
return &fb->Texture;
|
|
|
|
return mpFBTexture;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -188,6 +190,74 @@ namespace lunarium
|
|
|
|
return mClearColor;
|
|
|
|
return mClearColor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int OglGraphics::CreateRenderTexture(int width, int height, int channels)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
FrameBuffer* fb = new FrameBuffer;
|
|
|
|
|
|
|
|
fb->Texture.SetWidth(width);
|
|
|
|
|
|
|
|
fb->Texture.SetHeight(height);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GLint format = -1;
|
|
|
|
|
|
|
|
if (3 == channels)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fb->Texture.SetFormat(ImageFormat::RGB);
|
|
|
|
|
|
|
|
format = GL_RGB;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (4 == channels)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fb->Texture.SetFormat(ImageFormat::RGBA);
|
|
|
|
|
|
|
|
format = GL_RGBA;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR, "OglGraphics::CreateRenderTexture failed - invalid channels value: %n", channels);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Frame buffer
|
|
|
|
|
|
|
|
glGenFramebuffers(1, &fb->FBO);
|
|
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fb->FBO);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Texture
|
|
|
|
|
|
|
|
unsigned int id = -1;
|
|
|
|
|
|
|
|
glGenTextures(1, &id);
|
|
|
|
|
|
|
|
fb->Texture.SetGLTextureID(id);
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, fb->Texture.GetGLTextureID());
|
|
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
|
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Attach texture
|
|
|
|
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->Texture.GetGLTextureID(), 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Render Buffer for depth/stencil testing
|
|
|
|
|
|
|
|
glGenRenderbuffers(1, &fb->RBO);
|
|
|
|
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, fb->RBO);
|
|
|
|
|
|
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
|
|
|
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Atach the render buffer
|
|
|
|
|
|
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb->RBO);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::WARNING, "Unable to initialize framebuffer for rendering to a texture");
|
|
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// finalize the FrameBuffer object
|
|
|
|
|
|
|
|
fb->Buffer = new unsigned char[width * height * channels];
|
|
|
|
|
|
|
|
fb->Texture.SetData(nullptr);
|
|
|
|
|
|
|
|
int next_id = mFrameBuffers.size();
|
|
|
|
|
|
|
|
mFrameBuffers[next_id] = fb;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return next_id;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Draw Methods
|
|
|
|
// Draw Methods
|
|
|
|
void OglGraphics::DrawLine(glm::vec2 point1, glm::vec2 point2, Color color, float lineWidth, float angle)
|
|
|
|
void OglGraphics::DrawLine(glm::vec2 point1, glm::vec2 point2, Color color, float lineWidth, float angle)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -585,38 +655,41 @@ namespace lunarium
|
|
|
|
|
|
|
|
|
|
|
|
void OglGraphics::InitTextureFrameBuffer()
|
|
|
|
void OglGraphics::InitTextureFrameBuffer()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NOTE: METHOD IS NO LONGER NEEDED
|
|
|
|
|
|
|
|
|
|
|
|
// Frame buffer
|
|
|
|
// Frame buffer
|
|
|
|
glGenFramebuffers(1, &mFBO);
|
|
|
|
// glGenFramebuffers(1, &mFBO);
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
|
|
|
// glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
|
|
|
|
|
|
|
|
|
|
|
// Texture
|
|
|
|
// // Texture
|
|
|
|
unsigned int id = -1;
|
|
|
|
// unsigned int id = -1;
|
|
|
|
glGenTextures(1, &id);
|
|
|
|
// glGenTextures(1, &id);
|
|
|
|
mpFBTexture->SetGLTextureID(id);
|
|
|
|
// mpFBTexture->SetGLTextureID(id);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mpFBTexture->GetGLTextureID());
|
|
|
|
// glBindTexture(GL_TEXTURE_2D, mpFBTexture->GetGLTextureID());
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mFBWidth, mFBHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
|
|
|
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mFBWidth, mFBHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
// glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Attach texture
|
|
|
|
// // Attach texture
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpFBTexture->GetGLTextureID(), 0);
|
|
|
|
// glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpFBTexture->GetGLTextureID(), 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Render Buffer for depth/stencil testing
|
|
|
|
// // Render Buffer for depth/stencil testing
|
|
|
|
glGenRenderbuffers(1, &mRBO);
|
|
|
|
// glGenRenderbuffers(1, &mRBO);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, mRBO);
|
|
|
|
// glBindRenderbuffer(GL_RENDERBUFFER, mRBO);
|
|
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mFBWidth, mFBHeight);
|
|
|
|
// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mFBWidth, mFBHeight);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
|
// glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Atach the render buffer
|
|
|
|
// // Atach the render buffer
|
|
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mRBO);
|
|
|
|
// glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mRBO);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
|
|
// if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
|
|
{
|
|
|
|
// {
|
|
|
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::WARNING, "Unable to initialize framebuffer for rendering to a texture");
|
|
|
|
// Logger::Log(LogCategory::GRAPHICS, LogLevel::WARNING, "Unable to initialize framebuffer for rendering to a texture");
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|