|
|
|
|
@ -28,17 +28,10 @@ namespace lunarium
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct QuadTestData
|
|
|
|
|
{
|
|
|
|
|
Color color;
|
|
|
|
|
BufferLayout mBufferLayout;
|
|
|
|
|
VertexBuffer* mVertexBuffer;
|
|
|
|
|
IndexBuffer* mIndexBuffer;
|
|
|
|
|
Shader* mQuadShader;
|
|
|
|
|
} mTestData;
|
|
|
|
|
|
|
|
|
|
OpRes Renderer2D::Initialize()
|
|
|
|
|
{
|
|
|
|
|
// Configure OpenGL
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Disable byte-alignment restriction for texture loading
|
|
|
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1); // Disable byte-alignment restriction for texture storing
|
|
|
|
|
|
|
|
|
|
@ -48,108 +41,29 @@ namespace lunarium
|
|
|
|
|
|
|
|
|
|
mpCamera = nullptr;
|
|
|
|
|
|
|
|
|
|
u32* indices = new u32[mQuadData.MaxIndices];
|
|
|
|
|
// Need to adjust the set of indices because they reference verts deeper into the buffer
|
|
|
|
|
// See Hazel for example of this
|
|
|
|
|
int offset = 0;
|
|
|
|
|
for (int i = 0; i < mQuadData.MaxIndices; i+=6)
|
|
|
|
|
{
|
|
|
|
|
for ( int j = 0; j < 6; j++)
|
|
|
|
|
{
|
|
|
|
|
indices[i + j] = mQuadData.indices[(i + j) % 6] + offset;
|
|
|
|
|
}
|
|
|
|
|
offset += 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// INIT QUAD DATA
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Position
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2 }); // Tex_coords
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 4 }); // Color
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // Texture Sampler Index
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // translation
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // angle
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Scale
|
|
|
|
|
mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // tex_is_grey_scale
|
|
|
|
|
mQuadData.mVertexBuffer = VertexBuffer::Create(mQuadData.mBufferLayout, mQuadData.MaxVertices, nullptr, mQuadData.MaxIndices, indices);
|
|
|
|
|
|
|
|
|
|
// RAW VERTEX BUFFER
|
|
|
|
|
mQuadData.mRawVertexBuffer = new QuadData::Vertex[mQuadData.MaxVertices];
|
|
|
|
|
mQuadData.mRawBufferIndex = 0;
|
|
|
|
|
|
|
|
|
|
int layout_size = mQuadData.mBufferLayout.GetLayoutSizeInBytes();
|
|
|
|
|
int struct_size = sizeof(QuadData::Vertex);
|
|
|
|
|
if (struct_size != layout_size)
|
|
|
|
|
{
|
|
|
|
|
Logger::Error(LogCategory::GRAPHICS,
|
|
|
|
|
"Quad::Vertex struct size does not match the vertex layout size! struct: %d, layout: %d", struct_size, layout_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//mQuadData.mIndexBuffer = new IndexBuffer(mQuadData.MaxIndices * sizeof(u32));
|
|
|
|
|
|
|
|
|
|
std::string vert_source = File::ReadTextFile("quad.vert");
|
|
|
|
|
std::string frag_source = File::ReadTextFile("quad.frag");
|
|
|
|
|
mQuadData.mQuadShader = new Shader(vert_source.c_str(), nullptr, frag_source.c_str());
|
|
|
|
|
if (!mQuadData.mQuadShader->IsValid())
|
|
|
|
|
{
|
|
|
|
|
return OpRes::Fail("Failed to create the quad shader");
|
|
|
|
|
}
|
|
|
|
|
OpRes result = InitQuadData();
|
|
|
|
|
if (Failed(result)) { return OpRes::Fail("Could not initialize the 2D Renderer: %s", result.Description.c_str()); }
|
|
|
|
|
|
|
|
|
|
// TODO: INIT SPRITE DATA
|
|
|
|
|
// INIT LINE DATA
|
|
|
|
|
result = InitLineData();
|
|
|
|
|
if (Failed(result)) { return OpRes::Fail("Could not initialize the 2D Renderer: %s", result.Description.c_str()); }
|
|
|
|
|
|
|
|
|
|
// INIT ELLIPSE DATA
|
|
|
|
|
result = InitEllipseData();
|
|
|
|
|
if (Failed(result)) { return OpRes::Fail("Could not initialize the 2D Renderer: %s", result.Description.c_str()); }
|
|
|
|
|
|
|
|
|
|
// TODO: INIT WHITE TEXTURE
|
|
|
|
|
u8 data[4] = {255, 255, 255, 255};
|
|
|
|
|
mpWhiteTexture = Texture::Create(data, 1, 1);
|
|
|
|
|
mLoadedTextures.push_back(mpWhiteTexture);
|
|
|
|
|
|
|
|
|
|
// TODO: INIT TEXT SYSTEM
|
|
|
|
|
// INIT TEXT SYSTEM
|
|
|
|
|
mTextAPI.Initialize().LogIfFailed(LogCategory::GRAPHICS);
|
|
|
|
|
|
|
|
|
|
mDefaultFont = mTextAPI.LoadFont(lunarium::OpenFontData, lunarium::OpenDataSize, "Open Font");
|
|
|
|
|
//mDefaultFont = mTextAPI.LoadFont(lunarium::RobotoFontData, lunarium::RobotoDataSize, "Roboto Font");
|
|
|
|
|
|
|
|
|
|
// DEBUG: INIT TEST DATA
|
|
|
|
|
// mTestData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2}); // Position
|
|
|
|
|
|
|
|
|
|
// GLfloat vertices[6][2] = {
|
|
|
|
|
// { -0.5f, 0.5f, },
|
|
|
|
|
// { 0.5f, -0.5f, },
|
|
|
|
|
// { -0.5f, -0.5f, },
|
|
|
|
|
|
|
|
|
|
// { -0.5f, 0.5f, },
|
|
|
|
|
// { 0.5f, 0.5f, },
|
|
|
|
|
// { 0.5f, -0.5f, }
|
|
|
|
|
// };
|
|
|
|
|
// u32 indices[6] = { 0, 1, 2, 3, 4, 5 };
|
|
|
|
|
|
|
|
|
|
// // mTestData.mIndexBuffer = new IndexBuffer(6, indices);
|
|
|
|
|
// mTestData.mVertexBuffer = VertexBuffer::Create(mTestData.mBufferLayout, 6, nullptr, 6, indices);
|
|
|
|
|
// std::string vert_source = File::ReadTextFile("test.vert");
|
|
|
|
|
// std::string frag_source = File::ReadTextFile("test.frag");
|
|
|
|
|
// mTestData.mQuadShader = new Shader(vert_source.c_str(), nullptr, frag_source.c_str());
|
|
|
|
|
// if (!mTestData.mQuadShader->IsValid())
|
|
|
|
|
// {
|
|
|
|
|
// return OpRes::Fail("Failed to create the test shader");
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// glGenVertexArrays(1, &mTVAO);
|
|
|
|
|
// glGenBuffers(1, &mTVBO);
|
|
|
|
|
|
|
|
|
|
// glBindBuffer(GL_ARRAY_BUFFER, mTVBO);
|
|
|
|
|
// glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 12, vertices, GL_STATIC_DRAW);
|
|
|
|
|
|
|
|
|
|
// glBindVertexArray(mTVAO);
|
|
|
|
|
// glEnableVertexAttribArray(0);
|
|
|
|
|
// glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
|
|
|
|
|
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
// glBindVertexArray(0);
|
|
|
|
|
|
|
|
|
|
return OpRes::OK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Renderer2D::Shutdown()
|
|
|
|
|
{
|
|
|
|
|
VertexBuffer::Destroy(&mQuadData.mVertexBuffer);
|
|
|
|
|
VertexBuffer::Destroy(&mQuadData.VertexBuffer);
|
|
|
|
|
//delete[] mQuadData.mIndexBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -207,9 +121,9 @@ namespace lunarium
|
|
|
|
|
int texture_slot = -1;
|
|
|
|
|
if (texture)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < mLoadedTextures.size(); i++)
|
|
|
|
|
for (int i = 0; i < mQuadData.LoadedTextures.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
if (texture == mLoadedTextures[i])
|
|
|
|
|
if (texture == mQuadData.LoadedTextures[i])
|
|
|
|
|
{
|
|
|
|
|
texture_slot = i;
|
|
|
|
|
break;
|
|
|
|
|
@ -218,8 +132,8 @@ namespace lunarium
|
|
|
|
|
|
|
|
|
|
if (-1 == texture_slot)
|
|
|
|
|
{
|
|
|
|
|
mLoadedTextures.push_back(texture);
|
|
|
|
|
texture_slot = mLoadedTextures.size() - 1;
|
|
|
|
|
mQuadData.LoadedTextures.push_back(texture);
|
|
|
|
|
texture_slot = mQuadData.LoadedTextures.size() - 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@ -227,19 +141,7 @@ namespace lunarium
|
|
|
|
|
texture_slot = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//unsigned char* vertices_wl = (unsigned char*)vertices; // vertices write location pointer
|
|
|
|
|
|
|
|
|
|
// glm::mat4 model(1.0f);
|
|
|
|
|
// model = glm::translate(model, glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f));
|
|
|
|
|
// model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
// glm::mat4 model = glm::mat4(1.0f);
|
|
|
|
|
// model = glm::translate(model, glm::vec3(quad.X, quad.Y, 0.0f));
|
|
|
|
|
// model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f));
|
|
|
|
|
// model = glm::scale(model, glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f));
|
|
|
|
|
|
|
|
|
|
if (mQuadData.mRawBufferIndex + 4 > mQuadData.MaxVertices)
|
|
|
|
|
if (mQuadData.RawBufferIndex + 4 > mQuadData.MaxVertices)
|
|
|
|
|
{
|
|
|
|
|
Flush();
|
|
|
|
|
}
|
|
|
|
|
@ -248,92 +150,73 @@ namespace lunarium
|
|
|
|
|
float left = sub_texture_area.X;
|
|
|
|
|
if (left < 0)
|
|
|
|
|
{
|
|
|
|
|
sub_texture_area = Rectangle::MakeFromTopLeft(0, 0, mLoadedTextures[texture_slot]->GetWidth(), mLoadedTextures[texture_slot]->GetHeight());
|
|
|
|
|
sub_texture_area = Rectangle::MakeFromTopLeft(0, 0, mQuadData.LoadedTextures[texture_slot]->GetWidth(),
|
|
|
|
|
mQuadData.LoadedTextures[texture_slot]->GetHeight());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float xScale = (sub_texture_area.HalfWidth * 2) / mLoadedTextures[texture_slot]->GetWidth();
|
|
|
|
|
float xOffset = sub_texture_area.left() / mLoadedTextures[texture_slot]->GetWidth();
|
|
|
|
|
float yScale = (sub_texture_area.HalfHeight * 2) / mLoadedTextures[texture_slot]->GetHeight();
|
|
|
|
|
float yOffset = sub_texture_area.top() / mLoadedTextures[texture_slot]->GetHeight();
|
|
|
|
|
float scale_x = (sub_texture_area.HalfWidth * 2) / mQuadData.LoadedTextures[texture_slot]->GetWidth();
|
|
|
|
|
float offset_x = sub_texture_area.left() / mQuadData.LoadedTextures[texture_slot]->GetWidth();
|
|
|
|
|
float scale_y = (sub_texture_area.HalfHeight * 2) / mQuadData.LoadedTextures[texture_slot]->GetHeight();
|
|
|
|
|
float offset_y = sub_texture_area.top() / mQuadData.LoadedTextures[texture_slot]->GetHeight();
|
|
|
|
|
|
|
|
|
|
yOffset *= -1.0f;
|
|
|
|
|
|
|
|
|
|
// mImageShader.SetUniformf("uvManip", { xScale, xOffset, yScale * -1.0f, yOffset});
|
|
|
|
|
// vec2(vertex.z * uvManip.x + uvManip.y, vertex.w * uvManip.z - uvManip.w);
|
|
|
|
|
// Need to invert the offset_y because OpenGL likes being weird
|
|
|
|
|
offset_y *= -1.0f;
|
|
|
|
|
|
|
|
|
|
// FIRST
|
|
|
|
|
QuadData::Vertex v1;
|
|
|
|
|
int vert_size = sizeof(QuadData::Vertex);
|
|
|
|
|
v1.pos = mQuadData.vert_pos[0];
|
|
|
|
|
v1.tex_coord = glm::vec2(mQuadData.vert_tex[0].x * xScale + xOffset, mQuadData.vert_tex[0].y * yScale - yOffset);
|
|
|
|
|
v1.tex_coord = glm::vec2(mQuadData.vert_tex[0].x * scale_x + offset_x, mQuadData.vert_tex[0].y * scale_y - offset_y);
|
|
|
|
|
v1.color = color;
|
|
|
|
|
v1.tex_slot = texture_slot;
|
|
|
|
|
v1.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
|
|
|
|
|
v1.angle = angle;
|
|
|
|
|
v1.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
|
|
|
|
|
v1.tex_is_grey_scale = tex_is_grey_scale;
|
|
|
|
|
memcpy(&mQuadData.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v1, vert_size);
|
|
|
|
|
mQuadData.mRawBufferIndex += 1;
|
|
|
|
|
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v1, vert_size);
|
|
|
|
|
mQuadData.RawBufferIndex += 1;
|
|
|
|
|
|
|
|
|
|
// SECOND
|
|
|
|
|
QuadData::Vertex v2;
|
|
|
|
|
v2.pos = mQuadData.vert_pos[1];
|
|
|
|
|
v2.tex_coord = glm::vec2(mQuadData.vert_tex[1].x * xScale + xOffset, mQuadData.vert_tex[1].y * yScale - yOffset);
|
|
|
|
|
v2.tex_coord = glm::vec2(mQuadData.vert_tex[1].x * scale_x + offset_x, mQuadData.vert_tex[1].y * scale_y - offset_y);
|
|
|
|
|
v2.color = color;
|
|
|
|
|
v2.tex_slot = texture_slot;
|
|
|
|
|
v2.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
|
|
|
|
|
v2.angle = angle;
|
|
|
|
|
v2.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
|
|
|
|
|
v2.tex_is_grey_scale = tex_is_grey_scale;
|
|
|
|
|
memcpy(&mQuadData.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v2, vert_size);
|
|
|
|
|
mQuadData.mRawBufferIndex += 1;
|
|
|
|
|
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v2, vert_size);
|
|
|
|
|
mQuadData.RawBufferIndex += 1;
|
|
|
|
|
|
|
|
|
|
// THIRD
|
|
|
|
|
QuadData::Vertex v3;
|
|
|
|
|
v3.pos = mQuadData.vert_pos[2];
|
|
|
|
|
v3.tex_coord = glm::vec2(mQuadData.vert_tex[2].x * xScale + xOffset, mQuadData.vert_tex[2].y * yScale - yOffset);
|
|
|
|
|
v3.tex_coord = glm::vec2(mQuadData.vert_tex[2].x * scale_x + offset_x, mQuadData.vert_tex[2].y * scale_y - offset_y);
|
|
|
|
|
v3.color = color;
|
|
|
|
|
v3.tex_slot = texture_slot;
|
|
|
|
|
v3.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
|
|
|
|
|
v3.angle = angle;
|
|
|
|
|
v3.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
|
|
|
|
|
v3.tex_is_grey_scale = tex_is_grey_scale;
|
|
|
|
|
memcpy(&mQuadData.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v3, vert_size);
|
|
|
|
|
mQuadData.mRawBufferIndex += 1;
|
|
|
|
|
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v3, vert_size);
|
|
|
|
|
mQuadData.RawBufferIndex += 1;
|
|
|
|
|
|
|
|
|
|
// FOURTH
|
|
|
|
|
QuadData::Vertex v4;
|
|
|
|
|
v4.pos = mQuadData.vert_pos[3];
|
|
|
|
|
v4.tex_coord = glm::vec2(mQuadData.vert_tex[3].x * xScale + xOffset, mQuadData.vert_tex[3].y * yScale - yOffset);
|
|
|
|
|
v4.tex_coord = glm::vec2(mQuadData.vert_tex[3].x * scale_x + offset_x, mQuadData.vert_tex[3].y * scale_y - offset_y);
|
|
|
|
|
v4.color = color;
|
|
|
|
|
v4.tex_slot = texture_slot;
|
|
|
|
|
v4.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
|
|
|
|
|
v4.angle = angle;
|
|
|
|
|
v4.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
|
|
|
|
|
v4.tex_is_grey_scale = tex_is_grey_scale;
|
|
|
|
|
memcpy(&mQuadData.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v4, vert_size);
|
|
|
|
|
mQuadData.mRawBufferIndex += 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// memcpy(mQuadData.mRawVertexBuffer + mQuadData.mRawBufferIndex, vertices, sizeof(QuadData::Vertex) * 4);
|
|
|
|
|
// mQuadData.mRawBufferIndex += 4;
|
|
|
|
|
|
|
|
|
|
// if (!mQuadData.mVertexBuffer->PushVertices(vertices, 4))
|
|
|
|
|
// {
|
|
|
|
|
// //Logger::Info(LogCategory::GRAPHICS, "Quad VertexBuffer is full, flushing and retrying");
|
|
|
|
|
// Flush();
|
|
|
|
|
// DrawQuad(quad, color, texture);
|
|
|
|
|
// }
|
|
|
|
|
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v4, vert_size);
|
|
|
|
|
mQuadData.RawBufferIndex += 1;
|
|
|
|
|
mQuadData.NumQuads++;
|
|
|
|
|
|
|
|
|
|
// INDICES
|
|
|
|
|
// if (!mQuadData.mVertexBuffer->PushIndices(mQuadData.indices, 6))
|
|
|
|
|
// {
|
|
|
|
|
// Logger::Error(LogCategory::GRAPHICS, "Quad IndexBuffer is full - This shouldn't happen because the VertexBuffer should fill up first!");
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
mQuadData.mNumQuads++;
|
|
|
|
|
// Update render stats
|
|
|
|
|
mFrameStats.NumTris += 2;
|
|
|
|
|
mFrameStats.NumVerts += 4;
|
|
|
|
|
|
|
|
|
|
@ -341,9 +224,6 @@ namespace lunarium
|
|
|
|
|
|
|
|
|
|
void Renderer2D::DrawString(const char* string, Rectangle bounding_box, Color color, float scale, int font)
|
|
|
|
|
{
|
|
|
|
|
//Logger::Warn(LogCategory::GRAPHICS, "Renderer2D::DrawString is not yet implemented");
|
|
|
|
|
// mText.DrawString(font, string, glm::vec2(boundingArea.left(), boundingArea.top()),
|
|
|
|
|
// glm::vec2(boundingArea.right(), boundingArea.bottom()), color, scale, mProjection);
|
|
|
|
|
u32 f = font < 0 ? mDefaultFont : font;
|
|
|
|
|
mTextAPI.DrawString(*this, f, string, bounding_box, color, scale);
|
|
|
|
|
}
|
|
|
|
|
@ -352,66 +232,165 @@ namespace lunarium
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
// HELPERS
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Renderer2D::Flush()
|
|
|
|
|
void Renderer2D::Flush(int flush_mode)
|
|
|
|
|
{
|
|
|
|
|
if (mQuadData.mNumQuads > 0)
|
|
|
|
|
// Draw quads
|
|
|
|
|
if (mQuadData.NumQuads > 0 && flush_mode & (1 << FlushMode::Quads) > 0)
|
|
|
|
|
{
|
|
|
|
|
if (!mQuadData.mVertexBuffer->PushVertices(mQuadData.mRawVertexBuffer, mQuadData.mNumQuads * 4))
|
|
|
|
|
mQuadData.MarkedForReset = true;
|
|
|
|
|
if (!mQuadData.VertexBuffer->PushVertices(mQuadData.RawVertexBuffer, mQuadData.NumQuads * 4))
|
|
|
|
|
{
|
|
|
|
|
Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the quad buffer!");
|
|
|
|
|
ResetDrawingData();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//mQuadData.mIndexBuffer->Bind();
|
|
|
|
|
mQuadData.mQuadShader->Use();
|
|
|
|
|
for (int i = 0; i < mLoadedTextures.size(); i++)
|
|
|
|
|
mQuadData.QuadShader->Use();
|
|
|
|
|
for (int i = 0; i < mQuadData.LoadedTextures.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
mLoadedTextures[i]->Bind(i);
|
|
|
|
|
mQuadData.LoadedTextures[i]->Bind(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Uniform umodel;
|
|
|
|
|
// umodel.Type = UniformType::FMAT4;
|
|
|
|
|
// umodel.Location = -1;
|
|
|
|
|
// umodel.Name = "model";
|
|
|
|
|
|
|
|
|
|
Uniform uprojview;
|
|
|
|
|
uprojview.Type = UniformType::FMAT4;
|
|
|
|
|
uprojview.Location = -1;
|
|
|
|
|
uprojview.Name = "projview";
|
|
|
|
|
|
|
|
|
|
//mQuadData.mQuadShader->SetUniform(umodel, (void*)glm::value_ptr(glm::mat4(1.0f))).LogIfFailed(LogCategory::GRAPHICS);
|
|
|
|
|
mQuadData.mQuadShader->SetUniform(uprojview, (void*)glm::value_ptr(mpCamera->GetViewProjection())).LogIfFailed(LogCategory::GRAPHICS);
|
|
|
|
|
mQuadData.QuadShader->SetUniform(uprojview, (void*)glm::value_ptr(mpCamera->GetViewProjection())).LogIfFailed(LogCategory::GRAPHICS);
|
|
|
|
|
|
|
|
|
|
//Uniform uni { "spriteColor", UniformType::F3, -1 };
|
|
|
|
|
//Color c = ;
|
|
|
|
|
//mQuadData.mQuadShader->SetUniform(uni, Color::Red().arr).LogIfFailed(LogCategory::GRAPHICS, "Failed to set uniform for the test shader!");
|
|
|
|
|
mQuadData.VertexBuffer->Bind();
|
|
|
|
|
|
|
|
|
|
mQuadData.mVertexBuffer->Bind();
|
|
|
|
|
glDrawElements(GL_TRIANGLES, mQuadData.NumQuads * 6, GL_UNSIGNED_INT, nullptr);
|
|
|
|
|
|
|
|
|
|
glDrawElements(GL_TRIANGLES, mQuadData.mNumQuads * 6, GL_UNSIGNED_INT, nullptr);
|
|
|
|
|
// glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
|
|
|
|
// glLineWidth(20.0f);
|
|
|
|
|
// glDrawElements(GL_TRIANGLES, mQuadData.mNumQuads * 6, GL_UNSIGNED_INT, nullptr);
|
|
|
|
|
|
|
|
|
|
// glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
|
|
|
|
mFrameStats.DrawCalls++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw Lines
|
|
|
|
|
if (mLineData.NumLines > 0 && flush_mode & (1 << FlushMode::Lines) > 0)
|
|
|
|
|
{
|
|
|
|
|
mLineData.MarkedForReset = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw Ellipses
|
|
|
|
|
if (mEllipseData.NumEllipses > 0 && flush_mode & (1 << FlushMode::Ellipses) > 0)
|
|
|
|
|
{
|
|
|
|
|
mEllipseData.MarkedForReset = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset drawing data
|
|
|
|
|
for (int i = 0; i < mLoadedTextures.size(); i++)
|
|
|
|
|
ResetDrawingData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
// HELPERS HELPERS
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
OpRes Renderer2D::InitQuadData()
|
|
|
|
|
{
|
|
|
|
|
u32* indices = new u32[mQuadData.MaxIndices];
|
|
|
|
|
// Need to adjust the set of indices because they reference verts deeper into the buffer
|
|
|
|
|
// See Hazel for example of this
|
|
|
|
|
int offset = 0;
|
|
|
|
|
for (int i = 0; i < mQuadData.MaxIndices; i+=6)
|
|
|
|
|
{
|
|
|
|
|
for ( int j = 0; j < 6; j++)
|
|
|
|
|
{
|
|
|
|
|
indices[i + j] = mQuadData.indices[(i + j) % 6] + offset;
|
|
|
|
|
}
|
|
|
|
|
offset += 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// INIT QUAD DATA
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Position
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2 }); // Tex_coords
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 4 }); // Color
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // Texture Sampler Index
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // translation
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // angle
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Scale
|
|
|
|
|
mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // tex_is_grey_scale
|
|
|
|
|
mQuadData.VertexBuffer = VertexBuffer::Create(mQuadData.BufferLayout, mQuadData.MaxVertices, nullptr, mQuadData.MaxIndices, indices);
|
|
|
|
|
|
|
|
|
|
// RAW VERTEX BUFFER
|
|
|
|
|
mQuadData.RawVertexBuffer = new QuadData::Vertex[mQuadData.MaxVertices];
|
|
|
|
|
mQuadData.RawBufferIndex = 0;
|
|
|
|
|
|
|
|
|
|
int layout_size = mQuadData.BufferLayout.GetLayoutSizeInBytes();
|
|
|
|
|
int struct_size = sizeof(QuadData::Vertex);
|
|
|
|
|
if (struct_size != layout_size)
|
|
|
|
|
{
|
|
|
|
|
Logger::Error(LogCategory::GRAPHICS,
|
|
|
|
|
"Quad::Vertex struct size does not match the vertex layout size! struct: %d, layout: %d", struct_size, layout_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//mQuadData.mIndexBuffer = new IndexBuffer(mQuadData.MaxIndices * sizeof(u32));
|
|
|
|
|
|
|
|
|
|
std::string vert_source = File::ReadTextFile("quad.vert");
|
|
|
|
|
std::string frag_source = File::ReadTextFile("quad.frag");
|
|
|
|
|
mQuadData.QuadShader = new Shader(vert_source.c_str(), nullptr, frag_source.c_str());
|
|
|
|
|
if (!mQuadData.QuadShader->IsValid())
|
|
|
|
|
{
|
|
|
|
|
mLoadedTextures[i]->Unbind();
|
|
|
|
|
return OpRes::Fail("Failed to create the quad shader");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mLoadedTextures.clear();
|
|
|
|
|
mQuadData.mVertexBuffer->Clear();
|
|
|
|
|
mQuadData.mNumQuads = 0;
|
|
|
|
|
mQuadData.mRawBufferIndex = 0;
|
|
|
|
|
// INIT WHITE TEXTURE
|
|
|
|
|
u8 data[4] = {255, 255, 255, 255};
|
|
|
|
|
mQuadData.WhiteTexture = Texture::Create(data, 1, 1);
|
|
|
|
|
mQuadData.LoadedTextures.push_back(mQuadData.WhiteTexture);
|
|
|
|
|
|
|
|
|
|
return OpRes::OK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OpRes Renderer2D::InitLineData()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// TODO: Add the debug texture back to the map
|
|
|
|
|
mLoadedTextures.push_back(mpWhiteTexture);
|
|
|
|
|
return OpRes::OK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OpRes Renderer2D::InitEllipseData()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
return OpRes::OK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Renderer2D::ResetDrawingData()
|
|
|
|
|
{
|
|
|
|
|
// Reset Quad Data
|
|
|
|
|
if (mQuadData.MarkedForReset)
|
|
|
|
|
{
|
|
|
|
|
// Clear loaded textures
|
|
|
|
|
for (int i = 0; i < mQuadData.LoadedTextures.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
mQuadData.LoadedTextures[i]->Unbind();
|
|
|
|
|
}
|
|
|
|
|
mQuadData.LoadedTextures.clear();
|
|
|
|
|
|
|
|
|
|
// Except for the white texture
|
|
|
|
|
mQuadData.LoadedTextures.push_back(mQuadData.WhiteTexture);
|
|
|
|
|
|
|
|
|
|
mQuadData.VertexBuffer->Clear();
|
|
|
|
|
mQuadData.NumQuads = 0;
|
|
|
|
|
mQuadData.RawBufferIndex = 0;
|
|
|
|
|
|
|
|
|
|
mQuadData.MarkedForReset = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset Line Data
|
|
|
|
|
if (mLineData.MarkedForReset)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
mLineData.MarkedForReset = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset Ellipse Data
|
|
|
|
|
if (mEllipseData.MarkedForReset)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
mEllipseData.MarkedForReset = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Texture* Renderer2D::GetTextDebugTexture()
|
|
|
|
|
{
|
|
|
|
|
return mTextAPI.GetDebugTexture();
|
|
|
|
|
|