This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

MultiSample AntiAliasing using multisample FBO

I am trying to implement anti aliasing using multisampling. Here i have used FBO1(fboID) for multisampling.
I am reendering my texture image to a multisampled render buffer(colorBufID) and using it as an attachment point

for FBO. Then i have created another FBO2(frameBUfID) and blit  from FBO1 to FBO2 but i get error at glBlitFrameBuffer.

Could you please explain if the implementation is correct .

#include <math.h>
#include "Timer.h"
#include <time.h>
#include <string>
#include "win_process.h"
#include "Matrix.h"
#include "ETCHeader.h"
#include "gts_log.h"
//#include "Texture.h"
#include "imageload.h"

#define EGL_EGLEXT_PROTOTYPES 1
#define GL_GLEXT_PROTOTYPES 1
#include "GLES3/gl3.h"
#include "GLES3/gl3ext.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"
//#include <stdbool.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
//#include <GLES/gl.h>
//#include <GLES/glext.h>

using namespace std;

#define WINDOW_W 1920
#define WINDOW_H 1080
#define FRAMECOUNT 500
unsigned int uiWidth  = WINDOW_W;
unsigned int uiHeight = WINDOW_H;
extern EGLDisplay sEGLDisplay;
extern EGLContext sEGLContext;
extern EGLSurface sEGLSurface;


char *bmp_texpath = {
   
    "./assets/Raw1.bmp",
   
    };
   
   
ImageData img ;
GLuint bmp_texid;
GLuint depthTexID;

GLuint texId[5];
std::string asset = "assets/";
GLuint bufferObjectIds[2] = {0};
GLuint texbuf ;
GLuint vertexArrayId; 
float scalingFactor = 0.75f;
Timer fpsTimer;
GLuint uiProgramObject;
//GLuint modelViewMatrixLocation;
    GLuint fboID;
    GLuint colorBufID;
    GLuint defaultDepthBuffer;
    GLuint frameBufID;

GLuint positionLocation;
GLuint textureCoordinateLocation;
GLuint textureLocation;
int num_textures = 5;
int cur_index = 0;
bool compress = false;
float fps_time = 0.0,cur_time = 0.0;
int framecount = 0;
int angle = 0 ;
clock_t curTime,lastTime;


GLuint esLoadShader ( GLenum type, const char *shaderSrc )
{
   
       GLuint shader;
       GLint compiled;
    shader = glCreateShader ( type );
       if ( shader == 0 )
       {
              return 0;
       }

       glShaderSource ( shader, 1, &shaderSrc, NULL );
       glCompileShader ( shader );
       glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
       if ( !compiled )
       {
              GLint infoLen = 0;
              glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
              if ( infoLen > 1 )
              {
                 char *infoLog =(char *) malloc ( sizeof ( char ) * infoLen );
                 glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
                 printf("Log START:\n%s\nLog END\n\n", infoLog);
                 free ( infoLog );
              }
              glDeleteShader ( shader );
              return 0;
       }
       return shader;
}

GLuint esLoadProgram ( char *vertShaderSrc, char *fragShaderSrc )
{
    GLint uprogramObject;
       GLint linked;
          GLuint vertexShader;
       GLuint fragmentShader;
       vertexShader = esLoadShader ( GL_VERTEX_SHADER, vertShaderSrc );
       if ( vertexShader == 0 )
       {
              return 0;
       }
       fragmentShader = esLoadShader ( GL_FRAGMENT_SHADER, fragShaderSrc );
    if ( fragmentShader == 0 )
       {
              glDeleteShader ( vertexShader );
              return 0;
       }
       uprogramObject = glCreateProgram ( );
       if ( uprogramObject == 0 )
       {
              return 0;
       }
       glAttachShader ( uprogramObject, vertexShader );
       glAttachShader ( uprogramObject, fragmentShader );
       glLinkProgram ( uprogramObject );
       glGetProgramiv ( uprogramObject, GL_LINK_STATUS, &linked );

       if ( !linked )
       {
              GLint infoLen = 0;
              glGetProgramiv ( uprogramObject, GL_INFO_LOG_LENGTH, &infoLen );
              if ( infoLen > 1 )
              {
                 char *infoLog = (char *)malloc ( sizeof ( char ) * infoLen );
                 glGetProgramInfoLog ( uprogramObject, infoLen, NULL, infoLog );
                 printf("Log START:\n%s\nLog END\n\n", infoLog);
                 free ( infoLog );
              }
              glDeleteProgram ( uprogramObject );
              return 0;
       }
       glDeleteShader ( vertexShader );
       glDeleteShader ( fragmentShader );
       return uprogramObject;
}


int loadBMPTexture()
{
   
    GLint maxSamples;
        glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
        printf("%d\n",maxSamples);
   
        GL_CHECK(glGenFramebuffers(1, &fboID));
        printf("here\n");
        GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER,fboID));
        printf("3\n");
           
        printf("2");
        GL_CHECK(glGenRenderbuffers(1,&colorBufID));
       
        GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, colorBufID));
        printf("4\n");
        GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8,img.OriginalImageWidth ,img.OriginalImageHeight ));
        printf("6\n");
        GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBufID));
            printf("7\n");   
       
       
        GetImageFromBMP(&img,bmp_texpath);
       
       

        if(img.imagedata != NULL)
        {
            GL_CHECK(glGenTextures(1,&bmp_texid));
            GL_CHECK(glActiveTexture(GL_TEXTURE0));
            GL_CHECK(glBindTexture(GL_TEXTURE_2D, bmp_texid));
            GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.OriginalImageWidth, img.OriginalImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.imagedata));
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            printf("1\n");
            //GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
           
           
           
            /*
            glGenTextures( 1, &depthTexID );
            GL_CHECK(glBindTexture( GL_TEXTURE_2D, depthTexID ));
            GL_CHECK(glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, img.OriginalImageWidth, img.OriginalImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.imagedata ));
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
            //glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY );
           
            */
           
           
           
           
        }
        else
        {
            printf("Could not load %s",bmp_texpath);
            return -1;
        }
       
       
        GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bmp_texid, 0));
        printf("15\n");
       
            if( GL_FRAMEBUFFER_COMPLETE== glCheckFramebufferStatus( GL_FRAMEBUFFER ))
            {printf("\nFBO crreation complete\n");
            }
            else
            {
            printf("not complete");
        }
           
        GL_CHECK(glGenRenderbuffers(1,&defaultDepthBuffer));
        printf("8\n");
        GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer));
        printf("9\n");
        GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER,4, GL_DEPTH_COMPONENT16, img.OriginalImageWidth,img.OriginalImageHeight));
        GL_CHECK(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer ));
        GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0));
        /*
        GetImageFromBMP(&img,bmp_texpath);
       
        if(img.imagedata != NULL)
        {
            GL_CHECK(glGenTextures( 1, &depthTexID ));
            GL_CHECK(glBindTexture( GL_TEXTURE_2D, depthTexID ));
            GL_CHECK(glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, img.OriginalImageWidth, img.OriginalImageHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL ));
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
           
               
        }
        else
        {
            printf("Could not load %s",bmp_texpath);
            return -1;
        }
       
        GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexID, 0));

        */
        //glBindRenderbuffer( GL_RENDERBUFFER, 0 );
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        printf("11\n");
        printf("12\n");
        //GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexID, 0));
       
        glGenFramebuffers(1, &frameBufID);
        
        GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBufID));
        printf("14\n");
        GL_CHECK(glBindFramebuffer( GL_FRAMEBUFFER,fboID  ));
       
           
            //glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
            //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
       
       
    //}
    return 0;
}

int multisample_init()
{

   
    if(loadBMPTexture() == -1)
        return -1;
    GLfloat vertices[] =
    {
        -1,     -1,    0, // bottom-left
        -1,      1,    0, // bottom-right
         1,      1,    0, // top-right
         1,     -1,    0, // top-left
    };

    GLfloat texcoords_bmp[] =
    {
        0, 0,
        0, 1,
        1, 1,
        1, 0
    };
   

    GLushort indices[] =
    {
        0, 2, 1,
        0, 3, 2
    };

    GL_CHECK(glGenVertexArrays(1, &vertexArrayId));
    GL_CHECK(glBindVertexArray(vertexArrayId));

    GL_CHECK(glGenBuffers(2, bufferObjectIds));
    GL_CHECK(glGenBuffers(1, &texbuf));

    GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bufferObjectIds[0]));
    GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));

       
    GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjectIds[1]));
    GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));
       
   
    GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, texbuf));
    GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords_bmp), texcoords_bmp, GL_STATIC_DRAW));

    positionLocation          = GL_CHECK(glGetAttribLocation (uiProgramObject, "attributePosition"));
    printf("\nvalue of positionLocation:%d\n",positionLocation);
    textureCoordinateLocation = GL_CHECK(glGetAttribLocation (uiProgramObject, "attributeTextureCoordinate"));
    printf("\nvalue of textureCoordinateLocation:%d\n",textureCoordinateLocation);
    textureLocation           = GL_CHECK(glGetUniformLocation(uiProgramObject, "uniformTexture"));
    printf("\nvalue of textureLocation:%d\n",textureLocation);

    glEnableVertexAttribArray(positionLocation);
    GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bufferObjectIds[0]));
    GL_CHECK(glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0));

    return 0;
}

int multisample_render()
{
    GLubyte *pixels;
    pixels = (GLubyte*) malloc(img.OriginalImageWidth * img.OriginalImageHeight * 4);
       
    printf("16\n");
   
    GL_CHECK(glEnableVertexAttribArray(textureCoordinateLocation));
            lastTime = clock();
            GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, texbuf));
            GL_CHECK(glVertexAttribPointer(textureCoordinateLocation, 2, GL_FLOAT, GL_FALSE, 0, 0));
            //GL_CHECK(glBindTexture(GL_TEXTURE_2D, bmp_texid));
           
       
       
        //GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
        //glDrawBuffers(1, DrawBuffers[0]);
    /*
            const GLenum attachments[1] =
        {
          GL_COLOR_ATTACHMENT0,
         };
        */
           
            curTime  = clock();
            double deltaTime =  (double)(curTime - lastTime) / (double)CLOCKS_PER_SEC;
            //printf("Time : %f\tCompression:%d\n",deltaTime,compress);
    //    }

        if (textureLocation != -1)
        {
            printf("\nvalue of texturelocation%d\n",textureLocation);
            GL_CHECK(glUniform1i(textureLocation, 0));
        }
       
           
               GL_CHECK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)0));
          
              
               GL_CHECK(glBindFramebuffer( GL_FRAMEBUFFER, 0 ));
            GL_CHECK(glBindFramebuffer( GL_READ_FRAMEBUFFER, fboID));
            GL_CHECK(glBindFramebuffer( GL_DRAW_FRAMEBUFFER,frameBufID));
            //GL_CHECK(glBindFramebuffer( GL_DRAW_FRAMEBUFFER,0));
            //GL_CHECK(glDrawBuffers(1,attachments));
            //GL_CHECK(glReadBuffer(GL_COLOR_ATTACHMENT0));
            GL_CHECK(glBlitFramebuffer( 0, 0, img.OriginalImageWidth, img.OriginalImageHeight, 0, 0, img.OriginalImageWidth, img.OriginalImageHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST ));
        //    GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fboID));
       
              
            //glReadPixels(0, 0, img.OriginalImageWidth, img.OriginalImageHeight, GL_RGBA8, GL_UNSIGNED_BYTE, pixels);
            //glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
            //glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );

    //}
       
       
       
   
    EGL_CHECK(eglSwapBuffers(sEGLDisplay,sEGLSurface));
   
    angle+=2;
    if(angle > 360)
        angle = 0;
    return 0;
}


int MultiSample() {


    char fstr[]=
    "#version 300 es \n"
    "precision mediump float;\n"
    "uniform sampler2D uniformTexture;\n"
    "in      vec2      varyingTextureCoordinate;\n"
    "out     vec4      colour;\n"
    "void main()\n"
    "{\n"
    "    colour = texture(uniformTexture, varyingTextureCoordinate);\n"
    "}\n";
   
    char vstr[]=
    "#version 300 es \n"
    "in        vec4 attributePosition; \n"
    "in        vec2 attributeTextureCoordinate;\n"
    "out         vec2 varyingTextureCoordinate;\n"
    "void main()\n"
    "{\n"
    "    varyingTextureCoordinate = attributeTextureCoordinate;\n"
    "    gl_Position              = attributePosition;\n"
    "}\n";

   
    uiProgramObject=esLoadProgram ( vstr, fstr );

    GL_CHECK(glUseProgram(uiProgramObject));
    GL_CHECK(glViewport(0, 0, uiWidth,uiHeight));
   
    if(!multisample_init())
    {   
        while(1)   
        {   
            float a = 0.0,r = 0.0,g = 0.0,b = 0.0;
           
       
            //for(int fp =0;fp < FRAMECOUNT;fp++)
            //{
                //GL_CHECK(glClearColor(r,g,b,a));
                //GL_CHECK(glClear(GL_COLOR_BUFFER_BIT));
                multisample_render();
           
             //   a += 0.01;
              //  if( a > 1.0)
                //    a = 0.0;
                //r=g=b=a;
            //}
            compress =1;
            angle = 0;
        }
    }
   
    GL_CHECK(glDeleteProgram(uiProgramObject));
    GL_CHECK(glDeleteBuffers(2,bufferObjectIds));
    GL_CHECK(glDeleteBuffers(1,&texbuf));
    return 0;
}
Parents
  • Hi shanksanhoi,

    Can I ask why you are manually implementing MSAA? Is this to better understand or experiment with?

    If not however, I would like to kindly point out that Mali natively supports 4xMSAA with virtually no performance hit. We also support 16xMSAA but with a performance penalty.

    To set this, you simply need to change your EGL_SAMPLES to either 0, 4 or 16.

    I hope this helps, if you have any further questions, please feel free to ask.

    Kind Regards,

    Michael McGeagh

Reply
  • Hi shanksanhoi,

    Can I ask why you are manually implementing MSAA? Is this to better understand or experiment with?

    If not however, I would like to kindly point out that Mali natively supports 4xMSAA with virtually no performance hit. We also support 16xMSAA but with a performance penalty.

    To set this, you simply need to change your EGL_SAMPLES to either 0, 4 or 16.

    I hope this helps, if you have any further questions, please feel free to ask.

    Kind Regards,

    Michael McGeagh

Children