Logo Search packages:      
Sourcecode: yorick-gl version File versions  Download package

gltexsubs.c

/*
 * $Id: gltexsubs.c,v 1.1.1.1 2005/09/18 22:07:52 dhmunro Exp $
 * This file contains functions that deal with version and OS
 * specific features of 3D textures.
 */
/* Copyright (c) 2005, The Regents of the University of California.
 * All rights reserved.
 * This file is part of yorick (http://yorick.sourceforge.net).
 * Read the accompanying LICENSE file for details.
 */

#include "glcode.h"
#include "glfunc.h"
#include "glBasic.h"
#include "gl3dtex.h"
#include "glcubetex.h"
#include "yio.h"
#include <errno.h>
#include <stdlib.h>

extern void texpal_make_current(void);
extern void yglLdTexPal(long nx, long ny, long nz, unsigned char *tex);

extern int isExtensionSupported(const char *extension);
extern void *LookupFunction(const char *funcName);
extern int TexExtSetup(void);
extern int yglTexExtSetup(void);
static void yglGenCubeTex(void);

/* It is not possible to infer anything about the openGL features
   that will be available at run time from the OpenGL features
   present on the computer where the code is compiled.
   The first reason is the obvious point that the code might
   be run on a different machine than the one that compiled it.
   The other point is that the program might display on a
   remote computer using glx (the features then depend on the
   remote computer's openGL).
   Another problem is that Microsoft has no plans to release a
   version of OpenGL newer than version 1.1. Many Window's OpenGL
   drivers report that they are version 1.2, 1.3, or 1.4,
   so the features of newer versions of OpenGL are often available
   on Windows, they just can't be accessed through Microsoft's
   OpenGL library.
   On Windows, OpenGL extensions are accessed via function pointers
   acquired at run time. There is thus no point trying to decide at
   compile time what features are present. The best approach seems to
   be to define constants for any interesting extensions that aren't
   present in <GL/gl.h> and query at runtime.
   In the case of Unix systems, extensions are accessed through entries
   must be present in the OpenGL library or the machine where the code
   is running. On Unix systems it is not possible to call an
   extension unless it is available at compile time. However, it is
   still necessary to check for the presence of the extension at run time.
   
   The most reasonable approach to using funcitonality newer than OpenGL 1.1
   seems to be to only use extensions. On Windows machines, all attempts to
   check for the extension are deferred until runtime. On Unix systems,
   the extension must be present on the machine that is compiling the code
   and on the machine displaying the output during the run.
   The only reasonably portable approach is to access all OpenGL features
   added after version 1.1 as extensions. One problem with this approach
   is that the headers on a Windows computer will not define any
   useful extensions. The solution is to hand code all the constants
   needed to query for the extension.

   As near as I can tell, it is not possible to build a code on Linux
   that can use both an ATI and an Nvidia extension (the code will
   link against either a library supplied by ATI or a library supplied
   by Nvidia, but not both). This argues pretty strongly against
   using vendor specific extensions.

   To keep the messing about with extensions localized, I will define
   my own function for each type of functionality I provided by
   extensions that I want to use. If the functionality is not present,
   the function will simply return.
*/

/* Set a flag indicating whether the computer on which yorgl was compiled
   has 3D textures available, which means OpenGL 1.2 or later.
   Whether this function should be called at run time depends 
   on whether the OpenGL on the "desktop" computer is version 1.2
   or newer. An example of where this might fail is a program running
   on a Linux computer and displaying back to a Windows computer
   via glx. Windows only has 3D textures as an extension. */

#ifdef GL_TEXTURE_3D
int host_has_3dtex= 1;
#else
int host_has_3dtex= 0;
#endif


void myglTexImage3D(GLenum target, GLint level, GLint internalformat,
                    GLsizei width, GLsizei height, GLsizei depth,
                    GLint border, GLenum format, GLenum type,
                    const GLvoid* pixels)
{
  /* If earlier tests indicate that both client and server have 3D textures
     built-in, call that function. This test ensures this branch will
     not be taken on any machine where the ifdef causes the function
     call to be absent */
  if(glCurrWin3d->hasTex3d) {
#ifdef GL_TEXTURE_3D
    glTexImage3D(target, level, internalformat, width, height, depth,
               border, format, type, pixels);
#endif
    return;
  }
  /* This code the 3D texture extension on either Windows or a Unix system.
     It returns doing nothing if the 3D texture extension isn't available.
  */
  if(!glCurrWin3d->hasTex3dExt) return;
#ifdef WIN32
  (*(glCurrWin3d->myglTexImage3D_ptr)) (target, level, internalformat, width, height, depth,
           border, format, type, pixels);
#else
  glTexImage3DEXT(target, level, internalformat, width, height, depth,
               border, format, type, pixels);
#endif
}

int yglQueryTex3d(glWinProp *win)
{
  char *version, msg[100];
  double vernum;
  int res;
  GLenum err;
  const GLubyte *errstr;
  char *rest;

  /* clear earlier GL errors */
  err= glGetError();
  errstr= gluErrorString(err);
  /* the 3D window may not have been created yet */
  if(!win) {
    glWinProp *newWin= 0;  /* zero forces window creation */
    yglPrepDraw(newWin);
    win= glCurrWin3d;
    if(!win) return 0;
  }
  if(win->hasTex3d || win->hasTex3dExt) return 1;
  if(win->tex3dChecked) return 0;  /* previous check showed no 3D text. */
  /* Make sure the OpenGL context is current */
  yglMakeCurrent(win);
  version = (char*) glGetString(GL_VERSION);
  DEMAND(version, "Failed to get OpenGL version number")
  sprintf(msg, "OpenGL version number is %s\n", version);
  YputsOut(msg);
  vernum= strtod(version, &rest);
  glCurrWin3d->tex3dChecked= 1;  /* note check for 3D texture occurred */

  if(host_has_3dtex && vernum > 1.199) {
    /* This code was compiled on a computer the OpenGL 1.2 or later
       and the display is on a computer with OpenGL 1.2 or later.
    */
    win->hasTex3d= 1;   /* has 3D texture support */
#ifdef GL_TEXTURE_3D
    win->myGL_TEXTURE_3D= GL_TEXTURE_3D;
    win->myGL_PROXY_TEXTURE_3D= GL_PROXY_TEXTURE_3D;
#endif
    return 1;
  }
  
  res = isExtensionSupported("GL_EXT_texture3D");
  if(res) {
    win->hasTex3dExt= 1;   /* has 3D texture extension */
    win->myGL_TEXTURE_3D= GL_TEXTURE_3D_EXT;
    win->myGL_PROXY_TEXTURE_3D= GL_PROXY_TEXTURE_3D_EXT;
#ifdef WIN32
    win->myglTexImage3D_ptr = (MYTEX3DFUNC) LookupFunction("glTexImage3DEXT");
#endif
    return 1;
  } else {
    return 0;   /* no 3D texture support */
  }
}

void *LookupFunction(const char *funcName)
{
  /* The LookupFunction function finds function pointers 
     in dynamic libraries. */
#ifdef WIN32
  return wglGetProcAddress(funcName);
#elif defined(IRIX)
  void *libHandle = dlopen("libgl.so", RTLD_LAZY);
  void *func = dlsym(libHandle, funcName);
  dlclose(libHandle);
  return func;
#else
  /* other OSes... */
  return 0;
#endif
}

Generated by  Doxygen 1.6.0   Back to index