   wglBindTexImageARB invalid enumerator
  I have implemented rendering to texture using pbuffers. The stuff works on a GF FX 5200, but on an ATI XT 800 (WinXP home SP 2, Catalyst 5.11), I get an error 'invalid enumerator' when calling wglBindTexImageARB (<valid pbuffer handle>, WGL_FRONT_LEFT_ARB), and I have no clue why. (#define WGL_FRONT_LEFT_ARB 0x2083).I can provide code or even an entire Visual C++ 6.0 project or .NET 2003 solution together with instructions, but I thought I'd rather wait for specific questions here before cluttering this post with sides of code. :)[Edited by - karx11erx on December 15, 2005 5:49:44 AM]
  I think some code might be handy.. dont dump it all however, just the parts relivent to the problem...   ;  Ok, but you better duck. ;) It's from an old 3D shooter (Descent 2) I am maintaining (d2x-xl), and is for cameras and monitors (camera views). You may argue I could write a small sample app to check this, but I am not an OpenGL guru at all, and it was much easier to add this code into an existing app than writing a new one. And then, the stuff needs to work in the application, not in some small test program. :)- CreateCameras() and CreateCamera() initialize cameras for various object types.- RenderCamera() walks through all cameras and renders those whose target texture  (view) is visible and that have timed out (time out mechanism to improve framerate on slow gfx cards).- ogl_loadtexture() is the 'low level' texture initialization and binding function.- ogl_loadbmtexture_m() calls ogl_loadtexture() with the current texture (or frame) from the applications texture pool.- ogl_bindbmtex() binds a previously initialized texture (again).- g3_draw_tmap_2() renders a face, blending up to three textures (base, overlay, lightmap), properly processing color key and alpha transparency through use of  a shader program.The whole rendering process works in several stages:- First for every camera, the scene from the view point of the camera is rendered, creating the camera views in pixel buffers.- Then the player view is rendered face by face using g3_draw_tmap_2(). For each face's texture, the application calls ogl_loadbmtexture_m() to initialize a texture buffer (RGBA) using the games texture data (BMP or RGBA), unless the face is a camera view and has a connected pbuffer.- The applications binds each face's texture buffer right in g3_draw_tmap_2(). If the  face is a camera view, the texture management data (type _ogl_texture) contains the related pbuffer's handles and additionally to binding a texture, wglBindTexImageARB is called. If the texture was already bound, it's releasedbefore binding it again (may be superfluous, but looks like the safe path).so this goes like: RenderCamera() -> render_frame() -> ogl_loadbmtexture_m() -> ogl_loadtexture() -> g3_draw_tmap_2 -> ogl_bindbmtex() <- problem.I have a few questions here:- Right after creation of the pbuffer, a texture is created (glGenTextures()), bound (glBind()) and assigned some properties.- Later on during use of a pbuffer as a texture in rendering, another texture is created, bound with glBind(), and then bound with wglBindImageARB().Do I need the first texture at all?Do I need to create the other texture, or do I simply need to call wglBindImageARB() for pbuffer textures?Data types:typedef struct _ogl_pbuffer {   HANDLE   hBuf;   HDC hDC;   HGLRC    hRC;   charbBound;} ogl_pbuffer;typedef struct _ogl_texture {   GLuint handle;   GLint  internalformat;   GLenum format;   int    w,h,tw,th,lw;   int    bytesu;   int    bytes;   GLfloatu,v;   GLfloatprio;   int    wrapstate;   fix    lastrend;   unsigned    long numrend;   char   wantmip;   ogl_pbuffer pbuffer;} ogl_texture;Texture management:int ogl_pbuffer_avail (ogl_pbuffer *pb){intbLost;if (!wglQueryPbufferARB)return -1;if (!(pb->hDC && pb->hDC && pb->hRC))return -1;wglQueryPbufferARB (pb->hBuf, WGL_PBUFFER_LOST_ARB, &bLost);return !bLost;}//------------------------------------------------------------------------------int ogl_bindteximage (ogl_texture *tex){#if 0if (tex->pbuffer.bBound) {   wglReleaseTexImageARB (tex->pbuffer.hBuf, WGL_FRONT_LEFT_ARB);   tex->pbuffer.bBound = 0;   }#endif#if 1glBindTexture (GL_TEXTURE_2D, tex->pbuffer.texId);#   if 1glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE_EXT);glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE_EXT);glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR /*GL_LINEAR_MIPMAP_LINEAR*/);glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);#   elseglTexParameteri(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_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);#   endifglBindTexture (GL_TEXTURE_2D, tex->pbuffer.texId);#endifif (!(tex->pbuffer.bBound ||    (tex->pbuffer.bBound = wglBindTexImageARB (tex->pbuffer.hBuf, WGL_FRONT_LEFT_ARB)))) {#ifdef _DEBUG   char *psz = (char *) gluErrorString (glGetError ());#endif   return 1;   }return 0;}//------------------------------------------------------------------------------int ogl_bindbmtex (grs_bitmap *bm, int transp){   ogl_texture   *tex = bm->gltexture;   int    bPBuffer = tex && (ogl_pbuffer_avail (&tex->pbuffer) == 1);if (bPBuffer && tex->pbuffer.bBound) {   glDeleteTextures (1, &tex->handle);   tex->handle = 0;   wglReleaseTexImageARB (tex->pbuffer.hBuf, WGL_FRONT_LEFT_ARB);   tex->pbuffer.bBound = 0;   }if (bm->bm_curframe)   bm = bm->bm_curframe;if (!tex || (tex->handle <= 0)) {   if (!ogl_loadbmtexture (bm, transp)) return 1;   tex = bm->gltexture;   }if (bPBuffer) {   if (ogl_bindteximage (tex)) return 1;   }else   glBindTexture (GL_TEXTURE_2D, tex->handle);bm->gltexture->lastrend = GameTime;bm->gltexture->numrend++;return 0;}//------------------------------------------------------------------------------int ogl_loadtexture (unsigned char * data, int dxo,int dyo, ogl_texture *tex, int transp, int superTransp){tex->tw=pow2ize (tex->w);tex->th=pow2ize (tex->h);//calculate smallest texture size that can accomodate us (must be multiples of 2)if (gr_badtexture > 0)    return 1;#ifndef __macosx__// always fails on OS X, but textures work fine!if (tex_format_verify (tex))   return 1;#endif//calculate u/v values that would make the resulting texture correctly sizedtex->u = (float) ((double)tex->w / (double)tex->tw);tex->v = (float) ((double)tex->h / (double)tex->th);if ((ogl_pbuffer_avail (&tex->pbuffer) < 1) && data)   if (transp >= 0) // convert texture data to RGBA ogl_filltexbuf (data,texbuf,tex->lw,tex->w,tex->h,dxo,dyo,  tex->tw,tex->th,tex->format,   transp, superTransp);   else // texture data is already RGBA memcpy (texbuf, data, tex->w * tex->h * 4);// Give our data to OpenGL.if (ogl_pbuffer_avail (&tex->pbuffer) == 1)    {   if (ogl_bindteximage (tex)) return 1;   }else    {   glGenTextures (1, &tex->handle);   glPrioritizeTextures (1,&tex->handle, &tex->prio);   glBindTexture (GL_TEXTURE_2D, tex->handle);   glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);   if (tex->wantmip){ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_texmagfilt); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_texminfilt); }   else{ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); }   if (tex->wantmip && GL_needmipmaps) gluBuild2DMipmaps (    GL_TEXTURE_2D, tex->internalformat,tex->tw, tex->th, tex->format,GL_UNSIGNED_BYTE,texbuf);   else glTexImage2D (    GL_TEXTURE_2D, 0, tex->internalformat,    tex->tw, tex->th, 0, tex->format, // RGBA textures.    GL_UNSIGNED_BYTE, // imageData is a GLubyte pointer.    texbuf);   }tex_set_size (tex);r_texcount++; return 0;}//------------------------------------------------------------------------------int ogl_loadbmtexture_m (grs_bitmap *bm, int domipmap, int transp, ogl_pbuffer *pb){   unsigned char *buf;   ogl_texture *t;while (bm->bm_parent && (bm->bm_parent != bm) && (bm->bm_parent->bm_curframe != bm))   bm = bm->bm_parent;buf = bm->bm_data;if (!(t = bm->gltexture)) {   t = bm->gltexture = ogl_get_free_texture ();   if (!t) return 1;   ogl_init_texture (t);   t->lw = bm->bm_w;   t->w = bm->bm_w;   t->h = bm->bm_h;   t->wantmip = domipmap;   if (pb) t->pbuffer = *pb;   else memset (&t->pbuffer, 0, sizeof (ogl_pbuffer));   }else {   if (t->handle > 0) return 1;   if (!t->w) { t->lw = bm->bm_w; t->w = bm->bm_w; t->h = bm->bm_h; }   }if (bm->bm_flags & BM_FLAG_RLE) {   // expand application texture data   }ogl_loadtexture (buf, 0, 0, bm->gltexture, (bm->bm_flags & BM_FLAG_TGA) ? -1 : transp, (bm->bm_flags & (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT)) != 0);return 0;}Render function:bool g3_draw_tmap_2 (   int nv,   g3s_point **pointlist,   g3s_uvl *uvl_list,   g3s_uvl *uvl_lMap,   grs_bitmap *bmBot,   grs_bitmap *bm,   ogl_texture *lightMap,   int orient,   int bBlend){   int    c, bDrawBM;   g3s_point   *p, **pp;   GLhandleARB   lmProg;glDepthFunc (GL_LEQUAL);if (bBlend)   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);else   glDisable (GL_BLEND);r_tpolyc++;if (bmBot->bm_curframe)   bmBot = bmBot->bm_curframe;if (bm && bm->bm_curframe)   bm = bm->bm_curframe;bDrawBM = bm && ((tmap_drawer_ptr == draw_tmap_flat) || !bTexMergeOk);if (bLightMapsOk && bUseLightMaps && lightMap && !IsMultiGame) {   //render using a lightmap   }else    {//lightMapping disabled - render old way   if (tmap_drawer_ptr == draw_tmap_flat) { // render untextured face - just colorize and apply transparency }   else if (tmap_drawer_ptr == draw_tmap) { // render texture int bMergeTex = bTexMergeOk && bUseHiresTextures && bm;  r_tpolyc++; glActiveTexture (GL_TEXTURE0_ARB); glEnable (GL_TEXTURE_2D); if (ogl_bindbmtex (bmBot, 0))    return 1; ogl_texwrap (bmBot->gltexture, GL_REPEAT); if (bMergeTex) {   //multitexturing using shader program    glUseProgramObject (texMergeProg);    glUniform1i (glGetUniformLocation (texMergeProg, "btmTex"), 0);    glActiveTexture (GL_TEXTURE1_ARB);    glEnable (GL_TEXTURE_2D);    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_RGBA);    if (ogl_bindbmtex (bm, 0))  return 1;    glUniform1i (glGetUniformLocation (texMergeProg, "topTex"), 1);    ogl_texwrap (bm->gltexture, GL_REPEAT);    } glBegin (GL_TRIANGLE_FAN); for (c = 0, pp = pointlist; c < nv; c++, pp++) {    set_tmap_color (uvl_list + c, c, bmBot, !bDrawBM);    glMultiTexCoord2f (GL_TEXTURE0_ARB, f2glf (uvl_list [c].u), f2glf (uvl_list [c].v));    if (bMergeTex) {  set_texcoord (uvl_list + c, orient, 1);  }    p = *pp;    glVertex3d (f2glf (p->p3_vec.x), f2glf (p->p3_vec.y), -f2glf (p->p3_vec.z));    } glEnd (); if (bMergeTex) {    glActiveTexture (GL_TEXTURE1_ARB);    glBindTexture (GL_TEXTURE_2D, 0);    glDisable (GL_TEXTURE_2D); // Disable the 2nd texture    glUseProgramObject (0);    } }   if (bDrawBM) { r_tpolyc++; glActiveTexture (GL_TEXTURE0_ARB); glEnable (GL_TEXTURE_2D); if (!ogl_bindbmtex (bm, 0))    return 1; ogl_texwrap (bm->gltexture,GL_REPEAT); glBegin (GL_TRIANGLE_FAN); for (c = 0, pp = pointlist; c < nv; c++, pp++) {    set_tmap_color (uvl_list + c, c, bm, 1);    set_texcoord (uvl_list + c, orient, 0);    p = *pp;    glVertex3d (f2glf (p->p3_vec.x), f2glf (p->p3_vec.y), -f2glf (p->p3_vec.z));    } glEnd (); glDepthFunc (GL_LESS); }   glActiveTexture (GL_TEXTURE0_ARB);   glBindTexture (GL_TEXTURE_2D,0);   glDisable (GL_TEXTURE_2D);   tmap_color.index =   light_color.index = 0;   }if (!bBlend)   glEnable (GL_BLEND);return 0;}Camera handling:int OglCreateCamBuf (tCamera *pc){   PIXELFORMATDESCRIPTOR pfd;   int pf; static int pfAttribs [] = { WGL_SUPPORT_OPENGL_ARB, TRUE, WGL_DRAW_TO_PBUFFER_ARB, TRUE, WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, WGL_RED_BITS_ARB, 8, WGL_GREEN_BITS_ARB, 8, WGL_BLUE_BITS_ARB, 8, WGL_ALPHA_BITS_ARB, 8, WGL_DEPTH_BITS_ARB, 24, WGL_DOUBLE_BUFFER_ARB, FALSE, 0};   static int pbAttribs [] = { WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0};if (!bRender2TextureOk)   return 0;wglChoosePixelFormatARB (hGlDC, (const int *) pfAttribs, NULL, 1, &pfd, &pf);if (!pf)   return 0;if (!(pc->pb.hBuf = wglCreatePbufferARB (hGlDC, pf, pc->texBuf.bm_w, pc->texBuf.bm_h, pbAttribs)))   return 0;if (!(pc->pb.hDC = wglGetPbufferDCARB (pc->pb.hBuf))) {   wglDestroyPbufferARB (pc->pb.hBuf);   pc->pb.hBuf = NULL;   return 0;   }if (!(pc->pb.hRC = wglCreateContext (pc->pb.hDC))) {   wglReleasePbufferDCARB (pc->pb.hBuf, pc->pb.hDC);   wglDestroyPbufferARB (pc->pb.hBuf);   pc->pb.hDC = NULL;   pc->pb.hBuf = NULL;   return 0;   }glGenTextures (1, &pc->glTexId);glBindTexture (GL_TEXTURE_2D, pc->glTexId);glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE_EXT);glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE_EXT);glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);pc->pb.bBound = 1;wglShareLists (hGlRC, pc->pb.hRC);return 1;}//------------------------------------------------------------------------------int OglCamBufAvail (tCamera *pc, int bCheckTexture){if (bCheckTexture)   return pc->texBuf.gltexture ? ogl_pbuffer_avail (&pc->texBuf.gltexture->pbuffer) : -1;return ogl_pbuffer_avail (&pc->pb);}//------------------------------------------------------------------------------int OglEnableCamBuf (tCamera *pc){if (OglCamBufAvail (pc, 0) < 1)   return 0;ogl_freebmtexture (&pc->texBuf);if (!wglMakeContextCurrentARB (pc->pb.hDC, pc->pb.hDC, pc->pb.hRC))   return 0;glDrawBuffer (GL_FRONT);glReadBuffer (GL_FRONT);glViewport (0.0, 0.0, grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h); return 1;}//------------------------------------------------------------------------------int OglDisableCamBuf (tCamera *pc){if (OglCamBufAvail (pc, 0) < 1)   return 0;if (!wglMakeContextCurrentARB (hGlDC, hGlDC, hGlRC))   return 0;glDrawBuffer (GL_BACK);glReadBuffer (GL_FRONT);glViewport (0.0, 0.0, grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h);ogl_loadbmtexture_m (&pc->texBuf, 0, -1, &pc->pb);return 1;}//------------------------------------------------------------------------------int OglBindCamBuf (tCamera *pc){if ((OglCamBufAvail (pc, 0) < 1) && !OglCreateCamBuf (pc))   return 0;glBindTexture (GL_TEXTURE_2D, pc->glTexId);return pc->pb.bBound = wglBindTexImageARB (pc->pb.hBuf, WGL_FRONT_LEFT_ARB);}//------------------------------------------------------------------------------int OglReleaseCamBuf (tCamera *pc){if (OglCamBufAvail (pc, 0) < 1)   return 0;if (!pc->pb.bBound)   return 1;ogl_freebmtexture (&pc->texBuf);pc->pb.bBound = 0;return 1;}//------------------------------------------------------------------------------int OglDestroyCamBuf (tCamera *pc){if (OglCamBufAvail (pc, 0) < 0)   return 0;wglReleaseTexImageARB (pc->pb.hBuf, WGL_FRONT_LEFT_ARB);wglDeleteContext (pc->pb.hRC);wglReleasePbufferDCARB (pc->pb.hBuf, pc->pb.hDC);wglDestroyPbufferARB (pc->pb.hBuf);pc->pb.hRC = NULL;pc->pb.hDC = NULL;pc->pb.hBuf = NULL;return 1;}#endif//------------------------------------------------------------------------------short Num_cameras = 0;char nSideCameras [MAX_SEGMENTS][6];char bRenderCameras = 0;int bFullScreenCameras = 1;int nCameraFPS = 10;tCamera cameras [MAX_CAMERAS];int CreateCamera (tCamera *pc, short srcSeg, short srcSide, short tgtSeg, short tgtSide, object *objP){   vms_angvec   a;   short    sideVerts [4];   int    h, i;   vms_vector   *pv;memset (pc, 0, sizeof (tCamera));//determine camera texture sizeh = max (grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h);for (i = 1; i < h; i *= 2)   ;pc->texBuf.bm_rowsize = grd_curcanv->cv_bitmap.bm_w;pc->texBuf.bm_w =pc->texBuf.bm_h = i;OglCreateCamBuf (pc); //code will fall back to copy texture if this fails//set reference to camera objectif (objP)   pc->objP = objP;else {   pc->objP = &pc->obj;   //compute camera view angle   vm_extract_angles_vector (&a, Segments [srcSeg].sides [srcSide].normals);   vm_angles_2_matrix (&pc->obj.orient, &a);   get_side_verts (sideVerts, srcSeg, srcSide);   for (i = 0; i < 4; i++) {   pv = Vertices + sideVerts ;   pc->obj.pos.x += pv->x;   pc->obj.pos.y += pv->y;   pc->obj.pos.z += pv->z;   }   pc->obj.pos.x /= 4;   pc->obj.pos.y /= 4;   pc->obj.pos.z /= 4;   pc->obj.segnum = srcSeg;   }pc->segNum = tgtSeg;pc->sideNum = tgtSide;return 1;}//------------------------------------------------------------------------------int CreateCameras (void){//walk through all camera objects and initialize camera data for each one}//------------------------------------------------------------------------------void DestroyCameras (void){   int i;   tCamera   *pc = cameras;for (i = Num_cameras; i; i--, pc++) {   ogl_freebmtexture (&pc->texBuf);   glDeleteTextures (1, &pc->glTexId);   if (pc->screenBuf && (pc->screenBuf != pc->texBuf.bm_data)) free (pc->screenBuf);   if (pc->texBuf.bm_data) free (pc->texBuf.bm_data);   OglDestroyCamBuf (pc);   }memset (cameras, 0, sizeof (cameras));memset (nSideCameras, 0xFF, sizeof (nSideCameras));Num_cameras = 0;}//------------------------------------------------------------------------------int RenderCameras (void){   int i;   tCamera   *pc = cameras, *pCurCam = NULL;   object   *viewerSave = Viewer;   static   time_t t0 = 0;   time_t   t;   int nCamsRendered;   int cm = Cockpit_mode;   int frameCap = maxfps;   int nMaxWaitFrames = -1;   nCamsRendered = 0;for (i = 0; i < Num_cameras; i++, pc++) {// some timeout handling code hereViewer = pc->objP;if (OglReleaseCamBuf (pc) && OglEnableCamBuf (pc)) {   render_frame (0, 0);   nCamsRendered++;   pc->bValid = 1;   OglDisableCamBuf (pc);   }else { //fall back code here   }return 0;}//------------------------------------------------------------------------------ [Edited by - karx11erx on December 15, 2005 7:29:05 AM];  Source tags would be appreciated. It keeps all the source in a nice little box, syntax highlights it and preserves white space. You just place source and /source inside [] at the start and end respectively.   ;  Ahhh! I had seen this on this forum, but didn't know the proper tag (so I chose "code .. /code"). Thanks for the hint! :)Edit:I have added a few questions to my above post and pruned out some code not necessary for the understanding of my render process.Edit 2:Issue has disappeared - somehow during numerous code changes.[Edited by - karx11erx on December 15, 2005 5:52:08 PM]