OglGraphics mostly implemented but needs testing
Fonts and text rendering not yet implementedGui_Panel_Refactor
parent
a92e55ee01
commit
2c6b8eaa4c
@ -0,0 +1,96 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - DefaultShaders.h
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2018/01/12 (y/m/d)
|
||||||
|
* Mod Date - 2018/01/12 (y/m/d)
|
||||||
|
* Description - String definitions with default shader source code.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef DEFAULT_SHADERS_H_
|
||||||
|
#define DEFAULT_SHADERS_H_
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
friend class OglGraphics;
|
||||||
|
private:
|
||||||
|
const char* DefaultShapeVertex = "#version 330 core\n\
|
||||||
|
layout(location = 0) in vec4 vertex;\
|
||||||
|
\
|
||||||
|
uniform mat4 model;\
|
||||||
|
uniform mat4 projection;\
|
||||||
|
\
|
||||||
|
void main()\
|
||||||
|
{\
|
||||||
|
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\
|
||||||
|
}";
|
||||||
|
|
||||||
|
const char* DefaultShapeFragment = "#version 330 core\n\
|
||||||
|
in vec2 TexCoords;\
|
||||||
|
out vec4 color;\
|
||||||
|
\
|
||||||
|
uniform vec4 shapeColor;\
|
||||||
|
\
|
||||||
|
void main()\
|
||||||
|
{\
|
||||||
|
color = shapeColor;\
|
||||||
|
}";
|
||||||
|
|
||||||
|
const char* DefaultSpriteVertex = "#version 330 core\n\
|
||||||
|
layout(location = 0) in vec4 vertex;\
|
||||||
|
\
|
||||||
|
out vec2 TexCoords;\
|
||||||
|
\
|
||||||
|
uniform vec4 uvManip;\
|
||||||
|
uniform mat4 model;\
|
||||||
|
uniform mat4 projection;\
|
||||||
|
\
|
||||||
|
void main()\
|
||||||
|
{\
|
||||||
|
TexCoords = vec2(vertex.z * uvManip.x + uvManip.y, vertex.w * uvManip.z + uvManip.w);\
|
||||||
|
gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);\
|
||||||
|
}";
|
||||||
|
|
||||||
|
const char* DefaultSpriteFragment = "#version 330 core\n\
|
||||||
|
in vec2 TexCoords;\
|
||||||
|
out vec4 color;\
|
||||||
|
\
|
||||||
|
uniform sampler2D image;\
|
||||||
|
uniform vec4 spriteColor;\
|
||||||
|
\
|
||||||
|
void main()\
|
||||||
|
{\
|
||||||
|
color = vec4(spriteColor) * texture(image, TexCoords);\
|
||||||
|
}";
|
||||||
|
|
||||||
|
const char* DefaultTextVertex = "#version 330 core\n\
|
||||||
|
layout(location = 0) in vec4 vertex; \
|
||||||
|
out vec2 TexCoords;\
|
||||||
|
\
|
||||||
|
uniform mat4 projection;\
|
||||||
|
\
|
||||||
|
void main()\
|
||||||
|
{\
|
||||||
|
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\
|
||||||
|
TexCoords = vertex.zw;\
|
||||||
|
} ";
|
||||||
|
|
||||||
|
const char* DefaultTextFragment = "#version 330 core\n\
|
||||||
|
in vec2 TexCoords;\
|
||||||
|
out vec4 color;\
|
||||||
|
\
|
||||||
|
uniform sampler2D text;\
|
||||||
|
uniform vec4 textColor;\
|
||||||
|
\
|
||||||
|
void main()\
|
||||||
|
{\
|
||||||
|
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);\
|
||||||
|
color = vec4(textColor) * sampled;\
|
||||||
|
}";
|
||||||
|
|
||||||
|
} OGLDefaultShaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEFAULT_SHADERS_H_
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - IGraphics.h
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2021/09/02 (y/m/d)
|
||||||
|
* Mod Date - 2021/09/02 (y/m/d)
|
||||||
|
* Description - Graphics interface for the engine.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef IGRAPHICS_H_
|
||||||
|
#define IGRAPHICS_H_
|
||||||
|
|
||||||
|
#include <utils/types.h>
|
||||||
|
#include <utils/opRes.h>
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
class Core;
|
||||||
|
class Window;
|
||||||
|
class Image;
|
||||||
|
|
||||||
|
enum ImageFormat
|
||||||
|
{
|
||||||
|
RGB,
|
||||||
|
RGBA,
|
||||||
|
BGR,
|
||||||
|
BGRA
|
||||||
|
};
|
||||||
|
|
||||||
|
class IGraphics
|
||||||
|
{
|
||||||
|
protected: // Interface methods for use only by the engine
|
||||||
|
friend Core;
|
||||||
|
|
||||||
|
IGraphics() : mbIsInit(false) {}
|
||||||
|
|
||||||
|
virtual OpRes Initialized(Window* pWindow, bool enableDebugMessages = true) = 0;
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
|
virtual void ResizeCanvas() = 0;
|
||||||
|
|
||||||
|
virtual void BeginDraw() = 0;
|
||||||
|
virtual void EndDraw() = 0;
|
||||||
|
|
||||||
|
public: //
|
||||||
|
|
||||||
|
virtual void SetClearColor(Color c) = 0;
|
||||||
|
virtual Color GetClearColor() const = 0;
|
||||||
|
|
||||||
|
// Draw Methods
|
||||||
|
virtual void DrawLine(glm::vec2 point1, glm::vec2 point2, Color color, float lineWidth) = 0;
|
||||||
|
virtual void DrawEllipse(glm::vec2 center, glm::vec2 radii, Color color, float thickness, int resolution) = 0;
|
||||||
|
virtual void DrawFilledEllipse(glm::vec2 center, glm::vec2 radii, Color color, int resolution) = 0;
|
||||||
|
virtual void DrawBox(Rectangle dimensions, Color color, float thickness) = 0;
|
||||||
|
virtual void DrawFilledBox(glm::vec2 topLeft, glm::vec2 botRight, Color color) = 0;
|
||||||
|
virtual void DrawImage(Image& image, glm::vec2 topLeft, Color color) = 0;
|
||||||
|
virtual void DrawImage(Image& image, Rectangle source, Rectangle destination, Color color) = 0;
|
||||||
|
virtual void DrawString(const char* string, Rectangle boundingArea, Color color, int font = 0) = 0;
|
||||||
|
|
||||||
|
// Takes raw image data and creates and Image class instance out of it.
|
||||||
|
// The raw data must be in one of the ImageFormats and it must be 1 byte per channel.
|
||||||
|
virtual Image* CreateImage(const unsigned char* pData, int width, int height, ImageFormat format) = 0;
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
int DefaultFont() const;
|
||||||
|
|
||||||
|
// For weight, 400 is normal and 700 is bold
|
||||||
|
virtual int CreateNewFont(const char* fontName, float size = 12.0f, int weight = 400) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool mbIsInit;
|
||||||
|
int mDefaultFont;
|
||||||
|
Color mClearColor;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // IGRAPHICS_H_
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - Image.h
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2019/07/17 (y/m/d)
|
||||||
|
* Mod Date - 2019/07/18 (y/m/d)
|
||||||
|
* Description - Manage image data that can be rendered with OpenGL.
|
||||||
|
* Use the Graphics class to create instances of Image.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "Image.h"
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
unsigned int Image::GetGLTextureID() const
|
||||||
|
{
|
||||||
|
return mGLTextureID;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Image::GetWidth() const
|
||||||
|
{
|
||||||
|
return mWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Image::GetHeight() const
|
||||||
|
{
|
||||||
|
return mHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::FreeRawData()
|
||||||
|
{
|
||||||
|
delete[] mRawData;
|
||||||
|
mRawData = nullptr;
|
||||||
|
|
||||||
|
mRawDataSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::Image()
|
||||||
|
: mRawData(nullptr), mRawDataSize(0), mWidth(0), mHeight(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::~Image()
|
||||||
|
{
|
||||||
|
delete[] mRawData;
|
||||||
|
mRawData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - Image.h
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2019/07/17 (y/m/d)
|
||||||
|
* Mod Date - 2019/07/18 (y/m/d)
|
||||||
|
* Description - Manage image data that can be rendered with OpenGL.
|
||||||
|
* Use the Graphics class to create instances of Image.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef IMAGE_H_
|
||||||
|
#define IMAGE_H_
|
||||||
|
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
class OglGraphics;
|
||||||
|
class Image
|
||||||
|
{
|
||||||
|
friend OglGraphics;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
unsigned int GetGLTextureID() const;
|
||||||
|
int GetWidth() const;
|
||||||
|
int GetHeight() const;
|
||||||
|
|
||||||
|
void FreeRawData();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Image();
|
||||||
|
~Image();
|
||||||
|
|
||||||
|
unsigned char* mRawData;
|
||||||
|
int mRawDataSize;
|
||||||
|
int mWidth;
|
||||||
|
int mHeight;
|
||||||
|
|
||||||
|
unsigned int mGLTextureID;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // IMAGE_H_
|
||||||
@ -0,0 +1,426 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - OGLGraphics.cpp
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2021/08/30 (y/m/d)
|
||||||
|
* Mod Date - 2021/09/02 (y/m/d)
|
||||||
|
* Description - An openGL implementation of the engine Graphics interface.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "OGLGraphics.h"
|
||||||
|
#include "DefaultShaders.h"
|
||||||
|
#include "window.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include <utils/logger.h>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// DEBUG MESSAGE CALLBACK
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
std::map<int, std::string> OglGraphics::mDebugMsgTypes;
|
||||||
|
std::map<int, std::string> OglGraphics::mDebugMsgSources;
|
||||||
|
std::map<int, std::string> OglGraphics::mDebugMsgSeverity;
|
||||||
|
|
||||||
|
void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id,
|
||||||
|
GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
|
||||||
|
{
|
||||||
|
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::OGL_DEBUG,
|
||||||
|
"%s (type: %s, source: %s, severity: %s), message: %s",
|
||||||
|
(type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
|
||||||
|
OglGraphics::mDebugMsgSources[source].c_str(),
|
||||||
|
OglGraphics::mDebugMsgTypes[type].c_str(),
|
||||||
|
OglGraphics::mDebugMsgSeverity[severity].c_str(),
|
||||||
|
message);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// RESTRICTED METHODS
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
OglGraphics::OglGraphics()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
OpRes OglGraphics::Initialized(Window* pWindow, bool enableDebugMessages)
|
||||||
|
{
|
||||||
|
if (!pWindow->IsInit())
|
||||||
|
{
|
||||||
|
return OpRes::Fail("Can not initialize Graphics interface. The Window must be initialized first!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbIsInit)
|
||||||
|
{
|
||||||
|
return OpRes::Fail("Can not initialize Graphics interface. It is already initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
mpWindow = pWindow;
|
||||||
|
|
||||||
|
if (enableDebugMessages)
|
||||||
|
{
|
||||||
|
InitDebugMsgSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the 2D drawing systems
|
||||||
|
InitImageSystem();
|
||||||
|
// InitTextSystem();
|
||||||
|
InitShapeSystem();
|
||||||
|
|
||||||
|
return OpRes::OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::Shutdown()
|
||||||
|
{
|
||||||
|
// Nothing to clean up at this point
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OglGraphics::ResizeCanvas()
|
||||||
|
{
|
||||||
|
// Get viewport size from glfw window
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
glfwGetFramebufferSize(mpWindow->GetWindow(), &width, &height);
|
||||||
|
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
mProjection = glm::ortho(0.0f, (GLfloat)width, (GLfloat)height, 0.0f, -1.0f, 1.0f);
|
||||||
|
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO_VERBOSE,
|
||||||
|
"glViewport set to %d, %d", width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OglGraphics::BeginDraw()
|
||||||
|
{
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::EndDraw()
|
||||||
|
{
|
||||||
|
mpWindow->SwapBuffers();
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// USER METHODS
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void OglGraphics::SetClearColor(Color c)
|
||||||
|
{
|
||||||
|
mClearColor = c;
|
||||||
|
glClearColor(mClearColor.Red, mClearColor.Green, mClearColor.Blue, mClearColor.Alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color OglGraphics::GetClearColor() const
|
||||||
|
{
|
||||||
|
return mClearColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw Methods
|
||||||
|
void OglGraphics::DrawLine(glm::vec2 point1, glm::vec2 point2, Color color, float lineWidth)
|
||||||
|
{
|
||||||
|
mShapeShader.MakeActive();
|
||||||
|
mShapeShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection));
|
||||||
|
mShapeShader.SetUniformf("shapeColor", { color.Red, color.Green, color.Blue, color.Alpha });
|
||||||
|
glBindVertexArray(mRectVAO);
|
||||||
|
|
||||||
|
GLfloat lineVerts[6][4] = {
|
||||||
|
{ point1.x, point1.y, },
|
||||||
|
{ point2.x, point2.y, },
|
||||||
|
{ 0.0f, 0.0f, },
|
||||||
|
|
||||||
|
{ 0.0f, 0.0f, },
|
||||||
|
{ 0.0f, 0.0f, },
|
||||||
|
{ 0.0f, 0.0f, }
|
||||||
|
};
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mRectVBO);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(lineVerts), lineVerts);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
glLineWidth(lineWidth);
|
||||||
|
glDrawArrays(GL_LINES, 0, 2);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::DrawEllipse(glm::vec2 center, glm::vec2 radii, Color color, float thickness, int resolution)
|
||||||
|
{
|
||||||
|
mShapeShader.MakeActive();
|
||||||
|
mShapeShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection));
|
||||||
|
mShapeShader.SetUniformf("shapeColor", { color.Red, color.Green, color.Blue, color.Alpha });
|
||||||
|
glBindVertexArray(mEllipseVAO);
|
||||||
|
|
||||||
|
GLfloat points[360][2];
|
||||||
|
for (int i = 0; i < 360; i++)
|
||||||
|
{
|
||||||
|
float rad = i * 3.14159f / 180.0f;
|
||||||
|
points[i][0] = center.x + (radii.x * cos(rad));
|
||||||
|
points[i][1] = center.y + (radii.y * sin(rad));
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mEllipseVBO);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
glLineWidth(thickness);
|
||||||
|
glDrawArrays(GL_LINE_LOOP, 0, 360);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OglGraphics::DrawFilledEllipse(glm::vec2 center, glm::vec2 radii, Color color, int resolution)
|
||||||
|
{
|
||||||
|
mShapeShader.MakeActive();
|
||||||
|
mShapeShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection));
|
||||||
|
mShapeShader.SetUniformf("shapeColor", { color.Red, color.Green, color.Blue, color.Alpha });
|
||||||
|
glBindVertexArray(mEllipseVAO);
|
||||||
|
|
||||||
|
GLfloat points[362][2];
|
||||||
|
points[0][0] = center.x;
|
||||||
|
points[0][1] = center.y;
|
||||||
|
for (int i = 1; i < 362; i++)
|
||||||
|
{
|
||||||
|
float rad = (i - 1) * 3.14159f / 180.0f;
|
||||||
|
points[i][0] = center.x + (radii.x * cos(rad));
|
||||||
|
points[i][1] = center.y + (radii.y * sin(rad));
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mEllipseVBO);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 362);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::DrawFilledBox(glm::vec2 topLeft, glm::vec2 botRight, Color color)
|
||||||
|
{
|
||||||
|
mShapeShader.MakeActive();
|
||||||
|
mShapeShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection));
|
||||||
|
mShapeShader.SetUniformf("shapeColor", { color.Red, color.Green, color.Blue, color.Alpha });
|
||||||
|
glBindVertexArray(mRectVAO);
|
||||||
|
|
||||||
|
GLfloat vertices[6][4] = {
|
||||||
|
{ topLeft.x, botRight.y, },
|
||||||
|
{ botRight.x, topLeft.y, },
|
||||||
|
{ topLeft.x, topLeft.y, },
|
||||||
|
|
||||||
|
{ topLeft.x, botRight.y, },
|
||||||
|
{ botRight.x, botRight.y, },
|
||||||
|
{ botRight.x, topLeft.y, }
|
||||||
|
};
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mRectVBO);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
// Render quad
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::DrawBox(Rectangle dimensions, Color color, float thickness)
|
||||||
|
{
|
||||||
|
glm::vec2 topLeft(dimensions.Left, dimensions.Top);
|
||||||
|
glm::vec2 botRight(dimensions.right(), dimensions.bottom());
|
||||||
|
|
||||||
|
// left side top to bottom
|
||||||
|
DrawLine(glm::vec2(topLeft.x, topLeft.y), glm::vec2(topLeft.x, botRight.y), color, thickness);
|
||||||
|
|
||||||
|
// bottom left to right
|
||||||
|
DrawLine(glm::vec2(topLeft.x, botRight.y), glm::vec2(botRight.x, botRight.y), color, thickness);
|
||||||
|
|
||||||
|
// right side bottom to top
|
||||||
|
DrawLine(glm::vec2(botRight.x, botRight.y), glm::vec2(botRight.x, topLeft.y), color, thickness);
|
||||||
|
|
||||||
|
// top right to left
|
||||||
|
DrawLine(glm::vec2(botRight.x, topLeft.y), glm::vec2(topLeft.x, topLeft.y), color, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::DrawImage(Image& image, glm::vec2 topLeft, Color color)
|
||||||
|
{
|
||||||
|
DrawImage(image, Rectangle(0.0f, 0.0f, (float)image.GetWidth(), (float)image.GetHeight()),
|
||||||
|
Rectangle(topLeft.x, topLeft.y, (float)image.GetWidth(), (float)image.GetHeight()), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::DrawImage(Image& image, Rectangle source, Rectangle destination, Color color)
|
||||||
|
{
|
||||||
|
glm::mat4 id = glm::mat4(1.0f);
|
||||||
|
glm::vec3 pos = glm::vec3(destination.Left, destination.Top, 0.0f);
|
||||||
|
glm::mat4 trans = glm::translate(id, pos);
|
||||||
|
trans = glm::scale(trans, glm::vec3(destination.Width, destination.Height, 1.0f));
|
||||||
|
|
||||||
|
// float widthDiff = image.GetWidth() - source.Width;
|
||||||
|
|
||||||
|
// if (source.Width == image.GetWidth() && source.Height == image.GetHeight())
|
||||||
|
// {
|
||||||
|
// mImageShader.MakeActive();
|
||||||
|
// mImageShader.SetUniformf("uvManip", { 1.0f, 0.0f, 1.0f, 0.0f }); // No uv Manipulation
|
||||||
|
// mImageShader.SetUniformMatrix("model", 1, glm::value_ptr(trans));
|
||||||
|
// mImageShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection));
|
||||||
|
// mImageShader.SetUniformf("spriteColor", { color.Red, color.Green, color.Blue, color.Alpha });
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
|
||||||
|
// NOTE: Pretty sure these values will work out to be correct with out the if check
|
||||||
|
float xScale = source.Width / image.GetWidth();
|
||||||
|
float xOffset = source.Left / image.GetWidth();
|
||||||
|
float yScale = source.Height / image.GetHeight();
|
||||||
|
float yOffset = source.Top / image.GetHeight();
|
||||||
|
|
||||||
|
mImageShader.SetUniformf("uvManip", { xScale, xOffset, yScale, yOffset });
|
||||||
|
mImageShader.SetUniformMatrix("model", 1, glm::value_ptr(trans));
|
||||||
|
mImageShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection));
|
||||||
|
mImageShader.SetUniformf("spriteColor", { color.Red, color.Green, color.Blue, color.Alpha });
|
||||||
|
//}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, image.GetGLTextureID());
|
||||||
|
|
||||||
|
glBindVertexArray(mImageVAO);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::DrawString(const char* string, Rectangle boundingArea, Color color, int font)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Takes raw image data and creates and Image class instance out of it.
|
||||||
|
// The raw data must be in one of the ImageFormats and it must be 1 byte per channel.
|
||||||
|
Image* OglGraphics::CreateImage(const unsigned char* pData, int width, int height, ImageFormat format)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
int OglGraphics::DefaultFont() const
|
||||||
|
{
|
||||||
|
return mDefaultFont;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For weight, 400 is normal and 700 is bold
|
||||||
|
int OglGraphics::CreateNewFont(const char* fontName, float size, int weight)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// HELPER INIT METHODS
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void OglGraphics::InitDebugMsgSystem()
|
||||||
|
{
|
||||||
|
// DEBUG MESSAGE TYPES
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_ERROR] = "ERROR";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR] = "DEPRECATED_BEHAVIOR";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR] = "UNDEFINED_BEHAVIOR";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_PORTABILITY] = "PORTABILITY";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_PERFORMANCE] = "PERFORMANCE";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_OTHER] = "OTHER";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_MARKER] = "MARKER";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_PUSH_GROUP] = "PUSH_GROUP";
|
||||||
|
mDebugMsgTypes[GL_DEBUG_TYPE_POP_GROUP] = "POP_GROUP";
|
||||||
|
|
||||||
|
// DEBUG MESSAGE SOURCES
|
||||||
|
mDebugMsgSources[GL_DEBUG_SOURCE_API] = "API";
|
||||||
|
mDebugMsgSources[GL_DEBUG_SOURCE_WINDOW_SYSTEM] = "WINDOW_SYSTEM";
|
||||||
|
mDebugMsgSources[GL_DEBUG_SOURCE_SHADER_COMPILER] = "SHADER_COMPILER";
|
||||||
|
mDebugMsgSources[GL_DEBUG_SOURCE_THIRD_PARTY] = "THIRD_PARTY";
|
||||||
|
mDebugMsgSources[GL_DEBUG_SOURCE_APPLICATION] = "APPLICATION";
|
||||||
|
mDebugMsgSources[GL_DEBUG_SOURCE_OTHER] = "OTHER";
|
||||||
|
|
||||||
|
// DEBUG MESSAGE SEVERITY
|
||||||
|
mDebugMsgSeverity[GL_DEBUG_SEVERITY_HIGH] = "HIGH";
|
||||||
|
mDebugMsgSeverity[GL_DEBUG_SEVERITY_MEDIUM] = "MEDIUM";
|
||||||
|
mDebugMsgSeverity[GL_DEBUG_SEVERITY_LOW] = "LOW";
|
||||||
|
mDebugMsgSeverity[GL_DEBUG_SEVERITY_NOTIFICATION] = "NOTIFICATION";
|
||||||
|
|
||||||
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
|
glDebugMessageCallback(MessageCallback, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::InitImageSystem()
|
||||||
|
{
|
||||||
|
// Setup geometry
|
||||||
|
// https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites
|
||||||
|
GLuint VBO;
|
||||||
|
GLfloat vertices[] = {
|
||||||
|
// Pos // Tex
|
||||||
|
0.0f, 1.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
|
||||||
|
0.0f, 1.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 0.0f, 1.0f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &mImageVAO);
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindVertexArray(mImageVAO);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
// Setup Shader Program
|
||||||
|
mImageShader.SetSource(glShader::TYPE_VERTEX, OGLDefaultShaders.DefaultSpriteVertex, false);
|
||||||
|
mImageShader.SetSource(glShader::TYPE_FRAGMENT, OGLDefaultShaders.DefaultSpriteFragment, false);
|
||||||
|
if (!mImageShader.BuildProgram())
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR, "Unable to build default image shader program");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::InitTextSystem()
|
||||||
|
{
|
||||||
|
// TODO: Check to see if Dear ImGui can be used to render text
|
||||||
|
// If it can render text on the app window and doesn't need
|
||||||
|
// to render onto one of it's own windows then it should work.
|
||||||
|
// If not add FreeType to the project and put the text rendering
|
||||||
|
// into it's own class.
|
||||||
|
}
|
||||||
|
|
||||||
|
void OglGraphics::InitShapeSystem()
|
||||||
|
{
|
||||||
|
// Create rectangle buffers
|
||||||
|
glGenVertexArrays(1, &mRectVAO);
|
||||||
|
glGenBuffers(1, &mRectVBO);
|
||||||
|
glBindVertexArray(mRectVAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mRectVBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
// Create Ellipse buffers
|
||||||
|
glGenVertexArrays(1, &mEllipseVAO);
|
||||||
|
glGenBuffers(1, &mEllipseVBO);
|
||||||
|
glBindVertexArray(mEllipseVAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mEllipseVBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 362 * 2, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
|
||||||
|
// Load shape shaders
|
||||||
|
mShapeShader.SetSource(glShader::TYPE_VERTEX, OGLDefaultShaders.DefaultShapeVertex, false);
|
||||||
|
mShapeShader.SetSource(glShader::TYPE_FRAGMENT, OGLDefaultShaders.DefaultShapeFragment, false);
|
||||||
|
if (!mShapeShader.BuildProgram())
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::WARNING, "Unable to build shape shader program.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - OGLGraphics.h
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2021/08/30 (y/m/d)
|
||||||
|
* Mod Date - 2021/09/02 (y/m/d)
|
||||||
|
* Description - An openGL implementation of the engine Graphics interface.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef OGLGRAPHICS_H_
|
||||||
|
#define OGLGRAPHICS_H_
|
||||||
|
|
||||||
|
#include "IGraphics.h"
|
||||||
|
#include <glad/gl.h>
|
||||||
|
#include "glShader.h"
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
class OglGraphics : public IGraphics
|
||||||
|
{
|
||||||
|
private: // Interface methods for use only by the engine
|
||||||
|
friend Core;
|
||||||
|
|
||||||
|
OglGraphics();
|
||||||
|
|
||||||
|
virtual OpRes Initialized(Window* pWindow, bool enableDebugMessages = true);
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
|
virtual void ResizeCanvas();
|
||||||
|
|
||||||
|
virtual void BeginDraw();
|
||||||
|
virtual void EndDraw();
|
||||||
|
|
||||||
|
public: //
|
||||||
|
|
||||||
|
virtual void SetClearColor(Color c);
|
||||||
|
virtual Color GetClearColor() const;
|
||||||
|
|
||||||
|
// Draw Methods
|
||||||
|
virtual void DrawLine(glm::vec2 point1, glm::vec2 point2, Color color, float lineWidth);
|
||||||
|
virtual void DrawEllipse(glm::vec2 center, glm::vec2 radii, Color color, float thickness, int resolution);
|
||||||
|
virtual void DrawFilledEllipse(glm::vec2 center, glm::vec2 radii, Color color, int resolution);
|
||||||
|
virtual void DrawBox(Rectangle dimensions, Color color, float thickness);
|
||||||
|
virtual void DrawFilledBox(glm::vec2 topLeft, glm::vec2 botRight, Color color);
|
||||||
|
virtual void DrawImage(Image& image, glm::vec2 topLeft, Color color);
|
||||||
|
virtual void DrawImage(Image& image, Rectangle source, Rectangle destination, Color color);
|
||||||
|
virtual void DrawString(const char* string, Rectangle boundingArea, Color color, int font = 0);
|
||||||
|
|
||||||
|
// Takes raw image data and creates and Image class instance out of it.
|
||||||
|
// The raw data must be in one of the ImageFormats and it must be 1 byte per channel.
|
||||||
|
virtual Image* CreateImage(const unsigned char* pData, int width, int height, ImageFormat format);
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
int DefaultFont() const;
|
||||||
|
|
||||||
|
// For weight, 400 is normal and 700 is bold
|
||||||
|
virtual int CreateNewFont(const char* fontName, float size = 12.0f, int weight = 400);
|
||||||
|
|
||||||
|
private: // DATA
|
||||||
|
Window* mpWindow;
|
||||||
|
glm::mat4 mProjection;
|
||||||
|
|
||||||
|
// Sprite Data
|
||||||
|
unsigned int mImageVAO;
|
||||||
|
glShader mImageShader;
|
||||||
|
|
||||||
|
// Shapes
|
||||||
|
GLuint mRectVAO;
|
||||||
|
GLuint mRectVBO;
|
||||||
|
glShader mShapeShader;
|
||||||
|
|
||||||
|
// Ellipse
|
||||||
|
GLuint mEllipseVAO;
|
||||||
|
GLuint mEllipseVBO;
|
||||||
|
|
||||||
|
private: // Helper Initializers
|
||||||
|
void InitDebugMsgSystem();
|
||||||
|
void InitImageSystem();
|
||||||
|
void InitTextSystem();
|
||||||
|
void InitShapeSystem();
|
||||||
|
|
||||||
|
private: // Helper methods
|
||||||
|
|
||||||
|
private: // Debug Message System
|
||||||
|
|
||||||
|
friend void __stdcall MessageCallback(GLenum source, GLenum type, GLuint id,
|
||||||
|
GLenum severity, GLsizei length, const GLchar* message, const void* userParam);
|
||||||
|
static std::map<int, std::string> mDebugMsgTypes;
|
||||||
|
static std::map<int, std::string> mDebugMsgSources;
|
||||||
|
static std::map<int, std::string> mDebugMsgSeverity;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // OGLGRAPHICS_H_
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
#version 330 core
|
||||||
|
in vec2 TexCoords;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform sampler2D image;
|
||||||
|
uniform vec3 spriteColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
color = vec4(spriteColor, 1.0) * texture(image, TexCoords);
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>
|
||||||
|
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
TexCoords = vertex.zw;
|
||||||
|
gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);
|
||||||
|
}
|
||||||
@ -0,0 +1,322 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - glShader.cpp
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2018/06/26 (y/m/d)
|
||||||
|
* Mod Date - 2021/09/02 (y/m/d)
|
||||||
|
* Description - Manages a single OpenGL shader program
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "glShader.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
#include <glad/gl.h>
|
||||||
|
|
||||||
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
|
||||||
|
glShader::glShader()
|
||||||
|
: mProgram(0), mbProgramBuilt(false), mpLogger(Logger::GetInstance())
|
||||||
|
{
|
||||||
|
int glTypes[TYPE_COUNT];
|
||||||
|
glTypes[TYPE_VERTEX] = GL_VERTEX_SHADER;
|
||||||
|
glTypes[TYPE_GEOMETRY] = GL_GEOMETRY_SHADER;
|
||||||
|
glTypes[TYPE_FRAGMENT] = GL_FRAGMENT_SHADER;
|
||||||
|
|
||||||
|
for (int i = 0; i < TYPE_COUNT; i++)
|
||||||
|
{
|
||||||
|
mShaders[i].ID = 0;
|
||||||
|
mShaders[i].Source = "";
|
||||||
|
mShaders[i].IsCompiled = false;
|
||||||
|
mShaders[i].GLType = glTypes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glShader::IsBuilt() const
|
||||||
|
{
|
||||||
|
return mbProgramBuilt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool glShader::SetUniformi(const char * uniformName, std::vector<int> values, bool asVector)
|
||||||
|
{
|
||||||
|
int uniformLocation = glGetUniformLocation(mProgram, uniformName);
|
||||||
|
|
||||||
|
if (asVector)
|
||||||
|
{
|
||||||
|
int count = ((int)values.size()) / 4;
|
||||||
|
glUniform4iv(uniformLocation, count, (int*)values.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.size() == 1)
|
||||||
|
{
|
||||||
|
glUniform1i(uniformLocation, values[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (values.size() == 2)
|
||||||
|
{
|
||||||
|
glUniform2i(uniformLocation, values[0], values[1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (values.size() == 3)
|
||||||
|
{
|
||||||
|
glUniform3i(uniformLocation, values[0], values[1], values[2]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (values.size() == 4)
|
||||||
|
{
|
||||||
|
glUniform4i(uniformLocation, values[0], values[1], values[2], values[3]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glShader::SetUniformf(const char * uniformName, std::vector<float> values, bool asVector)
|
||||||
|
{
|
||||||
|
int uniformLocation = glGetUniformLocation(mProgram, uniformName);
|
||||||
|
|
||||||
|
if (asVector)
|
||||||
|
{
|
||||||
|
int count = ((int)values.size()) / 4;
|
||||||
|
glUniform4fv(uniformLocation, count, (float*)values.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.size() == 1)
|
||||||
|
{
|
||||||
|
glUniform1f(uniformLocation, values[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (values.size() == 2)
|
||||||
|
{
|
||||||
|
glUniform2f(uniformLocation, values[0], values[1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (values.size() == 3)
|
||||||
|
{
|
||||||
|
glUniform3f(uniformLocation, values[0], values[1], values[2]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (values.size() == 4)
|
||||||
|
{
|
||||||
|
glUniform4f(uniformLocation, values[0], values[1], values[2], values[3]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glShader::SetUniformMatrix(const char * uniformName, int numMats, float * pData)
|
||||||
|
{
|
||||||
|
int uniformLocation = glGetUniformLocation(mProgram, uniformName);
|
||||||
|
|
||||||
|
if (-1 == uniformLocation)
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Unable to find uniform location. Uniform name: %s", uniformName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glUniformMatrix4fv(uniformLocation, numMats, GL_FALSE, pData);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glShader::LogAllUniforms() const
|
||||||
|
{
|
||||||
|
GLint size; // size of the variable
|
||||||
|
GLenum type; // type of the variable (float, vec3 or mat4, etc)
|
||||||
|
|
||||||
|
const GLsizei bufSize = 16; // maximum name length
|
||||||
|
GLchar name[bufSize]; // variable name in GLSL
|
||||||
|
GLsizei length; // name length
|
||||||
|
int count = -1;
|
||||||
|
|
||||||
|
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORMS, &count);
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO, "Active Uniforms: %d", count);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
glGetActiveUniform(mProgram, (GLuint)i, bufSize, &length, &size, &type, name);
|
||||||
|
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO, "Uniform #%d Type: %u Name: %s", i, type, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glShader::SetSource(int sourceType, const char * source, bool loadFromFile)
|
||||||
|
{
|
||||||
|
if (sourceType < 0 || sourceType >= TYPE_COUNT)
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Can not set shader source (%s) - Invalid Source Type (%d)", source, (int)sourceType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadFromFile)
|
||||||
|
{
|
||||||
|
mShaders[sourceType].Source = LoadShaderFromFile(source);
|
||||||
|
if ("" == mShaders[sourceType].Source)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mShaders[sourceType].Source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool glShader::CompileShader(int sourceType)
|
||||||
|
{
|
||||||
|
if (sourceType < 0 || sourceType >= TYPE_COUNT)
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Can not compile source - Invalid Source Type: %d", (int)sourceType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("" == mShaders[sourceType].Source)
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Can not compile %s shader source - Source is empty", TypeNames[sourceType]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char infoLog[512];
|
||||||
|
|
||||||
|
// Create shader
|
||||||
|
mShaders[sourceType].ID = glCreateShader(mShaders[sourceType].GLType);
|
||||||
|
|
||||||
|
// compile source
|
||||||
|
const char* tempSource = mShaders[sourceType].Source.c_str();
|
||||||
|
glShaderSource(mShaders[sourceType].ID, 1, &tempSource, NULL);
|
||||||
|
glCompileShader(mShaders[sourceType].ID);
|
||||||
|
|
||||||
|
|
||||||
|
// check for errors
|
||||||
|
glGetShaderiv(mShaders[sourceType].ID, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(mShaders[sourceType].ID, 512, NULL, infoLog);
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Error compiling %s shader source: %s", TypeNames[sourceType], infoLog);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mShaders[sourceType].IsCompiled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glShader::BuildProgram(bool autoFreeShaders)
|
||||||
|
{
|
||||||
|
if ("" == mShaders[TYPE_VERTEX].Source || "" == mShaders[TYPE_FRAGMENT].Source)
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Cannot create shader program - vertex and fragment shader must be set!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mProgram = glCreateProgram();
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < TYPE_COUNT; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Compile shaders if needed
|
||||||
|
// -------------------------------------------
|
||||||
|
if (!mShaders[i].IsCompiled)
|
||||||
|
{
|
||||||
|
if (mShaders[i].Source == "")
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO_VERBOSE,
|
||||||
|
"Skipping compilation of %s shader source - source is empty", TypeNames[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!CompileShader(i))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the shader to the program
|
||||||
|
// -------------------------------------------
|
||||||
|
if (mShaders[i].Source != "")
|
||||||
|
glAttachShader(mProgram, mShaders[i].ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Link and check for errors
|
||||||
|
glLinkProgram(mProgram);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char infoLog[512];
|
||||||
|
|
||||||
|
glGetProgramiv(mProgram, GL_LINK_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetProgramInfoLog(mProgram, 512, NULL, infoLog);
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Failed to link the shader program. Info Log: %s", infoLog);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
if (autoFreeShaders)
|
||||||
|
{
|
||||||
|
FreeShaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
mbProgramBuilt = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void glShader::FreeShaders()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < TYPE_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (mShaders[i].IsCompiled)
|
||||||
|
{
|
||||||
|
glDeleteShader(mShaders[i].ID);
|
||||||
|
mShaders[i].ID = 0;
|
||||||
|
mShaders[i].IsCompiled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glShader::MakeActive()
|
||||||
|
{
|
||||||
|
glUseProgram(mProgram);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string glShader::LoadShaderFromFile(const char * filename)
|
||||||
|
{
|
||||||
|
std::ifstream ifs(filename);
|
||||||
|
|
||||||
|
if (!ifs.is_open())
|
||||||
|
{
|
||||||
|
Logger::Log(LogCategory::GRAPHICS, LogLevel::ERROR,
|
||||||
|
"Failed to load shader source from file (file not found): %s", filename);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << ifs.rdbuf();
|
||||||
|
ifs.close();
|
||||||
|
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - glShader.h
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2018/06/26 (y/m/d)
|
||||||
|
* Mod Date - 2021/09/02 (y/m/d)
|
||||||
|
* Description - Manages a single OpenGL shader program. Uses GLEW.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef GL_SHADER_H_
|
||||||
|
#define GL_SHADER_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
class Logger;
|
||||||
|
|
||||||
|
class glShader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct ShaderInfo
|
||||||
|
{
|
||||||
|
unsigned int ID;
|
||||||
|
std::string Source;
|
||||||
|
bool IsCompiled;
|
||||||
|
int GLType;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// To support more shader types:
|
||||||
|
// 1) Add a TYPE_* enum value here before TYPE_COUNT
|
||||||
|
// 2) in the constructor add a new GLType to the array in the correct place
|
||||||
|
enum { TYPE_VERTEX, TYPE_GEOMETRY, TYPE_FRAGMENT, TYPE_COUNT, TYPE_INVALID = TYPE_COUNT };
|
||||||
|
const char* TypeNames[3] = { "Vertex", "Geometry", "Fragment" };
|
||||||
|
|
||||||
|
glShader();
|
||||||
|
|
||||||
|
bool IsBuilt() const;
|
||||||
|
|
||||||
|
bool SetSource(int sourceType, const char* source, bool loadFromFile = true);
|
||||||
|
bool CompileShader(int sourceType);
|
||||||
|
bool BuildProgram(bool autoFreeShaders = true);
|
||||||
|
void FreeShaders();
|
||||||
|
|
||||||
|
void MakeActive();
|
||||||
|
|
||||||
|
bool SetUniformi(const char* uniformName, std::vector<int> values, bool asVector = false);
|
||||||
|
bool SetUniformf(const char* uniformName, std::vector<float> values, bool asVector = false);
|
||||||
|
bool SetUniformMatrix(const char* uniformName, int numMats, float* pData);
|
||||||
|
|
||||||
|
void LogAllUniforms() const;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
unsigned int mProgram;
|
||||||
|
bool mbProgramBuilt;
|
||||||
|
|
||||||
|
ShaderInfo mShaders[TYPE_COUNT];
|
||||||
|
|
||||||
|
Logger* mpLogger;
|
||||||
|
|
||||||
|
private: // Helper Methods
|
||||||
|
|
||||||
|
std::string LoadShaderFromFile(const char* filename);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GL_SHADER_H_
|
||||||
|
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File - types.cpp
|
||||||
|
* Author - Joey Pollack
|
||||||
|
* Date - 2021/08/30 (y/m/d)
|
||||||
|
* Mod Date - 2021/09/02 (y/m/d)
|
||||||
|
* Description - Defines some generic types for use through out the engine.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
namespace lunarium
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// COLOR
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
Color::Color(float _r, float _g, float _b, float _a)
|
||||||
|
: Red(_r), Green(_g), Blue(_b), Alpha(_a)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Color::Color()
|
||||||
|
: Red(0.0f), Green(0.0f), Blue(0.0f), Alpha(0.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// RECTANGLE
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
Rectangle::Rectangle()
|
||||||
|
: Left(0.0f), Top(0.0f), Width(0.0f), Height(0.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle::Rectangle(float _left, float _top, float _width, float _height)
|
||||||
|
: Left(_left), Top(_top), Width(_width), Height(_height)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
float Rectangle::Area() const
|
||||||
|
{
|
||||||
|
return Width * Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Rectangle::ContainsPoint(glm::vec2 point) const
|
||||||
|
{
|
||||||
|
if (point.x < this->Left || point.x > this->right())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (point.y < this->Top || point.y > this->bottom())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Rectangle::Intersects(const Rectangle& other, glm::vec2& centers) const
|
||||||
|
{
|
||||||
|
glm::vec2 myCenter = glm::vec2(this->Left + (this->Width / 2.0f), this->Top + (this->Height / 2.0f));
|
||||||
|
glm::vec2 otherCenter = glm::vec2(other.Left + (other.Width / 2.0f), other.Top + (other.Height / 2.0f));
|
||||||
|
centers = myCenter - otherCenter;
|
||||||
|
|
||||||
|
if (this->Left > other.right() || other.Left > this->right())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (this->Top > other.bottom() || other.Top > this->bottom())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue