Jump to content
  • Advertisement
Sign in to follow this  
soumya_iiitc

OpenGL Getting problem with Pbuffer

This topic is 3775 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am creating PBuffer using the function below and the time to create the Pbuffer increases with the increase of width and height. wglCreatePbufferARB(m_hMainApplicationWindowDC, iPixelFormat, width, height, pbufferAttributes); I am also getting speed problem when i use the call below: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, 0); Large width and height slows my application. Is there is any better method available to do this.Below is my code /////////////////////////////////////// MY CODE/////////////////////////////// #include "stdafx.h" // WGL_ARB_extensions_string PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; // WGL_ARB_pbuffer PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = NULL; PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = NULL; PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = NULL; PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = NULL; PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = NULL; // WGL_ARB_pixel_format PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL; // WGL_ARB_render_texture PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = NULL; PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB = NULL; // Constructors // --------------------------------------------------------------------------- PBuffer::PBuffer(void) { Initialisation(); } PBuffer::PBuffer(unsigned int width, unsigned int height) { Initialisation(); Create(width, height); } // Destructor // --------------------------------------------------------------------------- PBuffer::~PBuffer(void) { glDeleteTextures(1, &m_uiTexture); if (m_hRC != NULL) { wglMakeCurrent(m_hDC, m_hRC); wglDeleteContext(m_hRC); wglReleasePbufferDCARB(m_hPBuffer, m_hDC); wglDestroyPbufferARB(m_hPBuffer); m_hRC = NULL; } if (m_hDC != NULL) { ReleaseDC(g_pMainApplicationWindow->GetHWND(), m_hDC); m_hDC = NULL; } } // Methods // --------------------------------------------------------------------------- // Creation methods // --------------------------------------------------------------------------- void PBuffer::Initialisation(void) { m_hPBuffer = NULL; m_hDC = NULL; m_hRC = NULL; m_wglBindTexImageARB = NULL; m_pucTextureData = NULL; m_pRGBAStream = NULL; m_bStartOfNewFrame = NULL; m_uiGrabbedX = 0; m_uiGrabbedY = 0; m_uiGrabbedWidth = 0; m_uiGrabbedHeight = 0; m_uiWidth = 0; m_uiHeight = 0; m_sLastTopLeftExtents = Point2D(0, 0); m_sLastBottomRightExtents = Point2D(0, 0); m_html_set = false; m_bClearOutput = false; m_bSetLastExtents = false; m_bUsingMatrox = false; } // --------------------------------------------------------------------------- bool PBuffer::Create(unsigned int width, unsigned int height) { if (!InitialiseOpenGLExtensions()) return (false); // Create a p-buffer for off-screen rendering m_uiWidth = width; m_uiHeight = height; // Define the minimum pixel format requirements we will need for the // 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 pixelFormatAttributes[] = { 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, // Double buffering is not required WGL_STENCIL_BITS_ARB, 8, // Stencil buffer 0 // Terminate the list }; // Hold variables for speed if (g_pMainApplicationWindow) { m_hMainApplicationWindowDC = g_pMainApplicationWindow->GetHDC(); m_hMainApplicationWindowRC = g_pMainApplicationWindow->GetHGLRC(); } unsigned int uiCount = 0; int iPixelFormat; wglChoosePixelFormatARB(m_hMainApplicationWindowDC, (const int *)pixelFormatAttributes, NULL, 1, &iPixelFormat, &uiCount); if (uiCount == 0) { MessageBox(NULL, "Failed to find an acceptable pixel format!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } // Set some p-buffer attributes so that the p-buffer can be used as a // 2D RGBA texture target int pbufferAttributes[] = { WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, // RGBA texture format WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, // GL_TEXTURE_2D texture target 0 // Terminate the list }; // Create the p-buffer m_hPBuffer = wglCreatePbufferARB(m_hMainApplicationWindowDC, iPixelFormat, width, height, pbufferAttributes); m_hDC = wglGetPbufferDCARB(m_hPBuffer); m_hRC = wglCreateContext(m_hDC); if (!m_hPBuffer) { MessageBox(NULL, "Failed to create a required frame buffer!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } int iCreatedWidth = 0; int iCreatedHeight = 0; wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_WIDTH_ARB, &iCreatedWidth); wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &iCreatedHeight); if (iCreatedWidth != width || iCreatedHeight != height) { MessageBox(NULL, "Failed to create a required frame buffer with the specified dimensions!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } // The p-buffer has been successfully created // Set the p-buffer's context as the current context if (!wglMakeCurrent(m_hDC, m_hRC)) { MessageBox(NULL, "Failed to set the current context!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } // Clear the p-buffer glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reset the current context if (!wglMakeCurrent(m_hMainApplicationWindowDC, m_hMainApplicationWindowRC)) { MessageBox(NULL, "Failed to set the current context!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } // Create the p-buffer texture glGenTextures(1, &m_uiTexture); glBindTexture(GL_TEXTURE_2D, m_uiTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Initialise storage for texture data m_pucTextureData = (unsigned char *)new (nothrow) unsigned char [width * height * 4]; if (!m_pucTextureData) { MessageBox(NULL, "Failed to initialise the required texture data!", "Error", MB_OK); return(false); } memset(m_pucTextureData, 0, width * height * 4); } bool PBuffer::InitialiseOpenGLExtensions(void) { // Get function pointers to the required OpenGL extensions wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB"); char *strExtension = NULL; if (!wglGetExtensionsStringARB) { MessageBox(NULL, "Failed to initialise an OpenGL extension!", "Error", MB_OK); return(false); } strExtension = (char *)wglGetExtensionsStringARB(wglGetCurrentDC()); // WGL_ARB_pbuffer if (strstr(strExtension, "WGL_ARB_pbuffer") == NULL) { MessageBox(NULL, "A required OpenGL extension was not found!", "Error", MB_OK); return (false); } wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB"); wglGetPbufferDCARB =(PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB"); wglReleasePbufferDCARB =(PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB"); wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB"); wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB"); // WGL_ARB_pixel_format wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); // WGL_ARB_render_texture m_wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB"); wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress("wglReleaseTexImageARB"); wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB"); if (!wglCreatePbufferARB || !wglGetPbufferDCARB || !wglReleasePbufferDCARB || !wglDestroyPbufferARB || !wglQueryPbufferARB || !wglChoosePixelFormatARB || !m_wglBindTexImageARB || !wglReleaseTexImageARB || !wglSetPbufferAttribARB) { MessageBox(NULL, "Failed to initialise the OpenGL extensions!", "Error", MB_OK); return (false); } return (true); } void PBuffer::CompleteInitialisation(void) { // Hold variables for speed if (g_pMainApplicationWindow) { m_bUsingMatrox = g_pMainApplicationWindow->GetUsingMatrox(); if (m_bUsingMatrox) { m_pRGBAStream = g_pMainApplicationWindow->GetMatroxXmioInterface()->GetPipSession()->GetRGBAStream(); } } } void PBuffer::Clear(void) { m_bStartOfNewFrame = true; } bool PBuffer::StartRendering(void) { int iFlag = 0; wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_LOST_ARB, &iFlag); if (iFlag != 0) { // The p-buffer was lost MessageBox(NULL, "The p-buffer was lost!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } if (!wglMakeCurrent(m_hDC, m_hRC)) { MessageBox(NULL, "Failed to change the current context!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } // Clear the p-buffer if the first object is to be rendered if (m_bStartOfNewFrame) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } m_bStartOfNewFrame = false; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(0, m_uiWidth/m_uiHeight, 0.1f, 100.0f); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); return (true); } bool PBuffer::StopRendering(void) { Point2D sTopLeft; Point2D sBottomRight; // Retrieve the top left and bottom right of where the new graphics begin // and end in-order to copy the region to the output card g_pMainApplicationWindow->GetExtents(sTopLeft, sBottomRight); int iWidth = sBottomRight.GetX() - sTopLeft.GetX(); int iHeight = sBottomRight.GetY() - sTopLeft.GetY(); if ((iWidth < 0 || iHeight < 0) && (m_bClearOutput == false)) { // The width or height is invalid - more than likely no output data has // been created as yet wglMakeCurrent(m_hMainApplicationWindowDC, m_hMainApplicationWindowRC); return (false); } if (m_bClearOutput) { memset(m_pucTextureData, 0, m_uiWidth * m_uiHeight * 4); m_uiGrabbedX = 0; m_uiGrabbedY = 0; m_uiGrabbedWidth = m_uiWidth; m_uiGrabbedHeight = m_uiHeight; m_bClearOutput = false; if (!wglMakeCurrent(m_hMainApplicationWindowDC, m_hMainApplicationWindowRC)) { return (false); } return (true); } int iReadX = (int)sTopLeft.GetX(); int iReadY = m_uiHeight-((int)sBottomRight.GetY()); int iReadWidth = iWidth; int iReadHeight = iHeight; if (iReadX < 0) iReadX = 0; if (iReadX > m_uiWidth) iReadX = m_uiWidth; if (iReadY < 0) iReadY = 0; if (iReadY > m_uiHeight) iReadY = m_uiHeight; if (iReadWidth < 0) iReadWidth = 0; if (iReadWidth > m_uiWidth) iReadWidth = m_uiWidth; if (iReadHeight < 0) iReadHeight = 0; if (iReadHeight > m_uiHeight) iReadHeight = m_uiHeight; // NOTE: Shouldn't need this memset, but currently this slows this process // down so the flicker on the output doesn't happen; dumping the contents // of the pbuffer here on every interation of this sometimes shows the // read values (colours) are not quite correct hence the flicker. There // is a possiblity this is the correct solution as the previous data is // not cleared and therefore when the same data is written over the top // the alpha value will be higher to 255!; Clearing the pbuffer first will // stop this. memset(m_pucTextureData, 0, m_uiWidth * m_uiHeight * 4); glReadPixels(iReadX, iReadY, iReadWidth, iReadHeight, GL_RGBA, GL_UNSIGNED_BYTE, m_pucTextureData); m_uiGrabbedX = iReadX; m_uiGrabbedY = iReadY; m_uiGrabbedWidth = iReadWidth; m_uiGrabbedHeight = iReadHeight; m_sLastTopLeftExtents = sTopLeft; m_sLastBottomRightExtents = sBottomRight; m_bSetLastExtents = true; if (!wglMakeCurrent(m_hMainApplicationWindowDC, m_hMainApplicationWindowRC)) return (false); return (true); } bool PBuffer::BindTexImageARB(void) { glBindTexture(GL_TEXTURE_2D, m_uiTexture); if (!m_wglBindTexImageARB(m_hPBuffer, WGL_FRONT_LEFT_ARB)) { MessageBox(NULL, "Failed to bind frame buffer to render texture!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } return (true); } bool PBuffer::ReleaseTexImageARB(void) { if (!wglReleaseTexImageARB(m_hPBuffer, WGL_FRONT_LEFT_ARB)) { MessageBox(NULL, "Failed to release frame buffer from render texture!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } return (true); } void PBuffer::SetHtmlBuffer(unsigned char* val) { SControlPanelConfiguration sControlPanelConfiguration = g_pMainApplicationWindow->GetControlPanelConfiguration(); int iHDSDCardOutputWidth = 0; int iHDSDCardOutputHeight = 0; bool bSuccess = ConvertDimensionsEnumValueToWidthAndHeight(sControlPanelConfiguration.iDimension, &iHDSDCardOutputWidth, &iHDSDCardOutputHeight); if (!bSuccess) return; int width=iHDSDCardOutputWidth; int height=iHDSDCardOutputHeight; int size=width * height *4; m_html_set=true; if(val) memcpy(m_pucTextureData,val,size); } void PBuffer::BlitTextureToMatroxXmio(void) { if (g_pMainApplicationWindow) { if (m_bUsingMatrox) { if (m_uiGrabbedWidth != 0 && m_uiGrabbedHeight != 0) { if(m_html_set==true) { m_html_set=false; } m_pRGBAStream->AddBuffer( this->GetTextureData(), // IMAGE BUFFER TO CARD m_uiGrabbedX, // POSITION_X m_uiGrabbedY, // POSITION_Y m_uiGrabbedWidth, // IMAGE BUFFER WIDTH m_uiGrabbedHeight); // IMAGE BUFFER HEIGHT } } } } bool PBuffer::UseContext(bool useContext) { if (useContext) { int iFlag = 0; wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_LOST_ARB, &iFlag); if (iFlag != 0) { MessageBox(NULL, "The p-buffer was lost!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } if (!wglMakeCurrent(m_hDC, m_hRC)) { MessageBox(NULL, "Failed to change the current context!", "Error", MB_ICONEXCLAMATION | MB_OK); return (false); } } else { if (!wglMakeCurrent(m_hMainApplicationWindowDC, m_hMainApplicationWindowRC)) return (false); } return (true); } void PBuffer::DumpBufferToFile(unsigned char *buffer, int width, int height) { FILE *fp = fopen("C:\\pbuffer.tga", "wb"); _TGAHeader tgaHeader; tgaHeader.idLength = 0; tgaHeader.mapType = 0; tgaHeader.imageType = 2; tgaHeader.mapOrigin = 0; tgaHeader.mapLength = 0; tgaHeader.mapWidth = 0; tgaHeader.xOrigin = 0; tgaHeader.yOrigin = 0; tgaHeader.imageWidth = width; tgaHeader.imageHeight = height; tgaHeader.pixelDepth = 32; tgaHeader.imageDesc = 8; if ((fwrite(&tgaHeader, sizeof(_TGAHeader), 1, fp)) < 1) { return; } unsigned long ulOffset = 0; unsigned char *data = buffer; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { fwrite(data, 4, 1, fp); data+=4; } } fclose(fp); } //////////////////////////////////////// MY CODE ///////////////////////////////

Share this post


Link to post
Share on other sites
Advertisement
You can try also FBO. Although they don't have measurable different in terms of rendering performance, you have more flexibility to sharing resources for FBO as it use the current rendering context (instead of having its own rendering context). In this sense, you maybe able to squeeze out a little rendering time by sharing overhead among different FBO rendering.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!