Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   C++ (OpenGL) Texturen in PixelBuffer rendern (https://www.delphipraxis.net/123318-opengl-texturen-pixelbuffer-rendern.html)

Jan 30. Okt 2008 16:46


(OpenGL) Texturen in PixelBuffer rendern
 
Hallo DPler!

Ich programmiere zwar grade nicht mit Delphi aber ich dachte mir, dass mir hier trotzdem weitergeholfen werden kann.
Wenn ich im falschen Forum bin -> bitte verschieben, danke!

Also das Problem ist folgendes:
Ich arbeite an einem OpenGl Projekt, bei dem ich einen Graphen in eine Textur rendern will und diese dann auf einem Quad darstellen will.
Dazu nutze ich die OpenGL extensions um direkt off-screen in eine Textur zu rendern.
Das klappt auch bisher ganz gut, allerdings weigert sich OpenGL jetzt in diese Textur auch andere Texturen hineinzurendern.
Das bedeutet, dass ich nur farbige Objekte rendern kann, aber keine texturierten, sobald ich den rendering context auf den Pixelbuffer geschaltet habe. Vor und nach dem rendern in den Pixelbuffer funktioniert das rendern von texturierten Objekten tadellos.
Gibt es da irgendetwas besonderes was ich beachten muss?

MfG
Jan

littleDave 30. Okt 2008 16:55

Re: (OpenGL) Texturen in PixelBuffer rendern
 
Schon mal mit einem weiteren Aufruf von
Delphi-Quellcode:
glEnable(GL_TEXTURE_2D);
probiert? Wenn ja, müsst ich erst den Quelltext sehen, bevor ich da was sagen könnte.

Jan 30. Okt 2008 18:04

Re: (OpenGL) Texturen in PixelBuffer rendern
 
draw:
Code:
void drawpBuffer()
{
   int flag = 0;
   wglQueryPbufferARB( g_pbuffer.hPBuffer, WGL_PBUFFER_LOST_ARB, &flag );

   if( flag != 0 )
   {
      exit(-1);
   }



   if( !wglReleaseTexImageARB( g_pbuffer.hPBuffer, WGL_FRONT_LEFT_ARB ) )
   {
      exit(-1);
   }

   
   if( !wglMakeCurrent( g_pbuffer.hDC, g_pbuffer.hRC ) )
   {
      exit(-1);
   }


   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
   glLoadIdentity();

   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();
   xMatrix4D mOrtho = xMatrix4D_ortho(0,streetRes,0,streetRes, -1, 1);
   glMultMatrixf((float*)&mOrtho);
   glViewport(0, 0,streetRes, streetRes);


   glDisable(GL_DEPTH_TEST);

   //RENDER TO PBUFFER


   glClearColor(0.3, 0.7, 0.3, 0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   

   glEnable(GL_TEXTURE_2D);
   glMatrixMode(GL_MODELVIEW);

    glBindTexture( GL_TEXTURE_2D, TexIDpng[10] );
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

   glBegin(GL_QUADS);
   //quad with texture
   glColor4f(1,0,0,0.5);
   glNormal3f(0,0,1);
   glTexCoord2f(1,1);
   glVertex2f(0,0);
   glTexCoord2f(0,1);
   glVertex2f(3 ,0);
   glTexCoord2f(0,0);
   glVertex2f(3 ,-3);
   glTexCoord2f(1,0);
   glVertex2f(0,-3);

   glEnd();

   glDisable(GL_TEXTURE_2D);


   glMatrixMode(GL_PROJECTION);
   glPopMatrix();

   glMatrixMode(GL_MODELVIEW);
   glPopMatrix();

//QT window reactivate
   mainWindow->openGL->makeCurrent();



   glBindTexture( GL_TEXTURE_2D, pbufferTex );
   if( !wglBindTexImageARB( g_pbuffer.hPBuffer, WGL_FRONT_LEFT_ARB ) )
   {
      exit(-1);
   }

//cg shader update
   cgGLSetTextureParameter(myCgFragmentParam_TextureStreets,pbufferTex);
   cgGLEnableTextureParameter(myCgFragmentParam_TextureStreets);
}
und so sieht die Init aus:

Code:
void initpBuffer()
{
   initpb = true;
   GLuint PixelFormat;

   PIXELFORMATDESCRIPTOR pfd;
   memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));


   pfd.nSize     = sizeof(PIXELFORMATDESCRIPTOR);
   pfd.nVersion  = 1;
   pfd.dwFlags   = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
   pfd.iPixelType = PFD_TYPE_RGBA;
   pfd.cColorBits = 16;
   pfd.cDepthBits = 16;

   
   //PixelFormat = ChoosePixelFormat( g_hDC, &pfd );


   g_hDC = wglGetCurrentDC();
   PixelFormat = ChoosePixelFormat( g_hDC, &pfd );
   SetPixelFormat( g_hDC, PixelFormat, &pfd);
   g_hRC = wglCreateContext( g_hDC );
   wglMakeCurrent( g_hDC, g_hRC );



   wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
   char *ext = NULL;

   if( wglGetExtensionsStringARB )
      ext = (char*)wglGetExtensionsStringARB( wglGetCurrentDC() );
   else
   {
//       MessageBox(NULL,"Unable to get address for wglGetExtensionsStringARB!",
//          "ERROR",MB_OK|MB_ICONEXCLAMATION);
      exit(-1);
   }

   //
   // WGL_ARB_pbuffer
   //

   if( strstr( ext, "WGL_ARB_pbuffer" ) == NULL )
   {
      exit(-1);
   }
   else
   {
      wglCreatePbufferARB   = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
      wglGetPbufferDCARB    = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB");
      wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB");
      wglDestroyPbufferARB  = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB");
      wglQueryPbufferARB    = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB");

      if( !wglCreatePbufferARB || !wglGetPbufferDCARB || !wglReleasePbufferDCARB ||
         !wglDestroyPbufferARB || !wglQueryPbufferARB )
      {
         exit(-1);
      }
   }

   //
   // WGL_ARB_pixel_format
   //

   if( strstr( ext, "WGL_ARB_pixel_format" ) == NULL )
   {
      return;
   }
   else
   {
      wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");

      if( !wglChoosePixelFormatARB )
      {
         exit(-1);
      }
   }

   //
   // WGL_ARB_render_texture
   //

   if( strstr( ext, "WGL_ARB_render_texture" ) == NULL )
   {
      exit(-1);
   }
   else
   {
      wglBindTexImageARB    = (PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB");
      wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress("wglReleaseTexImageARB");
      wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB");

      if( !wglBindTexImageARB || !wglReleaseTexImageARB || !wglSetPbufferAttribARB )
      {
         exit(-1);
      }
   }

   //-------------------------------------------------------------------------
   // Create a p-buffer for off-screen rendering.
   //-------------------------------------------------------------------------

   g_pbuffer.hPBuffer = NULL;
   g_pbuffer.nWidth  = streetRes;
   g_pbuffer.nHeight = streetRes;

   //
   // 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 count = 0;
   int pixelFormat;

   wglChoosePixelFormatARB( g_hDC,(const int*)pf_attr, NULL, 1, &pixelFormat, &count);

   if( count == 0 )
   {
      exit(-1);
   }

   //
   // 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...
   //

   g_pbuffer.hPBuffer = wglCreatePbufferARB( g_hDC, pixelFormat, g_pbuffer.nWidth, g_pbuffer.nHeight, pb_attr );
   g_pbuffer.hDC     = wglGetPbufferDCARB( g_pbuffer.hPBuffer );
   g_pbuffer.hRC     = wglCreateContext( g_pbuffer.hDC );

   if( !g_pbuffer.hPBuffer )
   {
      exit(-1);
   }

   int h;
   int w;
   wglQueryPbufferARB( g_pbuffer.hPBuffer, WGL_PBUFFER_WIDTH_ARB, &h );
   wglQueryPbufferARB( g_pbuffer.hPBuffer, WGL_PBUFFER_WIDTH_ARB, &w );

   if( h != g_pbuffer.nHeight || w != g_pbuffer.nWidth )
   {
      exit(-1);
   }

   //
   // 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( g_pbuffer.hDC, g_pbuffer.hRC ) )
   {
      exit(-1);
   }

   drawpBuffer();

}
Das ist der code der den pbuffer betrifft. Hoffe das hilft weiter.

mfg
Jan

Lossy eX 31. Okt 2008 09:23

Re: (OpenGL) Texturen in PixelBuffer rendern
 
Ich denke das Verhalten so wie es ist ist vollkommen okay. Denn ein pBuffer tritt als eingenständiger RenderKontext in Erscheinung. Und als eigenständiger RenderKontext besitzt er auch eine eigene Statemachine und einen eigenen Namespace für Texturen, Displaylisten etc. Wenn du jetzt eine Textur in deinem Hauptkontext erstellst und diese im pBuffer benutzen wolltest müsstest du sie dort neu laden oder du weißt OpenGL an, dass diese beiden Kontexe sich einen Namespace teilen sollen. Das geht mit der Methode wglShareLists. Diese Methode solltest du direkt nach dem Erstellen des pBuffers aufrufen.

Jan 1. Nov 2008 13:22

Re: (OpenGL) Texturen in PixelBuffer rendern
 
Der Hinweis ist GENAU was ich gebraucht habe. Ich wusste nicht, dass jeweils ein eigenes Set von States für jeden RenderKontext erstellt wird.
Vielen Dank!

Jan


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz