#include "SuperAA.h" #include SuperAA::SuperAA(int aaValue) : m_aa(aaValue), m_vao(0), m_width(0), m_height(0) { if (aaValue > 1) { const char* vertexShader = R"glsl( #version 410 core // outputs out vec2 fsTexCoord; void main(void) { const vec4 vertices[] = vec4[](vec4(-1.0, -1.0, 0.0, 1.0), vec4(-1.0, 1.0, 0.0, 1.0), vec4( 1.0, -1.0, 0.0, 1.0), vec4( 1.0, 1.0, 0.0, 1.0)); fsTexCoord = (vertices[gl_VertexID % 4].xy + 1.0) / 2.0; gl_Position = vertices[gl_VertexID % 4]; } )glsl"; std::string fragmentShaderVersion = R"glsl( #version 410 core )glsl"; std::string aaString = "const int aa = "; aaString += std::to_string(aaValue); aaString += ";\n"; std::string fragmentShader = R"glsl( // inputs uniform sampler2D tex1; // base tex in vec2 fsTexCoord; // outputs out vec4 fragColor; vec4 GetTextureValue(sampler2D s, vec2 texCoord) { vec2 size = vec2(textureSize(s,0)); // want the values as floats ivec2 texPos = ivec2(size * texCoord); vec4 texColour = vec4(0.0); for(int i=0; i < aa; i++) { for(int j=0; j < aa; j++) { texColour += texelFetch(s,ivec2(texPos.x+i,texPos.y+j),0); } } texColour /= float(aa * aa); return texColour; } void main() { fragColor = GetTextureValue(tex1, fsTexCoord); } )glsl"; std::string fragmentShaderString = fragmentShaderVersion + aaString + fragmentShader; // load shaders m_shader.LoadShaders(vertexShader, fragmentShaderString.c_str()); m_shader.GetUniformLocationMap("tex1"); // setup uniform memory m_shader.EnableShader(); glUniform1i(m_shader.attribLocMap["tex1"], 0); // texture will be bound to unit zero m_shader.DisableShader(); glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); // no states needed since we do it in the shader glBindVertexArray(0); } } // need an active context bound to the current thread to destroy our objects SuperAA::~SuperAA() { m_shader.UnloadShaders(); m_fbo.Destroy(); if (m_vao) { glDeleteVertexArrays(1, &m_vao); m_vao = 0; } } void SuperAA::Init(int width, int height) { if (m_aa > 1) { m_fbo.Destroy(); m_fbo.Create(width * m_aa, height * m_aa); m_width = width; m_height = height; } } void SuperAA::Draw() { if (m_aa > 1) { glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, m_fbo.GetTextureID()); glBindVertexArray(m_vao); glViewport(0, 0, m_width, m_height); m_shader.EnableShader(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_shader.DisableShader(); glBindVertexArray(0); } } GLuint SuperAA::GetTargetID() { return m_fbo.GetFBOID(); // will return 0 if no render target which will be our default frame buffer (back buffer) }