Hello.
I have some problem with AMD graphics card. I have a batch renderer and it renders text
I have tried to use OpenGL 4.6 and 3.0, the result is the same.
I have tried AMD radeon HD 6770, 6850, 5770 and the result is the same.
On GTX 1050 it renders as it should.
Does anybody know how to fix this?
Shader
#shader vertex
#version 330 core
layout(location = 0) in vec4 positionA;
layout(location = 1) in vec2 uvA;
layout(location = 2) in int staticA;
layout(location = 3) in vec4 colorA;
layout(location = 4) in float isGuiA;
layout(location = 5) in float texIndexA;
flat out int texIndex;
flat out int isGui;
out vec4 color;
out vec2 uv;
uniform mat4 u_ViewProjection;
uniform mat4 u_Projection;
void main()
{
if (staticA == 0)
{
gl_Position = u_ViewProjection * positionA;
}
else if (staticA > 1)
{
gl_Position = u_Projection * positionA;
}
uv = uvA;
color = colorA;
isGui = int(isGuiA);
texIndex = int(texIndexA);
};
#shader fragment
#version 330 core
layout(location = 0) out vec4 gl_FragColor;
flat in int texIndex;
flat in int isGui;
in vec4 color;
in vec2 uv;
uniform vec4 u_outlineColor;
uniform float u_width;
uniform float u_edge;
uniform float u_borderwidth;
uniform float u_borderedge;
uniform vec2 u_offset;
uniform sampler2D u_Texture[8];
void main()
{
if (isGui == 1)
{
vec4 texColor = texture(u_Texture[texIndex], uv);
gl_FragColor = color * texColor;
}
else if (isGui == 0)
{
float distance = 1.0 - texture(u_Texture[texIndex], uv).a;
float alpha = 1.0 - smoothstep(u_width, u_width + u_edge, distance);
float distance2 = 1.0 - texture(u_Texture[texIndex], uv + u_offset).a;
float outlinealpha = 1.0 - smoothstep(u_borderwidth, u_borderwidth + u_borderedge, distance2);
float overallalpha = alpha + (1.0 - alpha) * outlinealpha;
vec3 overallcolor = mix(vec3(u_outlineColor.r, u_outlineColor.g, u_outlineColor.b), vec3(color.r, color.g, color.b), alpha / overallalpha);
gl_FragColor = vec4(overallcolor, overallalpha);
}
};
Batch renderer
Batch.h
#pragma once
#include "../pch.h"
#include "Gui/Character.h"
#include <array>
#include <mutex>
namespace OGL {
#define MAX_TEXTURE_SLOTS 8
#define RENDERER_MAX_SPRITES 1000
#define RENDERER_INDICES_SIZE RENDERER_MAX_SPRITES * 6
class Batch {
private:
struct TextVertex {
glm::vec2 m_Vertex;
glm::vec2 m_UV;
int m_Static;
glm::vec4 m_Color;
float m_IsGui;
float m_TexIndex;
};
struct VertAttribWrapper {
std::array<uint32_t, MAX_TEXTURE_SLOTS> m_TextureSlots;
unsigned int m_TextureSlotsIndex = 2;
float m_TextureIndex = 0;
TextVertex* m_BufferT = nullptr;
TextVertex* m_BufferPtrT = nullptr;
GLuint m_Vao;
GLuint m_Vbo;
IndexBuffer m_Ibo;
~VertAttribWrapper()
{
glDeleteBuffers(1, &m_Vbo);
}
};
VertAttribWrapper m_TextB;
Shader* m_Shader = nullptr;
const unsigned int maxTextureSlots = MAX_TEXTURE_SLOTS;
void InitText();
Batch();
Batch(const Batch&) = delete;
Batch& operator=(const Batch&) { return *this; }
~Batch();
public:
Shader* m_TextShader = Shader::Get("Font");
GLsizei m_TIndexCount = 0;
static Batch& GetInstance();
void Submit(Character* character);
void Submit(float* mesh2D, glm::vec4 color, Texture* texture = nullptr);
void FlushText(Shader* shader);
void BeginText();
void EndText();
};
}
Batch.cpp
#include "Batch.h"
#include "Gui/Gui.h"
#include "../Utils.h"
using namespace OGL;
Batch::Batch()
{
InitText();
std::cout << BOLDGREEN << "Initialized Batch rendering" << RESET << std::endl;
}
Batch::~Batch()
{
}
Batch& Batch::GetInstance()
{
static Batch instance;
return instance;
}
void Batch::Submit(Character* c)
{
if (m_TextB.m_TextureSlotsIndex > maxTextureSlots - 1)
{
EndText();
FlushText(m_Shader);
BeginText();
}
m_TextB.m_TextureIndex = 0.0f;
//std::cout << "Batch " << c.position.x << " " << c.position.y << std::endl;
for (unsigned int i = 0; i < maxTextureSlots; i++)
{
if (m_TextB.m_TextureSlots[i] == c->m_Font->m_FontAtlas->m_RendererID)
{
m_TextB.m_TextureIndex = (float)i;
break;
}
}
if (m_TextB.m_TextureIndex == 0.0f)
{
m_TextB.m_TextureIndex = (float)m_TextB.m_TextureSlotsIndex;
m_TextB.m_TextureSlots[m_TextB.m_TextureSlotsIndex] = c->m_Font->m_FontAtlas->m_RendererID;
m_TextB.m_TextureSlotsIndex++;
}
m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[0] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[1]) * c->m_Scale.y + c->m_Position.y));
m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[2], c->m_Mesh2D[3]);
m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
m_TextB.m_BufferT->m_Color = c->m_Color;
m_TextB.m_BufferT->m_IsGui = 0.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[4] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[5]) * c->m_Scale.y + c->m_Position.y));
m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[6], c->m_Mesh2D[7]);
m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
m_TextB.m_BufferT->m_Color = c->m_Color;
m_TextB.m_BufferT->m_IsGui = 0.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[8] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[9]) * c->m_Scale.y + c->m_Position.y));
m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[10], c->m_Mesh2D[11]);
m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
m_TextB.m_BufferT->m_Color = c->m_Color;
m_TextB.m_BufferT->m_IsGui = 0.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TextB.m_BufferT->m_Vertex = glm::vec2((c->m_Mesh2D[12] * c->m_Scale.x + c->m_Position.x), ((c->m_Mesh2D[13]) * c->m_Scale.y + c->m_Position.y));
m_TextB.m_BufferT->m_UV = glm::vec2(c->m_Mesh2D[14], c->m_Mesh2D[15]);
m_TextB.m_BufferT->m_Static = c->m_IsRelatedToCam;
m_TextB.m_BufferT->m_Color = c->m_Color;
m_TextB.m_BufferT->m_IsGui = 0.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TIndexCount += 6;
}
void Batch::Submit(float* mesh2D, glm::vec4 color, Texture* texture)
{
if (m_TextB.m_TextureSlotsIndex > maxTextureSlots - 1)
{
EndText();
FlushText(m_Shader);
BeginText();
}
m_TextB.m_TextureIndex = 0.0f;
if (texture != nullptr)
{
for (unsigned int i = 0; i < maxTextureSlots; i++)
{
if (m_TextB.m_TextureSlots[i] == texture->m_RendererID)
{
m_TextB.m_TextureIndex = (float)i;
break;
}
}
if (m_TextB.m_TextureIndex == 0.0f)
{
m_TextB.m_TextureIndex = (float)m_TextB.m_TextureSlotsIndex;
m_TextB.m_TextureSlots[m_TextB.m_TextureSlotsIndex] = texture->m_RendererID;
m_TextB.m_TextureSlotsIndex++;
}
}
m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[0]), mesh2D[1]);
m_TextB.m_BufferT->m_UV = glm::vec2(0,0);
m_TextB.m_BufferT->m_Static = true;
m_TextB.m_BufferT->m_Color = color;
m_TextB.m_BufferT->m_IsGui = 1.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[2]), (mesh2D[3]));
m_TextB.m_BufferT->m_UV = glm::vec2(1.0f, 0.0f);
m_TextB.m_BufferT->m_Static = true;
m_TextB.m_BufferT->m_Color = color;
m_TextB.m_BufferT->m_IsGui = 1.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[4]), (mesh2D[5]));
m_TextB.m_BufferT->m_UV = glm::vec2(1.0f, 1.0f);
m_TextB.m_BufferT->m_Static = true;
m_TextB.m_BufferT->m_Color = color;
m_TextB.m_BufferT->m_IsGui = 1.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TextB.m_BufferT->m_Vertex = glm::vec2((mesh2D[6]), ((mesh2D[7])));
m_TextB.m_BufferT->m_UV = glm::vec2(0.0f, 1.0f);
m_TextB.m_BufferT->m_Static = true;
m_TextB.m_BufferT->m_Color = color;
m_TextB.m_BufferT->m_IsGui = 1.0f;
m_TextB.m_BufferT->m_TexIndex = m_TextB.m_TextureIndex;
m_TextB.m_BufferT++;
m_TIndexCount += 6;
}
void Batch::BeginText()
{
m_TextB.m_BufferT = m_TextB.m_BufferPtrT;
m_TIndexCount = 0;
}
void Batch::EndText()
{
uint32_t dataSize = (uint8_t*)m_TextB.m_BufferT - (uint8_t*)m_TextB.m_BufferPtrT;
glBindBuffer(GL_ARRAY_BUFFER, m_TextB.m_Vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, m_TextB.m_BufferPtrT);
}
void Batch::FlushText(Shader* shader)
{
glBindVertexArray(m_TextB.m_Vao);
m_TextB.m_Ibo.Bind();
shader->Bind();
int samplers[MAX_TEXTURE_SLOTS];
for (unsigned int i = 0; i < m_TextB.m_TextureSlotsIndex; i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, m_TextB.m_TextureSlots[i]);
}
for (unsigned int i = 0; i < maxTextureSlots; i++)
{
samplers[i] = i;
}
Gui& g = Gui::GetInstance();
shader->SetUniform1iv("u_Texture", samplers);
shader->SetUniformMat4f("u_Projection", g.m_ViewProjecTionMat4RelatedToCamera);
shader->SetUniformMat4f("u_ViewProjection", Window::GetInstance().GetCamera().GetViewProjectionMatrix());
shader->SetUniform2fv("u_offset", g.m_TextProps.m_ShadowOffset);
shader->SetUniform1f("u_width", g.m_TextProps.m_Width);
shader->SetUniform1f("u_edge", g.m_TextProps.m_Edge);
shader->SetUniform1f("u_borderwidth", g.m_TextProps.m_BorderWidth);
shader->SetUniform1f("u_borderedge", g.m_TextProps.m_BorderEdge);
shader->SetUniform4fv("u_outlineColor", g.m_TextProps.m_OutLineColor);
glDrawElements(GL_TRIANGLES, m_TIndexCount, GL_UNSIGNED_INT, NULL);
shader->UnBind();
m_TextB.m_Ibo.UnBind();
glBindVertexArray(0);
m_TextB.m_TextureSlotsIndex = 1;
m_TextB.m_TextureSlots[0] = Texture::s_WhiteTexture->m_RendererID;
for (unsigned int i = m_TextB.m_TextureSlotsIndex; i < MAX_TEXTURE_SLOTS; i++)
{
m_TextB.m_TextureSlots[i] = 0;
glBindTexture(GL_TEXTURE_2D, 0);
}
}
void Batch::InitText()
{
glGenVertexArrays(1, &m_TextB.m_Vao);
glBindVertexArray(m_TextB.m_Vao);
glGenBuffers(1, &m_TextB.m_Vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_TextB.m_Vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(TextVertex) * 4 * RENDERER_MAX_SPRITES, NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_Vertex));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_UV));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_Static));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_Color));
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_IsGui));
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (const GLvoid*)offsetof(TextVertex, m_TexIndex));
glBindBuffer(GL_ARRAY_BUFFER, 0);
unsigned int indices[RENDERER_INDICES_SIZE];
unsigned int offset = 0;
for (unsigned int i = 0; i < RENDERER_INDICES_SIZE; i += 6)
{
indices[i + 0] = offset + 0;
indices[i + 1] = offset + 1;
indices[i + 2] = offset + 2;
indices[i + 3] = offset + 2;
indices[i + 4] = offset + 3;
indices[i + 5] = offset + 0;
offset += 4;
}
m_TextB.m_BufferPtrT = new TextVertex[RENDERER_MAX_SPRITES];
m_TextB.m_Ibo.Init(indices, RENDERER_INDICES_SIZE);
glBindVertexArray(0);
m_TextB.m_TextureSlots[0] = Texture::s_WhiteTexture->m_RendererID;
for (unsigned int i = 1; i < MAX_TEXTURE_SLOTS; i++)
{
m_TextB.m_TextureSlots[i] = 0;
}
}
Call
Main.cpp
OGL::Batch::GetInstance().m_TIndexCount = 0;
OGL::Batch::GetInstance().BeginText();
OnGuiRender();
OGL::Batch::GetInstance().EndText();
glDisable(GL_DEPTH_TEST);
OGL::Batch::GetInstance().FlushText(fontShader);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);