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; }