SFML/ruby/RubyOpenGL/common/common.h

334 lines
8.5 KiB
C

/*
* Last edit by previous maintainer:
* 2000/01/06 16:37:43, kusano
*
* Copyright (C) 1999 - 2005 Yoshi <yoshi@giganet.net>
* Copyright (C) 2006 John M. Gabriele <jmg3000@gmail.com>
* Copyright (C) 2007 James Adam <james@lazyatom.com>
*
* This program is distributed under the terms of the MIT license.
* See the included MIT-LICENSE file for the terms of this license.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _RBOGL_H_
#define _RBOGL_H_
#include <ruby.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <mach-o/dyld.h>
#include <stdlib.h>
#include <string.h>
#elif defined WIN32
#include <windows.h>
#include <GL/gl.h>
#else
#include <GL/gl.h>
#include <GL/glx.h>
#endif
#include "gl-enums.h"
#ifdef __APPLE__
#ifndef APIENTRY
#define APIENTRY /* to nothing */
#endif
#endif
typedef struct RArray RArray;
extern VALUE cProc;
#define LOAD_GL_FUNC(_NAME_) \
if (fptr_##_NAME_==NULL) \
fptr_##_NAME_ = load_gl_function(#_NAME_, 1);
#define FORCE_PIXEL_STORE_MODE \
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); \
glPixelStorei(GL_PACK_ALIGNMENT, 1); \
glPixelStorei(GL_PACK_SKIP_PIXELS, 0); \
glPixelStorei(GL_PACK_SKIP_ROWS, 0); \
glPixelStorei(GL_PACK_ROW_LENGTH, 0); \
glPixelStorei(GL_PACK_SKIP_IMAGES, 0); \
glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
/* glPixelStorei(GL_PACK_SKIP_VOLUMES_SGIS, 0);
glPixelStorei(GL_PACK_IMAGE_DEPTH_SGIS, 0); */
#define RESTORE_PIXEL_STORE_MODE \
glPopClientAttrib();
/* -------------------------------------------------------------------- */
#ifndef NUM2DBL
#define NUM2DBL(_val) num2double(_val)
static inline double num2double( VALUE val )
{
struct RFloat* flt;
if (NIL_P(val)) return 0;
flt = RFLOAT(f_float(0, val));
return flt->value;
}
#endif
/* -------------------------------------------------------------------- */
#define ARY2INTEGRAL(_type_,_convert_) \
static inline int ary2c##_type_( arg, cary, maxlen ) \
VALUE arg; \
GL##_type_ cary[]; \
int maxlen; \
{ \
int i; \
struct RArray* ary; \
VALUE entry; \
ary = RARRAY(rb_Array(arg)); \
if (maxlen < 1) \
maxlen = ary->len; \
else \
maxlen = maxlen < ary->len ? maxlen : ary->len; \
for (i=0; i < maxlen; i++) \
{ \
entry = rb_ary_entry((VALUE)ary,i); \
cary[i] = (GL##_type_)_convert_(entry); \
} \
return i; \
}
ARY2INTEGRAL(int,NUM2INT)
ARY2INTEGRAL(uint,NUM2UINT)
ARY2INTEGRAL(byte,NUM2INT)
ARY2INTEGRAL(ubyte,NUM2INT)
ARY2INTEGRAL(short,NUM2INT)
ARY2INTEGRAL(ushort,NUM2INT)
ARY2INTEGRAL(boolean,NUM2INT)
#undef ARY2INTEGRAL
/* -------------------------------------------------------------------- */
static inline int ary2cflt(arg, cary, maxlen)
VALUE arg;
float cary[];
int maxlen;
{
int i;
struct RArray* ary;
ary = RARRAY(rb_Array(arg));
if (maxlen < 1)
maxlen = ary->len;
else
maxlen = maxlen < ary->len ? maxlen : ary->len;
for (i=0; i < maxlen; i++)
cary[i] = (float)NUM2DBL(rb_ary_entry((VALUE)ary,i));
return i;
}
/* -------------------------------------------------------------------- */
static inline int ary2cdbl(arg, cary, maxlen)
VALUE arg;
double cary[];
int maxlen;
{
int i;
struct RArray* ary;
ary = RARRAY(rb_Array(arg));
if (maxlen < 1)
maxlen = ary->len;
else
maxlen = maxlen < ary->len ? maxlen : ary->len;
for (i=0; i < maxlen; i++)
cary[i] = NUM2DBL(rb_ary_entry((VALUE)ary,i));
return i;
}
/* -------------------------------------------------------------------- */
static inline void mary2ary(src, ary)
VALUE src;
VALUE ary;
{
struct RArray* tmp_ary;
int i;
tmp_ary = RARRAY(rb_Array(src));
for (i = 0; i < tmp_ary->len; i++)
{
if (TYPE(tmp_ary->ptr[i]) == T_ARRAY)
mary2ary((VALUE)tmp_ary->ptr[i], ary);
else
rb_ary_push(ary, tmp_ary->ptr[i]);
}
}
/* -------------------------------------------------------------------- */
static inline void ary2cmat4x4dbl(ary, cary)
VALUE ary;
double cary[];
{
int i,j;
RArray *ary_r,*ary_c;
memset(cary, 0x0, sizeof(double[4*4]));
ary_c = RARRAY(rb_Array(ary));
if (TYPE(ary_c->ptr[0]) != T_ARRAY)
ary2cdbl((VALUE)ary_c, cary, 16);
else
{
for (i = 0; i < ary_c->len && i < 4; i++)
{
ary_r = RARRAY(rb_Array(ary_c->ptr[i]));
for(j = 0; j < ary_r->len && j < 4; j++)
cary[i*4+j] = (GLdouble)NUM2DBL(ary_r->ptr[j]);
}
}
}
static inline void ary2cmat4x4flt(ary, cary)
VALUE ary;
float cary[];
{
int i,j;
RArray *ary_r,*ary_c;
memset(cary, 0x0, sizeof(float[4*4]));
ary_c = RARRAY(rb_Array(ary));
if (TYPE(ary_c->ptr[0]) != T_ARRAY)
ary2cflt((VALUE)ary_c, cary, 16);
else
{
for (i = 0; i < ary_c->len && i < 4; i++)
{
ary_r = RARRAY(rb_Array(ary_c->ptr[i]));
for(j = 0; j < ary_r->len && j < 4; j++)
cary[i*4+j] = (GLfloat)NUM2DBL(ary_r->ptr[j]);
}
}
}
/* -------------------------------------------------------------------- */
/*Need to find proper size for glReadPixels array*/
static inline int glformat_size(GLenum format)
{
switch(format)
{
case GL_COLOR_INDEX:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_LUMINANCE:
return 1;
case GL_LUMINANCE_ALPHA:
return 2;
case GL_RGB:
case GL_BGR_EXT:
return 3;
case GL_RGBA:
case GL_BGRA_EXT:
case GL_ABGR_EXT:
return 4;
case 1:
case 2:
case 3:
case 4:
return format;
default:
return -1;
}
}
/* -------------------------------------------------------------------- */
static inline int gltype_size(GLenum type)
{
switch(type)
{
case GL_BYTE:
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
return 1;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
return 2;
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
return 4;
case GL_BITMAP:
return 0;
default:
return -1;
}
}
/* -------------------------------------------------------------------- */
static inline VALUE allocate_buffer_with_string( int size )
{
return rb_str_new(NULL, size);
}
/* -------------------------------------------------------------------- */
static inline void *load_gl_function(const char *name,int raise)
{
void *func_ptr = NULL;
#if defined(__APPLE__)
static const struct mach_header* library = NULL;
char* symbolName;
NSSymbol symbol;
if (library == NULL)
library = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL",NSADDIMAGE_OPTION_RETURN_ON_ERROR);
if (library == NULL)
rb_raise(rb_eRuntimeError,"Can't load OpenGL library for dynamic loading");
/* prepend a '_' for the Unix C symbol mangling convention */
symbolName = ALLOC_N(char,strlen(name) + 2);
symbolName[0] = '_';
strcpy(symbolName+1, name);
symbol = NSLookupSymbolInImage(library,symbolName,NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
xfree(symbolName);
if (symbol == NULL)
func_ptr = NULL;
else
func_ptr = NSAddressOfSymbol(symbol);
#elif defined(WIN32) || defined(_WIN32)
func_ptr = wglGetProcAddress((LPCSTR)name);
#elif defined(GLX_VERSION_1_4)
func_ptr = glXGetProcAddress((const GLubyte *)name);
#else
func_ptr = glXGetProcAddressARB((const GLubyte *)name);
#endif
if (func_ptr == NULL && raise == 1)
rb_raise(rb_eNotImpError,"Function %s is not available at this machine",name);
return func_ptr;
}
#endif /* _RBOGL_H_ */