Module: qopengl.cpp

Flat functions
 

TestRCvoid TestRC(HWND hWnd, HDC * hDC,HGLRC *hRC)
GetCurrentQGLContextQGLContext *GetCurrentQGLContext()
SetCurrentQGLContextvoid SetCurrentQGLContext(QGLContext *glc)

Expert function to influence the current GLContext


class QGLContext
.h

constructorQGLContext(QXWindow *iwin,XVisualInfo *vi,QGLContext *share, bool direct)

Flat functions
 

GetHD">sprintf(buf,"QGLCtx: iwin=%p, hdc=%p, hRC=%p",iwin,iwin->GetHDsprintf(buf,"QGLCtx: iwin=%p, hdc=%p, hRC=%p",iwin,iwin->GetHDC(),hRC);

MessageBox(0,buf,"QGLContext ctor",MB_OK);
HDC hDC=iwin->GetHDC();
Select(); Select(); Select();
estRC(iwin->GetHWND(),&hDC,&hRC);
*/
//wglMakeCurrent(hDC, *hRC );
#else
if(share)shctx=share->ctx;
else shctx=0;
ctx=glXCreateContext(XDSP,vi,shctx,direct);
#endif
}
QGLContext::QGLContext(GLXContext _ctx)
Create from existing context


class QGLContext
.h

destructor~QGLContext()
GetGLXContextGLXContext GetGLXContext()
SetWindowvoid SetWindow(QXWindow *nwin)
SetDrawablevoid SetDrawable(QDrawable *draw)

Sets drawable to paint on

Selectvoid Select(QDrawable *draw,QDrawable *read)

Uses this context as the current context for this thread


Flat functions
 

GetHD">sprintf(buf,"xw=%p, hdc=%p, hRC=%p",xw,xw->GetHDsprintf(buf,"xw=%p, hdc=%p, hRC=%p",xw,xw->GetHDC(),hRC);

MessageBox(0,buf,"trace",MB_OK);*/
if(xw)
{
log(QLOG_INFO,"QGLContext:Select: hdc=%p, hrc=%p",xw->GetHDC(),hRC);
wglMakeCurrent(xw->GetHDC(),hRC);
#ifdef OBS
// Test
glClearColor(.4,.5,.6,1);
glClear(GL_COLOR_BUFFER_BIT);
#endif
}
else qerr("QGLContext:Select(); drawable doesn't seem to be a QXWindow");
#else
//glXMakeCurrent(app->GetDisplay()->GetXDisplay(),win->GetXWindow(),ctx);
if(drawableRead==0)
{ glXMakeCurrent(XDSP,drawable->GetGLXDrawable(),ctx);
} else
{ // Use both DRAW & READ
glXMakeCurrentReadSGI(XDSP,draw->GetGLXDrawable(),read->GetGLXDrawable(),
ctx);
}
#endif
curglc=this;
//qdbg("QGLCtx:Select RET\n");
}
void QGLContext::Swap()


class QGLContext
.h

Setup2DWindowvoid Setup2DWindow()

Use defaults settings to provide a parallel view in 2D

Setup3DWindowvoid Setup3DWindow(int dist)

Generate default 3D view, camera at z=-$dist results in pixel-pixel mapping

Viewportvoid Viewport(int x,int y,int wid,int hgt)
DrawBuffervoid DrawBuffer(int d)
ReadBuffervoid ReadBuffer(int d)
Clearvoid Clear(int buffers)
MatrixModevoid MatrixMode(int m)
LoadIdentityvoid LoadIdentity()
Orthovoid Ortho(qdouble l,qdouble r,qdouble t,qdouble b, qdouble n,qdouble f)

Left/right/top/bottom/near/far

Disablevoid Disable(int n)
Enablevoid Enable(int n)
BlendFuncvoid BlendFunc(int sf,int df)


/*
 * QOpenGL - wrapper around OpenGL / GLX contexts / WGL
 * 28-04-97: Created!
 * 03-03-98: Bug removed; if a context was created, then deleted, it might
 * still be cached as current (in curglc), which could lead to spurious
 * problems when a following new Context resulted in the same pointer value!
 * 28-02-99: Major revisions in class hierarchy; QDrawable etc.
 * 27-07-00: Win32 WGL support. A bit woven here & there.
 * (C) MarketGraph/RVG
 */

#include <qlib/opengl.h>
#include <qlib/app.h>
#include <qlib/display.h>
#ifdef WIN32
#include <windows.h>
#include <GL/gl.h>
#endif
#include <GL/glx.h>
#include <qlib/debug.h>
DEBUG_ENABLE

// Shortcut for context selection
#define SEL		if(curglc!=this)Select()

// Global current GL context for fast context switching checks
static QGLContext *curglc;

#ifdef ND_TEST_WIN32_GLRC
void TestRC(HWND hWnd, HDC * hDC,HGLRC *hRC)
{ int i;
  //*hRC=wglCreateContext(*hDC);
  //wglMakeCurrent(*hDC,*hRC);
      glClearColor( 0.2f, 0.5f, 0.3f, 0.0f );
      glClear( GL_COLOR_BUFFER_BIT );

      glPushMatrix();
      glRotatef( 25.0f, 0.0f, 0.0f, 1.0f );
      glBegin( GL_TRIANGLES );
      glColor3f( 1.0f, 0.0f, 0.0f ); glVertex2f( 0.0f, 1.0f );
      glColor3f( 0.0f, 1.0f, 0.0f ); glVertex2f( 0.87f, -0.5f );
      glColor3f( 0.0f, 0.0f, 1.0f ); glVertex2f( -0.87f, -0.5f );
      glEnd();
      glPopMatrix();
  SwapBuffers(*hDC);
  glFlush();
  for(i=0;i<100000000;i++);
  glFinish();
  for(i=0;i<100000000;i++);
  SwapBuffers(hDC);
  for(i=0;i<100000000;i++);
  glFinish();
  for(i=0;i<100000000;i++);
}
#endif

// Global functions
QGLContext *GetCurrentQGLContext()
{ return curglc;
}
void SetCurrentQGLContext(QGLContext *glc)
// Expert function to influence the current GLContext
{ curglc=glc;
}

QGLContext::QGLContext(QXWindow *iwin,XVisualInfo *vi,QGLContext *share,
QGLContext::QGLContext(QXWindow *iwin,XVisualInfo *vi,QGLContext *share,  bool direct)
{
  GLXContext shctx;

  //qdbg("***** QGLCtx ctor %p\n",this);
  //internal=(QGLContextInternal*)qcalloc(sizeof(*internal));
  flags=0;
  ctx=0;
  //win=iwin;
  drawable=iwin;
  drawableRead=iwin;
#ifdef WIN32
  // Create WGL context
  //qerr("QGLContext ctor nyi/win32");
  // create the render context (RC)
  hRC=wglCreateContext(iwin->GetHDC());
  // Share display lists
  if(share)
    wglShareLists(share->GetHRC(),hRC);
/*
char buf[80];
GetHD">sprintf(buf,"QGLCtx: iwin=%p, hdc=%p, hRC=%p",iwin,iwin->GetHDC(),hRC);
MessageBox(0,buf,"QGLContext ctor",MB_OK);
HDC hDC=iwin->GetHDC();
Select(); Select(); Select();
//TestRC(iwin->GetHWND(),&hDC,&hRC);
*/
  //wglMakeCurrent(hDC, *hRC );
#else
  if(share)shctx=share->ctx;
  else     shctx=0;
  ctx=glXCreateContext(XDSP,vi,shctx,direct);
#endif
}
QGLContext::QGLContext(GLXContext _ctx)
// Create from existing context
{
#ifdef WIN32
  qerr("QGLContext ctor(GLXContext ctx) nyi/win32");
#endif
  flags=F_USER_CTX;
  ctx=_ctx;
  drawable=0;
  drawableRead=0;
}

QGLContext::~QGLContext()
{ //qdbg("***** QGLCtx dtor %p\n",this);
  //if(internal->glxContext)
  // Destroy context if we own it
#ifdef WIN32
  //qerr("QGLContext dtor nyi/win32");
#else
  // GLX
  if(ctx!=0&&((flags&F_USER_CTX)==0))
    glXDestroyContext(XDSP,ctx);
#endif
  //if(internal)qfree(internal);
  // 3-3-98; Cancel this context if it is active!!
  if(curglc==this)
    curglc=0;
}

GLXContext QGLContext::GetGLXContext()
{ return ctx;				// internal->glxContext;
}

#ifdef OBS
void QGLContext::SetWindow(QXWindow *nwin)
{ win=nwin;
}
// GetWindow is inline
#endif

void QGLContext::SetDrawable(QDrawable *draw)
// Sets drawable to paint on
{
  drawable=draw;
}

//void QGLContext::Select(QXWindow *nwin)
void QGLContext::Select(QDrawable *draw,QDrawable *read)
// Uses this context as the current context for this thread
{
  // Cached
  if(curglc==this)return;

//qdbg("QGLCtx:Select; this=%p, draw=%p\n",this,draw);
  if(draw)drawable=draw;
  drawableRead=read;
#ifdef WIN32
  // Make current
  QXWindow *xw;
  //xw=dynamic_cast<QXWindow*>(drawable);
  xw=(QXWindow*)drawable;
/*char buf[128];
GetHD">sprintf(buf,"xw=%p, hdc=%p, hRC=%p",xw,xw->GetHDC(),hRC);
MessageBox(0,buf,"trace",MB_OK);*/
  if(xw)
  {
//qlog(QLOG_INFO,"QGLContext:Select: hdc=%p, hrc=%p",xw->GetHDC(),hRC);
    wglMakeCurrent(xw->GetHDC(),hRC);
#ifdef OBS
    // Test
    glClearColor(.4,.5,.6,1);
    glClear(GL_COLOR_BUFFER_BIT);
#endif
  }
  else qerr("QGLContext:Select(); drawable doesn't seem to be a QXWindow");
#else
  //glXMakeCurrent(app->GetDisplay()->GetXDisplay(),win->GetXWindow(),ctx);
  if(drawableRead==0)
  { glXMakeCurrent(XDSP,drawable->GetGLXDrawable(),ctx);
  } else
  { // Use both DRAW & READ
    glXMakeCurrentReadSGI(XDSP,draw->GetGLXDrawable(),read->GetGLXDrawable(),
      ctx);
  }
#endif
  curglc=this;
  //qdbg("QGLCtx:Select RET\n");
}
void QGLContext::Swap()
{
  SEL;
#ifdef WIN32
  QXWindow *xw;
  xw=(QXWindow*)drawable;
  if(xw)SwapBuffers(xw->GetHDC());
#else
  // GLX
  glXSwapBuffers(XDSP,drawable->GetGLXDrawable());
#endif
}

/*****************
* WINDOW SUPPORT *
*****************/
void QGLContext::Setup2DWindow()
// Use defaults settings to provide a parallel view in 2D
{ int wid,hgt;
  QASSERT_V(drawable);

  SEL;
//qdbg("QGLContext:Setup2DWindow\n");
  //qdbg("  xw=%x, win=%p\n",win->GetXWindow(),win);
  wid=drawable->GetWidth();
  hgt=drawable->GetHeight();
//qdbg("  drawable %p = %dx%d\n",drawable,wid,hgt);
  //qdbg(" vp\n");
  Viewport(0,0,wid,hgt);
  MatrixMode(GL_PROJECTION);
  LoadIdentity();
  MatrixMode(GL_MODELVIEW);
  LoadIdentity();
  //qdbg(" ortho\n");
  Ortho(0,(qdouble)wid,0,(qdouble)hgt,-1,1);
  //qdbg("QGLContext:Setup2DWindow() RET\n");
}

void QGLContext::Setup3DWindow(int dist)
// Generate default 3D view, camera at z=-$dist results in pixel-pixel mapping
{
  int wid,hgt;
  GLfloat idDistance;
  QASSERT_V(drawable);

  SEL;
  idDistance=dist;			// Convert to float
  wid=drawable->GetWidth();
  hgt=drawable->GetHeight();
//qdbg("QGLCtx:3D: %dx%d drawable\n",wid,hgt);
//QShowGLErrors("QGLCtx:1");
  // 3D view
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
//QShowGLErrors("QGLCtx:2");
  //GLfloat idDistance=1000;              // Distance (Z) to fully cover window
  //gluPerspective(60,(GLfloat)720/(GLfloat)576,0.1,1000);
  glFrustum(-wid/idDistance/2,wid/idDistance/2,
            -hgt/idDistance/2,hgt/idDistance/2, 1,100000);
//QShowGLErrors("QGLCtx:3");
  glMatrixMode(GL_MODELVIEW);
//QShowGLErrors("QGLCtx:4");
  glLoadIdentity();

  // Setup camera distance; objects at this distance map 1:1 on the drawable
  glTranslatef(0,0,-idDistance);
//QShowGLErrors("QGLCtx:5");
}

/*********
* OPENGL *
*********/
void QGLContext::Viewport(int x,int y,int wid,int hgt)
{ 
  //qdbg("QGLCtx:Viewport()\n");
  //qdbg("  curglc=%p, this=%p\n",curglc,this);
  SEL;
  //qdbg("  vprt\n");
  glViewport(x,y,wid,hgt);
  //qdbg("QGLCtx:Viewport() RET\n");
}

void QGLContext::DrawBuffer(int d)
{ SEL;
  //printf("GLC:DrawBuffer %d ctx %p\n",d,glXGetCurrentContext());
  glDrawBuffer(d);
}
void QGLContext::ReadBuffer(int d)
{ SEL;
  //printf("GLC:ReadBuffer %d ctx %p\n",d,glXGetCurrentContext());
  glReadBuffer(d);
}
void QGLContext::Clear(int buffers)
{ SEL;
  glClear(buffers);
}

void QGLContext::MatrixMode(int m)
{ SEL;
  glMatrixMode(m);
}
void QGLContext::LoadIdentity()
{ SEL;
  glLoadIdentity();
}
void QGLContext::Ortho(qdouble l,qdouble r,qdouble t,qdouble b,
void QGLContext::Ortho(qdouble l,qdouble r,qdouble t,qdouble b,  qdouble n,qdouble f)
// Left/right/top/bottom/near/far
{ SEL;
  glOrtho(l,r,t,b,n,f);
}

void QGLContext::Disable(int n)
{ SEL;
  glDisable(n);
}
void QGLContext::Enable(int n)
{ SEL;
  glEnable(n);
}
void QGLContext::BlendFunc(int sf,int df)
{ SEL;
  glBlendFunc(sf,df);
}