share/base_config.o \
share/config.o \
share/video.o \
+ share/glext.o \
share/binary.o \
share/state.o \
share/audio.o \
share/base_config.o \
share/config.o \
share/video.o \
+ share/glext.o \
share/binary.o \
share/audio.o \
share/state.o \
mq = back_draw(mq, 0);
mq = sol_back(&gd->back.draw, mq, 0, FAR_DIST, t);
}
- else back_draw(mq, t);
+ else back_draw(mq, 0);
}
glPopMatrix();
glMultMatrixf(M);
glTranslatef(-view->c[0], -view->c[1], -view->c[2]);
+ /* Draw the background. */
+
+ mq = game_draw_back(mq, gd, pose, +1, t);
+
+ /* Draw the reflection. */
+
if (gd->draw.reflective && config_get_d(CONFIG_REFLECTION))
{
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
/* Draw the scene reflected into color and depth buffers. */
-
+
glFrontFace(GL_CW);
glPushMatrix();
{
}
glPopMatrix();
glFrontFace(GL_CCW);
+
+ glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFF);
}
glDisable(GL_STENCIL_TEST);
}
- /* Draw the scene normally. */
+ /* Ready the lights for foreground rendering. */
game_draw_light();
- if (gd->draw.reflective)
- {
- if (config_get_d(CONFIG_REFLECTION))
- {
- /* Draw background while preserving reflections. */
-
- glEnable(GL_STENCIL_TEST);
- {
- glStencilFunc(GL_NOTEQUAL, 1, 0xFFFFFFFF);
- mq = game_draw_back(mq, gd, pose, +1, t);
- }
- glDisable(GL_STENCIL_TEST);
-
- /* Draw mirrors. */
+ /* When reflection is disabled, mirrors must be rendered opaque */
+ /* to prevent the background from showing. */
- mq = game_refl_all(mq, gd);
- }
- else
+ if (gd->draw.reflective && !config_get_d(CONFIG_REFLECTION))
+ {
+ glEnable(GL_COLOR_MATERIAL);
{
- /* Draw background. */
-
- mq = game_draw_back(mq, gd, pose, +1, t);
-
- /*
- * Draw mirrors, first fully opaque with a custom
- * material color, then blending normally with the
- * opaque surfaces using their original material
- * properties. (Keeps background from showing
- * through.)
- */
-
- glEnable(GL_COLOR_MATERIAL);
- {
- glColor4f(0.0, 0.0, 0.05, 1.0);
- mq = game_refl_all(mq, gd);
- glColor4f(1.0, 1.0, 1.0, 1.0);
- }
- glDisable(GL_COLOR_MATERIAL);
-
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
mq = game_refl_all(mq, gd);
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
+ glDisable(GL_COLOR_MATERIAL);
}
- else
- {
- mq = game_draw_back(mq, gd, pose, +1, t);
- mq = game_refl_all(mq, gd);
- }
+ /* Draw the mirrors and the rest of the foreground. */
+
+ mq = game_refl_all (mq, gd);
mq = game_draw_fore(mq, gd, pose, T, +1, t);
}
glPopMatrix();
GLfloat dx = 60.0f * fsinf(t / 10.0f);
GLfloat dz = 180.0f * fsinf(t / 12.0f);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
{
glScalef(-BACK_DIST, BACK_DIST, -BACK_DIST);
- glRotatef(dz, 0.0f, 0.0f, 1.0f);
- glRotatef(dx, 1.0f, 0.0f, 0.0f);
+ if (t) glRotatef(dz, 0.0f, 0.0f, 1.0f);
+ if (t) glRotatef(dx, 1.0f, 0.0f, 0.0f);
mq = sol_draw(&back.draw, mq, 1, 1);
}
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
}
glPopMatrix();
--- /dev/null
+/*
+ * Copyright (C) 2003-2011 Neverball authors
+ *
+ * NEVERBALL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <SDL.h>
+
+#include "glext.h"
+
+/*---------------------------------------------------------------------------*/
+
+#ifndef CONF_OPENGLES
+
+PFNGLACTIVETEXTURE_PROC glActiveTexture_;
+
+PFNGLGENBUFFERS_PROC glGenBuffers_;
+PFNGLBINDBUFFER_PROC glBindBuffer_;
+PFNGLBUFFERDATA_PROC glBufferData_;
+PFNGLBUFFERSUBDATA_PROC glBufferSubData_;
+PFNGLDELETEBUFFERS_PROC glDeleteBuffers_;
+PFNGLISBUFFER_PROC glIsBuffer_;
+
+PFNGLPOINTPARAMETERFV_PROC glPointParameterfv_;
+
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+int glext_check(const char *needle)
+{
+ const GLubyte *haystack, *c;
+
+ /* Search for the given string in the OpenGL extension strings. */
+
+ for (haystack = glGetString(GL_EXTENSIONS); *haystack; haystack++)
+ {
+ for (c = (const GLubyte *) needle; *c && *haystack; c++, haystack++)
+ if (*c != *haystack)
+ break;
+
+ if ((*c == 0) && (*haystack == ' ' || *haystack == '\0'))
+ return 1;
+ }
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void glext_init(void)
+{
+#ifndef CONF_OPENGLES
+
+ if (glext_check("ARB_multitexture"))
+ {
+ glActiveTexture_ = (PFNGLACTIVETEXTURE_PROC)
+ SDL_GL_GetProcAddress("glActiveTextureARB");
+ }
+
+ if (glext_check("ARB_vertex_buffer_object"))
+ {
+ glGenBuffers_ = (PFNGLGENBUFFERS_PROC)
+ SDL_GL_GetProcAddress("glGenBuffersARB");
+ glBindBuffer_ = (PFNGLBINDBUFFER_PROC)
+ SDL_GL_GetProcAddress("glBindBufferARB");
+ glBufferData_ = (PFNGLBUFFERDATA_PROC)
+ SDL_GL_GetProcAddress("glBufferDataARB");
+ glBufferSubData_ = (PFNGLBUFFERSUBDATA_PROC)
+ SDL_GL_GetProcAddress("glBufferSubDataARB");
+ glDeleteBuffers_ = (PFNGLDELETEBUFFERS_PROC)
+ SDL_GL_GetProcAddress("glDeleteBuffersARB");
+ glIsBuffer_ = (PFNGLISBUFFER_PROC)
+ SDL_GL_GetProcAddress("glIsBufferARB");
+ }
+
+ if (glext_check("ARB_point_parameters"))
+ {
+ glPointParameterfv_ = (PFNGLPOINTPARAMETERFV_PROC)
+ SDL_GL_GetProcAddress("glPointParameterfvARB");
+ }
+
+#endif
+}
+
+/*---------------------------------------------------------------------------*/
+/*
+ * Copyright (C) 2003-2011 Neverball authors
+ *
+ * NEVERBALL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
#ifndef GLEXT_H
#define GLEXT_H
/*---------------------------------------------------------------------------*/
+/* Include the system OpenGL headers. */
#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN /* Ha ha. */
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
/*---------------------------------------------------------------------------*/
-/*#ifndef GL_ARB_multitexture*/
-#define GL_TEXTURE0 0x84C0
-#define GL_TEXTURE1 0x84C1
+/* Exercise extreme paranoia in defining a cross-platform OpenGL interface. */
+/* If we're compiling against OpenGL ES then we must assume native linkage */
+/* of the extensions we use. Otherwise, GetProc them regardless of whether */
+/* they need it or not. */
+
+#if defined(GL_VERSION_ES_CM_1_0) || \
+ defined(GL_VERSION_ES_CM_1_1) || \
+ defined(GL_OES_VERSION_1_0)
+
+#define CONF_OPENGLES 1
+
+#else /* ... define the extension API. */
+
+/*---------------------------------------------------------------------------*/
+/* ARB_multisample */
+
+#ifndef GL_MULTISAMPLE
+#define GL_MULTISAMPLE 0x809D
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* ARB_multitexture */
+
+#ifndef GL_TEXTURE0
+#define GL_TEXTURE0 0x84C0
+#endif
+
+#ifndef GL_TEXTURE1
+#define GL_TEXTURE1 0x84C1
+#endif
+
+#ifndef GL_TEXTURE2
+#define GL_TEXTURE2 0x84C2
+#endif
+
+typedef void (*PFNGLACTIVETEXTURE_PROC)(GLenum);
+
+extern PFNGLACTIVETEXTURE_PROC glActiveTexture_;
+
+/*---------------------------------------------------------------------------*/
+/* ARB_vertex_buffer_object */
+
+#ifndef GL_ARRAY_BUFFER
+#define GL_ARRAY_BUFFER 0x8892
+#endif
+
+#ifndef GL_ELEMENT_ARRAY_BUFFER
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#endif
+
+#ifndef GL_STATC_DRAW
+#define GL_STATIC_DRAW 0x88E4
+#endif
+
+#ifndef GL_DYNAMIC_DRAW
+#define GL_DYNAMIC_DRAW 0x88E8
+#endif
+
+typedef void (*PFNGLGENBUFFERS_PROC)(GLsizei, GLuint *);
+typedef void (*PFNGLBINDBUFFER_PROC)(GLenum, GLuint);
+typedef void (*PFNGLBUFFERDATA_PROC)(GLenum, GLsizeiptr, const GLvoid *, GLenum);
+typedef void (*PFNGLBUFFERSUBDATA_PROC)(GLenum, GLintptr, GLsizeiptr, const GLvoid *);
+typedef void (*PFNGLDELETEBUFFERS_PROC)(GLsizei, const GLuint *);
+typedef GLboolean (*PFNGLISBUFFER_PROC)(GLuint);
+
+extern PFNGLGENBUFFERS_PROC glGenBuffers_;
+extern PFNGLBINDBUFFER_PROC glBindBuffer_;
+extern PFNGLBUFFERDATA_PROC glBufferData_;
+extern PFNGLBUFFERSUBDATA_PROC glBufferSubData_;
+extern PFNGLDELETEBUFFERS_PROC glDeleteBuffers_;
+extern PFNGLISBUFFER_PROC glIsBuffer_;
+
+/*---------------------------------------------------------------------------*/
+/* ARB_point_sprite */
+
+#ifndef GL_POINT_SPRITE
+#define GL_POINT_SPRITE 0x8861
+#endif
+
+#ifndef GL_COORD_REPLACE
+#define GL_COORD_REPLACE 0x8862
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* ARB_point_parameters */
+
+#ifndef GL_POINT_DISTANCE_ATTENUATIAN
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#endif
-typedef void (*PFNGLACTIVETEXTUREARBPROC)(GLenum);
-/*#endif*/
+typedef void (*PFNGLPOINTPARAMETERFV_PROC)(GLenum, const GLfloat *);
-extern PFNGLACTIVETEXTUREARBPROC glActiveTexture_;
+extern PFNGLPOINTPARAMETERFV_PROC glPointParameterfv_;
/*---------------------------------------------------------------------------*/
+#endif /* !CONF_OPENGLES */
+int glext_check(const char *);
+void glext_init(void);
+
+/*---------------------------------------------------------------------------*/
#endif
static void draw_enable(GLboolean c, GLboolean u, GLboolean p)
{
- glBindBuffer(GL_ARRAY_BUFFER, vert_obj);
+ glBindBuffer_(GL_ARRAY_BUFFER, vert_obj);
if (c)
{
static void draw_disable(void)
{
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer_(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
/* Copy this off to the VBO. */
- glBindBuffer (GL_ARRAY_BUFFER, vert_obj);
- glBufferSubData(GL_ARRAY_BUFFER,
- id * WIDGET_LEN * sizeof (struct vert),
- RECT_LEN * sizeof (struct vert), v);
+ glBindBuffer_ (GL_ARRAY_BUFFER, vert_obj);
+ glBufferSubData_(GL_ARRAY_BUFFER,
+ id * WIDGET_LEN * sizeof (struct vert),
+ RECT_LEN * sizeof (struct vert), v);
}
static void gui_text(int id, int x, int y,
/* Copy this off to the VBO. */
- glBindBuffer (GL_ARRAY_BUFFER, vert_obj);
- glBufferSubData(GL_ARRAY_BUFFER,
- (id * WIDGET_LEN + RECT_LEN) * sizeof (struct vert),
- TEXT_LEN * sizeof (struct vert), v);
+ glBindBuffer_ (GL_ARRAY_BUFFER, vert_obj);
+ glBufferSubData_(GL_ARRAY_BUFFER,
+ (id * WIDGET_LEN + RECT_LEN) * sizeof (struct vert),
+ TEXT_LEN * sizeof (struct vert), v);
}
/*---------------------------------------------------------------------------*/
memset(vert_buf, 0, sizeof (vert_buf));
- glGenBuffers(1, &vert_obj);
- glBindBuffer(GL_ARRAY_BUFFER, vert_obj);
- glBufferData(GL_ARRAY_BUFFER, sizeof (vert_buf), vert_buf, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glGenBuffers_(1, &vert_obj);
+ glBindBuffer_(GL_ARRAY_BUFFER, vert_obj);
+ glBufferData_(GL_ARRAY_BUFFER, sizeof (vert_buf), vert_buf, GL_STATIC_DRAW);
+ glBindBuffer_(GL_ARRAY_BUFFER, 0);
/* Cache digit glyphs for HUD rendering. */
/* Release the VBOs. */
- if (glIsBuffer(vert_obj))
- glDeleteBuffers(1, &vert_obj);
+ if (glIsBuffer_(vert_obj))
+ glDeleteBuffers_(1, &vert_obj);
/* Release any remaining widget texture and display list indices. */
void part_free(void)
{
- if (glIsBuffer(coin_vbo))
- glDeleteBuffers(1, &coin_vbo);
+ if (glIsBuffer_(coin_vbo))
+ glDeleteBuffers_(1, &coin_vbo);
if (glIsTexture(coin_draw_mtrl.o))
glDeleteTextures(1, &coin_draw_mtrl.o);
/* Draw the entire buffer. Dead particles have zero opacity anyway. */
#ifdef PARTICLEVBO
- glBindBuffer(GL_ARRAY_BUFFER, coin_vbo);
+ glBindBuffer_(GL_ARRAY_BUFFER, coin_vbo);
#else
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer_(GL_ARRAY_BUFFER, 0);
#endif
glClientActiveTexture(GL_TEXTURE1);
glEnable(GL_POINT_SPRITE);
{
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
- glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, c);
+ glPointParameterfv_(GL_POINT_DISTANCE_ATTENUATION, c);
glPointSize(s);
glDrawArrays(GL_POINTS, 0, PART_MAX_COIN);
/* Initialize a vertex buffer object for billboard drawing. */
- glGenBuffers(1, &draw->bill);
- glBindBuffer(GL_ARRAY_BUFFER, draw->bill);
- glBufferData(GL_ARRAY_BUFFER, sizeof (data), data, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glGenBuffers_(1, &draw->bill);
+ glBindBuffer_(GL_ARRAY_BUFFER, draw->bill);
+ glBufferData_(GL_ARRAY_BUFFER, sizeof (data), data, GL_STATIC_DRAW);
+ glBindBuffer_(GL_ARRAY_BUFFER, 0);
}
static void sol_free_bill(struct s_draw *draw)
{
- if (glIsBuffer(draw->bill))
- glDeleteBuffers(1, &draw->bill);
+ if (glIsBuffer_(draw->bill))
+ glDeleteBuffers_(1, &draw->bill);
}
static void sol_draw_bill(GLfloat w, GLfloat h, GLboolean edge)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
*/
- glBindBuffer(GL_ARRAY_BUFFER, draw->bill);
+ glBindBuffer_(GL_ARRAY_BUFFER, draw->bill);
glTexCoordPointer(2, GL_FLOAT, s * 4, (GLvoid *) ( 0));
glVertexPointer (2, GL_FLOAT, s * 4, (GLvoid *) (s * 2));
/* Initialize buffer objects for all data. */
- glGenBuffers(1, &mp->vbo);
- glBindBuffer(GL_ARRAY_BUFFER, mp->vbo);
- glBufferData(GL_ARRAY_BUFFER, vn * vs, vv, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glGenBuffers_(1, &mp->vbo);
+ glBindBuffer_(GL_ARRAY_BUFFER, mp->vbo);
+ glBufferData_(GL_ARRAY_BUFFER, vn * vs, vv, GL_STATIC_DRAW);
+ glBindBuffer_(GL_ARRAY_BUFFER, 0);
- glGenBuffers(1, &mp->ebo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mp->ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, gn * gs, gv, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glGenBuffers_(1, &mp->ebo);
+ glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, mp->ebo);
+ glBufferData_(GL_ELEMENT_ARRAY_BUFFER, gn * gs, gv, GL_STATIC_DRAW);
+ glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
mp->mp = draw->mv + mi;
mp->ebc = gn * 3;
static void sol_free_mesh(struct d_mesh *mp)
{
- if (glIsBuffer(mp->ebo))
- glDeleteBuffers(1, &mp->ebo);
- if (glIsBuffer(mp->vbo))
- glDeleteBuffers(1, &mp->vbo);
+ if (glIsBuffer_(mp->ebo))
+ glDeleteBuffers_(1, &mp->ebo);
+ if (glIsBuffer_(mp->vbo))
+ glDeleteBuffers_(1, &mp->vbo);
}
static const struct d_mtrl *sol_draw_mesh(const struct d_mesh *mp,
/* Bind the mesh data. */
- glBindBuffer(GL_ARRAY_BUFFER, mp->vbo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mp->ebo);
+ glBindBuffer_(GL_ARRAY_BUFFER, mp->vbo);
+ glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, mp->ebo);
glVertexPointer (3, T, s, (GLvoid *) offsetof (struct d_vert, p));
glNormalPointer ( T, s, (GLvoid *) offsetof (struct d_vert, n));
/* Revert the buffer object state. */
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer_(GL_ARRAY_BUFFER, 0);
+ glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
return mq;
}
/* Revert the buffer object state. */
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer_(GL_ARRAY_BUFFER, 0);
+ glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
return mq;
}
/*---------------------------------------------------------------------------*/
-PFNGLACTIVETEXTUREARBPROC glActiveTexture_;
-
-int check_extension(const char *needle)
-{
- const GLubyte *haystack, *c;
-
- /* Search for the given string in the OpenGL extension strings. */
-
- for (haystack = glGetString(GL_EXTENSIONS); *haystack; haystack++)
- {
- for (c = (const GLubyte *) needle; *c && *haystack; c++, haystack++)
- if (*c != *haystack)
- break;
-
- if ((*c == 0) && (*haystack == ' ' || *haystack == '\0'))
- return 1;
- }
-
- return 0;
-}
-
int video_mode(int f, int w, int h)
{
int stereo = config_get_d(CONFIG_STEREO) ? 1 : 0;
if (SDL_SetVideoMode(w, h, 0, SDL_OPENGL | (f ? SDL_FULLSCREEN : 0)))
{
+ glext_init();
+
config_set_d(CONFIG_FULLSCREEN, f);
config_set_d(CONFIG_WIDTH, w);
config_set_d(CONFIG_HEIGHT, h);
/* If GL supports multisample, and SDL got a multisample buffer... */
-#ifdef GL_ARB_multisample
- if (check_extension("ARB_multisample"))
+ if (glext_check("ARB_multisample"))
{
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
- if (buffers)
- glEnable(GL_MULTISAMPLE_ARB);
- }
-#endif
-
- if (check_extension("ARB_multitexture"))
- {
- union
- {
- void *ob;
- PFNGLACTIVETEXTUREARBPROC fn;
- } cast;
-
- cast.ob = SDL_GL_GetProcAddress("glActiveTextureARB");
- glActiveTexture_ = cast.fn;
+ if (buffers) glEnable(GL_MULTISAMPLE);
}
/* Attempt manual swap control if SDL's is broken. */
void video_clear(void)
{
+/*
+ if (config_get_d(CONFIG_REFLECTION))
+ glClear(GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT);
+ else
+ glClear(GL_DEPTH_BUFFER_BIT);
+*/
if (config_get_d(CONFIG_REFLECTION))
glClear(GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);