Exemple #1
0
int Splat_Prepare(SDL_Window *userWindow, int userViewportWidth, int userViewportHeight) {
  int width, height;
  window = userWindow;
  viewportWidth = userViewportWidth;
  viewportHeight = userViewportHeight;
  SDL_GetWindowSize(userWindow, &width, &height);

  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

  window_glcontext = SDL_GL_CreateContext(window);
  if (!window_glcontext) {
    Splat_SetError("OpenGL context creation failed.  Check glGetError() and/or SDL_GetError() for more information.");
    Splat_Finish();
    return -1;
  }

  // Our shading model--Flat
  glShadeModel(GL_FLAT);

  // Default the clear color to black.
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

  // Setup our viewport.
  glViewport(0, 0, viewportWidth, viewportHeight);

  // Change to the projection matrix and set up our ortho view
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, width, 0, height);

  // Set up modelview for 2D integer coordinates
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef(0.375f, height + 0.375f, 0.0f);
  glScalef(1.0f, -1.0f, 0.001f); // Make the positive Z-axis point "out" from the view (e.g images at depth 4 will be higher than those at depth 0), and swap the Y axis

  /* Deactivate the system cursor */
  SDL_ShowCursor(SDL_DISABLE);

  glDisable(GL_DITHER);

  /* Create the frame buffer for rendering to texture*/
  glGenFramebuffers(1, &framebuffer);

  glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

  /* Set up the texture to which we're going to render */
  glGenTextures(1, &frameTexture);
  glBindTexture(GL_TEXTURE_2D, frameTexture);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, viewportWidth, viewportHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

  /* Configure the framebuffer texture */
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameTexture, 0);
  GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
  glDrawBuffers(1, DrawBuffers);

  GLenum err = glGetError();
  if (err != GL_NO_ERROR) {
    Splat_SetError("OpenGL error occurred during initialization");
    Splat_Finish();
    return -1;
  }

  return 0;
}
Exemple #2
0
void nativeRecord::init(){
	_eglCreateImageKHR = ( PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress ( "eglCreateImageKHR" );
	_eglDestroyImageKHR = ( PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress( "eglDestroyImageKHR" );
	_glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress( "glEGLImageTargetTexture2DOES" );
	if(_eglCreateImageKHR == NULL){
		LOGD("_eglCreateImageKHR error");
		exit(1);
	}
	if(_eglDestroyImageKHR == NULL){
		LOGD("_eglDestroyImageKHR error");
		exit(1);
	}
	if(_glEGLImageTargetTexture2DOES == NULL){
		LOGD("_glEGLImageTargetTexture2DOES error");
		exit(1);
	}
	buffer =  new GraphicBuffer ( gWidth ,  gHeight ,
			HAL_PIXEL_FORMAT_BGRA_8888,
            GraphicBuffer :: USAGE_SW_READ_OFTEN |
            GraphicBuffer :: USAGE_HW_TEXTURE );
	if((buffer->initCheck ()) != NO_ERROR)
		exit (1);
	android_native_buffer_t * anb = buffer->getNativeBuffer();
	const EGLint attrs [] =
	{
			EGL_IMAGE_PRESERVED_KHR , EGL_TRUE,
			EGL_NONE, EGL_NONE
	};
	pEGLImage = _eglCreateImageKHR(eglGetCurrentDisplay(),EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)anb, attrs);

	if(EGL_SUCCESS != eglGetError()) {
		LOGI("_eglCreateImageKHR failed.");
				return;
	}
	glGenTextures(1 , &iFBOTex );
	checkGlError("glGenTextures(1 , &iFBOTex );");
	glBindTexture(GL_TEXTURE_2D , iFBOTex);
	checkGlError("glBindTexture(GL_TEXTURE_2D , iFBOTex);");
//	glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
//	glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER, GL_LINEAR );

	glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, gWidth, gHeight,
				 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
	if(GL_NO_ERROR != glGetError()) {
		LOGI("glTexImage2D failed.");
		return;
	}

	glGenFramebuffers (1, &iFBO);
	checkGlError("glGenFramebuffers (1, &iFBO);");
	glBindFramebuffer (GL_FRAMEBUFFER, iFBO);
	checkGlError("glBindFramebuffer (GL_FRAMEBUFFER, iFBO)");
	glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, iFBOTex, 0);

	GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if(status != GL_FRAMEBUFFER_COMPLETE) {
		LOGI("glCheckFramebufferStatus %d", status);
	}

	checkGlError("glFramebufferTexture2D");
	_glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, pEGLImage);
	checkGlError("_glEGLImageTargetTexture2DOES");
	glBindFramebuffer (GL_FRAMEBUFFER,0);
	checkGlError("glBindFramebuffer (GL_FRAMEBUFFER,0)");

	pixels = (char*)malloc(720*1280*4);
	memset(pixels,0,720*1280*4);
}
Exemple #3
0
static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
	int error = 0;

	// Get the b frame from the stack
	mlt_frame b_frame = (mlt_frame) mlt_frame_pop_frame( a_frame );

	// Get the transition object
	mlt_transition transition = (mlt_transition) mlt_frame_pop_service( a_frame );

	// Get the properties of the transition
	mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );

	// Get the properties of the a frame
	mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );

	// Get the movit objects
	mlt_service service = MLT_TRANSITION_SERVICE( transition );
	mlt_service_lock( service );
	EffectChain* chain = GlslManager::get_chain( service );
	Effect* effect = (Effect*) mlt_properties_get_data( properties, "movit effect", NULL );
	MltInput* a_input = GlslManager::get_input( service );
	MltInput* b_input = (MltInput*) mlt_properties_get_data( properties, "movit input B", NULL );
	mlt_image_format output_format = *format;

	if ( !chain || !a_input ) {
		mlt_service_unlock( service );
		return 2;
	}

	// Get the transition parameters
	int reverse = mlt_properties_get_int( properties, "reverse" );
	double mix = mlt_properties_get( properties, "mix" ) ?
		mlt_properties_get_double( properties, "mix" ) :
		mlt_transition_get_progress( transition, a_frame );
	double inverse = 1.0 - mix;

	// Set the movit parameters
	bool ok = effect->set_float( "strength_first",  reverse ? mix : inverse );
	ok     |= effect->set_float( "strength_second", reverse ? inverse : mix );
	assert( ok );

	// Get the frames' textures
	GLuint* texture_id[2] = {0, 0};
	*format = mlt_image_glsl_texture;
	mlt_frame_get_image( a_frame, (uint8_t**) &texture_id[0], format, width, height, 0 );
	a_input->useFBOInput( chain, *texture_id[0] );
	*format = mlt_image_glsl_texture;
	mlt_frame_get_image( b_frame, (uint8_t**) &texture_id[1], format, width, height, 0 );
	b_input->useFBOInput( chain, *texture_id[1] );

	// Set resolution to that of the a_frame
	*width = mlt_properties_get_int( a_props, "width" );
	*height = mlt_properties_get_int( a_props, "height" );

	// Setup rendering to an FBO
	GlslManager* glsl = GlslManager::get_instance();
	glsl_fbo fbo = glsl->get_fbo( *width, *height );
	if ( output_format == mlt_image_glsl_texture ) {
		glsl_texture texture = glsl->get_texture( *width, *height, GL_RGBA );

		glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
		check_error();
		glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
		check_error();
		glBindFramebuffer( GL_FRAMEBUFFER, 0 );
		check_error();

		GlslManager::render( service, chain, fbo->fbo, *width, *height );

		glFinish();
		check_error();
		glBindFramebuffer( GL_FRAMEBUFFER, 0 );
		check_error();

		*image = (uint8_t*) &texture->texture;
		mlt_frame_set_image( a_frame, *image, 0, NULL );
		mlt_properties_set_data( properties, "movit.convert", texture, 0,
			(mlt_destructor) GlslManager::release_texture, NULL );
		*format = output_format;
	}
	else {
		// Use a PBO to hold the data we read back with glReadPixels()
		// (Intel/DRI goes into a slow path if we don't read to PBO)
		GLenum gl_format = ( output_format == mlt_image_rgb24a || output_format == mlt_image_opengl )?
			GL_RGBA : GL_RGB;
		int img_size = *width * *height * ( gl_format == GL_RGB? 3 : 4 );
		glsl_pbo pbo = glsl->get_pbo( img_size );
		glsl_texture texture = glsl->get_texture( *width, *height, gl_format );

		if ( fbo && pbo && texture ) {
			// Set the FBO
			glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
			check_error();
			glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
			check_error();
			glBindFramebuffer( GL_FRAMEBUFFER, 0 );
			check_error();

			GlslManager::render( service, chain, fbo->fbo, *width, *height );

			// Read FBO into PBO
			glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, pbo->pbo );
			check_error();
			glBufferData( GL_PIXEL_PACK_BUFFER_ARB, img_size, NULL, GL_STREAM_READ );
			check_error();
			glReadPixels( 0, 0, *width, *height, gl_format, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0) );
			check_error();

			// Copy from PBO
			uint8_t* buf = (uint8_t*) glMapBuffer( GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY );
			check_error();

			*format = gl_format == GL_RGBA ? mlt_image_rgb24a : mlt_image_rgb24;
			*image = (uint8_t*) mlt_pool_alloc( img_size );
			mlt_frame_set_image( a_frame, *image, img_size, mlt_pool_release );
			memcpy( *image, buf, img_size );

			// Release PBO and FBO
			glUnmapBuffer( GL_PIXEL_PACK_BUFFER_ARB );
			check_error();
			glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, 0 );
			check_error();
			glBindFramebuffer( GL_FRAMEBUFFER, 0 );
			check_error();
			glBindTexture( GL_TEXTURE_2D, 0 );
			check_error();
			GlslManager::release_texture( texture );
		}
		else {
			error = 1;
		}
	}
	if ( fbo ) GlslManager::release_fbo( fbo );
	mlt_service_unlock( service );

	return error;
}
Exemple #4
0
bool LLRenderTarget::addColorAttachment(U32 color_fmt)
{
	if (color_fmt == 0)
	{
		return true;
	}

	U32 offset = mTex.size();
	if (offset >= 4 ||
		(offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)))
	{
		llerrs << "Too many color attachments!" << llendl;
	}

	U32 tex;
	LLImageGL::generateTextures(1, &tex);
	gGL.getTexUnit(0)->bindManual(mUsage, tex);

	stop_glerror();


	{
		clear_glerror();
		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
		if (glGetError() != GL_NO_ERROR)
		{
			llwarns << "Could not allocate color buffer for render target." << llendl;
			return false;
		}
	}
	
	sBytesAllocated += mResX*mResY*4;

	stop_glerror();

	
	if (offset == 0)
	{ //use bilinear filtering on single texture render targets that aren't multisampled
		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
		stop_glerror();
	}
	else
	{ //don't filter data attachments
		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
		stop_glerror();
	}

	if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
	{
		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
		stop_glerror();
	}
	else
	{
		// ATI doesn't support mirrored repeat for rectangular textures.
		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
		stop_glerror();
	}
		
	if (mFBO)
	{
		stop_glerror();
		glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
			LLTexUnit::getInternalType(mUsage), tex, 0);
			stop_glerror();

		check_framebuffer_status();
		
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}

	mTex.push_back(tex);

	if (gDebugGL)
	{ //bind and unbind to validate target
		bindTarget();
		flush();
	}

	return true;
}
Exemple #5
0
bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat eFormat, GLuint uDepthStencilFormat)
{
    CCASSERT(eFormat != Texture2D::PixelFormat::A8, "only RGB and RGBA formats are valid for a render texture");

    bool bRet = false;
    void *data = NULL;
    do 
    {
        w = (int)(w * CC_CONTENT_SCALE_FACTOR());
        h = (int)(h * CC_CONTENT_SCALE_FACTOR());

        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO);

        // textures must be power of two squared
        unsigned int powW = 0;
        unsigned int powH = 0;

        if (Configuration::getInstance()->supportsNPOT())
        {
            powW = w;
            powH = h;
        }
        else
        {
            powW = ccNextPOT(w);
            powH = ccNextPOT(h);
        }

        int dataLen = (int)(powW * powH * 4);
        data = malloc(dataLen);
        CC_BREAK_IF(! data);

        memset(data, 0, dataLen);
        _pixelFormat = eFormat;

        _texture = new Texture2D();
        if (_texture)
        {
            _texture->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h));
        }
        else
        {
            break;
        }
        GLint oldRBO;
        glGetIntegerv(GL_RENDERBUFFER_BINDING, &oldRBO);
        
        if (Configuration::getInstance()->checkForGLExtension("GL_QCOM"))
        {
            _textureCopy = new Texture2D();
            if (_textureCopy)
            {
                _textureCopy->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h));
            }
            else
            {
                break;
            }
        }

        // generate FBO
        glGenFramebuffers(1, &_FBO);
        glBindFramebuffer(GL_FRAMEBUFFER, _FBO);

        // associate texture with FBO
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0);

        if (uDepthStencilFormat != 0)
        {
            //create and attach depth buffer
            glGenRenderbuffers(1, &_depthRenderBufffer);
            glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBufffer);
            glRenderbufferStorage(GL_RENDERBUFFER, uDepthStencilFormat, (GLsizei)powW, (GLsizei)powH);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBufffer);

            // if depth format is the one with stencil part, bind same render buffer as stencil attachment
            if (uDepthStencilFormat == GL_DEPTH24_STENCIL8)
            {
                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBufffer);
            }
        }

        // check if it worked (probably worth doing :) )
        CCASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Could not attach texture to framebuffer");

        _texture->setAliasTexParameters();

        // retained
        setSprite(Sprite::createWithTexture(_texture));

        _texture->release();
        _sprite->setScaleY(-1);

        _sprite->setBlendFunc( BlendFunc::ALPHA_PREMULTIPLIED );

        glBindRenderbuffer(GL_RENDERBUFFER, oldRBO);
        glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO);
        
        // Diabled by default.
        _autoDraw = false;
        
        // add sprite for backward compatibility
        addChild(_sprite);
        
        bRet = true;
    } while (0);
    
    CC_SAFE_FREE(data);
    
    return bRet;
}
void RenderTexture::onBegin()
{
    //
    Director *director = Director::getInstance();
    
    _oldProjMatrix = director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, _projectionMatrix);
    
    _oldTransMatrix = director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _transformMatrix);
    
    if(!_keepMatrix)
    {
        director->setProjection(director->getProjection());

#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
        Mat4 modifiedProjection = director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
        modifiedProjection = GLViewImpl::sharedOpenGLView()->getReverseOrientationMatrix() * modifiedProjection;
        director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION,modifiedProjection);
#endif

        const Size& texSize = _texture->getContentSizeInPixels();
        
        // Calculate the adjustment ratios based on the old and new projections
        Size size = director->getWinSizeInPixels();
        float widthRatio = size.width / texSize.width;
        float heightRatio = size.height / texSize.height;
        
        Mat4 orthoMatrix;
        Mat4::createOrthographicOffCenter((float)-1.0 / widthRatio, (float)1.0 / widthRatio, (float)-1.0 / heightRatio, (float)1.0 / heightRatio, -1, 1, &orthoMatrix);
        director->multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, orthoMatrix);
    }
    else
    {
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
        Mat4 modifiedProjection = director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
        modifiedProjection = GLViewImpl::sharedOpenGLView()->getReverseOrientationMatrix() * modifiedProjection;
        director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, modifiedProjection);
#endif
    }
    
    //calculate viewport
    {
        Rect viewport;
        viewport.size.width = _fullviewPort.size.width;
        viewport.size.height = _fullviewPort.size.height;
        float viewPortRectWidthRatio = float(viewport.size.width)/_fullRect.size.width;
        float viewPortRectHeightRatio = float(viewport.size.height)/_fullRect.size.height;
        viewport.origin.x = (_fullRect.origin.x - _rtTextureRect.origin.x) * viewPortRectWidthRatio;
        viewport.origin.y = (_fullRect.origin.y - _rtTextureRect.origin.y) * viewPortRectHeightRatio;
        //glViewport(_fullviewPort.origin.x, _fullviewPort.origin.y, (GLsizei)_fullviewPort.size.width, (GLsizei)_fullviewPort.size.height);
        glViewport(viewport.origin.x, viewport.origin.y, (GLsizei)viewport.size.width, (GLsizei)viewport.size.height);
    }

    // Adjust the orthographic projection and viewport
    
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO);
    glBindFramebuffer(GL_FRAMEBUFFER, _FBO);

    //TODO move this to configration, so we don't check it every time
    /*  Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture. The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture. Create a temporary texture to overcome this. At the end of RenderTexture::begin(), switch the attached texture to the second one, call glClear, and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers.
     */
    if (Configuration::getInstance()->checkForGLExtension("GL_QCOM"))
    {
        // -- bind a temporary texture so we can clear the render buffer without losing our texture
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureCopy->getName(), 0);
        CHECK_GL_ERROR_DEBUG();
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0);
    }
}
	bool Framebuffer::init(unsigned int width, unsigned int height, unsigned int layerNumber)
	{
		// todo clear all if allready initilized

		_width = width;
		_height = height;

		_layerNumber = layerNumber;
		glGenFramebuffers(1, &_handle);
		glBindFramebuffer(GL_FRAMEBUFFER, _handle);

		_layers = new unsigned int[_layerNumber];
		glGenTextures(_layerNumber, _layers);

		for (unsigned int i = 0; i < _layerNumber; ++i)
		{
			_layerNames.push_back("layer" + std::to_string(i));
			glBindTexture(GL_TEXTURE_2D, _layers[i]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
			glFramebufferTexture2D(GL_FRAMEBUFFER, (GLenum)(GL_COLOR_ATTACHMENT0 + i), GL_TEXTURE_2D, _layers[i], 0);
		}
		glBindTexture(GL_TEXTURE_2D, 0);

		glGenRenderbuffers(1, &_depth);

		glBindRenderbuffer(GL_RENDERBUFFER, _depth);
		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, _width, _height);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depth);
		glBindRenderbuffer(GL_RENDERBUFFER, 0);

		if (!checkStatus())
			return false;
		glBindFramebuffer(GL_FRAMEBUFFER, 0);


		// x,y vertex positions
		float ss_quad_pos[] = {
			-1.0, -1.0,
			1.0, -1.0,
			1.0,  1.0,
			1.0,  1.0,
			-1.0,  1.0,
			-1.0, -1.0
		};
		// per-vertex texture coordinates
		float ss_quad_st[] = {
			0.0, 0.0,
			1.0, 0.0,
			1.0, 1.0,
			1.0, 1.0,
			0.0, 1.0,
			0.0, 0.0
		};
		unsigned int indice[] = {0,1,2,3,4,5};
		_vbo.init(6, &indice[0]);
		_vbo.addAttribute(OpenGLTools::Attribute(sizeof(float) * 2, 2, GL_FLOAT));
		_vbo.addAttribute(OpenGLTools::Attribute(sizeof(float) * 2, 2, GL_FLOAT));
		_vbo.setBuffer(0, reinterpret_cast<byte *>(&ss_quad_pos));
		_vbo.setBuffer(1, reinterpret_cast<byte *>(&ss_quad_st));

		return true;
	}
Exemple #8
0
static FboDesc CreateSurfaces(GLsizei width, GLsizei height, int numComponents, int numTargets)
{
    FboDesc surface;
    glGenFramebuffers(1, &surface.FboHandle);
    glBindFramebuffer(GL_FRAMEBUFFER, surface.FboHandle);

    for (int attachment = 0; attachment < numTargets; ++attachment) {

        GLuint textureHandle;
        glGenTextures(1, &textureHandle);
        glBindTexture(GL_TEXTURE_2D, textureHandle);
        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);
        
        surface.TextureHandle[attachment] = textureHandle;

        switch (numComponents) {
            case 1: glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, 0); break;
            case 2: glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, width, height, 0, GL_RG, GL_FLOAT, 0); break;
            case 3: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, 0); break;
            case 4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); break;
            default: pezFatal("Illegal slab format.");
        }

        pezCheck(GL_NO_ERROR == glGetError(), "Unable to create FBO texture");

        // glTexImage2DMultisample
        // GL_TEXTURE_2D_MULTISAMPLE
        // glRenderbufferStorageMultisample

        GLuint colorbuffer;
        glGenRenderbuffers(1, &colorbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachment, GL_TEXTURE_2D, textureHandle, 0);
        pezCheck(GL_NO_ERROR == glGetError(), "Unable to attach color buffer");
    }
    
    // Create a depth texture:
    glGenTextures(1, &surface.DepthTexture);
    glBindTexture(GL_TEXTURE_2D, surface.DepthTexture);
    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);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0);
    pezCheck(GL_NO_ERROR == glGetError(), "Unable to create depth texture");
    
    // Create a FBO and attach the depth texture:
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, surface.DepthTexture, 0);
    pezCheck(GL_NO_ERROR == glGetError(), "Unable to attach depth texture");

    pezCheck(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER), "Unable to create FBO.");

    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    return surface;
}
		bool RenderTargetTexture::Init(RenderTarget::Properties* props)
		{
			m_properties = *static_cast<RenderTargetTextureProperties*>(props);
			Clear();

			//	generate frame buffer
			glGenFramebuffers(1, &m_fb);
			//	create color texture
			if (m_color_texture)
				safe_delete(m_color_texture);
			m_color_texture = new Texture2D;
			m_color_texture->Create(m_properties.m_texture_width, m_properties.m_texture_height, ImageModule::IMAGE_FORMAT_RGBA8, 0, false);

			//	if multisample
			//	generate render buffers
			glGenRenderbuffers(1, &m_depth_rb);
			glGenRenderbuffers(1, &m_color_rb);
			//	generate resolve frame buffer
			glGenFramebuffers(1, &m_resolve_fb);

			//	tune resolve frame buffer
			glBindFramebuffer(GL_FRAMEBUFFER, m_resolve_fb);
			//	bind color texture
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture->GetCode(), 0);

			Check();

			//	tune render frame buffer
			glBindFramebuffer(GL_FRAMEBUFFER, m_fb);

			//	tune color render buffer
			glBindRenderbuffer(GL_RENDERBUFFER, m_color_rb);

			int max_samples;
			glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
			//	for csaa some extra staff needed
			// create a regular MSAA color buffer
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_RGBA8, m_color_texture->GetWidth(), m_color_texture->GetHeight());
			// check the number of samples
			glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &max_samples);

			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rb);

			Check();

			//	tune depth render buffer
			glBindRenderbuffer(GL_RENDERBUFFER, m_depth_rb);

			//	for csaa another method should be used
			//	create a regular MSAA depth buffer
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_DEPTH_COMPONENT24, m_color_texture->GetWidth(), m_color_texture->GetHeight());

			//	attach depth buffer to frame buffer
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth_rb);

			Check();

			glBindFramebuffer(GL_FRAMEBUFFER, 0);

			return true;
		}
Exemple #10
0
static enum piglit_result
exec_test(struct test_info *info, int sample_count)
{
    GLuint fb, tex, rb;
    GLint result;
    struct attachment_info *att;
    GLint maxColorSamples, maxDepthSamples;

    glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorSamples);
    glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthSamples);

    glGenFramebuffers(1, &fb);
    glBindFramebuffer(GL_FRAMEBUFFER, fb);

    printf("Testing fbo completeness for config '%s'\n", info->name);

    for (att=info->attachments; att->target; att++) {
        int attachment_sample_count = att->multisample ? sample_count : 0;
        printf("  Att target=%s att=%s samples=%d dims=%d,%d,%d fixed=%d\n",
               piglit_get_gl_enum_name(att->target),
               piglit_get_gl_enum_name(att->attachment),
               attachment_sample_count,
               SURFACE_WIDTH, SURFACE_HEIGHT,
               att->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ? SURFACE_DEPTH : 1,
               att->fixedsamplelocations);

        switch (att->target) {
        case GL_TEXTURE_2D_MULTISAMPLE:
        case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
            if (att->attachment == GL_DEPTH_ATTACHMENT && sample_count > maxDepthSamples)
                return PIGLIT_SKIP;
            if ((att->attachment == GL_COLOR_ATTACHMENT0 ||
                att->attachment == GL_COLOR_ATTACHMENT1) && sample_count > maxColorSamples)
                return PIGLIT_SKIP;
        }

        switch (att->target) {
        case GL_TEXTURE_2D_MULTISAMPLE:
            glGenTextures(1, &tex);
            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
            glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,
                                    attachment_sample_count, choose_format(att),
                                    SURFACE_WIDTH, SURFACE_HEIGHT,
                                    att->fixedsamplelocations);

            if (!piglit_check_gl_error(GL_NO_ERROR))
                return PIGLIT_FAIL;

            glFramebufferTexture2D(GL_FRAMEBUFFER, att->attachment,
                                   att->target, tex, 0);
            break;

        case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
            glGenTextures(1, &tex);
            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex);
            glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
                    attachment_sample_count, choose_format(att),
                    SURFACE_WIDTH, SURFACE_HEIGHT, SURFACE_DEPTH,
                    att->fixedsamplelocations);

            if (!piglit_check_gl_error(GL_NO_ERROR))
                return PIGLIT_FAIL;

            glFramebufferTextureLayer(GL_FRAMEBUFFER, att->attachment,
                    tex, 0, att->layer);
            break;

        case GL_RENDERBUFFER:
            /* RENDERBUFFER has fixedsamplelocations implicitly */
            assert(att->fixedsamplelocations);
            glGenRenderbuffers(1, &rb);
            glBindRenderbuffer(GL_RENDERBUFFER, rb);
            if (att->multisample) {
                glRenderbufferStorageMultisample(GL_RENDERBUFFER,
                                                 attachment_sample_count, choose_format(att),
                                                 SURFACE_WIDTH, SURFACE_HEIGHT);
            }
            else {
                /* non-MSAA renderbuffer */
                glRenderbufferStorage(GL_RENDERBUFFER, choose_format(att),
                                      SURFACE_WIDTH, SURFACE_HEIGHT);
            }

            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                                      att->attachment, att->target, rb);

            if (!piglit_check_gl_error(GL_NO_ERROR))
                return PIGLIT_FAIL;
            break;

        default:
            assert(!"Unsupported target");
        }
    }

    result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (result != info->expected) {
        printf("glCheckFramebufferStatus: expected %s, got %s\n",
               piglit_get_gl_enum_name(info->expected),
               piglit_get_gl_enum_name(result));
        return PIGLIT_FAIL;
    }

    if (result == GL_FRAMEBUFFER_COMPLETE && info->attachments->multisample)
        return check_sample_positions(sample_count);

    return PIGLIT_PASS;
}
Exemple #11
0
/* Run through multiple variants to detect mrt settings
 */
void test_srgb_fbo(GLint ifmt, GLenum fmt, GLenum type)
{
	GLint width, height;
	GLuint fbo, fbotex;
	GLenum mrt_bufs[16];

	GLfloat quad_color[] =  {1.0, 0.0, 0.0, 1.0};
	GLfloat vertices[] = {
			-0.45, -0.75, 0.1,
			 0.45, -0.75, 0.1,
			-0.45,  0.75, 0.1,
			 0.45,  0.75, 0.1 };
	EGLSurface surface;

	RD_START("srgb-fbo", "fmt=%s (%x), ifmt=%s (%x), type=%s (%x)",
			formatname(fmt), fmt,
			formatname(ifmt), ifmt,
			typename(type), type);

	display = get_display();

	/* get an appropriate EGL frame buffer configuration */
	ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config));
	DEBUG_MSG("num_config: %d", num_config);

	/* create an EGL rendering context */
	ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list));

	surface = make_window(display, config, 64, 64);

	ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width));
	ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height));

	DEBUG_MSG("Buffer: %dx%d", width, height);

	/* connect the context to the surface */
	ECHK(eglMakeCurrent(display, surface, surface, context));

	program = get_program(vertex_shader_source, fragment_shader_source);

	GCHK(glBindAttribLocation(program, 0, "aPosition"));

	link_program(program);

	GCHK(glGenFramebuffers(1, &fbo));
	GCHK(glGenTextures(1, &fbotex));
	GCHK(glBindFramebuffer(GL_FRAMEBUFFER, fbo));

	GCHK(glBindTexture(GL_TEXTURE_2D, fbotex));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
	GCHK(glTexImage2D(GL_TEXTURE_2D, 0, ifmt, width, height, 0, fmt, type, 0));
	GCHK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
			GL_TEXTURE_2D, fbotex, 0));

	DEBUG_MSG("status=%04x", glCheckFramebufferStatus(GL_FRAMEBUFFER));

	GCHK(glBindFramebuffer(GL_FRAMEBUFFER, fbo));

	GCHK(glDrawBuffers(1, (const GLenum[]){GL_COLOR_ATTACHMENT0}));
Exemple #12
0
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no  error occured
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES2RenderToTexture::InitView()
{
	// Find the largest square power of two texture that fits into the viewport
	m_i32TexSize = 1;
	int iSize = PVRT_MIN(PVRShellGet(prefWidth), PVRShellGet(prefHeight));
	while (m_i32TexSize * 2 < iSize) m_i32TexSize *= 2;

	srand(PVRShellGetTime());
	m_ui32Framenum = rand() % 5000;

	// Get the initial time
	m_ui32Time = PVRShellGetTime();

	/*
		Initialize VBO data and load textures
	*/
	LoadVbos();
	LoadTextures();

	/*
		Load and compile the shaders & link programs
	*/
	CPVRTString ErrorStr;
	if (!LoadShaders(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	// Set the sampler2D uniforms to corresponding texture units
	glUniform1i(glGetUniformLocation(m_ShaderProgram.uiId, "sTexture"), 0);

	/*
		Initialize Print3D
	*/

	// Is the screen rotated?
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	
	/*
		Create two handles for a frame buffer object.
	*/
	glGenFramebuffers(2, m_auiFbo);
	m_i32CurrentFbo = 1;

	/*
		Get the currently bound frame buffer object. On most platforms this just gives 0.
	 */
	glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo);

	/*
		Attach the renderable objects (e.g. textures) to the frame buffer object now as 
		they will stay attached to the frame buffer object even when it is not bound.
	*/

	// We have two FBOs so we're doing the same for each
	for(int i = 0; i < 2; ++i)
	{
		/*
			Firstly, to do anything with a frame buffer object we need to bind it. In the case
			below we are binding our frame buffer object to the frame buffer.
		*/
		glBindFramebuffer(GL_FRAMEBUFFER, m_auiFbo[i]);

		/*
			To render to a texture we need to attach it texture to the frame buffer object.
			GL_COLOR_ATTACHMENT0 tells it to attach the texture to the colour buffer, the 0 on the
			end refers to the colour buffer we want to attach it to as a frame buffer object can
			have more than one colour buffer.
		*/
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_auiTexture[i], 0);

		// Clear the color buffer for this FBO
		glClear(GL_COLOR_BUFFER_BIT);

		/*
			Create and bind a depth buffer to the frame buffer object.

			A depth buffer isn't needed for this training course but will likely be 
			required for most uses of frame buffer objects so its attachment is being 
			demonstrated here.
		*/

		// Generate and bind the handle for the render buffer (which will become our depth buffer)
		glGenRenderbuffers(1, &m_auiDepthBuffer[i]);
		glBindRenderbuffer(GL_RENDERBUFFER, m_auiDepthBuffer[i]);

		/* 
			Currently it is unknown to GL that we want our new render buffer to be a depth buffer.
			glRenderbufferStorage will fix this and in this case will allocate a depth buffer of
			m_i32TexSize by m_i32TexSize.
		*/
		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_i32TexSize, m_i32TexSize);

		// Now we have our depth buffer attach it to our frame buffer object.
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_auiDepthBuffer[i]);
	}

	/*
		Unbind the frame buffer object so rendering returns back to the backbuffer.
	*/
	glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo);

	// Use a nice bright blue as clear colour
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);

	return true;
}
Exemple #13
0
void
piglit_init(int argc, char**argv)
{
	GLuint tex;
	piglit_require_extension("GL_ARB_gpu_shader5");

	glGenFramebuffers(1, &ms_fbo);
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ms_fbo);
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
	glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4,
				GL_RGBA, 64, 64, GL_TRUE);
	glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
			       GL_TEXTURE_2D_MULTISAMPLE, tex, 0);

	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		printf("fbo setup failed.\n");
		piglit_report_result(PIGLIT_SKIP);
	}

	/* Test quantity varies from -1 to +1 over 64 pixels --
	 * so moving 1px changes its value by 1/32.
	 */
	draw_prog = piglit_build_simple_program(
		"#version 150\n"
		"uniform vec2 sample_pos;\n"
		"in vec2 p;\n"
		"out vec2 test;\n"
		"out vec2 ref;\n"
		"void main() {\n"
		"	gl_Position = vec4(p, 0, 1);\n"
		"	test = p;\n"
		"	ref = p;\n"
		"	ref.xy += sample_pos / 32;\n"
		"}\n",

		"#version 150\n"
		"#extension GL_ARB_gpu_shader5: require\n"
		"const int sample_id = 0;\n"
		"in vec2 test;\n"
		"in vec2 ref;\n"
		"void main() {\n"
		"	gl_FragColor = vec4(" GAIN " * abs(\n"
		"		interpolateAtSample(test, sample_id) - ref), 0, 1);\n"
		"}\n");
	if (!draw_prog) {
		printf("draw_prog compile/link failed\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	test_prog = piglit_build_simple_program(
		"#version 150\n"
		"in vec2 p;\n"
		"void main() {\n"
		"	gl_Position = vec4(p, 0, 1);\n"
		"}\n",

		"#version 150\n"
		"uniform sampler2DMS s;\n"
		"void main() {\n"
		"	vec4 temp = \n"
		"		texelFetch(s, ivec2(gl_FragCoord.xy), 0) +\n"
		"		texelFetch(s, ivec2(gl_FragCoord.xy), 1) +\n"
		"		texelFetch(s, ivec2(gl_FragCoord.xy), 2) +\n"
		"		texelFetch(s, ivec2(gl_FragCoord.xy), 3);\n"
		"	gl_FragColor = vec4(temp.x, 1-temp.y, temp.z, temp.w);\n"
		"}\n");
	if (!test_prog) {
		printf("test_prog compile/link failed\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	sample_pos_loc = glGetUniformLocation(draw_prog, "sample_pos");

	glUseProgram(test_prog);
	glUniform1i(glGetUniformLocation(test_prog, "s"), 0);

	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		printf("shader setup failed\n");
		piglit_report_result(PIGLIT_SKIP);
	}

	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	
	glEnableVertexAttribArray(0);
	glGenBuffers(1, &bo);
	glBindBuffer(GL_ARRAY_BUFFER, bo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid const *)0);
}
void Effects::setup(int w, int h) {
	width = w;
	height = h;
	
	cracks.setup(w,h);
	
	// create fbo
	glGenFramebuffers(1, &fbo_handle); eglGetError();
	glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);
	
	// create texture.
	glGenTextures(1, &fbo_tex); eglGetError();
	glActiveTexture(GL_TEXTURE0); eglGetError();
	glBindTexture(GL_TEXTURE_2D, fbo_tex); eglGetError();
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); eglGetError();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); eglGetError();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); eglGetError();

	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0); eglGetError();
	glGenRenderbuffers(1, &fbo_depth); eglGetError();

	// render buffer
	glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth); eglGetError();	
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); eglGetError();

	GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0};
	glDrawBuffers(1, drawbufs);
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	
	if(!shader.load("effects/effects")) {
		printf("Error loading effects shader.\n");
	}
	
	vertices[0].setPos(-1, -1, 0);
	vertices[1].setPos(1, -1, 0);
	vertices[2].setPos(1, 1, 0);
	vertices[3].setPos(-1, 1, 0);
	
	float mw = 1;
	float mh = 1;
	vertices[0].setTex(0, 0);
	vertices[1].setTex(mw, 0);
	vertices[2].setTex(mw, mh);
	vertices[3].setTex(0, mh);
	
	glGenVertexArraysAPPLE(1, &vao); eglGetError();
	glBindVertexArrayAPPLE(vao); eglGetError();

	GLint pos_attrib = glGetAttribLocation(shader.getProgram(), "pos");
	GLint tex_attrib = glGetAttribLocation(shader.getProgram(), "tex");
	glEnableVertexAttribArray(pos_attrib);
	glEnableVertexAttribArray(tex_attrib);

	glGenBuffers(1, &vbo); eglGetError();
	glBindBuffer(GL_ARRAY_BUFFER, vbo); eglGetError();
	
	glBufferData(
		GL_ARRAY_BUFFER	
		,sizeof(Vertex) * 4
		,vertices[0].pos
		,GL_STATIC_DRAW
	); eglGetError();
	
	glVertexAttribPointer(
		pos_attrib
		,3
		,GL_FLOAT
		,GL_FALSE
		,sizeof(Vertex)
		,offsetof(Vertex, pos)
	);
	
	glVertexAttribPointer(
		tex_attrib
		,2
		,GL_FLOAT
		,GL_FALSE
		,sizeof(Vertex)
		,(GLvoid*)offsetof(Vertex, tex)
	);
	
	calcCenter();	
	
	unbind();
	
	flip(false);
	mirror(false);	
	crack(false);
}
void MediaSurface::Update()
{
	if ( !AndroidSurfaceTexture )
	{
		LOG( "!AndroidSurfaceTexture" );
		return;
	}
	if ( TexId <= 0 )
	{
		//LOG( "TexId <= 0" );
		return;
	}
	AndroidSurfaceTexture->Update();
	if ( AndroidSurfaceTexture->nanoTimeStamp == LastSurfaceTexNanoTimeStamp )
	{
		return;
	}
	LastSurfaceTexNanoTimeStamp = AndroidSurfaceTexture->nanoTimeStamp;

	// don't mess up Unity state
	GLStateSave	stateSave;

	// If we haven't allocated our GL objects yet, do it now.
	// This isn't done at Init, because GL may not be current then.
	if ( UnitSquare.vertexArrayObject == 0 )
	{
		LOG( "Allocating GL objects" );

		UnitSquare = BuildTesselatedQuad( 1, 1 );

		CopyMovieProgram = BuildProgram(
			"uniform highp mat4 Mvpm;\n"
			"attribute vec4 Position;\n"
			"attribute vec2 TexCoord;\n"
			"varying  highp vec2 oTexCoord;\n"
			"void main()\n"
			"{\n"
			"   gl_Position = Position;\n"
			"   oTexCoord = TexCoord;\n"
			"}\n"
		,
			"#extension GL_OES_EGL_image_external : require\n"
			"uniform samplerExternalOES Texture0;\n"
			"varying highp vec2 oTexCoord;\n"
			"void main()\n"
			"{\n"
			"	gl_FragColor = texture2D( Texture0, oTexCoord );\n"
			"}\n"
		);
	}

	// If the SurfaceTexture has changed dimensions, we need to
	// reallocate the texture and FBO.
	glActiveTexture( GL_TEXTURE0 );
	glBindTexture( GL_TEXTURE_EXTERNAL_OES, AndroidSurfaceTexture->textureId );
	// FIXME: no way to get texture dimensions even in ES 3.0???
	int	width = 960;
	int height = 540;
	if ( width != TexIdWidth || height != TexIdHeight )
	{
		LOG( "New surface size: %ix%i", width, height );

		TexIdWidth = width;
		TexIdHeight = height;

		if ( Fbo )
		{
			glDeleteFramebuffers( 1, &Fbo );
		}

		glActiveTexture( GL_TEXTURE1 );
		glBindTexture( GL_TEXTURE_2D, TexId );
		glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
				TexIdWidth, TexIdHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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_LINEAR_MIPMAP_LINEAR );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

		glBindTexture( GL_TEXTURE_2D, 0 );
		glActiveTexture( GL_TEXTURE0 );

		glGenFramebuffers( 1, &Fbo );
		glBindFramebuffer( GL_FRAMEBUFFER, Fbo );
		glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
				TexId, 0 );
		glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	}

	glBindFramebuffer( GL_FRAMEBUFFER, Fbo );
	glDisable( GL_DEPTH_TEST );
	glDisable( GL_SCISSOR_TEST );
	glDisable( GL_STENCIL_TEST );
	glDisable( GL_CULL_FACE );
	glDisable( GL_BLEND );

	const GLenum fboAttachments[1] = { GL_COLOR_ATTACHMENT0 };
	glInvalidateFramebuffer( GL_FRAMEBUFFER, 1, fboAttachments );

	glViewport( 0, 0, TexIdWidth, TexIdHeight );
	glUseProgram( CopyMovieProgram.program );
	UnitSquare.Draw();
	glUseProgram( 0 );
	glBindTexture( GL_TEXTURE_EXTERNAL_OES, 0 );
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );

	glBindTexture( GL_TEXTURE_2D, TexId );
	glGenerateMipmap( GL_TEXTURE_2D );
	glBindTexture( GL_TEXTURE_2D, 0 );
}
bool setupDeferred(int w, int h) {
  std::cout << "setupDeferred " << w << " " << h << std::endl;
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, deferredFbo);

  //color
  glBindTexture(GL_TEXTURE_2D, deferredColorTex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,w,h,0,GL_RGBA,GL_FLOAT,0);
  glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
                         GL_TEXTURE_2D,deferredColorTex,0);

  //normal
  GLenum normalInnerFormat;
  GLenum normalType;

  normalInnerFormat=GL_RGBA32F;
  normalType=GL_FLOAT;

  // normalInnerFormat=GL_RGBA16F;
  // normalType=GL_HALF_FLOAT;

  glBindTexture(GL_TEXTURE_2D, deferredNormalTex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_2D,0,normalInnerFormat,w,h,0,GL_RGBA,normalType,0);

  glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT1,
                         GL_TEXTURE_2D,deferredNormalTex,0);

  //depth
  glBindTexture(GL_TEXTURE_2D, deferredDepthTex);
  glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT32F,w,h,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);
  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);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);

  glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,
                         GL_TEXTURE_2D,deferredDepthTex,0);

  //
  GLenum drawBufs[]={GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1};
  glDrawBuffers(2,drawBufs);

  //check fbo status
  GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

  if(status == GL_FRAMEBUFFER_COMPLETE) {
    //restore default FBO
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    return true;
  } else if(status==GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
    std::cout << "fbo error: incomplete attachment\n";
  } else if(status==GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) {
    std::cout << "fbo error: incomplete missing attachment\n";
  } else if(status==GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) {
    std::cout << "fbo error: incomplete draw buffer\n";
  } else if(status==GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER) {
    std::cout << "fbo error: incomplete read buffer\n";
  } else if(status==GL_FRAMEBUFFER_UNSUPPORTED) {
    std::cout << "fbo error: unsupported\n";
  }

  return false;
}
/* get buffer as Image */
Image* RenderTexture::newImage(bool fliimage)
{
    CCASSERT(_pixelFormat == Texture2D::PixelFormat::RGBA8888, "only RGBA8888 can be saved as image");

    if (nullptr == _texture)
    {
        return nullptr;
    }

    const Size& s = _texture->getContentSizeInPixels();

    // to get the image size to save
    //        if the saving image domain exceeds the buffer texture domain,
    //        it should be cut
    int savedBufferWidth = (int)s.width;
    int savedBufferHeight = (int)s.height;

    GLubyte *buffer = nullptr;
    GLubyte *tempData = nullptr;
    Image *image = new (std::nothrow) Image();

    do
    {
        CC_BREAK_IF(! (buffer = new (std::nothrow) GLubyte[savedBufferWidth * savedBufferHeight * 4]));

        if(! (tempData = new (std::nothrow) GLubyte[savedBufferWidth * savedBufferHeight * 4]))
        {
            delete[] buffer;
            buffer = nullptr;
            break;
        }

        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO);
        glBindFramebuffer(GL_FRAMEBUFFER, _FBO);

        //TODO move this to configration, so we don't check it every time
        /*  Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture. The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture. Create a temporary texture to overcome this. At the end of RenderTexture::begin(), switch the attached texture to the second one, call glClear, and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers.
         */
        if (Configuration::getInstance()->checkForGLExtension("GL_QCOM"))
        {
            // -- bind a temporary texture so we can clear the render buffer without losing our texture
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureCopy->getName(), 0);
            CHECK_GL_ERROR_DEBUG();
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0);
        }
        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glReadPixels(0,0,savedBufferWidth, savedBufferHeight,GL_RGBA,GL_UNSIGNED_BYTE, tempData);
        glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO);

        if ( fliimage ) // -- flip is only required when saving image to file
        {
            // to get the actual texture data
            // #640 the image read from rendertexture is dirty
            for (int i = 0; i < savedBufferHeight; ++i)
            {
                memcpy(&buffer[i * savedBufferWidth * 4],
                       &tempData[(savedBufferHeight - i - 1) * savedBufferWidth * 4],
                       savedBufferWidth * 4);
            }

            image->initWithRawData(buffer, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8);
        }
        else
        {
            image->initWithRawData(tempData, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8);
        }
        
    } while (0);

    CC_SAFE_DELETE_ARRAY(buffer);
    CC_SAFE_DELETE_ARRAY(tempData);

    return image;
}
Exemple #18
0
void R_AttachFBOTextureDepth(int texId)
{
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0);
}
GLNonMultiviewRenderTexture::GLNonMultiviewRenderTexture(int width, int height, int sample_count,
                                     int jcolor_format, int jdepth_format, bool resolve_depth,
                                     const TextureParameters* texture_parameters, int viewport[]):GLRenderTexture(width, height, sample_count, jcolor_format, jdepth_format,
                                                                                                  resolve_depth, texture_parameters, viewport) {
    GLRenderImage* colorbuffer = new GLRenderImage(width, height, jcolor_format, texture_parameters);
    GLenum depth_format;

    setImage(colorbuffer);
    initialize();
    getImage()->isReady();
    switch (jdepth_format)
    {
        case DepthFormat::DEPTH_24:
            depth_format = GL_DEPTH_COMPONENT24_OES;
            break;

        case DepthFormat::DEPTH_24_STENCIL_8:
            depth_format = GL_DEPTH24_STENCIL8_OES;
            break;

        default:
            depth_format = GL_DEPTH_COMPONENT16;
            break;
    }
    if (sample_count <= 1)
    {
        generateRenderTextureNoMultiSampling(jdepth_format, depth_format,
                                             width, height);
    }
    else if (resolve_depth)
    {
        generateRenderTexture(sample_count, jdepth_format, depth_format,
                              width, height, jcolor_format);
    }
    else
    {
        generateRenderTextureEXT(sample_count, jdepth_format,
                                 depth_format, width, height);
    }
    if (jdepth_format != DepthFormat::DEPTH_0)
    {
        GLenum attachment = DepthFormat::DEPTH_24_STENCIL_8 == jdepth_format ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, renderTexture_gl_render_buffer_->id());
    }

    glScissor(0, 0, width, height);
    glViewport(0, 0, width, height);
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    if (resolve_depth && sample_count > 1)
    {
        delete renderTexture_gl_resolve_buffer_;
        renderTexture_gl_resolve_buffer_ = new GLFrameBuffer();
        glBindFramebuffer(GL_FRAMEBUFFER, renderTexture_gl_resolve_buffer_->id());
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                               colorbuffer->getTarget(), colorbuffer->getId(), 0);
        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        if (status != GL_FRAMEBUFFER_COMPLETE)
        {
            LOGE("resolve FBO %i is not complete: 0x%x",
                 renderTexture_gl_resolve_buffer_->id(), status);
        }
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    checkGLError(" GLNonMultiviewRenderTexture:");
}
Exemple #20
0
void R_AttachFBOTexturePackedDepthStencil(int texId)
{
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, 0);
}
Exemple #21
0
void QGLTextureGlyphCache::resizeTextureData(int width, int height)
{
    // ### the QTextureGlyphCache API needs to be reworked to allow
    // ### resizeTextureData to fail

    int oldWidth = m_width;
    int oldHeight = m_height;

    GLuint oldTexture = m_texture;
    createTextureData(width, height);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);

    GLuint tmp_texture;
    glGenTextures(1, &tmp_texture);
    glBindTexture(GL_TEXTURE_2D, tmp_texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_2D, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                           GL_TEXTURE_2D, tmp_texture, 0);

    glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
    glBindTexture(GL_TEXTURE_2D, oldTexture);

    pex->transferMode(BrushDrawingMode);

    glDisable(GL_STENCIL_TEST);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_BLEND);

    glViewport(0, 0, oldWidth, oldHeight);

    GLfloat* vertexCoordinateArray = pex->staticVertexCoordinateArray;
    vertexCoordinateArray[0] = -1.0f;
    vertexCoordinateArray[1] = -1.0f;
    vertexCoordinateArray[2] =  1.0f;
    vertexCoordinateArray[3] = -1.0f;
    vertexCoordinateArray[4] =  1.0f;
    vertexCoordinateArray[5] =  1.0f;
    vertexCoordinateArray[6] = -1.0f;
    vertexCoordinateArray[7] =  1.0f;

    GLfloat* textureCoordinateArray = pex->staticTextureCoordinateArray;
    textureCoordinateArray[0] = 0.0f;
    textureCoordinateArray[1] = 0.0f;
    textureCoordinateArray[2] = 1.0f;
    textureCoordinateArray[3] = 0.0f;
    textureCoordinateArray[4] = 1.0f;
    textureCoordinateArray[5] = 1.0f;
    textureCoordinateArray[6] = 0.0f;
    textureCoordinateArray[7] = 1.0f;

    pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertexCoordinateArray);
    pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, textureCoordinateArray);

    pex->shaderManager->useBlitProgram();
    pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindTexture(GL_TEXTURE_2D, m_texture);

#ifdef QT_OPENGL_ES_2
    QDataBuffer<uchar> buffer(4*oldWidth*oldHeight);
    buffer.resize(4*oldWidth*oldHeight);
    glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());

    // do an in-place conversion from GL_RGBA to GL_ALPHA
    for (int i=0; i<oldWidth*oldHeight; ++i)
        buffer.data()[i] = buffer.at(4*i + 3);

    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight,
                    GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data());
#else
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
#endif

    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                              GL_RENDERBUFFER_EXT, 0);
    glDeleteTextures(1, &tmp_texture);
    glDeleteTextures(1, &oldTexture);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);

    glViewport(0, 0, pex->width, pex->height);
    pex->updateClipScissorTest();
}
Exemple #22
0
void TerrainQuadtree::generateTextures() {
	// prepare viewport and projection
	//glDisable(GL_DEPTH_TEST);

	// do not setup the proj more than once
	if (this->parent == NULL) {
		glViewport(0, 0, this->textureSize, this->textureSize);
		glMatrixMode(GL_PROJECTION);
		glPolygonMode(GL_FRONT, GL_FILL);
		glLoadIdentity();
		glOrtho(0.0, (double)this->textureSize, 0.0, (double)this->textureSize, 0.0, 1.0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glTranslated(0.0, 0.0, -1.0);

		generationScreenList = glGenLists(1);
		glNewList(generationScreenList, GL_COMPILE);
		glBegin(GL_QUADS);
		glTexCoord2f(0.0, 0.0);
		glVertex3f(0.0, 0.0, 0.0);
		glTexCoord2f(1.0, 0.0);
		glVertex3f(this->textureSize, 0.0, 0.0);
		glTexCoord2f(1.0, 1.0);
		glVertex3f(this->textureSize, this->textureSize, 0.0);
		glTexCoord2f(0.0, 1.0);
		glVertex3f(0.0, this->textureSize, 0.0);
		glEnd();
		glEndList();
	}

	// generate topography
	glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->topoTexture->id, 0);
	this->positionTexture->bind(GL_TEXTURE0);

	this->generatorShader->bind();
	glUniform1i(glGetUniformLocation(this->generatorShader->program, "positionTexture"), 0);
	glCallList(generationScreenList);
	this->generatorShader->unbind();
	//glBindFramebuffer(GL_FRAMEBUFFER, 0);

	// generate normals
	//glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->normalTexture->id, 0);
	this->topoTexture->bind(GL_TEXTURE1);

	this->generatorShaderN->bind();
	glUniform1f(glGetUniformLocation(this->generatorShaderN->program, "size"), (float)this->textureSize);
	glUniform1f(glGetUniformLocation(this->generatorShaderN->program, "radius"), this->planet->radius);
	glUniform1i(glGetUniformLocation(this->generatorShaderN->program, "topoTexture"), 1);
	glUniform1i(glGetUniformLocation(this->generatorShaderN->program, "positionTexture"), 0);
	glCallList(generationScreenList);
	this->generatorShaderN->unbind();
	//glBindFramebuffer(GL_FRAMEBUFFER, 0);

	// generate colors
	//glBindFramebuffer(GL_FRAMEBUFFER, this->framebuffer);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->colorTexture->id, 0);
	this->generatorShaderC->bind();
	glUniform1i(glGetUniformLocation(this->generatorShaderC->program, "topoTexture"), 1);
	glCallList(generationScreenList);
	this->generatorShaderC->unbind();
	//glBindFramebuffer(GL_FRAMEBUFFER, 0);

	//glEnable(GL_DEPTH_TEST);
	this->ready = true;
}
Exemple #23
0
bool WaterBallDrawer::setup(int w, int h) {
  assert(w && h);
  win_w = w;
  win_h = h;
  pm.ortho(0, w, h, 0, 0.0f, 100.0f);

  // create basic shader 
  const char* atts[] = { "a_pos", "a_size" } ;
  const char* frags[] = { "out_normals", "out_alpha" };
  basic_prog.create(GL_VERTEX_SHADER, rx_to_data_path("shaders/waterdrop_basic.vert"));
  basic_prog.create(GL_FRAGMENT_SHADER, rx_to_data_path("shaders/waterdrop_basic.frag"));
  basic_prog.link(2, atts, 2, frags);
  glUseProgram(basic_prog.id);
  glUniformMatrix4fv(glGetUniformLocation(basic_prog.id, "u_pm"), 1, GL_FALSE, pm.ptr());
  glUniform1i(glGetUniformLocation(basic_prog.id, "u_normals_tex"), 0);
  glUniform1i(glGetUniformLocation(basic_prog.id, "u_alpha_tex"), 1);

  // create water render shader
  water_prog.create(GL_VERTEX_SHADER, rx_to_data_path("shaders/waterdrop_water.vert"));
  water_prog.create(GL_FRAGMENT_SHADER, rx_to_data_path("shaders/waterdrop_water.frag"));
  water_prog.link();
  glUseProgram(water_prog.id);
  glUniform1i(glGetUniformLocation(water_prog.id, "u_normals_tex"), 0);
  glUniform1i(glGetUniformLocation(water_prog.id, "u_alpha_tex"), 1);
  glUniform1i(glGetUniformLocation(water_prog.id, "u_background_tex"), 2);

  glGenVertexArrays(1, &water_vao);

  glGenVertexArrays(1, &basic_vao);
  glBindVertexArray(basic_vao);
  glGenBuffers(1, &basic_vbo);
  glBindBuffer(GL_ARRAY_BUFFER, basic_vbo);
  
  glEnableVertexAttribArray(0); // pos
  glEnableVertexAttribArray(1); // size
  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(WaterDrop), (GLvoid*) 0);
  glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(WaterDrop), (GLvoid*) 32);

  glVertexAttribDivisor(0, 1);
  glVertexAttribDivisor(1, 1);

  normals_tex = rx_create_texture(rx_to_data_path("images/waterdrop_normals.png"));
  alpha_tex = rx_create_texture(rx_to_data_path("images/waterdrop_alpha.png"));
  background_tex = rx_create_texture(rx_to_data_path("images/waterdrop_background.png"));
  glBindTexture(GL_TEXTURE_2D, background_tex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  // fbo
  glGenFramebuffers(1, &fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  
  glGenTextures(1, &scene_normals_tex);
  glBindTexture(GL_TEXTURE_2D, scene_normals_tex);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, win_w, win_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, scene_normals_tex, 0);

  glGenTextures(1, &scene_alpha_tex);
  glBindTexture(GL_TEXTURE_2D, scene_alpha_tex);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, win_w, win_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, scene_alpha_tex, 0);

  if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    printf("Framebuffer not complete.\n");
    return false;
  }

  glBindFramebuffer(GL_FRAMEBUFFER, 0);

  return true;
}
Exemple #24
0
int main()
{
	GLsizei multiSamples = 8;

	GLFWwindow* window = initWindow();
	if (window == nullptr)
	{
		std::cout << "Unable to initialize window." << std::endl;
		return -1;
	}

	// Start the timer
	GLfloat deltaTime, lastFrame, currentFrame;
	lastFrame = 0.0f;
	currentFrame = 0.0f;

	// Setup the viewport;
	GLfloat screenWidth = 800, screenHeight = 600;
	glViewport(0, 0, screenWidth, screenHeight);

	// Setup Camera
	Camera cam = initCamera();
	glfwSetWindowUserPointer(window, &cam);

	// Load Models
	Model planet = Model("./Models/planet/planet.obj");
	Model asteroid = Model("./Models/rock/rock.obj");

	// Load and Compile Shaders
	GLuint program = compileShaders("../OpenGL3-3/shaders/advanced/instance/basic.vert.glsl", "../OpenGL3-3/shaders/advanced/instance/basic.frag.glsl");
	GLuint modelShader = compileShaders("../OpenGL3-3/shaders/newModel/model.vert.glsl", "../OpenGL3-3/shaders/newModel/model.frag.glsl");
	GLuint instancedModelShader = compileShaders("../OpenGL3-3/shaders/newModel/imodel.vert.glsl", "../OpenGL3-3/shaders/newModel/model.frag.glsl");
	GLuint frameBufferShader = compileShaders("../OpenGL3-3/shaders/advanced/fbo.vert.glsl", "../OpenGL3-3/shaders/advanced/fbo.frag.glsl");

	// Setup MVP model
	glm::mat4 model, view, proj;
	view = cam.GetViewMatrix();
	proj = glm::perspective(glm::radians(45.0f), (float)screenWidth / (float)screenHeight, 0.1f, 1000.0f);

#pragma region quad

	GLfloat quadVertices[] = {
		// Positions     // Colors
		-0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
		0.05f, -0.05f, 0.0f, 1.0f, 0.0f,
		-0.05f, -0.05f, 0.0f, 0.0f, 1.0f,

		-0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
		0.05f, -0.05f, 0.0f, 1.0f, 0.0f,
		0.05f, 0.05f, 0.0f, 1.0f, 1.0f
	};

	glm::vec2 translations[100];
	int index = 0;
	GLfloat offset = 0.1f;
	for (GLint y = -10; y < 10; y += 2)
	{
		for (GLint x = -10; x < 10; x += 2)
		{
			glm::vec2 translation;
			translation.x = (GLfloat)x / 10.0f + offset;
			translation.y = (GLfloat)y / 10.0f + offset;
			translations[index++] = translation;
		}
	}

	GLfloat fboQuad[] = 
	{
		-1.0f, 1.0f, 0.0f, 1.0f,
		-1.0f, -1.0f, 0.0f, 0.0f,
		1.0f, -1.0f, 1.0f, 0.0f,

		1.0f, -1.0f, 1.0f, 0.0f,
		1.0f, 1.0f, 1.0f, 1.0f,
		-1.0f, 1.0f, 0.0f, 1.0f
	};

#pragma endregion

	GLuint VBO, VAO, instanceVBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &instanceVBO);
	glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 100, &translations[0], GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	// Create the Framebuffer
	GLuint FBO;
	glGenFramebuffers(1, &FBO);
	glBindFramebuffer(GL_FRAMEBUFFER, FBO);

	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);

	glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, multiSamples, GL_RGB, screenWidth, screenHeight, GL_TRUE);// , GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture, 0);
	
	GLuint sampleRBO;

	glGenRenderbuffers(1, &sampleRBO);
	glBindRenderbuffer(GL_RENDERBUFFER, sampleRBO);
	glRenderbufferStorageMultisample(GL_RENDERBUFFER, multiSamples, GL_DEPTH24_STENCIL8, screenWidth, screenHeight);
	glBindRenderbuffer(GL_RENDERBUFFER, 0);

	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, sampleRBO);
	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		std::cout << "FRAMEBUFFER INCOMPLETE!" << std::endl;

	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	GLuint regularFBO;
	glGenFramebuffers(1, &regularFBO);
	glBindFramebuffer(GL_FRAMEBUFFER, regularFBO);

	GLuint tex;
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glBindTexture(GL_TEXTURE_2D, 0);

	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		std::cout << "FRAMEBUFFER 2 INCOMPLETE!" << std::endl;

	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	GLuint fboVAO, fboVBO;
	glGenVertexArrays(1, &fboVAO);
	glGenBuffers(1, &fboVBO);
	glBindVertexArray(fboVAO);
	
	glBindBuffer(GL_ARRAY_BUFFER, fboVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(fboQuad), fboQuad, GL_STATIC_DRAW);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2*sizeof(GLfloat)));

	glBindVertexArray(0);

	glBindVertexArray(VAO);
	{
		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLvoid*)0);
		glEnableVertexAttribArray(1);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLvoid*)(sizeof(GLfloat) * 2));
		glEnableVertexAttribArray(2);
		glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
		glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glVertexAttribDivisor(2, 1);
	}
	glBindVertexArray(0);

	std::cout << sizeof(glm::mat4) << std::endl;

	const int amount = 100000;
	glm::mat4* modelMats;
	modelMats = new glm::mat4[amount];
	srand(glfwGetTime());
	GLfloat radius = 150.0f;
	offset = 25.0f;
	for (GLuint i = 0; i < amount; i++)
	{
		glm::mat4 model;
		GLfloat angle = (GLfloat)i / (GLfloat)amount * 360.0f;
		GLfloat displacement = (rand() % (GLint)(2 * offset)) / 100.0f - offset;
		GLfloat x = sin(angle) * radius + displacement;
		displacement = (rand() % (GLint)(2 * offset * 100)) / 100.0f - offset;
		GLfloat y = displacement * 0.4f;
		displacement = (rand() % (GLint)(2 * offset * 100)) / 100.0f - offset;
		GLfloat z = cos(angle) * radius + displacement;
		model = glm::translate(model, glm::vec3(x, y, z));
		GLfloat scale = (rand() % 20) / 100.0f + 0.05f;
		model = glm::scale(model, glm::vec3(scale));
		GLfloat rotAngle = (rand() % 360);
		model = glm::rotate(model, rotAngle, glm::vec3(0.4f, 0.6f, 0.8f));
		modelMats[i] = model;
	}


	for (GLuint i = 0; i < asteroid.meshes.size(); i++)
	{
		GLuint VAO = asteroid.meshes[i].VAO;
		GLuint buffer;
		glBindVertexArray(VAO);
		glGenBuffers(1, &buffer);
		glBindBuffer(GL_ARRAY_BUFFER, buffer);
		glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &modelMats[0], GL_STATIC_DRAW);
		GLsizei vec4Size = sizeof(glm::vec4);
		glEnableVertexAttribArray(3);
		glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)0);
		glEnableVertexAttribArray(4);
		glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(vec4Size));
		glEnableVertexAttribArray(5);
		glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(2 * vec4Size));
		glEnableVertexAttribArray(6);
		glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(3 * vec4Size));

		glVertexAttribDivisor(3, 1);
		glVertexAttribDivisor(4, 1);
		glVertexAttribDivisor(5, 1);
		glVertexAttribDivisor(6, 1);
		glBindVertexArray(0);
	}

	glUseProgram(modelShader);
	glUniformMatrix4fv(glGetUniformLocation(modelShader, "projection"), 1, GL_FALSE, glm::value_ptr(proj));
	glUseProgram(instancedModelShader);
	glUniformMatrix4fv(glGetUniformLocation(instancedModelShader, "projection"), 1, GL_FALSE, glm::value_ptr(proj));

	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	while (!glfwWindowShouldClose(window))
	{
		glfwPollEvents();
		currentFrame = glfwGetTime();
		deltaTime = currentFrame - lastFrame;
		lastFrame = currentFrame;
		glBindFramebuffer(GL_FRAMEBUFFER, FBO);
		glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glEnable(GL_DEPTH_TEST);
		handleMovement(window, deltaTime);

		glUseProgram(instancedModelShader);
		glUniformMatrix4fv(glGetUniformLocation(instancedModelShader, "view"), 1, GL_FALSE, glm::value_ptr(cam.GetViewMatrix()));
		glUseProgram(modelShader);
		glUniformMatrix4fv(glGetUniformLocation(modelShader, "view"), 1, GL_FALSE, glm::value_ptr(cam.GetViewMatrix()));


		glm::mat4 model;
		model = glm::translate(model, glm::vec3(0.0f, -5.0f, 0.0f));
		model = glm::scale(model, glm::vec3(4.0f));
		glUniformMatrix4fv(glGetUniformLocation(modelShader, "model"), 1, GL_FALSE, glm::value_ptr(model));
		planet.draw(modelShader);

		glUseProgram(instancedModelShader);
		glBindTexture(GL_TEXTURE_2D, asteroid.textures_loaded[0].id);
		for (GLuint i = 0; i < asteroid.meshes.size(); i++)
		{
			glBindVertexArray(asteroid.meshes[i].VAO);
			glDrawElementsInstanced(GL_TRIANGLES, asteroid.meshes[i].vertices.size(), GL_UNSIGNED_INT, 0, amount);
			glBindVertexArray(0);
		}
		glBindTexture(GL_TEXTURE_2D, 0);
		glBindFramebuffer(GL_READ_FRAMEBUFFER, FBO);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, regularFBO);
		glBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glDisable(GL_DEPTH_TEST);
		
		glUseProgram(frameBufferShader);
		glBindVertexArray(fboVAO);
		glBindTexture(GL_TEXTURE_2D, tex);
		//glUniform1i(glGetUniformLocation(frameBufferShader, "myTexture"), 0);
		glDrawArrays(GL_TRIANGLES, 0, 6);
		glBindVertexArray(0);
		glBindTexture(GL_TEXTURE_2D, 0);
		glfwSwapBuffers(window);

	}
	glfwTerminate();
	return 0;
}
Exemple #25
0
int main(int argc, char **argv)
{
    // init global vars
    initSharedMem();

    // register exit callback
    atexit(exitCB);

    // init GLUT and GL
    initGLUT(argc, argv);
    initGL();

    // create a texture object
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    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_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap generation included in OpenGL v1.4
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glBindTexture(GL_TEXTURE_2D, 0);

    // get OpenGL info
    glInfo glInfo;
    glInfo.getInfo();
    //glInfo.printSelf();

#ifdef _WIN32
    // check if FBO is supported by your video card
    if(glInfo.isExtensionSupported("GL_ARB_framebuffer_object"))
    {
        // get pointers to GL functions
        glGenFramebuffers                     = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers");
        glDeleteFramebuffers                  = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers");
        glBindFramebuffer                     = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer");
        glCheckFramebufferStatus              = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus");
        glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)wglGetProcAddress("glGetFramebufferAttachmentParameteriv");
        glGenerateMipmap                      = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress("glGenerateMipmap");
        glFramebufferTexture1D                = (PFNGLFRAMEBUFFERTEXTURE1DPROC)wglGetProcAddress("glFramebufferTexture1D");
        glFramebufferTexture2D                = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D");
        glFramebufferTexture3D                = (PFNGLFRAMEBUFFERTEXTURE3DPROC)wglGetProcAddress("glFramebufferTexture3D");
        glFramebufferTextureLayer             = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)wglGetProcAddress("glFramebufferTextureLayer");
        glFramebufferRenderbuffer             = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbuffer");
        glIsFramebuffer                       = (PFNGLISFRAMEBUFFERPROC)wglGetProcAddress("glIsFramebuffer");
        glBlitFramebuffer                     = (PFNGLBLITFRAMEBUFFERPROC)wglGetProcAddress("glBlitFramebuffer");
        glGenRenderbuffers                    = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffers");
        glDeleteRenderbuffers                 = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffers");
        glBindRenderbuffer                    = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbuffer");
        glRenderbufferStorage                 = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorage");
        glRenderbufferStorageMultisample      = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)wglGetProcAddress("glRenderbufferStorageMultisample");
        glGetRenderbufferParameteriv          = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)wglGetProcAddress("glGetRenderbufferParameteriv");
        glIsRenderbuffer                      = (PFNGLISRENDERBUFFERPROC)wglGetProcAddress("glIsRenderbuffer");

        // check once again FBO extension
        if(glGenFramebuffers && glDeleteFramebuffers && glBindFramebuffer && glCheckFramebufferStatus &&
           glGetFramebufferAttachmentParameteriv && glGenerateMipmap && glFramebufferTexture1D && glFramebufferTexture2D && glFramebufferTexture3D &&
           glFramebufferTextureLayer && glFramebufferRenderbuffer && glIsFramebuffer && glBlitFramebuffer &&
           glGenRenderbuffers && glDeleteRenderbuffers && glBindRenderbuffer && glRenderbufferStorage &&
           glRenderbufferStorageMultisample && glGetRenderbufferParameteriv && glIsRenderbuffer)
        {
            fboSupported = fboUsed = true;
            std::cout << "Video card supports GL_ARB_framebuffer_object." << std::endl;
        }
        else
        {
            fboSupported = fboUsed = false;
            std::cout << "Video card does NOT support GL_ARB_framebuffer_object." << std::endl;
        }
    }

    // check EXT_swap_control is supported
    if(glInfo.isExtensionSupported("WGL_EXT_swap_control"))
    {
        // get pointers to WGL functions
        wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
        wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
        if(wglSwapIntervalEXT && wglGetSwapIntervalEXT)
        {
            // disable v-sync
            wglSwapIntervalEXT(0);
            std::cout << "Video card supports WGL_EXT_swap_control." << std::endl;
        }
    }

#else // for linux, do not need to get function pointers, it is up-to-date
    if(glInfo.isExtensionSupported("GL_ARB_framebuffer_object"))
    {
        fboSupported = fboUsed = true;
        std::cout << "Video card supports GL_ARB_framebuffer_object." << std::endl;
    }
    else
    {
        fboSupported = fboUsed = false;
        std::cout << "Video card does NOT support GL_ARB_framebuffer_object." << std::endl;
    }
#endif

    if(fboSupported)
    {
        // create a MSAA framebuffer object
        // NOTE: All attachment images must have the same # of samples.
        // Ohterwise, the framebuffer status will not be completed.
        glGenFramebuffers(1, &fboMsaaId);
        glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);

        // create a MSAA renderbuffer object to store color info
        glGenRenderbuffers(1, &rboColorId);
        glBindRenderbuffer(GL_RENDERBUFFER, rboColorId);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaCount, GL_RGB8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);

        // create a MSAA renderbuffer object to store depth info
        // NOTE: A depth renderable image should be attached the FBO for depth test.
        // If we don't attach a depth renderable image to the FBO, then
        // the rendering output will be corrupted because of missing depth test.
        // If you also need stencil test for your rendering, then you must
        // attach additional image to the stencil attachement point, too.
        glGenRenderbuffers(1, &rboDepthId);
        glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaCount, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);

        // attach msaa RBOs to FBO attachment points
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorId);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId);


        // create a normal (no MSAA) FBO to hold a render-to-texture
        glGenFramebuffers(1, &fboId);
        glBindFramebuffer(GL_FRAMEBUFFER, fboId);

        glGenRenderbuffers(1, &rboId);
        glBindRenderbuffer(GL_RENDERBUFFER, rboId);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);

        // attach a texture to FBO color attachement point
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);

        // attach a rbo to FBO depth attachement point
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);

        //@@ disable color buffer if you don't attach any color buffer image,
        //@@ for example, rendering the depth buffer only to a texture.
        //@@ Otherwise, glCheckFramebufferStatus will not be complete.
        //glDrawBuffer(GL_NONE);
        //glReadBuffer(GL_NONE);

        // check FBO status
        printFramebufferInfo(fboMsaaId);
        bool status = checkFramebufferStatus(fboMsaaId);
        if(!status)
            fboUsed = false;

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    // start timer, the elapsed time will be used for rotating the teapot
    timer.start();

    // the last GLUT call (LOOP)
    // window will be shown and display callback is triggered by events
    // NOTE: this call never return main().
    glutMainLoop(); /* Start GLUT event-processing loop */

    return 0;
}
int main(int argc, char *argv[])
{
	auto t_start = std::chrono::high_resolution_clock::now();
	GLfloat directionx, directiony, directionz;
	directionx = 0.0f;
	directiony = 0.0f;
	directionz = 1.0f;
	GLboolean quit = GL_FALSE;
	GLenum errorValue;

	// Initialize SDL
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		std::cerr << "SDL video initialization failed! Error: " << SDL_GetError() << std::endl;
		quit = GL_TRUE;
		SDL_Delay(5000);
	}
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_Window* window = SDL_CreateWindow("OpenGL tutorial", 100, 100, width, height, SDL_WINDOW_OPENGL);
	SDL_GLContext context = SDL_GL_CreateContext(window);

	// Initialize GLEW
	glewExperimental = GL_TRUE;
	glewInit();
	
	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after GLEW init: " << errorValue << std::endl;
	}
	
	// Create Vertex Array Objects, don't bind yet
	/*
	VAOs are used to store all of the links between the vertex attributes and VBOs with raw vertex data.
	Since VBOs are just containers for the raw data that the graphics card reads and manipulates,
	the meaning and usage of the data has to be specified for each VBO & shader program.
	This might be quite cumbersome, if many shader programs are used, since the layout of the attributes would
	have to be specified every time. This is wheree VAOs come in: they can be used to store the links between
	VBO and the specified attributes. This way, a new VAO can be bound for each different shader program,
	which can then be changed easily at will by just calling glUseProgram(shaderProg1);.
	The graphics card then knows how to use the raw data in the VBO, since its usage and meaning has been
	specified beforehand and the links between VBOs and attributes has been saved to the VAO.

	As soon as VAO has been bound, all glVertexAttribPointer calls store the information to that VAO.
	*/
	GLuint vaoCube, vaoQuad;
	glGenVertexArrays(1, &vaoCube);
	glGenVertexArrays(1, &vaoQuad);

	// Create a Vertex Buffer Objects and upload vertex data
	/*
	VBOs are used to upload the vertex data to the graphics card.
	glGenBuffers(); creates a VBO, which can then be made active by binding it
	with glBindBuffer();. When the VBO has been set as active by binding it,
	the vertex data can be loaded to it with glBufferData();.

	Note that VBO/OpenGL doesn't know what the data means or is used for, it's just raw data.
	The usage of the data has to be specified, meaning which indices in the data correspond to which
	attribute (pos, color, texcoord, etc.).
	*/
	GLuint vboCube, vboQuad;
	glGenBuffers(1, &vboCube);
	glGenBuffers(1, &vboQuad);

	glBindBuffer(GL_ARRAY_BUFFER, vboCube);
	glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, vboQuad);
	glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);

	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after VBOs: " << errorValue << std::endl;
	}

	// Generate shader programs
	GLuint sceneVertexShader, sceneFragmentShader, sceneShaderProgram;
	createShaderprogram(sceneVertexSource, sceneFragmentSource, sceneVertexShader, sceneFragmentShader, sceneShaderProgram);

	GLuint screenVertexShader, screenFragmentShader, screenShaderProgram;
	createShaderprogram(screenVertexSource, screenFragmentSource, screenVertexShader, screenFragmentShader, screenShaderProgram);

	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after generating shader programs: " << errorValue << std::endl;
	}

	// Specify the layout of the vertex data (bind vertex arrays)
	/*
	Since OpenGL doesn't know how the attributes of the vertices are
	specified in the arrays containing the vertex information (position, color, texture coordinates),
	they need to be specified by the user.
	Each attribute also saves the VBO that's been bound to the current GL_ARRAY_BUFFER.
	This means different VBOs can be used for each attribute if so desired.

	Only calls after a VAO has been bound will "stick" to it.
	As soon as VAO has been bound, all glVertexAttribPointer calls store the information to that VAO.
	See more complete explanation of VAO above.
	*/
	glBindVertexArray(vaoCube);
	glBindBuffer(GL_ARRAY_BUFFER, vboCube);
	specifySceneVertexAttributes(sceneShaderProgram);

	glBindVertexArray(vaoQuad);
	glBindBuffer(GL_ARRAY_BUFFER, vboQuad);
	specifyScreenVertexAttributes(screenShaderProgram);

	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after specifying the layout of vertex data: " << errorValue << std::endl;
	}

	// Load textures
	GLuint texKitten = loadTexture("sample.png");
	GLuint texPuppy = loadTexture("sample2.png");

	glUseProgram(sceneShaderProgram);
	glUniform1i(glGetUniformLocation(sceneShaderProgram, "texKitten"), 0);
	glUniform1i(glGetUniformLocation(sceneShaderProgram, "texPuppy"), 1);

	glUseProgram(screenShaderProgram);
	glUniform1i(glGetUniformLocation(screenShaderProgram, "texFramebuffer"), 0);

	GLint uniModel = glGetUniformLocation(sceneShaderProgram, "model");

	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after loading textures: " << errorValue << std::endl;
	}

	// Create frame buffer
	GLuint frameBuffer;
	glGenFramebuffers(1, &frameBuffer);
	glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after creating a frame buffer: " << errorValue << std::endl;
	}

	// Create texture to hold color buffer
	GLuint texColorBuffer;
	glGenTextures(1, &texColorBuffer);
	glBindTexture(GL_TEXTURE_2D, texColorBuffer);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);

	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after color buffer texture creation: " << errorValue << std::endl;
	}

	// Create Renderbuffer Object to hold depth and stencil buffers
	GLuint rboDepthStencil;
	glGenRenderbuffers(1, &rboDepthStencil);
	glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil);


	// Error checking
	errorValue = glGetError();
	if (errorValue != 0)
	{
		std::cerr << "GL_Error after RBO: " << errorValue << std::endl;
	}

	/*
	Set up projection:
	View matrix:
	First vector gives the position of the camera
	Second vector gives the point where the camera is centered or looking at
	Third vector defines "up", here up is the z-axis, xy-plane is the "ground"
	*/
	glm::mat4 view = glm::lookAt(
		glm::vec3(2.5f, 2.5f, 2.0f),
		glm::vec3(0.0f, 0.0f, 0.0f),
		glm::vec3(0.0f, 0.0f, 1.0f)
		);

	glUseProgram(sceneShaderProgram);

	GLint uniView = glGetUniformLocation(sceneShaderProgram, "view");
	glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));

	// Projection matrix
	glm::mat4 proj = glm::perspective(glm::radians(45.0f), GLfloat(width) / GLfloat(height), 1.0f, 10.0f);
	GLint uniProj = glGetUniformLocation(sceneShaderProgram, "proj");
	glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));

	GLint uniColor = glGetUniformLocation(sceneShaderProgram, "overrideColor");

	// Final error check will write errors (if any are encountered at this point) to file
	GLint status, status2, status3, status4, OpenGLError;
	OpenGLError = glGetError();
	GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	glGetShaderiv(sceneVertexShader, GL_COMPILE_STATUS, &status);
	glGetShaderiv(sceneFragmentShader, GL_COMPILE_STATUS, &status2);
	glGetShaderiv(screenVertexShader, GL_COMPILE_STATUS, &status3);
	glGetShaderiv(screenFragmentShader, GL_COMPILE_STATUS, &status4);

	if (
		OpenGLError != 0
		|| status == 0
		|| status2 == 0
		|| status3 == 0
		|| status4 == 0
		|| frameBufferStatus != GL_FRAMEBUFFER_COMPLETE)
	{
		char buffer1[512], buffer2[512], buffer3[512], buffer4[512];
		glGetShaderInfoLog(sceneVertexShader, 512, NULL, buffer1);
		glGetShaderInfoLog(sceneFragmentShader, 512, NULL, buffer2);
		glGetShaderInfoLog(screenVertexShader, 512, NULL, buffer3);
		glGetShaderInfoLog(screenFragmentShader, 512, NULL, buffer4);

		std::ofstream errorOutput;
		GLchar* errorOutFilename = "shader_errors.txt";
		errorOutput.open(errorOutFilename);
		
		errorOutput
			<< "GL_Error: " << OpenGLError
			<< "\n Scene vertex shader status: " << status
			<< "\n Scene vertex shader log: " << buffer1
			<< "\n Scene fragment shader status: " << status2
			<< "\n Scene fragment shader log: " << buffer2
			<< "\n Screen vertex shader status: " << status3
			<< "\n Screen vertex shader log: " << buffer3
			<< "\n Screen fragment shader status: " << status4
			<< "\n Screen fragment shader log: " << buffer4
			<< "\n Frame buffer status: " << frameBufferStatus
			<< "\n OpenGL version: " << glGetString(GL_VERSION);
		
		errorOutput.close();
		
		std::cerr << "An error has occured with shaders or frame buffer! See "
			<< errorOutFilename
			<< " for more info!\n Terminating program in 10s!"
			<< std::endl;

		SDL_Delay(10000);
		quit = GL_TRUE;
	}

	SDL_Event e;

	while (!quit)
	{
		while (SDL_PollEvent(&e) != 0)
		{
			if (e.type == SDL_QUIT)
			{
				quit = GL_TRUE;
			}
			else if (e.type == SDL_KEYDOWN)
			{
				switch (e.key.keysym.sym)
				{
				case SDLK_RETURN:
					directionx = 1.0f;
					directiony = 0.0f;
					directionz = 0.0f;
					break;
				case SDLK_SPACE:
					directionx = 0.0f;
					directiony = 1.0f;
					directionz = 0.0f;
					break;
				case SDLK_LCTRL:
					directionx = 0.0f;
					directiony = 0.0f;
					directionz = 1.0f;
				default:
					directionx = 0.0f;
					directiony = 0.0f;
					directionz = 1.0f;
					break;
				}
			}
		}

		// Bind framebuffer and draw 3D scene
		glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
		glBindVertexArray(vaoCube);
		glEnable(GL_DEPTH_TEST);
		glUseProgram(sceneShaderProgram);
		
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texKitten);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texPuppy);

		// Clear screen to greenish
		glClearColor(0.15f, 0.7f, 0.5f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Calculate transformation
		auto t_now = std::chrono::high_resolution_clock::now();
		float time = std::chrono::duration_cast<std::chrono::duration<float>>(t_now - t_start).count();
		
		glm::mat4 model;
		model = glm::rotate(model, time * glm::radians(180.f), glm::vec3(directionx, directiony, directionz));
		glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));

		// Draw cube
		glDrawArrays(GL_TRIANGLES, 0, 36);

		glEnable(GL_STENCIL_TEST);

		// Draw floor
		glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to 1
		glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilMask(0xFF); // Write to stencil buffer
		glDepthMask(GL_FALSE); // Don't write to depth buffer
		glClear(GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default)

		glDrawArrays(GL_TRIANGLES, 36, 6);

		// Draw cube reflection

		glStencilFunc(GL_EQUAL, 1, 0xFF); // Pass test if stencil value is 1
		glStencilMask(0x00); // Don't write anything to stencil buffer
		glDepthMask(GL_TRUE); // Write to depth buffer

		model = glm::scale(glm::translate(model, glm::vec3(0, 0, -1)), glm::vec3(1, 1, -1));
		glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));

		glUniform3f(uniColor, 0.3f, 0.3f, 0.3f);
		glDrawArrays(GL_TRIANGLES, 0, 36);
		glUniform3f(uniColor, 1.0f, 1.0f, 1.0f);

		glDisable(GL_STENCIL_TEST);

		// Bind default framebuffer and draw contents of our framebuffer
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glBindVertexArray(vaoQuad);
		glDisable(GL_DEPTH_TEST);
		glUseProgram(screenShaderProgram);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texColorBuffer);

		glDrawArrays(GL_TRIANGLES, 0, 6);

		// Swap buffers
		SDL_GL_SwapWindow(window);
		
	}
	glDeleteRenderbuffers(1, &rboDepthStencil);
	glDeleteTextures(1, &texColorBuffer);
	glDeleteFramebuffers(1, &frameBuffer);
	
	glDeleteTextures(1, &texKitten);
	glDeleteTextures(1, &texPuppy);

	glDeleteProgram(screenShaderProgram);
	glDeleteShader(screenFragmentShader);
	glDeleteShader(screenVertexShader);

	glDeleteProgram(sceneShaderProgram);
	glDeleteShader(sceneFragmentShader);
	glDeleteShader(sceneVertexShader);

	glDeleteBuffers(1, &vboCube);
	glDeleteBuffers(1, &vboQuad);

	glDeleteVertexArrays(1, &vaoCube);
	glDeleteVertexArrays(1, &vaoQuad);

	SDL_GL_DeleteContext(context);
	SDL_Quit();
	return 0;
}
CubeTextureFBO::CubeTextureFBO(unsigned int size, int format, GLuint targets, bool storeDepth) {
    this->size = size;
    this->store_depths = storeDepth;

    const GLenum faces[6] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
                             GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
                             GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
                            };

    texture.resize(targets);

    // Initialize Texture
    glGenTextures(targets, &texture[0]);
    for (size_t i = 0; i < targets; i++) {
        glBindTexture(GL_TEXTURE_CUBE_MAP, texture[i]);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        for (size_t j = 0; j < 6; j++) {
            glTexImage2D(faces[j], 0, format, size, size, 0, GL_RGBA, GL_FLOAT, NULL);
        }
    }



    if(!storeDepth) {
        //Create depth bufferGLuint rboId;
        glGenRenderbuffers(1, &depth);
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
    } else {
        glGenTextures(targets, &depth);

        glBindTexture(GL_TEXTURE_CUBE_MAP, depth);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        for (size_t j = 0; j < 6; j++) {
            glTexImage2D(faces[j], 0, GL_DEPTH_COMPONENT24, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
        }
    }

    // Create FBO and attach buffers
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    for (uint i = 0; i < targets; i++) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, texture[i], 0);
    }
    if (!storeDepth) {
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
    } else {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, depth, 0);
    }


    CHECK_GL_ERRORS();
    CHECK_GL_FBO_COMPLETENESS();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Exemple #28
0
void ShadowMap::create(const ObjectVec & scene, const gml::mat4x4_t &worldview
					, const gml::vec3_t & position, const gml::vec3_t & target
					, const gml::vec3_t & up)
{
	if ( !m_isReady )
	{
#if !defined(NDEBUG)
		fprintf(stderr, "Trying to create shadow map when cubemap not ready\n");
#endif
		return;
	}

	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
	glViewport(0, 0, m_shadowMapSize, m_shadowMapSize);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_FRONT);
	glEnable(GL_DEPTH_TEST);

	if (isGLError()) return;
	
	if (LT_POINT == m_type)
	{
		gml::vec3_t _light_pos = gml::extract3(gml::mul(worldview, gml::vec4_t(position, 1.0)));
		for (unsigned short i = 0; i < 6; ++i)
			m_cameras[i]->setPosition(_light_pos);
	}
	else if (LT_DIRECTIONAL == m_type)
	{
		gml::vec3_t _light_pos = gml::extract3(gml::mul(worldview, gml::vec4_t(position, 1.0)));
		gml::vec3_t _light_target = gml::extract3(gml::mul(worldview, gml::vec4_t(target, 1.0)));
		gml::vec3_t _light_up = gml::extract3(gml::mul(worldview, gml::vec4_t(up, 1.0)));
		m_cameras[0]->lookAt(_light_pos, _light_target, _light_up);
	}
		
	const Shader::Shader* _pdptshdr = m_manager->getDepthShader();

	if (LT_POINT == m_type)
	{
		for (unsigned short i = 0; i < 6; ++i) {
	
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_shadowmap, 0);
			if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)) return;
			glClear(GL_DEPTH_BUFFER_BIT);
			if (isGLError()) return;

			if (_pdptshdr->getIsReady()) {
				_pdptshdr->bindGL();
				if (isGLError()) return;

				Shader::GLProgUniforms shaderUniforms;
				shaderUniforms.m_projection = m_cameras[i]->getProjection();

				for (ObjectVec::const_iterator itr = scene.begin(); itr != scene.end(); ++itr)
				{
					shaderUniforms.m_modelView = gml::mul(m_cameras[i]->getWorldView(), 
						gml::mul(worldview, (*itr)->getObjectToWorld()));
					shaderUniforms.m_normalTrans = gml::transpose( gml::inverse(shaderUniforms.m_modelView) );

					if ( !_pdptshdr->setUniforms(shaderUniforms, false) || isGLError() ) return;

					(*itr)->rasterize();
					if (isGLError()) return;
				}
		
				_pdptshdr->unbindGL();
				glFinish();
			}
		}
	}
	else if (LT_DIRECTIONAL == m_type)
	{
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowmap, 0);
		if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)) return;
		glClear(GL_DEPTH_BUFFER_BIT);
		if (isGLError()) return;

		if (_pdptshdr->getIsReady()) {
			_pdptshdr->bindGL();
			if (isGLError()) return;

			Shader::GLProgUniforms shaderUniforms;
			shaderUniforms.m_projection = m_cameras[0]->getProjection();

			for (ObjectVec::const_iterator itr = scene.begin(); itr != scene.end(); ++itr)
			{
				shaderUniforms.m_modelView = gml::mul(m_cameras[0]->getWorldView(), 
					gml::mul(worldview, (*itr)->getObjectToWorld()));
				shaderUniforms.m_normalTrans = gml::transpose( gml::inverse(shaderUniforms.m_modelView) );

				if ( !_pdptshdr->setUniforms(shaderUniforms, false) || isGLError() ) return;

				(*itr)->rasterize();
				if (isGLError()) return;
			}
	
			_pdptshdr->unbindGL();
			glFinish();
		}
	}
	

	glDisable(GL_CULL_FACE);
	glDisable(GL_DEPTH_TEST);
}
Exemple #29
0
void InitGLES(void)
{
  GLint linked;
  GLuint vertexShader;
  GLuint fragmentShader;
  assert((vertexShader = LoadShader("vert.glsl", GL_VERTEX_SHADER)) != 0);
  assert((fragmentShader = LoadShader("frag.glsl", GL_FRAGMENT_SHADER)) != 0);
  assert((program = glCreateProgram()) != 0);
  glAttachShader(program, vertexShader);
  glAttachShader(program, fragmentShader);
  glLinkProgram(program);
  glGetProgramiv(program, GL_LINK_STATUS, &linked);
  if (!linked) {
    GLint infoLen = 0;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
    if (infoLen > 1) {
      char *infoLog = malloc(infoLen);
      glGetProgramInfoLog(program, infoLen, NULL, infoLog);
      fprintf(stderr, "Error linking program:\n%s\n", infoLog);
      free(infoLog);
    }
    glDeleteProgram(program);
    exit(1);
  }

  //*
  GLuint fbid;
  glGenFramebuffers(1, &fbid);
  glBindFramebuffer(GL_FRAMEBUFFER, fbid);

  GLuint texid;
  glGenTextures(1, &texid);
  glBindTexture(GL_TEXTURE_2D, texid);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  #ifdef _OGLES_30_
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, TARGET_SIZE, TARGET_SIZE, 0, GL_RGBA, GL_FLOAT, NULL);
  #endif
  #ifdef _OGLES_20_
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TARGET_SIZE, TARGET_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  #endif
  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_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texid, 0);

  GLuint rbid;
  glGenRenderbuffers(1, &rbid);
  glBindRenderbuffer(GL_RENDERBUFFER, rbid);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, TARGET_SIZE, TARGET_SIZE);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbid);

  CheckFrameBufferStatus();
  //*/

  glClearColor(0, 0, 0, 0);
  glViewport(0, 0, TARGET_SIZE, TARGET_SIZE);
  glEnable(GL_DEPTH_TEST);

  glUseProgram(program);
}
void ContextSwitchRenderer::drawWorkload() {
    SCOPED_TRACE();

    if (mWorkload > 8) {
        return; // This test does not support higher workloads.
    }

    // Set the background clear color to black.
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    // No culling of back faces
    glDisable(GL_CULL_FACE);
    // No depth testing
    glDisable(GL_DEPTH_TEST);

    EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);

    const int TOTAL_NUM_CONTEXTS = NUM_WORKER_CONTEXTS + 1;
    const float TRANSLATION = 0.9f - (TOTAL_NUM_CONTEXTS * 0.2f);
    for (int i = 0; i < TOTAL_NUM_CONTEXTS; i++) {
        eglWaitSyncKHR(mEglDisplay, fence, 0);
        eglDestroySyncKHR(mEglDisplay, fence);
        glUseProgram(mProgramId);

        // Set the texture.
        glActiveTexture (GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, mTextureId);
        glUniform1i(mTextureUniformHandle, 0);

        // Set the x translate.
        glUniform1f(mTranslateUniformHandle, (i * 0.2f) + TRANSLATION);

        glEnableVertexAttribArray(mPositionHandle);
        glEnableVertexAttribArray(mTexCoordHandle);
        glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, CS_VERTICES);
        glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, CS_TEX_COORDS);

        glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
        fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);

        // Switch to next context.
        if (i < (mWorkload - 1)) {
            eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i]);
            // Switch to FBO and re-attach.
            if (mOffscreen) {
                glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                        GL_RENDERBUFFER, mFboDepthId);
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                     GL_TEXTURE_2D, mFboTexId, 0);
                glViewport(0, 0, mFboWidth, mFboHeight);
            }
        }
        GLuint err = glGetError();
        if (err != GL_NO_ERROR) {
            ALOGE("GLError %d in drawWorkload", err);
            break;
        }
    }

    eglWaitSyncKHR(mEglDisplay, fence, 0);
    eglDestroySyncKHR(mEglDisplay, fence);

    // Switch back to the main context.
    eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
    if (mOffscreen) {
        glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                GL_RENDERBUFFER, mFboDepthId);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                             GL_TEXTURE_2D, mFboTexId, 0);
        glViewport(0, 0, mFboWidth, mFboHeight);
    }
}