Magic Library - True Type windows font

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
Bellaz89
Posts: 4
Joined: Thu Aug 31, 2006 7:26 pm

Post by Bellaz89 »

Well, thank you Emil_halim, especially for CG shader support :)
I'm member of Irrlicht Italia.org the Italian site for Irrlicht engine
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

@hybrid

here is the bases of MgicLibrary , some BlitzMax functions that control the 2d drawing including fadeing , rotating , scaling ,coloring , masking and others.....

header file

Code: Select all

/******************************************************

              BlitzMax stuff

          part of Magic Library
              By Emil Halim


******************************************************/


#ifndef __I_Magic_2D_BlitzMax_H_INCLUDED__
#define __I_Magic_2D_BlitzMax_H_INCLUDED__

struct MFont
 {
     GLuint  fnt;
     GLuint  BaseCharFont;
     f32     CharWidth;
     f32     CharHeight;
     f32     CharSpace;
 };

DLL_EXPORT void    ViewOrtho();
DLL_EXPORT void    ViewPerspective();
DLL_EXPORT void    SetRotation(f32 r);
DLL_EXPORT void    SetScale(f32 sx,f32 sy);
DLL_EXPORT void    StartDrawing();
DLL_EXPORT void    StopDrawing();
DLL_EXPORT void    SetDepth(f32 d);
DLL_EXPORT void    SetXXRotation(f32 r);
DLL_EXPORT void    SetYYRotation(f32 r);
DLL_EXPORT void    ApplyTransform(f32 x,f32 y);
DLL_EXPORT void    DrawImage(SMaterial img,f32 x ,f32 y);
DLL_EXPORT void    DrawFlipedImage(SMaterial img,f32 x ,f32 y);
DLL_EXPORT void    DrawInversedImage(SMaterial img,f32 x ,f32 y);
DLL_EXPORT void    DrawImageToFit(SMaterial img,f32 x ,f32 y,f32 w,f32 h);
DLL_EXPORT void    DrawImageRect(SMaterial img,f32 x ,f32 y,f32 xx,f32 yy,f32 ww,f32 hh);
DLL_EXPORT void    TileImage(SMaterial img,f32 RolX=0.0,f32 RolY=0.0);
DLL_EXPORT void    SetBlend (int);
DLL_EXPORT void    SetMaskMode(int);
DLL_EXPORT void    SetColor (GLubyte, GLubyte, GLubyte);
DLL_EXPORT void    SetAlpha (float);
DLL_EXPORT void    SetBaseChar(MFont*,GLuint base);
DLL_EXPORT void    SetFont (MFont*);
DLL_EXPORT void    DrawText (char *, float, float);
DLL_EXPORT void    DrawInversedText (char*, float,float);
DLL_EXPORT void    DrawText (char chr, float x, float y);
DLL_EXPORT MFont*  CreateFont (SMaterial, float, float, float);
DLL_EXPORT f32     TextLength(MFont* Font,const c8 *txt);
DLL_EXPORT f32     CenterX(MFont* Font,const c8 *txt);
DLL_EXPORT f32     FontHeight(MFont* Font);
DLL_EXPORT void    GrabImage(SMaterial image,f32 x,f32 y);
DLL_EXPORT void    Plot (float, float);
DLL_EXPORT void    DrawLine (float, float, float, float);
DLL_EXPORT void    DrawOval (float, float, float, float);
DLL_EXPORT void    DrawCircle (float, float, float, float);
DLL_EXPORT void    DrawRect (float, float, float, float);
DLL_EXPORT void    DrawFrame (float, float, float, float);
#define SetTransform(rotation,scale_x,scale_y) { SetRotation(rotation); SetScale( scale_x, scale_y); }
#define ImageWidth(Img)  Img.Texture1->getOriginalSize().Width
#define ImageHeight(Img) Img.Texture1->getOriginalSize().Height
enum
  {
    SOLIDBLEND = 1,
    MASKBLEND,
    ALPHABLEND,
    LIGHTBLEND,
    SHADEBLEND
  };

enum
  {
     MASK = 1,
     SOURCE,
     ORIGNAL
  };



#endif
here is the implemnting of functions

Code: Select all

//!******************************************************
//!   BlitzMax stuff
//!******************************************************

static GLubyte BZ__color[4];
MFont*  _currentFont;
static int _BltzScreenWith,_BltzScreenHieght;
IrrlichtDevice* _dvs;
f32 _BLTZ_ROT;
f32 _BLTZ_SCLx;
f32 _BLTZ_SCLy;
f32 _BLTZ_Depth;
f32 _BLTZ_XXROT;
f32 _BLTZ_YYROT;


DLL_EXPORT void ViewOrtho()            // Set Up An Ortho View
{
 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PRIMARY_COLOR_EXT);
 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
 glDisable(GL_LIGHTING);
 glDisable(GL_DEPTH_TEST);
 glDisable(GL_CULL_FACE);
 glMatrixMode(GL_PROJECTION);        // Select Projection
 glPushMatrix();            // Push The Matrix
 glLoadIdentity();           // Reset The Matrix
 glOrtho( 0, _BltzScreenWith , _BltzScreenHieght , 0, -10, 10 ); // Select Ortho Mode (640x480)
 glMatrixMode(GL_MODELVIEW);         // Select Modelview Matrix
 glPushMatrix();            // Push The Matrix
 glLoadIdentity();           // Reset The Matrix
 SetDepth(0);
}

DLL_EXPORT void ViewPerspective()           // Set Up A Perspective View
{
 glMatrixMode( GL_PROJECTION );        // Select Projection
 glPopMatrix();            // Pop The Matrix
 glMatrixMode( GL_MODELVIEW );        // Select Modelview
 glPopMatrix();            // Pop The Matrix
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_CULL_FACE);
 SetBlend(SOLIDBLEND);
}

DLL_EXPORT void StartDrawing()
 {
     glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
     glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PRIMARY_COLOR_EXT);
     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
     glDisable(GL_LIGHTING);
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_CULL_FACE);
 }

DLL_EXPORT void StopDrawing()
 {
      glEnable(GL_LIGHTING);
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_CULL_FACE);
      SetBlend(SOLIDBLEND);
 }

DLL_EXPORT void SetRotation(f32 r)
{
    _BLTZ_ROT = r;
}

DLL_EXPORT void SetScale(f32 sx,f32 sy)
{
    _BLTZ_SCLx = sx;
    _BLTZ_SCLy = sy;
}

DLL_EXPORT void SetDepth(f32 d)
{
    _BLTZ_Depth = d;
}

DLL_EXPORT void SetXXRotation(f32 r)
{
   _BLTZ_XXROT = r;
}

DLL_EXPORT void SetYYRotation(f32 r)
{
   _BLTZ_YYROT = r;
}

DLL_EXPORT void ApplyTransform(f32 x,f32 y)
 {
     glLoadIdentity();
     glTranslatef(x,y,_BLTZ_Depth);
     glScalef(_BLTZ_SCLx, _BLTZ_SCLy, 0.0f );
     glRotatef(_BLTZ_ROT, 0.0f, 0.0f, 1.0f );
     glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
     glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
 }

DLL_EXPORT void DrawImage(SMaterial img,f32 x ,f32 y)
{
     dimension2d<s32> size = img.Texture1->getOriginalSize();
     f32 w = (f32)(size.Width>>1);
     f32 h = (f32)(size.Height>>1);
     glLoadIdentity();
     glTranslatef(x,y,_BLTZ_Depth);
     glScalef(_BLTZ_SCLx, _BLTZ_SCLy, 0.0f );
     glRotatef(_BLTZ_ROT, 0.0f, 0.0f, 1.0f );
     glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
     glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
     glBegin(GL_QUADS);
            glTexCoord2f(0,0);glVertex2f(-w,-h);
            glTexCoord2f(0,1);glVertex2f(-w, h);
            glTexCoord2f(1,1);glVertex2f( w, h);
            glTexCoord2f(1,0);glVertex2f( w,-h);
     glEnd();
}

DLL_EXPORT void DrawFlipedImage(SMaterial img,f32 x ,f32 y)
{
     dimension2d<s32> size = img.Texture1->getOriginalSize();
     f32 w = (f32)(size.Width>>1);
     f32 h = (f32)(size.Height>>1);
     glLoadIdentity();
     glTranslatef(x,y,_BLTZ_Depth);
     glScalef( _BLTZ_SCLx, _BLTZ_SCLy, 0.0f );
     glRotatef(_BLTZ_ROT, 0.0f, 0.0f, 1.0f );
     glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
     glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
     glBegin(GL_QUADS);
            glTexCoord2f(1,0);glVertex2f(-w,-h);
            glTexCoord2f(1,1);glVertex2f(-w, h);
            glTexCoord2f(0,1);glVertex2f( w, h);
            glTexCoord2f(0,0);glVertex2f( w,-h);
     glEnd();
}

DLL_EXPORT void DrawInversedImage(SMaterial img,f32 x ,f32 y)
{
     dimension2d<s32> size = img.Texture1->getOriginalSize();
     f32 w = (f32)(size.Width>>1);
     f32 h = (f32)(size.Height>>1);
     glLoadIdentity();
     glTranslatef(x,y,_BLTZ_Depth);
     glScalef( _BLTZ_SCLx, _BLTZ_SCLy, 0.0f );
     glRotatef(_BLTZ_ROT, 0.0f, 0.0f, 1.0f );
     glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
     glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
     glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex2f(-w,-h);
            glTexCoord2f(0,0);glVertex2f(-w, h);
            glTexCoord2f(1,0);glVertex2f( w, h);
            glTexCoord2f(1,1);glVertex2f( w,-h);
     glEnd();
}

DLL_EXPORT void DrawImageToFit(SMaterial img,f32 x ,f32 y,f32 w,f32 h)
{
     dimension2d<s32> Tsize = img.Texture1->getSize();
     dimension2d<s32> size = img.Texture1->getOriginalSize();
     f32 tx = (f32)(size.Width)/(f32)(Tsize.Width);
     f32 ty = (f32)(size.Height)/(f32)(Tsize.Height);
     glLoadIdentity();
     glTranslatef(x,y,_BLTZ_Depth);
     glScalef( _BLTZ_SCLx, _BLTZ_SCLy, 0.0f );
     glRotatef(_BLTZ_ROT, 0.0f, 0.0f, 1.0f );
     glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
     glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
     glBegin(GL_QUADS);
            glTexCoord2f(0,0);glVertex2f(0,0);
            glTexCoord2f(0,ty);glVertex2f(0,h);
            glTexCoord2f(tx,ty);glVertex2f(w,h);
            glTexCoord2f(tx,0);glVertex2f(w,0);
     glEnd();
}

DLL_EXPORT void DrawImageRect(SMaterial img,f32 x ,f32 y,f32 xx,f32 yy,f32 ww,f32 hh)
{
     dimension2d<s32> size = img.Texture1->getOriginalSize();
     f32 tx1 = xx/(f32)(size.Width);
     f32 ty1 = yy/(f32)(size.Height);
     f32 tx2 = tx1+(ww/(f32)(size.Width));
     f32 ty2 = ty1+(hh/(f32)(size.Height));
     glLoadIdentity();
     glTranslatef(x,y,_BLTZ_Depth);
     glScalef( _BLTZ_SCLx, _BLTZ_SCLy, 0.0f );
     glRotatef(_BLTZ_ROT, 0.0f, 0.0f, 1.0f );
     glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
     glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
     glBegin(GL_QUADS);
            glTexCoord2f(tx1,ty1);glVertex2f(0,0);
            glTexCoord2f(tx1,ty2);glVertex2f(0,hh);
            glTexCoord2f(tx2,ty2);glVertex2f( ww,hh);
            glTexCoord2f(tx2,ty1);glVertex2f( ww,0);
     glEnd();
}

DLL_EXPORT void TileImage(SMaterial img,f32 RolX,f32 RolY)
{
    dimension2d<s32> size = img.Texture1->getOriginalSize();
    f32 w = (f32)(_BltzScreenWith>>1);
    f32 h = (f32)(_BltzScreenHieght>>1);
    f32 tilex = (f32)_BltzScreenWith/(f32)size.Width;
    f32 tiley = (f32)_BltzScreenHieght/(f32)size.Height;
    glLoadIdentity();
    glTranslatef(w,h,_BLTZ_Depth);
    glScalef( _BLTZ_SCLx, _BLTZ_SCLy, 0.0f );
    glRotatef(_BLTZ_ROT, 0.0f, 0.0f, 1.0f );
    glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
    glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f+RolX,  tiley+RolY); glVertex2f(-w,-h);
        glTexCoord2f(0.0f+RolX,  0.0f+RolY);  glVertex2f(-w, h);
        glTexCoord2f(tilex+RolX, 0.0f+RolY);  glVertex2f( w, h);
        glTexCoord2f(tilex+RolX, tiley+RolY); glVertex2f( w,-h);
    glEnd();
}

DLL_EXPORT void SetBlend (int md)
{
  while(1)
  {
    if(md==MASKBLEND)
      {
        glDisable(GL_BLEND);
        glEnable(GL_ALPHA_TEST);
        glAlphaFunc(GL_GEQUAL,0x3F000000);
        break;
      }
    if(md==SOLIDBLEND)
      {
        glDisable(GL_BLEND);
        glDisable(GL_ALPHA_TEST);
        break;
      }
    if(md==ALPHABLEND)
      {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
        glDisable(GL_ALPHA_TEST);
        break;
      }
    if(md==LIGHTBLEND)
      {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE);
        glDisable(GL_ALPHA_TEST);
        break;
      }
    if(md==SHADEBLEND)
      {
        glEnable(GL_BLEND);
        glBlendFunc(GL_DST_COLOR,GL_ZERO);
        glDisable(GL_ALPHA_TEST);
        break;
      }
      // case else
      {
        glDisable(GL_BLEND);
        glDisable(GL_ALPHA_TEST);
      }
    break;
  }
}

DLL_EXPORT void SetMaskMode(int mod)
 {
     if(mod==MASK)
      {
          glClear(GL_STENCIL_BUFFER_BIT);
          glColorMask(0,0,0,0);
          glEnable(GL_STENCIL_TEST);
          glStencilFunc(GL_ALWAYS,1,1);
          glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
          glEnable(GL_ALPHA_TEST);
          //glAlphaFunc(GL_GREATER, 0.0f);
          glAlphaFunc(GL_GEQUAL, 1.0f);
      }
     if(mod==SOURCE)
      {
          glColorMask(1,1,1,1);
	      glStencilFunc(GL_EQUAL,1,1);
	      glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
      }
     if(mod==ORIGNAL)
      {
          glDisable(GL_STENCIL_TEST);
      }
 }

DLL_EXPORT void SetColor (GLubyte red, GLubyte green, GLubyte blue)
{
  BZ__color[0]=red;
  BZ__color[1]=green;
  BZ__color[2]=blue;
  //glColor3ubv(BZ__color);
  glColor4ubv(BZ__color);
}


DLL_EXPORT void SetAlpha (float alpha)
{
  BZ__color[3]=alpha*255;
  glColor4ubv(BZ__color);
}



DLL_EXPORT void SetBaseChar(MFont* fnt,GLuint base)
 {
     fnt->BaseCharFont = base;
 }

DLL_EXPORT void SetFont (MFont* fnt)
{
  _currentFont=fnt;
}


DLL_EXPORT void DrawText (char *text, float x, float y)
{
  glLoadIdentity();
  glTranslatef(x,y,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,0.0f);
  glRotatef(_BLTZ_ROT,0.0f,0.0f,1.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glListBase(_currentFont->fnt-_currentFont->BaseCharFont);
  glCallLists(strlen(text),GL_UNSIGNED_BYTE,text);
}

DLL_EXPORT void DrawInversedText (char *text, float x, float y)
{
  glLoadIdentity();
  glTranslatef(x,y,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,0.0f);
  glRotatef(_BLTZ_ROT,.0f,.0f,1.0f);
  glRotatef(180,1.0f,.0f,.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glListBase(_currentFont->fnt-_currentFont->BaseCharFont);
  glCallLists(strlen(text),GL_UNSIGNED_BYTE,text);
}

DLL_EXPORT void DrawText (char chr, float x, float y)
{
  glLoadIdentity();
  glTranslatef(x,y,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,.0f);
  glRotatef(_BLTZ_ROT,0.0f,0.0f,1.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glListBase(_currentFont->fnt-_currentFont->BaseCharFont);
  glCallLists(1,GL_UNSIGNED_BYTE,&chr);
}

DLL_EXPORT f32 TextLength(MFont* Font,const c8 *txt)
 {
     return (strlen(txt)-1)*Font->CharSpace*_BLTZ_SCLx;
 }

DLL_EXPORT f32 CenterX(MFont* Font,const c8 *txt)
 {
     return (_BltzScreenWith - (strlen(txt)-1)*Font->CharSpace*_BLTZ_SCLx)/2;
 }

DLL_EXPORT f32 FontHeight(MFont* Font)
 {
     return Font->CharHeight*_BLTZ_SCLy;
 }

DLL_EXPORT MFont* CreateFont(SMaterial fnt, float cw, float ch, float sp)
{
  float    sx;
  float    sy;
  float    fw;
  float    fh;
  int      stepww;
  int      stephh;
  MFont* Font = new MFont;
  dimension2d<s32> size = fnt.Texture1->getOriginalSize();
  fw=cw/(float)size.Width;
  fh=ch/(float)size.Height;
  stepww=size.Width/cw;
  stephh=size.Height/ch;
  Font->fnt=glGenLists(stepww*stephh);
    {register int lop;
  for(lop=0; lop<=(stepww*stephh)-1; lop+=1)
    {
      sx = float(lop % stepww)*fw;
      sy = float(lop / stepww)*fh;

      f32 w = (f32)(cw/2);
      f32 h = (f32)(ch/2);

      glNewList(Font->fnt+lop,GL_COMPILE);
      glBegin(GL_QUADS);
   /*
      glTexCoord2f(sx,sy+fh);    glVertex2i(0,ch);
      glTexCoord2f(sx,sy);       glVertex2i(0,0);
      glTexCoord2f(sx+fw,sy);    glVertex2i(cw,0);
      glTexCoord2f(sx+fw,sy+fh); glVertex2i(cw,ch);
   */

      glTexCoord2f(sx,sy+fh);    glVertex2i(-w, h);
      glTexCoord2f(sx,sy);       glVertex2i(-w,-h);
      glTexCoord2f(sx+fw,sy);    glVertex2i( w,-h);
      glTexCoord2f(sx+fw,sy+fh); glVertex2i( w, h);

      glEnd();
      glTranslated(sp,0,0);
      glEndList();
    }
    }

   Font->CharWidth = cw;
   Font->CharHeight= ch;
   Font->CharSpace = sp;
   Font->BaseCharFont = 32;
   return Font;
}


DLL_EXPORT void GrabImage(SMaterial image,f32 x,f32 y)
{
  dimension2d<s32> size = image.Texture1->getOriginalSize();
  u32* imagedata = (u32*)image.Texture1->lock();
  glReadPixels(x,y,size.Width,size.Height,GL_BGRA_EXT,GL_UNSIGNED_BYTE, imagedata);
  DWORD* Temp = new DWORD[size.Width*size.Height];
  memcpy(Temp,imagedata,size.Width*size.Height*4);
  for(int i=0;i<size.Height;i++)
   {
      memcpy(&imagedata[i*size.Width],&Temp[(size.Height-i)*size.Width],size.Width*4);
   }
  delete [] Temp;
  image.Texture1->unlock();
}

DLL_EXPORT void Plot (float x, float y)
{
  glBegin(0);
  glVertex2f(x,y);
  glEnd();
}


DLL_EXPORT void DrawLine (float x1, float y1, float x2, float y2)
{
  glLoadIdentity();
  glTranslatef(x1,y1,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,.0f);
  glRotatef(_BLTZ_ROT,0.0f,0.0f,1.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glBegin(1);
  glVertex2f(0,0);
  glVertex2f(x2-x1,y2-y1);
  glEnd();
}


DLL_EXPORT void DrawOval (float x, float y, float w, float h)
{
  glLoadIdentity();
  glTranslatef(x,y,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,.0f);
  glRotatef(_BLTZ_ROT,0.0f,0.0f,1.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glBegin(9);
  float    theta;
  for(theta=0; theta<360; theta+=1)
    {
      glVertex2f(sin(theta)*w,cos(theta)*h);
    }
  glEnd();
}


DLL_EXPORT void DrawCircle(float x, float y, float w, float h)
{
  glLoadIdentity();
  glTranslatef(x,y,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,.0f);
  glRotatef(_BLTZ_ROT,0.0f,0.0f,1.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glBegin(0);
  float    theta;
  for(theta=0; theta<360; theta+=1)
    {
      glVertex2f(sin(theta)*w,cos(theta)*h);
    }
  glEnd();
}


DLL_EXPORT void DrawRect (float x1, float y1, float x2, float y2)
{
  glLoadIdentity();
  glTranslatef(x1,y1,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,.0f);
  glRotatef(_BLTZ_ROT,0.0f,0.0f,1.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glBegin(7);
  glVertex2f(0,0);
  glVertex2f(0,y2-y1);
  glVertex2f(x2-x1,y2-y1);
  glVertex2f(x2-x1,0);
  glEnd();
}


DLL_EXPORT void DrawFrame (float x1, float y1, float x2, float y2)
{
  glLoadIdentity();
  glTranslatef(x1,y1,_BLTZ_Depth);
  glScalef(_BLTZ_SCLx,_BLTZ_SCLy,.0f);
  glRotatef(_BLTZ_ROT,0.0f,0.0f,1.0f);
  glRotatef(_BLTZ_XXROT, 1.0f, 0.0f, 0.0f );
  glRotatef(_BLTZ_YYROT, 0.0f, 1.0f, 0.0f );
  glBegin(2);
  glVertex2f(0,0);
  glVertex2f(0,y2-y1);
  glVertex2f(x2-x1,y2-y1);
  glVertex2f(x2-x1,0);
  glEnd();
}
next i will post other things.

feel free to ask if you need some hints.
Zar
Posts: 29
Joined: Mon Aug 07, 2006 4:46 pm
Location: Brazil

Post by Zar »

Emil,

I've tried to setup DEV-C++ to use your Magic Library, but I got a lot of errors. I can't compile any of the examples provided and can't find the problem.

Could you please post the Project Options parameters? It would help a lot.

I also didn't understood which files should be inlcuded and where. I have donwloaded the Magic Library+update and extracted all files to the Irrlicht directory. I've tried to copy all files in the DLL directory to the project folder and to the Irrlicht bin folder. What am I missing?

Thanks in advance
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

hi Zar

first download those two files from previous page.

1- MagicLibrary1.1.zip

2- updateMagicLibrary1.1.zip

second extract "irrlicht-1.1" folder from MagicLibrary1.1.zip in where you installed your irrlicht , see next images
Image
Image

then do the same for updateMagicLibrary1.1.zip

that is all for installing MagicLibrary.

Who to compile an example

1- create a new project as shown next
Image

2- choose a console application and mark "Donot create any file" checkBox
Image

3- press create then save your project in the example you want to compile

4- add the main.cpp file of example to your project
Image
Image

5- from project menu choose "Build Option"
Image

6-form the "linker" table add the libraries as shown next
Image

7- from the "Directories" set the path of includes as shown next
Image

8- build your porject to get your exe file

9- copy the exe file to your "irrlicht-1.1\bin\Win32-gcc" then run it.


that is all , hope it is easy now.
Zar
Posts: 29
Joined: Mon Aug 07, 2006 4:46 pm
Location: Brazil

Post by Zar »

Emil,

Thanks a lot for this tutorial.

The linker options that were missing for me. Now I can compile and run the exe, but I still get a lot of warnings with DEV-C++.
afecelis
Admin
Posts: 3075
Joined: Sun Feb 22, 2004 10:44 pm
Location: Colombia
Contact:

Post by afecelis »

whoa Emil! quite a tutorial! :D Thanks for your hard work and thanks for the source files!

quick question: now we gotta include the magic dll with our apps; why wasn't it needed before? I mean, what new things are you linking in this dll?
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

thanks guys , i am happy to konw you like the tutorial.

@Zar

yes , there is alot of warning, i will take a look and try to reduce those ugly warning.

@afecelis

the dll replace the old static lib file , so with the dll there is no need to static lib.

also i am thinking to make one magic dll for VC++ and dev-C++ users , you know Dev-C++ allows to link directlly with DLLs.

dll reduce the size of exe , so exe files of examples will take small size when linking with dll and it will be more easy to download the MagicLibrary zip file.

i am looking forward to see your next modeling and put some magic effect to it.
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi Everybody

i have solved the ugly warning that happend when compiling magic examples

simply add the folowing lines after using namespace block in MagicIncludes.h header file, that is all.

Code: Select all

// Irrlicht Namespaces block
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


template class DLL_EXPORT irr::core::dimension2d<s32>;
template class DLL_EXPORT irr::core::dimension2d<f32>;
template class DLL_EXPORT irr::core::vector3d<f32>;
template class DLL_EXPORT irr::core::vector2d<f32>;
template class DLL_EXPORT irr::core::aabbox3d<f32>;
template class DLL_EXPORT irr::core::irrAllocator<f32>;
template class DLL_EXPORT irr::core::array<f32>;
template class DLL_EXPORT irr::core::irrAllocator<s32>;
template class DLL_EXPORT irr::core::array<s32>;
template class DLL_EXPORT irr::core::irrAllocator< irr::core::rect<irr::s32> >;
template class DLL_EXPORT irr::core::array< irr::core::rect<irr::s32> >;
template class DLL_EXPORT irr::core::irrAllocator<c8>;
template class DLL_EXPORT irr::core::string<c8>;
template class DLL_EXPORT irr::core::irrAllocator<vector3df>;
template class DLL_EXPORT irr::core::array<vector3df>;
template class DLL_EXPORT irr::core::line3d<f32>;
template class DLL_EXPORT irr::core::irrAllocator<triangle3df>;
template class DLL_EXPORT irr::core::array<triangle3df>;
template class DLL_EXPORT irr::core::irrAllocator<struct Script>;
template class DLL_EXPORT irr::core::array<struct Script>;

class DLL_EXPORT irr::core::matrix4;
class DLL_EXPORT irr::scene::ISceneNode;
class DLL_EXPORT irr::video::IMaterialRenderer;

struct DLL_EXPORT irr::video::S3DVertex;
struct DLL_EXPORT irr::video::SMaterial;
enjoy it.
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi everybody

i have successfully made HDR with render-to-buffer PBuffer

i have replaced my TpBuffer class with the PBuffer that comes with NVidia sdk , my next update of MagicLibrary will has this change.

so i did it with 4 render passes just like esaptonor did.
1- darker pass
2- blur in x direction pass
3- blur in y direction pass
4- combin all pass

there are also 4 cg shader program for each pass.

PBuffer make fast render to texture because there is no copy from color buffer to the texture instead render to a texture then use it dirctlly.

here is a screenshot
Image

here is the code

Code: Select all

/****************************************************
             hdrEffect with CG

               By Emil Halim
****************************************************/

#include <MagicIncludes.h>

// global declration of Irrlicht interfaces
IrrlichtDevice* device;
IVideoDriver*   driver;
ISceneManager*  smgr;


bool ProgramRun;

int main()
{
    device = createDevice(EDT_OPENGL, dimension2d<s32>(640, 480), 32);
    bool rslt = InitMagic(device);
    if(rslt == false)
          printf("Magic Library will only work with OpenGL driver");

	driver = device->getVideoDriver();
	smgr = device->getSceneManager();

	TCGShader* cgDark = new TCGShader;
	cgDark->AddToPixelProgram("void main(  float2 TexCoord0     : TEXCOORD0,         ");
    cgDark->AddToPixelProgram("            out float4 color     : COLOR,             ");
    cgDark->AddToPixelProgram("            uniform sampler2D txtr0)                  ");
    cgDark->AddToPixelProgram("{                                                     ");
    cgDark->AddToPixelProgram("   float4 Col = tex2D(txtr0,TexCoord0);               ");
    cgDark->AddToPixelProgram("   color = Col * Col * Col ;                          ");
    cgDark->AddToPixelProgram("}                                                     ");
    cgDark->setPixelProfile(CG_PROFILE_ARBFP1);
    cgDark->CompilePixelProgram("main");
    printf("%s \n", cgDark->GetCompiledPixelProgram());


    TCGShader* cgBlurX = new TCGShader;
	cgBlurX->AddToPixelProgram("void main(  float2 TexCoord0     : TEXCOORD0,         ");
    cgBlurX->AddToPixelProgram("            out float4 color     : COLOR,             ");
    cgBlurX->AddToPixelProgram("            uniform sampler2D txtr0)                  ");
    cgBlurX->AddToPixelProgram("{                                                     ");
    cgBlurX->AddToPixelProgram("   float2 u    =  float2(0.005,0.0);                  ");
    cgBlurX->AddToPixelProgram("   float4 Col1 = tex2D(txtr0,TexCoord0+u);            ");
    cgBlurX->AddToPixelProgram("   float4 Col2 = tex2D(txtr0,TexCoord0-u);            ");
    cgBlurX->AddToPixelProgram("   float4 Col3 = tex2D(txtr0,TexCoord0+u+u);          ");
    cgBlurX->AddToPixelProgram("   float4 Col4 = tex2D(txtr0,TexCoord0-u-u);          ");
    cgBlurX->AddToPixelProgram("   float4 avrCol1 = Col1 + Col2 + Col3 + Col4;        ");
    cgBlurX->AddToPixelProgram("   color  =  avrCol1 / 4.0;                           ");
    cgBlurX->AddToPixelProgram("}                                                     ");
    cgBlurX->setPixelProfile(CG_PROFILE_ARBFP1);
    cgBlurX->CompilePixelProgram("main");
    printf("%s \n", cgBlurX->GetCompiledPixelProgram());

    TCGShader* cgBlurY = new TCGShader;
    cgBlurY->AddToPixelProgram("void main(  float2 TexCoord0     : TEXCOORD0,         ");
    cgBlurY->AddToPixelProgram("            out float4 color     : COLOR,             ");
    cgBlurY->AddToPixelProgram("            uniform sampler2D txtr0)                  ");
    cgBlurY->AddToPixelProgram("{                                                     ");
    cgBlurY->AddToPixelProgram("   float2 v    =  float2(0.0,0.005);                  ");
    cgBlurY->AddToPixelProgram("   float4 Col5 = tex2D(txtr0,TexCoord0+v);            ");
    cgBlurY->AddToPixelProgram("   float4 Col6 = tex2D(txtr0,TexCoord0-v);            ");
    cgBlurY->AddToPixelProgram("   float4 Col7 = tex2D(txtr0,TexCoord0+v+v);          ");
    cgBlurY->AddToPixelProgram("   float4 Col8 = tex2D(txtr0,TexCoord0-v-v);          ");
    cgBlurY->AddToPixelProgram("   float4 avrCol2 = Col5 + Col6 + Col7 + Col8;        ");
    cgBlurY->AddToPixelProgram("   color  =  avrCol2 / 4.0;                           ");
    cgBlurY->AddToPixelProgram("}                                                     ");
    cgBlurY->setPixelProfile(CG_PROFILE_ARBFP1);
    cgBlurY->CompilePixelProgram("main");
    printf("%s \n", cgBlurY->GetCompiledPixelProgram());

    TCGShader* cgCombin = new TCGShader;
    cgCombin->AddToPixelProgram("void main(  float2 TexCoord0     : TEXCOORD0,         ");
    cgCombin->AddToPixelProgram("            out float4 color     : COLOR,             ");
    cgCombin->AddToPixelProgram("            uniform sampler2D txtr1,                  ");
    cgCombin->AddToPixelProgram("            uniform sampler2D txtr0)                  ");
    cgCombin->AddToPixelProgram("{                                                     ");
    cgCombin->AddToPixelProgram("   float4 Col1 = tex2D(txtr1,TexCoord0);              ");
    cgCombin->AddToPixelProgram("   float4 Col2 = tex2D(txtr0,TexCoord0);              ");
    cgCombin->AddToPixelProgram("   color  =  (Col1+Col2) * 0.70 ;                     ");
    cgCombin->AddToPixelProgram("}                                                     ");
    cgCombin->setPixelProfile(CG_PROFILE_ARBFP1);
    cgCombin->CompilePixelProgram("main");
    printf("%s \n", cgCombin->GetCompiledPixelProgram());

    PBuffer* DarkBuffer = new PBuffer("rgba depth texture2D");;
    DarkBuffer->Initialize(256, 256, false, true);
    DarkBuffer->Activate();
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
    glEnable(GL_DEPTH_TEST);
    TImageTexture * DarkTexture = new TImageTexture;
    DarkTexture->CreateImage(256, 256);
    DarkBuffer->Deactivate();


	PBuffer* BlurXBuffer = new PBuffer("rgba depth texture2D");;
    BlurXBuffer->Initialize(256, 256, false, true);
    BlurXBuffer->Activate();
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
    glEnable(GL_DEPTH_TEST);
    TImageTexture * BlurXTexture = new TImageTexture;
    BlurXTexture->CreateImage(256, 256);
    BlurXBuffer->Deactivate();

    PBuffer* BlurYBuffer = new PBuffer("rgba depth texture2D");;
    BlurYBuffer->Initialize(256, 256, false, true);
    BlurYBuffer->Activate();
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
    glEnable(GL_DEPTH_TEST);
    TImageTexture * BlurYTexture = new TImageTexture;
    BlurYTexture->CreateImage(256, 256);
    BlurYBuffer->Deactivate();

    SMaterial img;
    img.Texture1 = driver->getTexture("../../MagicLibrary/media/hdrtest.bmp");

    ProgramRun = true;
    int lastFPS = -1;

	while(device->run()&& ProgramRun)
	{
          if(KeyDown(KEY_ESCAPE))ProgramRun=false;


		         DarkBuffer->Activate();
		         driver->beginScene(true, true, SColor(0,0,0,0));
                 ViewOrtho();
                 SetBlend(MASKBLEND);
                 cgDark->StartShaderProgram();
                 driver->setMaterial(img);
                 glBegin(GL_QUADS);
                 glTexCoord2f(0, 1); glVertex2f(0,   0);
                 glTexCoord2f(1, 1); glVertex2f(640, 0);
                 glTexCoord2f(1, 0); glVertex2f(640, 480);
                 glTexCoord2f(0, 0); glVertex2f(0,   480);
                 glEnd();
                 cgDark->StopShaderProgram();
                 ViewPerspective();
                 DarkBuffer->Deactivate();


                 BlurXBuffer->Activate();
                 driver->beginScene(true, true, SColor(0,0,0,0));
                 ViewOrtho();
                 cgBlurX->StartShaderProgram();
                 glEnable(GL_TEXTURE_2D);
                 glBindTexture(GL_TEXTURE_2D, DarkTexture->Texture);
                 DarkBuffer->Bind(WGL_FRONT_LEFT_ARB);
                 glBegin(GL_QUADS);
                 glTexCoord2f(0, 1); glVertex2f(0,   0);
                 glTexCoord2f(1, 1); glVertex2f(640, 0);
                 glTexCoord2f(1, 0); glVertex2f(640, 480);
                 glTexCoord2f(0, 0); glVertex2f(0,   480);
                 glEnd();
                 DarkBuffer->Release(WGL_FRONT_LEFT_ARB);
                 cgBlurX->StopShaderProgram();
                 ViewPerspective();
                 BlurXBuffer->Deactivate();

                 BlurYBuffer->Activate();
                 driver->beginScene(true, true, SColor(0,0,0,0));
                 ViewOrtho();
                 cgBlurY->StartShaderProgram();
                 glEnable(GL_TEXTURE_2D);
                 glBindTexture(GL_TEXTURE_2D, BlurXTexture->Texture);
                 BlurXBuffer->Bind(WGL_FRONT_LEFT_ARB);
                 glBegin(GL_QUADS);
                 glTexCoord2f(0, 1); glVertex2f(0,   0);
                 glTexCoord2f(1, 1); glVertex2f(640, 0);
                 glTexCoord2f(1, 0); glVertex2f(640, 480);
                 glTexCoord2f(0, 0); glVertex2f(0,   480);
                 glEnd();
                 BlurXBuffer->Release(WGL_FRONT_LEFT_ARB);
                 cgBlurY->StopShaderProgram();
                 ViewPerspective();
                 BlurYBuffer->Deactivate();



        driver->beginScene(true, true, SColor(0,0,0,0));

        ViewOrtho();

        cgCombin->StartShaderProgram();

        ApplyTransform(20,20);

        glActiveTextureARB(GL_TEXTURE0_ARB);
        driver->setMaterial(img);

        glActiveTextureARB(GL_TEXTURE1_ARB);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, BlurYTexture->Texture);
        BlurYBuffer->Bind(WGL_FRONT_LEFT_ARB);

        glBegin(GL_QUADS);

        glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 1.0f );
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 1.0f );
        glVertex2f(0,   200);

		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 1.0f );
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 1.0f );
		glVertex2f(320, 200);

		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 0.0f );
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 0.0f );
        glVertex2f(320, 0);

        glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 0.0f );
        glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 0.0f );
        glVertex2f(0,   0);

        glEnd();
        BlurYBuffer->Release(WGL_FRONT_LEFT_ARB);

        cgCombin->StopShaderProgram();

        ApplyTransform(300,240);
        driver->setMaterial(img);
        glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex2f(0,   0);
        glTexCoord2f(1, 0); glVertex2f(320, 0);
        glTexCoord2f(1, 1); glVertex2f(320, 200);
        glTexCoord2f(0, 1); glVertex2f(0,   200);
        glEnd();

        ViewPerspective();

                 smgr->drawAll();

		driver->endScene();
		int fps = driver->getFPS();
        if (lastFPS != fps)
         {
            wchar_t tmp[1024];
            swprintf(tmp, 1024, L"hdrEffect with CG (%s)(fps:%d)",driver->getName(), fps);
            device->setWindowCaption(tmp);
            lastFPS = fps;
         }
	}

	device->drop();

	return 0;
}
hope it is usefull for someone.
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

hi everybody

this time i have added my AI class "TMove" that was posted in the WiKi with may MagicLibrary, also i have replaced my TPbuffer with PBUFFER that came with NVidia SDK.

the TMove class allows you to put a wayPoint to your Node , it is not only a points that guide the nude but you will supply a start & end angle of rotation of node while it moves
,also you could spicify the speed of movement.

here is a screenshots of AI demo
Image
Image
Image

here is a part of code

Code: Select all

 // creating TMove instance
   TMove* MyNode = new  TMove(node1,smgr);
    MyNode->setTriangleSelector(room->getTriangleSelector());
    MyNode->setRotationSpeed(0.1);
    MyNode->setMoveSpeed(0.0005);
    MyNode->addWayPoint(vector3df(100,0,30),60,120);
    MyNode->addWayPoint(vector3df(100,0,-30),60+45,120+45);
    MyNode->addWayPoint(vector3df(50,0,-80),60+45,120+45+45);
    MyNode->addWayPoint(vector3df(0,0,-80));

  // check of scan node in while loop
  while(device->run()&& ProgramRun)
	{

		driver->beginScene(true, true, SColor(0,0,0,0));

                 if(KeyDown(KEY_ESCAPE))ProgramRun=false;

                  static bool state = false;
                  static f32 Mx;
                  state = MyNode->ScanArea(node2,500);
                  //state = MyNode->ScanArea(node2,40,0,90);
                  if(state)
                  {
                     if(MyNode->GetDistance(node2) < 500)  Mx = 0.1;
                     if(MyNode->GetDistance(node2) < 150)
                      {
                          Mx = 0;
                          Bullet->setVisible(true);
                          Bullet->setPosition(MyNode->getBulletCoords(0.001));
                      }
                     MyNode->MoveForward(Mx);
                  }

                  smgr->drawAll();
		          guienv->drawAll();

                  ViewOrtho();
                  SetBlend(ALPHABLEND);
                  SetAlpha(0.6f);
                  SetColor(0,0,0);
                  SetScale(1.0f,1.0f);
                  driver->setMaterial(black);
                  DrawImageToFit(black,430,10,200,190);
                  SetAlpha(1.0);
                  SetColor(255,0,255);
                  glLineWidth(5);
                  DrawFrame(430,10,430+200,10+190);
                  SetColor(255,126,64);
                //  SetAlpha(1.0f);
                  SetScale(1.0f,1.5f);
                  glLineWidth(3);
                  DrawLine(480,70, 480+100,70);
                  driver->setMaterial(FontImage);
                  DrawText("state",490,50);
                  SetColor(40,240,50);
                  SetScale(0.6f,0.6f);
                  if(!state )
                   {
                      DrawText("Scaning Area",470,100);
                      DrawText("for node #2",470,130);
                   }
                  else if(Mx != 0)
                   {
                      SetColor(245,241,95);
                      DrawText("found node #2",470,100);
                      DrawText(" and  moving ",470,130);
                      DrawText("  toword it",470,160);
                   }
                  else
                   {
                      SetColor(91,241,249);
                      DrawText("start attack",470,100);
                      DrawText("   node #2 ",470,130);
                   }

                  ViewPerspective();

		driver->endScene();
		int fps = driver->getFPS();
         if (lastFPS != fps)
         {
            wchar_t tmp[1024];
            swprintf(tmp, 1024, L"simple AI Demo (%s)(fps:%d)",driver->getName(), fps);
            device->setWindowCaption(tmp);
            lastFPS = fps;
         }
	}
here is the link of the updating
http://bcxdx.spoilerspace.com/BCXGL/upd ... ary1.1.zip

just download it then extract it in your Irrlicht1.1 folder.

Enjoy it.
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Nice TpBuffer emil. I started reading on different render targets after the artefacts that showed up in espontors hdr. I saw the direct TpBuffer but i never understood :cry: i thought it was too good to be true to skip the cpu part and internally do everything in the gpu. It would be good if this RTT method becomes implemented in irrlicht.

You can always realse a patch im sure we (especially me) would love it.
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi Omer

i have found some problem with my TpBuffer so that i have replaced it with PBUffer of Nvidia sdk, they have the same features.

when using pbuffer there are some roles must be followed.

1- creating the pbuffer object.
2- activating it then preparing it to drawing in ,ie set aome gl states like depth clearecolor and so on....
3- creating a texture just as we do with OpenGL.
3- deactivate it and return to our window.

at this point we successfully make our pbuffer and ready to use it.so to start rendring in pbuffer we call Activate() function then draw as we usual do with irrlicht, when we finish our drawing we call Deactivate() method to render to our window

to set our pbuffer as a texture we call glEnable(GL_TEXTURE_2D) , glBindTexture() and Bind(WGL_FRONT_LEFT_ARB) method.
it is important to release our texture after we finishing use pbuffer's texture by calling
Release(WGL_FRONT_LEFT_ARB) method.

that is all, here is some parts of nvBuffer example

Code: Select all

//*************************************************************

    // Define a PBuffer object.
    PBuffer mypbuffer("rgba depth texture2D");
    // Initialize the PBuffer now that we have a valid context
    // that we can use during the p-buffer creation process.
    mypbuffer.Initialize(256, 256, false, true);

    // Initialize some graphics state for the PBuffer's rendering context.
    mypbuffer.Activate();

    // Clear color
    glClearColor( 0.0, 0.0, 0.0, 0.0 );

    GLuint dynamicTexture;
    glEnable(GL_TEXTURE_2D);
	glGenTextures(1, &dynamicTexture);
	glBindTexture(GL_TEXTURE_2D, dynamicTexture);
	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_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    // Initialize some state for the GLUT window's rendering context.
    mypbuffer.Deactivate();

//**************************************************************

while(device->run()&& ProgramRun)
	{

                 if(KeyDown(KEY_ESCAPE))ProgramRun=false;

                  // Make the PBuffer's rendering context current.
                  mypbuffer.Activate();

                   // Clear all pixels.
                   glClearColor( 0.0, 1.0, 0.0, 0.0 );
                   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

                   ViewOrtho();
		           SetBlend(ALPHABLEND);
                   driver->setMaterial(logoimage);
                   DrawImage(logoimage,320,240);
                   ViewPerspective();

	              // Make the our window's rendering context current and draw to it
                  mypbuffer.Deactivate();


                 // Make the PBuffer's rendering context current.
                  buffer.Activate();

                   // Clear all pixels.
                   glClearColor( 0.0, 0.0, 1.0, 0.0 );
                   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

                   smgr->drawAll();

	              // Make the glut window's rendering context current and draw to the glut window.
                  buffer.Deactivate();


                 driver->beginScene(true, true, SColor(0,200,0,0));

                  ViewOrtho();
                  ApplyTransform(10,20);

                  glEnable(GL_TEXTURE_2D);
                  glBindTexture(GL_TEXTURE_2D, dynamicTexture);
                  mypbuffer.Bind(WGL_FRONT_LEFT_ARB);
    	          glBegin(GL_QUADS);
                  glTexCoord2f(0, 1); glVertex2f(0,   0);
                  glTexCoord2f(1, 1); glVertex2f(320, 0);
                  glTexCoord2f(1, 0); glVertex2f(320, 200);
                  glTexCoord2f(0, 0); glVertex2f(0,   200);
                  glEnd();
                  mypbuffer.Release(WGL_FRONT_LEFT_ARB);


                  ApplyTransform(300,250);
                  glBindTexture(GL_TEXTURE_2D, Texture);
                  buffer.Bind(WGL_FRONT_LEFT_ARB);
    	          glBegin(GL_QUADS);
                  glTexCoord2f(0, 1); glVertex2f(0,   0);
                  glTexCoord2f(1, 1); glVertex2f(320, 0);
                  glTexCoord2f(1, 0); glVertex2f(320, 200);
                  glTexCoord2f(0, 0); glVertex2f(0,   200);
                  glEnd();
                  buffer.Release(WGL_FRONT_LEFT_ARB);

                  ViewPerspective();

                 smgr->drawAll();
		         guienv->drawAll();

		         driver->endScene();
		int fps = driver->getFPS();
         if (lastFPS != fps)
         {
            wchar_t tmp[1024];
            swprintf(tmp, 1024, L" Using Pbuffer Example (%s)(fps:%d)",driver->getName(), fps);
            device->setWindowCaption(tmp);
            lastFPS = fps;
         }
	}
here is the pbuffer class of nVidia sdk so that if any one want to implement it with irrlicht.

header file

Code: Select all

#ifndef __nvPBUFFERS_H__
#define __nvPBUFFERS_H__

#if defined(WIN32)
//#  include <windows.h>
//#  include <GL/gl.h>
//#  include <GL/wglext.h>
#  pragma warning (disable : 4786)
#elif defined(UNIX)
#  include <GL/glx.h>
#  include <GL/glxext.h>
#elif defined(MACOS)
#  include <AGL/agl.h>
#endif

#include <string>
#include <vector>

// The pixel format for the pbuffer is controlled by the mode string passed
// into the PBuffer constructor. This string can have the following attributes:
//
// r			- r pixel format (for float buffer).
// rg			- rg pixel format (for float buffer).
// rgb          - rgb pixel format. 8 bit or 16/32 bit in float buffer mode
// rgba         - same as "rgb alpha" string
// alpha        - must have alpha channel
// depth        - must have a depth buffer
// depth=n      - must have n-bit depth buffer
// stencil      - must have a stencil buffer
// double       - must support double buffered rendering
// samples=n    - must support n-sample antialiasing (n can be 2 or 4)
// float=n      - must support n-bit per channel floating point
//
// texture2D
// textureRECT
// textureCUBE  - must support binding pbuffer as texture to specified target
//              - binding the depth buffer is also supporting by specifying
//                '=depth' like so: texture2D=depth or textureRECT=depth
//              - the internal format of the texture will be rgba by default or
//                float if pbuffer is floating point
//
class DLL_EXPORT PBuffer
{
    public:
        // see above for documentation on strMode format
        // set managed to true if you want the class to cleanup OpenGL objects in destructor
        PBuffer(const char *strMode, bool managed = false);
        ~PBuffer();

        bool Initialize(int iWidth, int iHeight, bool bShareContexts, bool bShareObjects);
        void Destroy();

        void Activate(PBuffer *current = NULL); // to switch between pbuffers, pass active pbuffer as argument
        void Deactivate();

#if defined(WIN32)
        int Bind(int iBuffer);
        int Release(int iBuffer);

        void HandleModeSwitch();
#endif

        unsigned int GetSizeInBytes();
        unsigned int CopyToBuffer(void *ptr, int w=-1, int h=-1);

        inline int GetNumComponents()
        { return m_iNComponents; }

        inline int GetBitsPerComponent()
        { return m_iBitsPerComponent; }

        inline int GetWidth()
        { return m_iWidth; }

        inline int GetHeight()
        { return m_iHeight; }

        inline bool IsSharedContext()
        { return m_bSharedContext; }

#if defined(WIN32)
        inline bool IsTexture()
        { return m_bIsTexture; }
#endif

    protected:
#if defined(WIN32)
        HDC         m_hDC;     ///< Handle to a device context.
        HGLRC       m_hGLRC;   ///< Handle to a GL context.
        HPBUFFERARB m_hPBuffer;///< Handle to a pbuffer.

        HGLRC       m_hOldGLRC;
        HDC         m_hOldDC;

        std::vector<int> m_pfAttribList;
        std::vector<int> m_pbAttribList;

        bool m_bIsTexture;
#elif defined(UNIX)
        Display    *m_pDisplay;
        GLXPbuffer  m_glxPbuffer;
        GLXContext  m_glxContext;

        Display    *m_pOldDisplay;
        GLXPbuffer  m_glxOldDrawable;
        GLXContext  m_glxOldContext;

        std::vector<int> m_pfAttribList;
        std::vector<int> m_pbAttribList;
#elif defined(MACOS)
        AGLContext  m_context;
        WindowPtr   m_window;
        std::vector<int> m_pfAttribList;
#endif

        int m_iWidth;
        int m_iHeight;
        int m_iNComponents;
        int m_iBitsPerComponent;

        const char *m_strMode;
        bool m_bSharedContext;
        bool m_bShareObjects;

    private:
        std::string getStringValue(std::string token);
        int getIntegerValue(std::string token);
#if defined(UNIX) || defined(WIN32)
        void parseModeString(const char *modeString, std::vector<int> *pfAttribList, std::vector<int> *pbAttribList);

        bool m_bIsBound;
        bool m_bIsActive;
        bool m_bManaged;
#endif
};

#endif
cpp file

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include "nvpbuffer.h"

#if defined(MACOS)
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
#else
//#include <GL/gl.h>
//#include <GL/glext.h>
//#include <GL/glut.h>
#endif

//#include <glh/glh_extensions.h>

#include <string>
#include <vector>

using namespace std;

#ifndef PB_FPF
#if defined DEBUG || defined _DEBUG
#define PB_FPF fprintf
#else
#define PB_FPF
#endif
#endif

#if defined(WIN32)

PBuffer::PBuffer(const char *strMode, bool managed)
  : m_hDC(0), m_hGLRC(0), m_hPBuffer(0), m_hOldGLRC(0), m_hOldDC(0),
    m_bIsTexture(false), m_iWidth(0), m_iHeight(0), m_strMode(strMode),
    m_bSharedContext(false), m_bShareObjects(false), m_bIsBound(false),
    m_bIsActive(false), m_bManaged(managed)
{
    m_pfAttribList.push_back(WGL_DRAW_TO_PBUFFER_ARB);
    m_pfAttribList.push_back(true);
    m_pfAttribList.push_back(WGL_SUPPORT_OPENGL_ARB);
    m_pfAttribList.push_back(true);

    m_pbAttribList.push_back(WGL_PBUFFER_LARGEST_ARB);
    m_pbAttribList.push_back(true);

    PB_FPF(stdout, "Declare a Pbuffer with \"%s\" parameters\n", strMode);
    m_strMode = strMode;
    parseModeString(m_strMode, &m_pfAttribList, &m_pbAttribList);

    m_pfAttribList.push_back(0);
    m_pbAttribList.push_back(0);
}

PBuffer::~PBuffer()
{
    if (m_bManaged)
        Destroy();
}

// This function actually does the creation of the p-buffer.
// It can only be called once a window has already been created.
bool PBuffer::Initialize(int iWidth, int iHeight, bool bShareContexts, bool bShareObjects)
{
    HDC hdc = wglGetCurrentDC();
    HGLRC hglrc = wglGetCurrentContext();
    int format = 0;
    int nfattribs = 0;
    int niattribs = 0;

    m_iWidth = iWidth;
    m_iHeight = iHeight;

    m_bSharedContext = bShareContexts;
    m_bShareObjects = bShareObjects;

    if (m_bSharedContext)
    {
        // Get the pixel format for the on-screen window.
        format = GetPixelFormat(hdc);
        if (format == 0)
        {
            PB_FPF(stderr, "pbuffer creation error:  GetPixelFormat() failed\n");
            return false;
        }
    }
    else
    {
        unsigned int nformats;
        wglChoosePixelFormatARB(hdc, &m_pfAttribList[0], NULL, 1, &format, &nformats);
        if (nformats == 0)
        {
            PB_FPF(stderr, "pbuffer creation error:  Couldn't find a suitable pixel format.\n");
            return false;
        }
    }

    m_hPBuffer = wglCreatePbufferARB(hdc, format, m_iWidth, m_iHeight, &m_pbAttribList[0]);
    if (!m_hPBuffer)
    {
        DWORD err = GetLastError();
        PB_FPF(stderr, "pbuffer creation error:  wglCreatePbufferARB() failed\n");
        if (err == ERROR_INVALID_PIXEL_FORMAT)
        {
            PB_FPF(stderr, "error:  ERROR_INVALID_PIXEL_FORMAT\n");
        }
        else if (err == ERROR_NO_SYSTEM_RESOURCES)
        {
            PB_FPF(stderr, "error:  ERROR_NO_SYSTEM_RESOURCES\n");
        }
        else if (err == ERROR_INVALID_DATA)
        {
            PB_FPF(stderr, "error:  ERROR_INVALID_DATA\n");
        }

        return false;
    }

    // Get the device context.
    m_hDC = wglGetPbufferDCARB(m_hPBuffer);
    if (!m_hDC)
    {
        PB_FPF(stderr, "pbuffer creation error:  wglGetPbufferDCARB() failed\n");
        return false;
    }

    if (m_bSharedContext)
    {
        // Let's use the same gl context..
        // Since the device contexts are compatible (i.e. same pixelformat),
        // we should be able to use the same gl rendering context.
        m_hGLRC = hglrc;
    }
    else
    {
        // Create a new gl context for the p-buffer.
        m_hGLRC = wglCreateContext(m_hDC);
        if (!m_hGLRC)
        {
            PB_FPF(stderr, "pbuffer creation error:  wglCreateContext() failed\n");
            return false;
        }

        if(m_bShareObjects)
        {
            if(!wglShareLists(hglrc, m_hGLRC))
            {
                PB_FPF(stderr, "pbuffer: wglShareLists() failed\n");
                return false;
            }
        }
    }

    GLint texFormat = WGL_NO_TEXTURE_ARB;
    wglQueryPbufferARB(m_hPBuffer, WGL_TEXTURE_FORMAT_ARB, &texFormat);

    if (texFormat != WGL_NO_TEXTURE_ARB)
        m_bIsTexture = true;

    // Determine the actual width and height we were able to create.
    wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_WIDTH_ARB, &m_iWidth);
    wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &m_iHeight);

    PB_FPF(stdout, "Created a %d x %d pbuffer\n", m_iWidth, m_iHeight);

#ifdef _DEBUG
    // query pixel format
    int iattributes[] = {
      WGL_RED_BITS_ARB,
      WGL_GREEN_BITS_ARB,
      WGL_BLUE_BITS_ARB,
      WGL_ALPHA_BITS_ARB,
      WGL_FLOAT_COMPONENTS_NV,
      WGL_DEPTH_BITS_ARB,
      WGL_SAMPLES_EXT,
      WGL_AUX_BUFFERS_ARB
    };
    int ivalues[sizeof(iattributes) / sizeof(int)];

    if (wglGetPixelFormatAttribivARB(m_hDC, format, 0, sizeof(iattributes) / sizeof(int), iattributes, ivalues)) {
      PB_FPF(stdout, "r:%d g:%d b:%d a:%d float:%d depth:%d samples:%d aux:%d\n",
              ivalues[0], ivalues[1], ivalues[2], ivalues[3], ivalues[4], ivalues[5], ivalues[6], ivalues[7]);
    }
#endif

    return true;
}

void PBuffer::Destroy()
{
    if (m_hPBuffer)
    {
        if (!m_bSharedContext) wglDeleteContext(m_hGLRC);
        wglReleasePbufferDCARB(m_hPBuffer, m_hDC);
        wglDestroyPbufferARB(m_hPBuffer);
    }
}

void PBuffer::parseModeString(const char *modeString, vector<int> *pfAttribList, vector<int> *pbAttribList)
{
    if (!modeString || strcmp(modeString, "") == 0)
        return;

    m_iBitsPerComponent = 8;
	m_iNComponents = 0;
    bool bIsFloatBuffer = false;
    bool bIsATIFloatBuffer = false;
    bool bIsTexture = false;
    bool bNeedAlpha = false;

    char *mode = strdup(modeString);

    vector<std::string> tokens;
    char *buf = strtok(mode, " ");
    while (buf != NULL)
    {
        if (strstr(buf, "ati_float") != NULL)
            bIsATIFloatBuffer = true;
        else if (strstr(buf, "float") != NULL)
            bIsFloatBuffer = true;

        if (strstr(buf, "texture") != NULL)
            bIsTexture = true;

        if (strstr(buf, "alpha") != NULL)
            bNeedAlpha = true;

        tokens.push_back(buf);
        buf = strtok(NULL, " ");
    }

    pfAttribList->push_back(WGL_PIXEL_TYPE_ARB);
#ifdef WGL_ATI_pixel_format_float
    if (bIsATIFloatBuffer) {
      pfAttribList->push_back(WGL_TYPE_RGBA_FLOAT_ATI);
    } else
#endif
    {
      pfAttribList->push_back(WGL_TYPE_RGBA_ARB);
    }

    for (unsigned int i = 0; i < tokens.size(); i++)
    {
        std::string token = tokens[i];

        if (token == "rgb" && (m_iNComponents <= 1))
        {
/*            pfAttribList->push_back(WGL_RED_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(WGL_GREEN_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(WGL_BLUE_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);*/
			m_iNComponents += 3;
            continue;
        }
		else if (token == "rgb") PB_FPF(stderr, "warning : mistake in components definition (rgb + %d)\n", m_iNComponents);


        if (token == "rgba" && (m_iNComponents == 0))
        {
            /*pfAttribList->push_back(WGL_RED_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(WGL_GREEN_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(WGL_BLUE_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);*/
			m_iNComponents = 4;
            continue;
        }
		else if (token == "rgba") PB_FPF(stderr, "warning : mistake in components definition (rgba + %d)\n", m_iNComponents);

        if (token == "alpha" && (m_iNComponents <= 3))
        {
            /*pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);*/
			m_iNComponents++;
            continue;
        }
		else if (token == "alpha") PB_FPF(stderr, "warning : mistake in components definition (alpha + %d)\n", m_iNComponents);


        if (token == "r" && (m_iNComponents <= 1))// && bIsFloatBuffer)
        {
            /*pfAttribList->push_back(WGL_RED_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);*/
			m_iNComponents++;
            continue;
        }
		else if (token == "r") PB_FPF(stderr, "warning : mistake in components definition (r + %d)\n", m_iNComponents);

        if (token == "rg" && (m_iNComponents <= 1))// && bIsFloatBuffer)
        {
            /*pfAttribList->push_back(WGL_RED_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(WGL_GREEN_BITS_ARB);
            pfAttribList->push_back(m_iBitsPerComponent);*/
			m_iNComponents += 2;
            continue;
        }
		else if (token == "r") PB_FPF(stderr, "warning : mistake in components definition (rg + %d)\n", m_iNComponents);

        if (token.find("depth") == 0)
        {
            pfAttribList->push_back(WGL_DEPTH_BITS_ARB);
            pfAttribList->push_back(getIntegerValue(token));

            continue;
        }

        if (token.find("stencil") == 0)
        {
            pfAttribList->push_back(WGL_STENCIL_BITS_ARB);
            pfAttribList->push_back(8);

            continue;
        }

        if (token.find("samples") == 0)
        {
            pfAttribList->push_back(WGL_SAMPLE_BUFFERS_ARB);
            pfAttribList->push_back(1);
            pfAttribList->push_back(WGL_SAMPLES_ARB);
            pfAttribList->push_back(getIntegerValue(token));

            continue;
        }

        if (token.find("aux") == 0)
        {
            pfAttribList->push_back(WGL_AUX_BUFFERS_ARB);
            pfAttribList->push_back(getIntegerValue(token));
            continue;
        }

        if (token == "double")
        {
            pfAttribList->push_back(WGL_DOUBLE_BUFFER_ARB);
            pfAttribList->push_back(true);

            continue;
        }

        if (token.find("ati_float") == 0)
        {
            m_iBitsPerComponent = getIntegerValue(token);
            // type already set above
            continue;

        } else if (token.find("float") == 0)
        {
            m_iBitsPerComponent = getIntegerValue(token);
            //bIsFloatBuffer = true; done previously
            pfAttribList->push_back(WGL_FLOAT_COMPONENTS_NV);
            pfAttribList->push_back(true);

            continue;
        }

        if (token.find("texture") == 0)
        {
            if (token.find("textureRECT") == 0 || bIsFloatBuffer)
            {
                pbAttribList->push_back(WGL_TEXTURE_TARGET_ARB);
                pbAttribList->push_back(WGL_TEXTURE_RECTANGLE_NV);
            }
            else if (token.find("textureCUBE") == 0)
            {
                pbAttribList->push_back(WGL_TEXTURE_TARGET_ARB);
                pbAttribList->push_back(WGL_TEXTURE_CUBE_MAP_ARB);
            }
            else
            {
                pbAttribList->push_back(WGL_TEXTURE_TARGET_ARB);
                pbAttribList->push_back(WGL_TEXTURE_2D_ARB);
            }

            if (bIsFloatBuffer || bIsATIFloatBuffer)
            {
				if(m_iNComponents == 0)
				{
					PB_FPF(stderr, "components not specified. assuming rgba...\n");
					pfAttribList->push_back(WGL_RED_BITS_ARB);
					pfAttribList->push_back(m_iBitsPerComponent);
					pfAttribList->push_back(WGL_GREEN_BITS_ARB);
					pfAttribList->push_back(m_iBitsPerComponent);
					pfAttribList->push_back(WGL_BLUE_BITS_ARB);
					pfAttribList->push_back(m_iBitsPerComponent);
					pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
					pfAttribList->push_back(m_iBitsPerComponent);
					m_iNComponents = 4;
				}
            }

            if (bIsFloatBuffer) {
				switch(m_iNComponents)
				{
				case 1:
					pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
					pfAttribList->push_back(true);

					pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
					pbAttribList->push_back(WGL_TEXTURE_FLOAT_R_NV);
					break;
				case 2:
					pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
					pfAttribList->push_back(true);

					pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
					pbAttribList->push_back(WGL_TEXTURE_FLOAT_RG_NV);
					break;
				case 3:
					pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
					pfAttribList->push_back(true);

					pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
					pbAttribList->push_back(WGL_TEXTURE_FLOAT_RGB_NV);
					break;
				case 4:
					pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
					pfAttribList->push_back(true);

					pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
					pbAttribList->push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
					break;
				default:
			        PB_FPF(stderr, "Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", m_iNComponents);
					break;
				}
            }
            else
            {
				switch(m_iNComponents)
				{
				case 3:
					pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
					pfAttribList->push_back(true);

					pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
					pbAttribList->push_back(WGL_TEXTURE_RGB_ARB);
					break;
				case 4:
					pfAttribList->push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
					pfAttribList->push_back(true);

					pbAttribList->push_back(WGL_TEXTURE_FORMAT_ARB);
					pbAttribList->push_back(WGL_TEXTURE_RGBA_ARB);
					break;
				default:
			        PB_FPF(stderr, "Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", m_iNComponents);
					break;
				}
            }

            std::string option = getStringValue(token);
            if (option == "depth")
            {
                pfAttribList->push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
                pfAttribList->push_back(true);

                pbAttribList->push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
                pbAttribList->push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
            }

            continue;
        }

        if (token.find("mipmap") == 0 && bIsTexture)
        {
            pbAttribList->push_back(WGL_MIPMAP_TEXTURE_ARB);
            pbAttribList->push_back(true);

            continue;
        }

        PB_FPF(stderr, "unknown pbuffer attribute: %s\n", token.c_str());
    }

    if (m_iNComponents > 0)
    {
        pfAttribList->push_back(WGL_RED_BITS_ARB);
        pfAttribList->push_back(m_iBitsPerComponent);
    }
    if (m_iNComponents > 1)
    {
        pfAttribList->push_back(WGL_GREEN_BITS_ARB);
        pfAttribList->push_back(m_iBitsPerComponent);
    }
    if (m_iNComponents > 2)
    {
        pfAttribList->push_back(WGL_BLUE_BITS_ARB);
        pfAttribList->push_back(m_iBitsPerComponent);
    }
    if (m_iNComponents > 3)
    {
        pfAttribList->push_back(WGL_ALPHA_BITS_ARB);
        pfAttribList->push_back(m_iBitsPerComponent);
    }
}

// Check to see if the pbuffer was lost.
// If it was lost, destroy it and then recreate it.
void PBuffer::HandleModeSwitch()
{
    int lost = 0;

    wglQueryPbufferARB(m_hPBuffer, WGL_PBUFFER_LOST_ARB, &lost);

    if (lost)
    {
        this->~PBuffer();
        Initialize(m_iWidth, m_iHeight, m_bSharedContext, m_bShareObjects);
    }
}

int PBuffer::Bind(int iBuffer)
{
    if (!m_bIsTexture)
    {
        PB_FPF(stderr, "PBuffer::Bind() failed - pbuffer format does not support render to texture!\n");
        return 0;
    }

#if 0
    // SGG - with MRT it is legal to bind different buffers of a pbuffer simultaneously
    if (m_bIsBound)
    {
        PB_FPF(stderr, "PBuffer::Bind() failed - pbuffer is already bound.\n");
        return 0;
    }
#endif

    int ret = wglBindTexImageARB(m_hPBuffer, iBuffer);
    if (!ret)
        PB_FPF(stderr, "PBuffer::Bind() failed.\n");

    m_bIsBound = true;

    return ret;
}

int PBuffer::Release(int iBuffer)
{
    if (!m_bIsTexture)
    {
        PB_FPF(stderr, "PBuffer::Release() failed - pbuffer format does not support render to texture!\n");
        return 0;
    }

#if 0
    // SGG - with MRT it is legal to bind different buffers of a pbuffer simultaneously
    if (!m_bIsBound)
    {
        PB_FPF(stderr, "PBuffer::Release() failed - pbuffer is not bound.\n");
        return 0;
    }
#endif

    int ret = wglReleaseTexImageARB(m_hPBuffer, iBuffer);
    if (!ret)
        PB_FPF(stderr, "PBuffer::Release() failed.\n");

    m_bIsBound = false;

    return ret;
}


void PBuffer::Activate(PBuffer *current /* = NULL */)
{
    if (current == this)
    {
        return; // no switch necessary
    }

    if (NULL == current || !current->m_bIsActive)
    {
        if (m_bIsActive)
            return;

        m_hOldGLRC = wglGetCurrentContext();
        m_hOldDC = wglGetCurrentDC();
    }
    else
    {
        m_hOldGLRC = current->m_hOldGLRC;
        m_hOldDC = current->m_hOldDC;
        current->m_hOldGLRC = 0;
        current->m_hOldDC = 0;
        current->m_bIsActive = false;
    }

    if (!wglMakeCurrent(m_hDC, m_hGLRC))
        PB_FPF(stderr, "PBuffer::Activate() failed.\n");

    m_bIsActive = true;
}

void PBuffer::Deactivate()
{
    if (!m_bIsActive)
        return;

    if (!wglMakeCurrent(m_hOldDC, m_hOldGLRC))
        PB_FPF(stderr, "PBuffer::Deactivate() failed.\n");

    m_hOldGLRC = 0;
    m_hOldDC = 0;
    m_bIsActive = false;
}

#elif defined(UNIX)

PBuffer::PBuffer(const char *strMode, bool managed)
  : m_pDisplay(0), m_glxPbuffer(0), m_glxContext(0), m_pOldDisplay(0), m_glxOldDrawable(0),
    m_glxOldContext(0), m_iWidth(0), m_iHeight(0), m_strMode(strMode),
    m_bSharedContext(false), m_bShareObjects(false), m_bManaged(managed)
{
    m_pfAttribList.push_back(GLX_DRAWABLE_TYPE);
    m_pfAttribList.push_back(GLX_PBUFFER_BIT);
    m_pfAttribList.push_back(GLX_RENDER_TYPE);
    m_pfAttribList.push_back(GLX_RGBA_BIT);

    m_pbAttribList.push_back(GLX_LARGEST_PBUFFER);
    m_pbAttribList.push_back(true);
    m_pbAttribList.push_back(GLX_PRESERVED_CONTENTS);
    m_pbAttribList.push_back(true);

    m_strMode = strMode;
    parseModeString(m_strMode, &m_pfAttribList, &m_pbAttribList);

    m_pfAttribList.push_back(0);
    m_pbAttribList.push_back(0);
}

PBuffer::~PBuffer()
{
    if (m_bManaged)
        Destroy();
}

bool PBuffer::Initialize(int iWidth, int iHeight, bool bShareContexts, bool bShareObjects)
{
    Display *pDisplay = glXGetCurrentDisplay();
    int iScreen = DefaultScreen(pDisplay);
    GLXContext glxContext = glXGetCurrentContext();

    GLXFBConfig *glxConfig;
    int iConfigCount;

    m_bSharedContext = bShareContexts;
    m_bShareObjects = bShareObjects;

    m_iWidth = iWidth;
    m_iHeight = iHeight;

    if (m_bSharedContext)
    {
        glxConfig = glXGetFBConfigs(pDisplay, iScreen, &iConfigCount);
        if (!glxConfig)
        {
            PB_FPF(stderr, "pbuffer creation error:  glXGetFBConfigs() failed\n");
            return false;
        }
    }
    else
    {
        glxConfig = glXChooseFBConfigSGIX(pDisplay, iScreen, &m_pfAttribList[0], &iConfigCount);
        if (!glxConfig)
        {
            PB_FPF(stderr, "pbuffer creation error:  glXChooseFBConfig() failed\n");
            return false;
        }
    }

    m_glxPbuffer = glXCreateGLXPbufferSGIX(pDisplay, glxConfig[0], m_iWidth, m_iHeight, &m_pbAttribList[0]);

    if (!m_glxPbuffer)
    {
        PB_FPF(stderr, "pbuffer creation error:  glXCreatePbuffer() failed\n");
        return false;
    }

    if (m_bSharedContext)
    {
        m_glxContext = glxContext;
    }
    else
    {
        if (m_bShareObjects)
            m_glxContext = glXCreateContextWithConfigSGIX(pDisplay, glxConfig[0], GLX_RGBA_TYPE, glxContext, true);
        else
            m_glxContext = glXCreateContextWithConfigSGIX(pDisplay, glxConfig[0], GLX_RGBA_TYPE, NULL, true);

        if (!glxConfig)
        {
            PB_FPF(stderr, "pbuffer creation error:  glXCreateNewContext() failed\n");
            return false;
        }
    }

    m_pDisplay = pDisplay;

    unsigned int w, h;
    w = h = 0;

    glXQueryGLXPbufferSGIX(m_pDisplay, m_glxPbuffer, GLX_WIDTH, &w);
    glXQueryGLXPbufferSGIX(m_pDisplay, m_glxPbuffer, GLX_HEIGHT, &h);
    m_iWidth = w;
    m_iHeight = h;

    PB_FPF(stdout, "Created a %d x %d pbuffer\n", m_iWidth, m_iHeight);

    return true;
}

void PBuffer::Destroy()
{
    if (m_glxContext && !m_bSharedContext)
        glXDestroyContext(m_pDisplay, m_glxContext);

    if (m_glxPbuffer)
        glXDestroyGLXPbufferSGIX(m_pDisplay, m_glxPbuffer);

    m_glxContext = 0;
    m_glxPbuffer = 0;
    m_pDisplay = 0;
}

void PBuffer::parseModeString(const char *modeString, vector<int> *pfAttribList, vector<int> *pbAttribList)
{
    if (!modeString || strcmp(modeString, "") == 0)
        return;

    m_iBitsPerComponent = 8;
	m_iNComponents = 0;
    bool bIsFloatBuffer = false;
    bool bNeedAlpha = false;

    char *mode = strdup(modeString);

    vector<string> tokens;
    char *buf = strtok(mode, " ");
    while (buf != NULL)
    {
        if (strstr(buf, "float") != NULL)
            bIsFloatBuffer = true;

        if (strstr(buf, "alpha") != NULL)
            bNeedAlpha = true;

        tokens.push_back(buf);
        buf = strtok(NULL, " ");
    }

    for (unsigned int i = 0; i < tokens.size(); i++)
    {
        string token = tokens[i];

        if (token == "rgb" && !bIsFloatBuffer)
        {
            pfAttribList->push_back(GLX_RED_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(GLX_GREEN_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(GLX_BLUE_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
			m_iNComponents += 3;
            continue;
        }
		else if (token == "rgb") PB_FPF(stderr, "warning : mistake in components definition (rgb + %d)\n", m_iNComponents);

        if (token == "rgba" && (m_iNComponents == 0))
        {
            pfAttribList->push_back(GLX_RED_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(GLX_GREEN_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(GLX_BLUE_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
            pfAttribList->push_back(GLX_ALPHA_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
			m_iNComponents = 4;
            continue;
        }
		else if (token == "rgba") PB_FPF(stderr, "warning : mistake in components definition (rgba + %d)\n", m_iNComponents);

        if (token.find("alpha") != token.npos)
        {
            pfAttribList->push_back(GLX_ALPHA_SIZE);
            pfAttribList->push_back(m_iBitsPerComponent);
			m_iNComponents++;
            continue;
        }
		else if (token == "alpha") PB_FPF(stderr, "warning : mistake in components definition (alpha + %d)\n", m_iNComponents);

        if (token.find("depth") != token.npos)
        {
            pfAttribList->push_back(GLX_DEPTH_SIZE);
            pfAttribList->push_back(getIntegerValue(token));

            continue;
        }

        if (token.find("stencil") != token.npos)
        {
            pfAttribList->push_back(GLX_STENCIL_SIZE);
            pfAttribList->push_back(getIntegerValue(token));

            continue;
        }

        if (token.find("samples") != token.npos)
        {
            pfAttribList->push_back(GLX_SAMPLE_BUFFERS_ARB);
            pfAttribList->push_back(1);
            pfAttribList->push_back(GLX_SAMPLES_ARB);
            pfAttribList->push_back(getIntegerValue(token));

            continue;
        }

        if (token == "double")
        {
            pfAttribList->push_back(GLX_DOUBLEBUFFER);
            pfAttribList->push_back(true);

            continue;
        }

        if (token.find("float") == 0)
        {
            m_iBitsPerComponent = getIntegerValue(token);
            //bIsFloatBuffer = true; done previously
            pfAttribList->push_back(GLX_FLOAT_COMPONENTS_NV);
            pfAttribList->push_back(true);
            continue;
        }

        PB_FPF(stderr, "unknown pbuffer attribute: %s\n", token.c_str());
    }
}

void PBuffer::Activate(PBuffer *current /* = NULL */)
{
    if (current == this)
    {
        return; // no switch necessary
    }

    if (NULL == current || !current->m_bIsActive)
    {
        m_pOldDisplay = glXGetCurrentDisplay();
        m_glxOldDrawable = glXGetCurrentDrawable();
        m_glxOldContext = glXGetCurrentContext();
    }
    else
    {
        m_pOldDisplay = current->m_pOldDisplay;
        m_glxOldDrawable = current->m_glxOldDrawable;
        m_glxOldContext = current->m_glxOldContext;
        current->m_pOldDisplay = 0;
        current->m_glxOldDrawable = 0;
        current->m_glxOldContext = 0;
    }

    if (!glXMakeCurrent(m_pDisplay, m_glxPbuffer, m_glxContext))
        PB_FPF(stderr, "PBuffer::Activate() failed.\n");
}

void PBuffer::Deactivate()
{
    if (!glXMakeCurrent(m_pOldDisplay, m_glxOldDrawable, m_glxOldContext))
        PB_FPF(stderr, "PBuffer::Deactivate() failed.\n");

    m_pOldDisplay = 0;
    m_glxOldDrawable = 0;
    m_glxOldContext = 0;
}

#elif defined(MACOS)

PBuffer::PBuffer(const char *strMode)
  :
    m_iWidth(0), m_iHeight(0), m_strMode(strMode),
    m_bSharedContext(false), m_bShareObjects(false)
{
    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
}

PBuffer::~PBuffer()
{
    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
}

bool PBuffer::Initialize(int iWidth, int iHeight, bool bShareContexts, bool bShareObjects)
{
    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");

    return false;
}

void PBuffer::Activate()
{
    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
}

void PBuffer::Deactivate()
{
    PB_FPF(stderr, "pbuffer not implemented under Mac OS X yet\n");
}

#endif

std::string PBuffer::getStringValue(std::string token)
{
    size_t pos;
    if ((pos = token.find("=")) != token.npos)
    {
        std::string value = token.substr(pos+1, token.length()-pos+1);
        return value;
    }
    else
        return "";
}

int PBuffer::getIntegerValue(std::string token)
{
    size_t pos;
    if ((pos = token.find("=")) != token.npos)
    {
        std::string value = token.substr(pos+1, token.length()-pos+1);
        if (value.empty())
            return 1;
        return atoi(value.c_str());
    }
    else
        return 1;
}

//----------------------------------------------------------------------------------
//
/// return the total size in bytes of the PBuffer
//
//----------------------------------------------------------------------------------
unsigned int PBuffer::GetSizeInBytes()
{
	return m_iWidth * m_iHeight * (m_iNComponents/8);
}
/*************************************************************************/ /**

make a copy the entire PBuffer in the memory. You have to allocate this area (ptr).
if ever you want to read a smaller size : specify it through w,h. otherwise w=h=-1

 */ /*********************************************************************/
unsigned int PBuffer::CopyToBuffer(void *ptr, int w, int h)
{
	GLenum format;
	GLenum type;
	switch(m_iNComponents)
	{
	case 1: //
		format = GL_LUMINANCE; // is it right to ask for Red only component ?
		break;
	case 2:
		format = GL_LUMINANCE_ALPHA; //How to ask for GL_RG ??
		break;
	case 3:
		format = GL_RGB;
		break;
	case 4:
		format = GL_RGBA;
		break;
	}
	switch(m_iBitsPerComponent)
	{
	case 8:
		type = GL_UNSIGNED_BYTE;
		break;
	case 32:
		type = GL_FLOAT;
		break;
#ifdef GL_NV_half_float
    case 16:
		type = GL_HALF_FLOAT_NV;
		break;
#endif
	default:
		PB_FPF(stderr, "unknown m_iBitsPerComponent\n");
#	if defined(WIN32)
	//	_asm { int 3 }
#	endif
	}
	Activate();
	if((w < 0) || (w > m_iWidth))
		w = m_iWidth;
	if((h < 0) || (h > m_iHeight))
		h = m_iHeight;
	glReadPixels(0,0,w,h, format, type, ptr);
	Deactivate();
	return w * h * (m_iNComponents/8);
}
bey
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

Emil, i notice you are using my HDR test image, but it doesn't appear to have very good quality, is that due to the way you saved that screenshot? or is your image of it not good?
if its the image, would you like me to send you the jpg so it looks better for display?
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi esaptonor

actually i have got this image from your post in biggeners form.

it was jpg image format ,so the image quality is not good in my post because of convering form jpg to gif format ,ie due to the way i saved that screensho.

but it is so good in hdr example.



thank you for supporting me.
Last edited by Emil_halim on Sun Sep 17, 2006 10:03 am, edited 1 time in total.
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

ok, i have sent it now, if you don't get it, post here and i will try again.
Post Reply