Posted: Sun Sep 03, 2006 1:03 pm
Well, thank you Emil_halim, especially for CG shader support
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
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
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();
}
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;
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;
}
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;
}
}
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;
}
}
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
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);
}