Example #1
0
void init()
{
    glGenFramebuffers(1, &fb);
    glGenTextures(1, &color);
    glGenRenderbuffers(1, &depth);

    glBindFramebuffer(GL_FRAMEBUFFER, fb);

    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(	GL_TEXTURE_2D,
                    0,
                    GL_RGBA,
                    fbo_width, fbo_height,
                    0,
                    GL_RGBA,
                    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_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

    glBindRenderbuffer(GL_RENDERBUFFER, depth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo_width, fbo_height);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);

    CHECK_FRAMEBUFFER_STATUS();
}
void GFXGLWindowTarget::makeActive()
{
   if(mBackBufferFBO)
   {
      glBindFramebuffer( GL_FRAMEBUFFER, mBackBufferFBO);
      GFXGL->getOpenglCache()->setCacheBinded(GL_FRAMEBUFFER, mBackBufferFBO);
   }
   else
   {
      glGenFramebuffers(1, &mBackBufferFBO);
      _setupAttachments();
      CHECK_FRAMEBUFFER_STATUS();
   }
}
Example #3
0
void RenderTexture::Init(int width, int height, bool fboMode)
{
	GLenum err;
	canvas_hDC = wglGetCurrentDC();
	canvas_hRC = wglGetCurrentContext();

	m_texID = 0;
	m_FBO = fboMode;

	if (width == 0 || height == 0)
	{
		int screenSize[4];
		glGetIntegerv(GL_VIEWPORT, screenSize);

		nWidth = screenSize[2];
		nHeight = screenSize[3];
	}
	else
	{
		nWidth = width;
		nHeight = height;
	}

	// Find the (easiest) format to use
	if (video.supportNPOT && video.supportTexRects && GL_TEXTURE_RECTANGLE_ARB)
	{
		m_texFormat = GL_TEXTURE_RECTANGLE_ARB;
	}
	else
	{
		// If non-power-of-two textures aren't supported, force them to be power-of-two of the max texture size.
		m_texFormat = GL_TEXTURE_2D;

		GLint texSize; 
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize); 

		bool end=false;
		int curMax=0;

		// Make sure its square and a power-of-two
		for (size_t i=5; !end; i++)
		{
			int iSize = powf(2,(float)i);
			if (iSize < texSize)
				curMax = iSize;
			else
				end = true;
		}

		// Divide by 2 to make sure they're no where near their max texture size
		nWidth = nHeight = (curMax/2);
	}

	// Hmm... why was this here?
	//m_texFormat = GL_TEXTURE_2D;


	if (m_FBO)
	{ // Frame Buffer OBject mode (newer, better, only supported by newer cards and drivers though)
		
		// Reported crash in this section of the code by a user
		// add exception handling to try and capture it for future versions.
		try
		{
			LOG_INFO << "GFX Info: Initialising FrameBufferObject.";

			// Generate our buffers and texture
			glGenFramebuffers(1, &m_frameBuffer );
			glGenRenderbuffers(1, &m_depthRenderBuffer );
			glGenTextures(1, &m_texID);

			// --
			// Bind frame buffer and texture
			glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_frameBuffer);
			glBindTexture(m_texFormat, m_texID);

			// This is our dynamic texture, which will be loaded with new pixel data
			// after we're finshed rendering to the p-buffer.
			glTexImage2D(m_texFormat, 0, GL_RGBA8, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
			glTexParameteri(m_texFormat, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
			glTexParameteri(m_texFormat, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

			// And attach it to the FBO so we can render to it
			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_texFormat, m_texID, 0);

			// attach a depth buffer to the Frame buffer
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthRenderBuffer );
			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nWidth, nHeight);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthRenderBuffer);

			CHECK_FRAMEBUFFER_STATUS();

			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);	// Unbind the FBO for now
		}
		catch (...)
		{
			LOG_ERROR << "FrameBuffer Error:" << __FILE__ << ": line #" << __LINE__ << ":" << __FUNCTION__;
		}

	}
	else
	{ // Pixel Buffer Mode
		LOG_INFO << "Attempting to create a PixelBuffer.";

		//-------------------------------------------------------------------------
		// Create a p-buffer for off-screen rendering.
		//-------------------------------------------------------------------------
		
		// Define the minimum pixel format requirements we will need for our 
		// p-buffer. A p-buffer is just like a frame buffer, it can have a depth 
		// buffer associated with it and it can be double buffered.
		int pf_attr[] =
		{
			WGL_SUPPORT_OPENGL_ARB, TRUE,       // P-buffer will be used with OpenGL
			WGL_DRAW_TO_PBUFFER_ARB, TRUE,      // Enable render to p-buffer
			WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, // P-buffer will be used as a texture
			WGL_RED_BITS_ARB, 8,                // At least 8 bits for RED channel
			WGL_GREEN_BITS_ARB, 8,              // At least 8 bits for GREEN channel
			WGL_BLUE_BITS_ARB, 8,               // At least 8 bits for BLUE channel
			WGL_ALPHA_BITS_ARB, 8,              // At least 8 bits for ALPHA channel
			WGL_DEPTH_BITS_ARB, 16,             // At least 16 bits for depth buffer
			WGL_DOUBLE_BUFFER_ARB, FALSE,       // We don't require double buffering
			0                                   // Zero terminates the list
		};

		unsigned int iCount = 0;
		int iPixelFormat = 0;
		// g_hdc = wxglcanvas hdc

		wglChoosePixelFormatARB(canvas_hDC, (const int*)pf_attr, NULL, 1, &iPixelFormat, &iCount);

		if (iCount == 0)
		{
			LOG_ERROR << "wglChoosePixelFormatARB() Failed! PixelBuffer could not find an acceptable pixel format!" << glGetError();
			return;
		}

		// Set some p-buffer attributes so that we can use this p-buffer as a
		// 2D RGBA texture target.
		int pb_attr[] =
		{
			WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, // Our p-buffer will have a texture format of RGBA
			WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB,   // Of texture target will be GL_TEXTURE_2D
			0                                             // Zero terminates the list
		};

		// Create the p-buffer...
		m_hPBuffer = wglCreatePbufferARB(canvas_hDC, iPixelFormat, nWidth, nHeight, pb_attr );

		// Error check
		err = glGetError();
		if (!m_hPBuffer)
		{
			LOG_ERROR << "Could not create the PixelBuffer." << err;
			return;
		}
		else if (err==GL_NO_ERROR)
		{
			LOG_INFO << "Successfully created the PixelBuffer.";
		}
		else if (err==GL_INVALID_ENUM)
		{
			LOG_ERROR << "Invalid Enum during PixelBuffer creation.";
		}
		else if (err==GL_INVALID_VALUE)
		{
			LOG_ERROR << "Invalid Value during PixelBuffer creation.";
		}
		else if (err==GL_INVALID_OPERATION)
		{
			LOG_ERROR << "Invalid Operation during PixelBuffer creation.";
		}
		else if (err==GL_OUT_OF_MEMORY)
		{
			LOG_ERROR << "Critical error!  Out-of-Memory during PixelBuffer creation. PixelBuffer could not be created.";
			return;
		}
		else
		{
			LOG_ERROR << "PixelBuffer created, but an unknown error occured :" << err;
		}

		m_hDC = wglGetPbufferDCARB( m_hPBuffer );
		m_hRC = wglCreateContext( m_hDC );

		int h=0, w=0;
		wglQueryPbufferARB( m_hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &h );
		wglQueryPbufferARB( m_hPBuffer, WGL_PBUFFER_WIDTH_ARB, &w );

		if (h!=nHeight || w!=nWidth)
		{
			LOG_ERROR << "The width and height of the created PixelBuffer don't match the requirements. Image likely to come out distorted.";
			nHeight = h;
			nWidth = w;
		}

		if (!wglShareLists(canvas_hRC, m_hRC))
		{
			err = glGetError();
			LOG_ERROR << "Call to wglShareLists() failed for our PixelBuffer.";
		}

		// We were successful in creating a p-buffer. We can now make its context 
		// current and set it up just like we would a regular context 
		// attached to a window.
		if (!wglMakeCurrent(m_hDC, m_hRC))
		{
			err = glGetError();
			LOG_ERROR << "wglMakeCurrent() Failed! Could not make the PBuffer's context current!" << err;
		}

		// Setup OpenGL RenderState
		InitGL();

		// This is our dynamic texture, which will be loaded with new pixel data
		// after we're finshed rendering to the p-buffer.
		glGenTextures(1, &m_texID);
		glBindTexture(m_texFormat, m_texID);
		glTexImage2D(m_texFormat, 0, GL_RGBA8, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); //GL_FLOAT
		glTexParameteri(m_texFormat, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		glTexParameteri(m_texFormat, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		//glTexParameteri(texFormat, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
		//glTexParameteri(texFormat, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

		// Now set the current context back to original.
		if (!wglMakeCurrent(canvas_hDC, canvas_hRC))
		{
			err = glGetError();
			LOG_ERROR << "wglMakeCurrent() Failed! Could not return the context back to the wxGLCanvas!" << err;
		}
	}
}