-namespace gfx::drivers;
+#if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
-#if defined(_GLES)
-#define ES1_1
-#else
-// #define SHADERS
+// #define DIAGNOSTICS
+#if defined(_DEBUG) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
+ #define GL_DEBUGGING
#endif
-#define GL_BGRA_EXT 0x80E1
-
-#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
-# if defined(SHADERS)
-# include "gl_core_3_3.h"
-# else
-# include "gl_compat_4_4.h"
-# endif
-#endif
+import "Display"
import "glab"
import "immediate"
import "matrixStack"
-import "shading"
+import "defaultShader"
-#ifdef SHADERS
+namespace gfx::drivers;
-#undef glEnableClientState
-#undef glDisableClientState
-#undef GL_VERTEX_ARRAY
-#undef GL_NORMAL_ARRAY
-#undef GL_TEXTURE_COORD_ARRAY
-#undef GL_COLOR_ARRAY
+#include "gl123es.h"
-#define glEnableClientState glEnableVertexAttribArray
-#define glDisableClientState glDisableVertexAttribArray
-#define GL_VERTEX_ARRAY GLBufferContents::vertex
-#define GL_NORMAL_ARRAY GLBufferContents::normal
-#define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
-#define GL_COLOR_ARRAY GLBufferContents::color
+// ********** GL PLATFORMS INCLUDES **********
+// UNIX
+#if defined(__unix__) || defined(__APPLE__)
-#endif
+ // EGL
+ #if defined(__ANDROID__) || defined(__ODROID__)
+ import "egl"
-// We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
-// #define USEPBUFFER
-#if defined(__unix__) || defined(__APPLE__)
+ #if defined(__ANDROID__)
+ #include <android/native_activity.h>
+ #include <android/log.h>
+ #define printf(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
+ #endif
-#if !defined(__MINGW32__)
- #define GL_GLEXT_PROTOTYPES
-#endif
+ // Emscripten
+ #elif defined(__EMSCRIPTEN__)
+ #define property _property
+ #define uint _uint
-#define pointer _pointer
+ #include <emscripten/emscripten.h>
+ #include <emscripten/html5.h>
+ #undef property
+ #undef uint
- #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
+ // GLX
+ #elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
+ #define pointer _pointer
+ #define GL_GLEXT_PROTOTYPES
#define property _property
#define new _new
#undef new
#undef property
#undef class
+ #undef pointer
- #endif
+ #if !defined(__APPLE__)
+ default GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
+ default GLAPI void APIENTRY glUnlockArraysEXT (void);
+ #endif
-#endif
+ import "XInterface"
-#if defined(__APPLE__)
-#include <OpenGl/gl.h>
-#endif
+ // We were using PBUFFER for alpha compositing on Linux before, but it does not seem to work, nor be required anymore.
+ // #define USEPBUFFER
-#if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
+ #endif
-#if defined(__WIN32__)
+// Apple
+#elif defined(__APPLE__)
+ #include <OpenGl/gl.h>
+
+// WGL
+#elif defined(__WIN32__)
//#define WIN32_LEAN_AND_MEAN
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0502
#define String Sting_
#include <windows.h>
#undef String
-#endif
-
-#if defined(__ANDROID__) || defined(__ODROID__)
-
-#define uint _uint
-#define property _property
-#define new _new
-#define class _class
-#define Window X11Window
-#define Cursor X11Cursor
-#define Font X11Font
-#define Display X11Display
-#define Time X11Time
-#define KeyCode X11KeyCode
-#define Picture X11Picture
-#define Bool X11Bool
-
- #include <GLES/gl.h>
-
-#undef Bool
-#undef Picture
-#undef Window
-#undef Cursor
-#undef Font
-#undef Display
-#undef Time
-#undef KeyCode
-#undef uint
-#undef new
-#undef property
-#undef class
-#elif defined(__EMSCRIPTEN__)
-
- #define property _property
- #define uint _uint
-
- #include <GL/gl.h>
-
- //#include <GLES/gl.h>
- //#include <EGL/egl.h>
-
- //#include <GLES2/gl.h>
- //#include <EGL/egl.h>
-
- //#include <GLES2/gl2.h>
- #include <GL/glfw.h>
- #include <emscripten/emscripten.h>
-
- #undef property
- #undef uint
-
-#else
- #include <GL/gl.h>
-#endif
-
-#if defined(__ODROID__) && !defined(ES1_1)
-#define ES1_1
+ #include "wglDefs.h"
#endif
-#if defined(__EMSCRIPTEN__)
-#define EM_MODE
-// #define ES1_1
+#if defined(__WIN32__)
+#elif !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
+default:
+private:
#endif
-#undef pointer
-
-import "Display"
-
-#if defined(__unix__) || defined(__APPLE__)
-
- #if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
- import "XInterface"
- #endif
+/* OpenGL Versions Features Quick Reference
+
+ | OpenGL 1.1 | OpenGL 1.5 | GL ES 1.1 | OpenGL 2 | GL 3 (Compat) | GL 3 (Core) | GL ES 2 | WebGL 1 | GL ES 3 | WebGL 2
+ =======================================================================================================================================================================
+ glBegin() | X | X | - | X | X | - | - | - | - | -
+ glLoadMatrix() | X | X | - | X | X | - | - | - | - | -
+ glLineWidth() | X | X | - | X | X | - | - | - | - | -
+ glPointSize() | X | X | - | X | X | - | - | - | - | -
+ glLineStipple() | X | X | - | X | X | - | - | - | - | -
+ glPolygonStipple() | X | X | - | X | X | - | - | - | - | -
+ glColorMaterial() | X | X | - | X | X | - | - | - | - | -
+ GL_QUADS | X | X | - | X | X | - | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ GL_INT / GL_DOUBLE | X | X | - | X | X | X | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ GL_SELECT | X | X | - | (Slow) | (Slow) | (Slow) | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Non ² Textures | - | - | - | X | X | X | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexPointer() (PTR) | X | X | X | X | X | - | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexPointer() (VBO) | - | X | X | X | X | - | - | - | - | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glBufferData() | - | X | X | X | X | X | X | X | X | X
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glMapBuffer() | - | X | OES x | X | X | X | OES x | - | OES x | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glBindFramebuffer() | - | - | OES x | - | X | X | X | X | X | X
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexAttribPointer() (PTR) | - | - | - | X | X | X | X | - | X | -
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ glVertexAttribPointer() (VBO) | - | - | - | X | X | X | X | X | X | X
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ GLSL Version | - | - | - | 1.10 | 1.30 | 1.30 | 1.00 | 1.00 | 3.00 | 3.00
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ bool legacy :1; // | X | X | - | X | X | - | - | - | - | -
+ bool shaders :1; // | - | - | - | X | X | X | X | X | X | X
+ bool nonPow2Textures :1; // | - | - | - | X | X | X | - | - | - | -
+ bool vertexBuffer :1; // | - | X | X | X | X | X | X | X | X | X
+ bool frameBuffer :1; // | - | - | ~ | - | X | X | X | X | X | X
+// bool mapBuffer :1; // | - | X | ~ | X | X | X | ~ | - | ~ | -
+*/
-#endif
+default:
+// Capabilities Global set to capabilities of Display being rendered to
+GLCapabilities glCaps;
+// Requiring Graphics Reload:
+bool glCaps_nonPow2Textures, glCaps_vertexBuffer, glCaps_quads, glCaps_intAndDouble, glCaps_legacyFormats, glCaps_compatible, glCaps_vertexPointer;
+// Might toggle without Reload:
+bool glCaps_core, glCaps_shaders, glCaps_fixedFunction, glCaps_immediate, glCaps_legacy, glCaps_pointSize, glCaps_frameBuffer, glCaps_vao, glCaps_select;
+// bool mapBuffer;
+private:
-#define glLoadMatrix glLoadMatrixd
-#define glMultMatrix glMultMatrixd
-#define glGetMatrix glGetDoublev
-#define glTranslate glTranslated
-#define glScale glScaled
+// ********** Errors and Debugging **********
/*
-#define glVertex3v glVertex3dv
-#define glNormal3v glNormal3dv
+void CheckGLErrors()
+{
+ int e, nCount = 0;
+ while((e = glGetError()) && nCount++ < 10)
+ printf("GL error %d!\n", e);
+}
*/
-
-/*
-//#ifdef VERTEX_FORMAT_DOUBLE
-
-#define glLoadMatrix glLoadMatrixd
-#define glMultMatrix glMultMatrixd
-#define glGetMatrix glGetDoublev
-#define glVertex3v glVertex3dv
-#define glNormal3v glNormal3dv
-#define glTranslate glTranslated
-#define glScale glScaled
-//#define GL_VERTEX_FORMAT GL_DOUBLE
-
-#else
-
-#define glLoadMatrix glLoadMatrixf
-#define glMultMatrix glMultMatrixf
-#define glGetMatrix glGetFloatv
-#define glVertex3v glVertex3fv
-#define glNormal3v glNormal3fv
-#define glTranslate glTranslatef
-#define glScale glScalef
-//#define GL_VERTEX_FORMAT GL_FLOAT
-
+#ifdef GL_DEBUGGING
+#ifndef APIENTRY
+ #define APIENTRY
#endif
-*/
-
-#define GL_ARRAY_BUFFER_ARB 0x8892
-#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
-#define GL_STATIC_DRAW_ARB 0x88E4
-#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
-#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
-
-#define GL_MULTISAMPLE_ARB 0x809D
-
-#if defined(__WIN32__)
- #include "wglDefs.h"
-
- typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
- typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
+static void APIENTRY openglCallbackFunction(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const void* userParam)
+{
+ if(severity == GL_DEBUG_SEVERITY_NOTIFICATION)
+ return;
+ PrintLn("---------------------opengl-callback-start------------");
+ PrintLn("message: ", message);
+ PrintLn("type: ");
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
+ case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
+ case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
+ case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
+ }
- static PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = null;
- static PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = null;
+ PrintLn("id: ", id);
+ Print("severity: ");
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
+ case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
+ case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
+ default: PrintLn("(other)");
+ }
+ PrintLn("---------------------opengl-callback-end--------------");
+}
- static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = null;
- static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = null;
- static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = null;
- static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = null;
- static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = null;
- static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = null;
- static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = null;
- static PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB = null;
- static PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB = null;
- static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = null;
- static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = null;
+static void setupDebugging()
+{
+ if(glDebugMessageCallback)
+ {
+ GLuint unusedIds = 0;
-#elif defined(__ANDROID__) || defined(__ODROID__)
+ glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
- #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
- #define GL_RENDERBUFFER GL_RENDERBUFFER_OES
- #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
-
- #define GL_POLYGON_STIPPLE 0xFFFF
- #define GL_LINE_STIPPLE 0xFFFF
- #define GL_LINE 0xFFFF
- #define GL_FILL 0xFFFF
- #define GL_ALL_ATTRIB_BITS 0xFFFF
- #define GL_LIGHT_MODEL_LOCAL_VIEWER 0xFFFF
-
- #define GL_POLYGON 9
- #define GL_QUADS 7
-
- //#define GL_QUADS 0
- #define GL_QUAD_STRIP 0
- //#define GL_DOUBLE 0
- //#define GL_UNSIGNED_INT 0
- //#define GL_FILL 0
- //#define GL_LINE 0
- //#define GL_LINE_STIPPLE 0
- #define GL_BGRA_EXT 0
- #define GL_UNPACK_ROW_LENGTH 0
- #define GL_UNPACK_SKIP_PIXELS 0
- #define GL_UNPACK_SKIP_ROWS 0
- #define GL_RGBA8 0
- #define GL_PACK_ROW_LENGTH 0
- #define GL_PACK_SKIP_ROWS 0
- #define GL_PACK_SKIP_PIXELS 0
-
-#endif
-
-
-#if defined(__ANDROID__) || defined(__ODROID__)
- #define glBindFramebuffer glBindFramebufferOES
- #define glBindRenderbuffer glBindRenderbufferOES
- #define glFramebufferTexture2D glFramebufferTexture2DOES
- #define glGenFramebuffers glGenFramebuffersOES
- #define glGenRenderbuffers glGenRenderbuffersOES
- #define glDeleteFramebuffers glDeleteFramebuffersOES
- #define glDeleteRenderbuffers glDeleteRenderbuffersOES
-
- #define GL_INT 0x1404
- #define GL_UNSIGNED_INT 0x1405
- #define GL_DOUBLE 0x140A
- #define APIENTRY
+ glDebugMessageCallback(openglCallbackFunction, null);
+ glDebugMessageControl(GL_DONT_CARE,
+ GL_DONT_CARE,
+ GL_DONT_CARE,
+ 0,
+ &unusedIds,
+ GL_TRUE);
+ }
+}
#endif
-#if defined(ES1_1) || defined(SHADERS)
-
- #undef glRecti
- #undef glBegin
- #undef glTexCoord2i
- #undef glVertex2i
- #undef glTexCoord2d
- #undef glVertex2d
- #undef glTexCoord2f
- #undef glVertex2f
- #undef glEnd
- #undef glColor3f
- #undef glColor4ub
- #undef glColor4fv
- #undef glNormal3fv
- #undef glNormal3f
- #undef glTexCoord2fv
- #undef glVertex3d
- #undef glVertex3dv
- #undef glVertex3f
- #undef glVertex3fv
-
- #undef glLoadMatrixd
- #undef glMultMatrixd
- #undef glFrustum
- #undef glOrtho
- #undef glScaled
- #undef glScalef
- #undef glTranslated
- #undef glRotated
- #undef glMatrixMode
- #undef glLoadIdentity
- #undef glPushMatrix
- #undef glPopMatrix
-
- #undef glLineStipple
- #undef glColorMaterial
- #undef glLightModeli
-
- #define glRecti glimtkRecti
- #define glBegin glimtkBegin
- #define glTexCoord2i glimtkTexCoord2i
- #define glVertex2i glimtkVertex2i
- #define glTexCoord2d glimtkTexCoord2d
- #define glVertex2d glimtkVertex2d
- #define glTexCoord2f glimtkTexCoord2f
- #define glVertex2f glimtkVertex2f
- #define glEnd glimtkEnd
- #define glColor3f glimtkColor3f
- #define glColor4ub glimtkColor4ub
- #define glColor4fv glimtkColor4fv
- #define glNormal3fv glimtkNormal3fv
- #define glNormal3f glimtkNormal3f
- #define glTexCoord2fv glimtkTexCoord2fv
- #define glVertex3d glimtkVertex3d
- #define glVertex3dv glimtkVertex3dv
- #define glVertex3f glimtkVertex3f
- #define glVertex3fv glimtkVertex3fv
-
- #define glLoadMatrixd glmsLoadMatrixd
- #define glMultMatrixd glmsMultMatrixd
- #define glFrustum glmsFrustum
- #define glOrtho glmsOrtho
- #define glScaled glmsScaled
- #define glScalef glmsScaled
- #define glTranslated glmsTranslated
- #define glRotated glmsRotated
- #define glMatrixMode glmsMatrixMode
- #define glLoadIdentity glmsLoadIdentity
- #define glPushMatrix glmsPushMatrix
- #define glPopMatrix glmsPopMatrix
-
- #define glLineStipple glesLineStipple
- #define glColorMaterial glesColorMaterial
- #define glLightModeli glesLightModeli
-
-#endif
-
-public void glesColorMaterial(int a, int b)
-{
- PrintLn("glColorMaterial stub");
-}
static GLuint stippleTexture;
-#if defined(ES1_1) || defined(SHADERS) || defined(EM_MODE)
static bool stippleEnabled;
-#endif
-public void glesLineStipple( int i, unsigned short j )
+public void glsupLineStipple( int i, uint16 j )
{
uint texture[1*16];
int x;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
//glTranslated(1.0/backAttrib->texW/2.0f, 1.0/backAttrib->texH/2.0f, 0.0f);
- glScaled(i/16.0, 1, 1.0f);
- glTranslated(0.5, 0.5, 0);
- glMatrixMode(MatrixMode::projection);
+ GLScaled(i/16.0, 1, 1.0f);
+ GLTranslated(0.5, 0.5, 0);
+ GLMatrixMode(MatrixMode::projection);
}
-public void glesLightModeli( unsigned int pname, int param )
-{
-#if !defined(EM_MODE) && !defined(SHADERS)
- if(pname == GL_LIGHT_MODEL_TWO_SIDE)
- glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
+ // Exported to build _GLES version...
+ public void glsupLightModeli( unsigned int pname, int param )
+ {
+#if ENABLE_GL_FFP
+ if(pname == GL_LIGHT_MODEL_TWO_SIDE)
+ glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
#endif
-}
+ }
-#if defined(__ANDROID__) || defined(__ODROID__)
+#ifdef _GLES
+ void glFogi( unsigned int pname, int param ) { }
+ void glPolygonMode( unsigned int i, unsigned int j ) { }
+ void glBlendFuncSeparate(int a, int b, int c, int d)
+ {
+ glBlendFunc(a, b);
+ }
+
+#endif
+
+#if defined(_GLES) || defined(_GLES2)
void glClearDepth( double depth ) { glClearDepthf((float)depth); }
-void glFogi( unsigned int pname, int param ) { }
-void glPolygonMode( unsigned int i, unsigned int j ) { }
+#endif
+#if !ENABLE_GL_SELECT
// *** Picking won't be supported for now ***
void glPushName( unsigned int i ) { }
void glLoadName( unsigned int i ) { }
void glPopName() { }
-// Probably replace by regular glBlendFunc ...
-void glBlendFuncSeparate(int a, int b, int c, int d)
+#endif
+
+#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
+static inline uint getPrimitiveType(RenderPrimitiveType type)
{
- glBlendFunc(a, b);
+ static int primitiveTypes[RenderPrimitiveType] =
+ {
+ GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN,
+ GLIMTKMode::quads,
+ GLIMTKMode::quadStrip,
+ GL_LINE_STRIP
+ };
+ // NOTE: This will only work for single quads
+ return (type == quads && !glCaps_quads) ? GL_TRIANGLE_FAN : primitiveTypes[type];
}
-// For direct pixel blitting...
-void glRasterPos2d(double a, double b) { }
-void glPixelZoom(float a, float b) { }
-void glDrawPixels(int a, int b, int c, int d, void * e) { }
+public void GLSetupTexturing(bool enable)
+{
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.texturing(enable);
+#endif
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
#endif
+}
-#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
-static int primitiveTypes[RenderPrimitiveType] =
+public void GLSetupFog(bool enable)
{
- GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GLIMTKMode::quads, GLIMTKMode::quadStrip, GL_LINE_STRIP
-};
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.fog(enable);
#endif
-public void GLSetupTexturing(bool enable)
-{
-#ifdef SHADERS
- shader_texturing(enable);
-#else
- (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ (enable ? glEnable : glDisable)(GL_FOG);
#endif
}
+bool lightingEnabled;
-// Non OpenGL ES friendly stuff
+public void GLSetupLighting(bool enable)
+{
+ lightingEnabled = enable;
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.lighting(enable);
+#endif
-#if defined(ES1_1)
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ (enable ? glEnable : glDisable)(GL_LIGHTING);
+#endif
+}
+#endif
-//#undef GL_UNSIGNED_INT
-//#undef GL_DOUBLE
-#undef GL_INT
-//#undef GL_POLYGON
-//#undef GL_QUADS
-#undef GL_QUAD_STRIP
-#undef GL_POLYGON_STIPPLE
-#undef GL_LINE_STIPPLE
-#undef GL_LINE
-#undef GL_FILL
-#undef GL_ALL_ATTRIB_BITS
-#undef GL_LIGHT_MODEL_LOCAL_VIEWER
+/*static */GLuint lastBlitTex;
-#endif
+Shader activeShader;
static int displayWidth, displayHeight;
#define GL_CLAMP_TO_EDGE 0x812F
-static bool vboAvailable;
-
static bool useSingleGLContext = false;
class OGLDisplay : struct
{
+ GLCapabilities capabilities, originalCapabilities;
+ bool compat;
+ int version;
+
+ ColorAlpha * flippingBuffer;
+ int flipBufH, flipBufW;
+ bool depthWrite;
+ int x, y;
+ uint vao;
+ int maxTMU;
+
#if defined(__WIN32__)
HDC hdc;
HGLRC glrc;
Pixmap shapePixmap;
X11Picture shapePicture;
#endif
-
- ColorAlpha * flippingBuffer;
- int flipBufH, flipBufW;
- bool depthWrite;
- int x, y;
};
-#ifdef _DEBUG
-static void APIENTRY openglCallbackFunction(GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- GLsizei length,
- const GLchar* message,
- const void* userParam)
-{
- PrintLn("---------------------opengl-callback-start------------");
- PrintLn("message: ", message);
- PrintLn("type: ");
- switch (type)
- {
- case GL_DEBUG_TYPE_ERROR: PrintLn("ERROR"); break;
- case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: PrintLn("DEPRECATED_BEHAVIOR"); break;
- case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: PrintLn("UNDEFINED_BEHAVIOR"); break;
- case GL_DEBUG_TYPE_PORTABILITY: PrintLn("PORTABILITY"); break;
- case GL_DEBUG_TYPE_PERFORMANCE: PrintLn("PERFORMANCE"); break;
- case GL_DEBUG_TYPE_OTHER: PrintLn("OTHER"); break;
- }
-
- PrintLn("id: ", id);
- Print("severity: ");
- switch (severity)
- {
- case GL_DEBUG_SEVERITY_LOW: PrintLn("LOW"); break;
- case GL_DEBUG_SEVERITY_MEDIUM: PrintLn("MEDIUM"); break;
- case GL_DEBUG_SEVERITY_HIGH: PrintLn("HIGH"); break;
- }
- PrintLn("---------------------opengl-callback-end--------------");
-}
-#endif
-
class OGLSystem : struct
{
int maxTextureSize;
bool loadingFont;
- bool pow2textures;
#if defined(__WIN32__)
PIXELFORMATDESCRIPTOR pfd;
int format;
HDC hdc;
HGLRC glrc;
HWND hwnd;
-#elif !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
+#elif defined(__EMSCRIPTEN__)
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glc;
+#elif !defined(__ANDROID__) && !defined(__ODROID__)
XVisualInfo * visualInfo;
GLXContext glContext;
GLXDrawable glxDrawable;
#endif
+ GLCapabilities capabilities;
+ bool compat;
+ int version;
+
+ // Buffer Data
+ uint16 *shortBDBuffer;
+ uint shortBDSize;
};
class OGLSurface : struct
{
GLAB vertices;
GLAB normals;
+ GLAB tangents;
+ GLAB lightVectors;
GLAB texCoords;
GLAB texCoords2;
GLAB colors;
int current;
void * previous;
-static void setupDebugging()
-{
-#ifdef _DEBUG
- if(glDebugMessageCallback)
- {
- GLuint unusedIds = 0;
-
- glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
- glDebugMessageCallback(openglCallbackFunction, null);
- glDebugMessageControl(GL_DONT_CARE,
- GL_DONT_CARE,
- GL_DONT_CARE,
- 0,
- &unusedIds,
- GL_TRUE);
- }
-#endif
-}
-
#if defined(__WIN32__)
-static HGLRC winCreateContext(HDC hdc)
+static HGLRC winCreateContext(HDC hdc, int * contextVersion, bool * isCompatible, bool compatible)
{
+ HGLRC result = 0;
if(wglCreateContextAttribsARB)
{
- int attribs[] =
+ int versions[12][2] =
{
- WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
- WGL_CONTEXT_MINOR_VERSION_ARB, 4,
- WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | */WGL_CONTEXT_DEBUG_BIT_ARB,
- WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB /*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/,
- 0,0
+ { 4, 5 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, { 4, 0 },
+ { 3, 3 }, { 3, 2 }, { 3, 1 }, { 3, 0 },
+ { 2, 1 }, { 2, 0 }
};
- return wglCreateContextAttribsARB(hdc, null, attribs);
+
+ bool tryingCompat = compatible;
+ int v = 0;
+ while(!result)
+ {
+ for(v = 0; !result && v < sizeof(versions) / sizeof(versions[0]); v++)
+ {
+ int v0 = versions[v][0], v1 = versions[v][1];
+ if(!tryingCompat || v0 >= 3)
+ {
+ bool coreNotion = v0 > 3 || (v0 == 3 && v1 >= 3);
+ int attribs[] =
+ {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, v0, WGL_CONTEXT_MINOR_VERSION_ARB, v1,
+ #ifdef _DEBUG
+ WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
+ #endif
+ coreNotion ? WGL_CONTEXT_PROFILE_MASK_ARB : 0, coreNotion ? (tryingCompat ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB) : 0,
+ 0,0
+ };
+ result = wglCreateContextAttribsARB(hdc, null, attribs);
+ if(result)
+ {
+ if(contextVersion) *contextVersion = v0;
+ if(isCompatible) *isCompatible = tryingCompat || !coreNotion;
+ }
+ }
+ }
+ if(tryingCompat)
+ tryingCompat = false;
+ else
+ break;
+ }
}
- else
- return wglCreateContext(hdc);
+ if(!result)
+ {
+ if(contextVersion) *contextVersion = 1;
+ if(isCompatible) *isCompatible = true;
+ result = wglCreateContext(hdc);
+ }
+ return result;
}
#endif
bool LockSystem(DisplaySystem displaySystem)
{
-#if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
+#if defined(__EMSCRIPTEN__)
+ OGLSystem oglSystem = displaySystem.driverData;
+ emscripten_webgl_make_context_current(oglSystem.glc);
+#elif !defined(__ANDROID__) && !defined(__ODROID__)
OGLSystem oglSystem = displaySystem.driverData;
if(useSingleGLContext) return true;
#if defined(__WIN32__)
}
}
- void ::CheckExtensions(OGLSystem oglSystem)
+#if !defined(__EMSCRIPTEN__)
+ void ::CheckCapabilities(OGLSystem oglSystem, OGLDisplay oglDisplay, bool canCheckExtensions)
{
- const char * extensions = (const char *)glGetString(GL_EXTENSIONS);
- if(extensions)
- oglSystem.pow2textures = strstr(extensions, "GL_ARB_texture_non_power_of_two") ? false : true;
+ GLCapabilities capabilities;
+#if !defined(_GLES2)
+ const char * extensions = (canCheckExtensions && (!oglDisplay || oglDisplay.compat)) ? (const char *)glGetString(GL_EXTENSIONS) : null;
+#endif
+#ifdef DIAGNOSTICS
+ printf("extensions: %s\n", extensions);
+#endif
+
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &oglSystem.maxTextureSize);
+
+#if defined(_GLES)
+ capabilities = { fixedFunction = true, vertexPointer = true, vertexBuffer = true, pointSize = true, legacyFormats = true, frameBuffer = extensions && strstr(extensions, "GL_OES_framebuffer_object") };
+#elif defined(_GLES2)
+ capabilities = { glCaps_shaders = true, vertexBuffer = true, pointSize = true, frameBuffer = true, legacyFormats = true };
+#else
+ capabilities =
+ {
+ nonPow2Textures = glGetStringi || (extensions && (strstr(extensions, "GL_ARB_texture_non_power_of_two")));
+ intAndDouble = true;
+#ifdef GL_DEBUGGING
+ debug = true;
+#endif
+ compatible = oglDisplay.compat;
+ pointSize = oglDisplay.compat;
+#if ENABLE_GL_LEGACY
+ legacy = glBegin != null && oglDisplay.compat;
+ legacyFormats = glBegin != null && oglDisplay.compat;
+ immediate = glBegin != null && oglDisplay.compat;
+ fixedFunction = glBegin != null && oglDisplay.compat;
+ quads = glBegin != null && oglDisplay.compat;
+ select = glSelectBuffer != null && oglDisplay.compat;
+#endif
+#if ENABLE_GL_SHADERS
+ shaders = glCreateProgram != null;
+#endif
+#if ENABLE_GL_POINTER
+ vertexPointer = oglDisplay.compat;
+#endif
+#if ENABLE_GL_VAO
+ vao = glBindVertexArray != null && !oglDisplay.compat;
+#endif
+#if ENABLE_GL_FBO
+ frameBuffer = glBindFramebuffer != null;
+#endif
+ vertexBuffer = glBindBuffer != null;
+ // mapBuffer = glMapBuffer != null;
+ };
+#endif
+
+#ifdef DIAGNOSTICS
+ PrintLn("max texture size: ", oglSystem.maxTextureSize);
+#endif
+ if(oglDisplay) oglDisplay.capabilities = capabilities;
+ if(oglSystem) oglSystem.capabilities = capabilities;
}
+#endif
bool CreateDisplaySystem(DisplaySystem displaySystem)
{
bool result = false;
OGLSystem oglSystem = displaySystem.driverData = OGLSystem { };
+#ifdef _GLES
+ oglSystem.capabilities = { fixedFunction = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
+#elif defined(_GLES2)
+ oglSystem.capabilities = { shaders = true, vertexBuffer = true, frameBuffer = true, pointSize = true };
+#else
+ oglSystem.capabilities = { compatible = glCaps_compatible, shaders = true, fixedFunction = true, immediate = true, legacy = true, pointSize = true, quads = true, intAndDouble = true, vertexBuffer = true, frameBuffer = true, vao = true, nonPow2Textures = true };
+#endif
+
+#ifdef DIAGNOSTICS
+ PrintLn("OpenGL driver's CreateDisplaySystem()");
+#endif
+
#ifdef __WIN32__
oglSystem.hwnd = CreateWindow("static", null, 0,0,0,0,0,null,null,null,null);
SetPixelFormat(oglSystem.hdc, oglSystem.format, &oglSystem.pfd);
//Log("Successfully set pixel format\n");
- oglSystem.glrc = winCreateContext(oglSystem.hdc);
- wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
+#ifdef DIAGNOSTICS
+ PrintLn("winCreateContext()");
+#endif
+ oglSystem.glrc = winCreateContext(oglSystem.hdc, &oglSystem.version, &oglSystem.compat, displaySystem.glCapabilities.compatible);
+#ifdef DIAGNOSTICS
+ PrintLn("wglMakeCurrent()");
+#endif
+ if(oglSystem.glrc)
+ wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
}
}
/*else
}
}
#elif defined(__unix__) || defined(__APPLE__)
- vboAvailable = true;
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) || defined(__ODROID__)
+ #if defined(__ANDROID__)
egl_init_display(guiApp.desktop.windowHandle);
- #elif defined(__ODROID__)
+ #elif defined(__ODROID__)
egl_init_display((uint)displaySystem.window);
- CheckExtensions(oglSystem);
+ #endif
+ CheckCapabilities(oglSystem, null, true);
+
+ // TODO: Clean this up? Needed here?
+ GLEnableClientState(VERTICES);
+ /*
+ // Initialize GL state.
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ glEnable(GL_CULL_FACE);
+ glShadeModel(GL_SMOOTH);
+ glDisable(GL_DEPTH_TEST);
+ */
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ matrixStack[0][0].Identity();
+ matrixStack[1][0].Identity();
+ matrixStack[2][0].Identity();
+
+ GLMatrixMode(GL_MODELVIEW);
+ GLScaled(1.0, 1.0, -1.0);
+ GLMatrixMode(GL_PROJECTION);
+ glShadeModel(GL_FLAT);
+
+#if !defined(_GLES)
+ if(!glCaps_shaders)
+ ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+#endif
+ glFogi(GL_FOG_MODE, GL_EXP);
+ glFogf(GL_FOG_DENSITY, 0);
+ glEnable(GL_NORMALIZE);
+ glDepthFunc(GL_LESS);
+ glClearDepth(1.0);
+ glDisable(GL_MULTISAMPLE);
+
+ glViewport(0,0,eglWidth,eglHeight);
+ GLLoadIdentity();
+ GLOrtho(0,eglWidth,eglHeight,0,0.0,1.0);
+
+ glabCurArrayBuffer = 0;
+ glabCurElementBuffer = 0;
+
result = true;
#elif defined(__EMSCRIPTEN__)
- if(glfwInit() == GL_TRUE)
{
- const int width = 640, height = 480;
- if(glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 0, GLFW_WINDOW) == GL_TRUE)
- {
- //glfwSwapBuffers();
+ EmscriptenWebGLContextAttributes attribs = { 0 };
+ attribs.depth = 1;
+ attribs.antialias = 1;
+
+ /*
+ EM_BOOL alpha;
+ EM_BOOL depth;
+ EM_BOOL stencil;
+ EM_BOOL antialias;
+ EM_BOOL premultipliedAlpha;
+ EM_BOOL preserveDrawingBuffer;
+ EM_BOOL preferLowPowerToHighPerformance;
+ EM_BOOL failIfMajorPerformanceCaveat;
+ int majorVersion;
+ int minorVersion;
+ EM_BOOL enableExtensionsByDefault;
+ */
+
+ emscripten_webgl_init_context_attributes(&attribs);
+ oglSystem.maxTextureSize = 16384;
+ oglSystem.glc = emscripten_webgl_create_context("canvas", &attribs);
+ if(emscripten_webgl_make_context_current(oglSystem.glc) == EMSCRIPTEN_RESULT_SUCCESS)
result = true;
- }
- else
- printf("glfwOpenWindow() failed\n"); //glfwTerminate();
+
+ /*glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);*/
}
- else
- printf("glfwInit() failed\n"); //glfwTerminate();
#else
{
X11Window root = RootWindow( xGlobalDisplay, DefaultScreen( xGlobalDisplay ) );
if(oglSystem.glContext)
{
glXMakeCurrent(xGlobalDisplay, oglSystem.glxDrawable, oglSystem.glContext);
- // Setup Extensions
- CheckExtensions(oglSystem);
glXMakeCurrent(xGlobalDisplay, None, null);
result = true;
}
void DestroyDisplaySystem(DisplaySystem displaySystem)
{
OGLSystem oglSystem = displaySystem.driverData;
+ if(stippleTexture)
+ {
+ glDeleteTextures(1, &stippleTexture);
+ stippleTexture = 0;
+ }
+
+#if ENABLE_GL_SHADERS
+ defaultShader.free();
+ activeShader = null;
+#endif
+
+ delete oglSystem.shortBDBuffer;
+ glimtkTerminate();
#if defined(__WIN32__)
wglMakeCurrent( null, null );
#if defined(__ANDROID__) || defined(__ODROID__)
egl_term_display();
#elif defined(__EMSCRIPTEN__)
- glfwTerminate();
+ emscripten_webgl_destroy_context(oglSystem.glc);
#else
if(oglSystem.visualInfo)
{
XFree(oglSystem.visualInfo);
#endif
}
+ if(oglSystem.glContext)
+ glXDestroyContext(xGlobalDisplay, oglSystem.glContext);
if(oglSystem.glxDrawable)
{
delete oglSystem;
}
- static bool ::initialDisplaySetup(Display display)
+ /*static */bool ::initialDisplaySetup(Display display, bool canCheckExtensions, bool loadExtensions)
{
+ OGLDisplay oglDisplay = display.driverData;
+ OGLSystem oglSystem = display.displaySystem.driverData;
bool result = true;
- #ifdef SHADERS
- loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
- #endif
- glEnableClientState(GL_VERTEX_ARRAY);
+
+#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
+ if(loadExtensions && ogl_LoadFunctions() == ogl_LOAD_FAILED)
+ PrintLn("ogl_LoadFunctions() failed!");
+ CheckCapabilities(oglSystem, oglDisplay, canCheckExtensions);
+#endif
+
+ {
+ GLCapabilities capabilities = *&display.glCapabilities;
+ // PrintLn("Available OpenGL Capabilities: ", oglDisplay.capabilities);
+ // PrintLn("Desired OpenGL Capabilities: ", capabilities);
+
+ oglDisplay.originalCapabilities = oglDisplay.capabilities;
+
+ // Re-enable glCaps_shaders if no fixed function support
+ if(!oglDisplay.capabilities.fixedFunction)
+ capabilities.shaders = true;
+ // Re-enable fixed function if no glCaps_shaders support
+ if(!oglDisplay.capabilities.shaders)
+ {
+ capabilities.fixedFunction = true;
+ capabilities.shaders = false;
+ }
+
+ if(!capabilities.shaders && !capabilities.fixedFunction)
+ {
+ capabilities.fixedFunction = oglDisplay.capabilities.fixedFunction;
+ capabilities.shaders = oglDisplay.capabilities.shaders;
+ }
+
+ // Disable things that don't work with glCaps_shaders
+ if(capabilities.shaders)
+ {
+ capabilities.fixedFunction = false;
+ capabilities.legacy = false;
+ capabilities.immediate = false;
+ }
+
+ #if !ENABLE_GL_POINTER
+ // Re-enable vertex buffer if no pointer support
+ capabilities.vertexBuffer = true;
+ #endif
+
+ oglDisplay.capabilities &= capabilities;
+
+ // PrintLn("Selected OpenGL Capabilities: ", oglDisplay.capabilities);
+ oglSystem.capabilities = oglDisplay.capabilities;
+ }
+
+ #ifdef GL_DEBUGGING
+ if(oglDisplay.capabilities.debug)
+ setupDebugging();
+ #else
+ oglDisplay.capabilities.debug = false;
+ #endif
+
+#if ENABLE_GL_VAO
+ if(oglDisplay.capabilities.vao)
+ {
+ glGenVertexArrays(1, &oglDisplay.vao);
+ glBindVertexArray(oglDisplay.vao);
+ }
+#endif
+
+ oglSystem.capabilities = oglDisplay.capabilities;
+ SETCAPS(oglDisplay.capabilities);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+#if ENABLE_GL_LEGACY
+ if(oglDisplay.compat)
+ {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+#endif
+ defaultShader.select();
+ }
+#if ENABLE_GL_LEGACY
+ else
+ {
+ glDisableVertexAttribArray(GLBufferContents::color);
+ glDisableVertexAttribArray(GLBufferContents::normal);
+ glDisableVertexAttribArray(GLBufferContents::texCoord);
+ glDisableVertexAttribArray(GLBufferContents::vertex);
+ glDisableVertexAttribArray(GLBufferContents::tangent1);
+ glDisableVertexAttribArray(GLBufferContents::tangent2);
+#if ENABLE_GL_VAO
+ glBindVertexArray(0);
+#endif
+ glUseProgram(0);
+ }
+#endif
+
+#endif
+
+#if ENABLE_GL_VAO
+ if(glCaps_vao)
+ glBindVertexArray(oglDisplay.vao);
+#endif
+
+ GLEnableClientState(VERTICES);
GLABBindBuffer(GL_ARRAY_BUFFER, 0);
GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
glEnable(GL_BLEND);
- glMatrixMode(MatrixMode::modelView);
- glLoadIdentity(); // For setting up GLES stack
- glScaled(1.0, 1.0, -1.0);
+ GLMatrixMode(MatrixMode::texture);
+ GLLoadIdentity();
+
+ GLMatrixMode(MatrixMode::modelView);
+ GLLoadIdentity(); // For setting up GLES stack
+ GLScaled(1.0, 1.0, -1.0);
// glTranslatef(0.375f, 0.375f, 0.0f);
// glTranslatef(-0.625f, -0.625f, 0.0f);
- glMatrixMode(MatrixMode::projection);
-#if !defined(EM_MODE) && !defined(SHADERS)
- glShadeModel(GL_FLAT);
+ GLMatrixMode(MatrixMode::projection);
+ GLLoadIdentity();
+ if(display.width && display.height)
+ GLOrtho(0,display.width,display.height,0,0.0,1.0);
- // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
- glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
- glFogi(GL_FOG_MODE, GL_EXP);
- glFogf(GL_FOG_DENSITY, 0);
- glEnable(GL_NORMALIZE);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ glShadeModel(GL_FLAT);
+
+ #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+ GLLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+
+#if !defined(_GLES)
+ ;//GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+#endif
+ glFogi(GL_FOG_MODE, GL_EXP);
+ glFogf(GL_FOG_DENSITY, 0);
+ glEnable(GL_NORMALIZE);
+ }
#endif
glDepthFunc(GL_LESS);
glClearDepth(1.0);
- glDisable(GL_MULTISAMPLE_ARB);
+#if !defined(__EMSCRIPTEN__)
+ glDisable(GL_MULTISAMPLE);
+#endif
+
#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
display.ambient = Color { 50,50,50 };
#endif
{
bool result = false;
OGLDisplay oglDisplay = display.driverData;
-#if !defined(__ANDROID__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
OGLSystem oglSystem = display.displaySystem.driverData;
-#endif
if(!oglDisplay)
oglDisplay = display.driverData = OGLDisplay { };
- //printf("Inside CreateDisplay\n");
+ oglDisplay.capabilities = oglSystem.capabilities;
#if defined(__WIN32__) || defined(USEPBUFFER)
if(!display.alphaBlend)
#endif
{
- #if defined(__WIN32__)
+#if defined(__WIN32__)
oglDisplay.hdc = GetDC(display.window);
SetPixelFormat(oglDisplay.hdc, oglSystem.format, &oglSystem.pfd);
- if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
+ if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, &oglDisplay.version, &oglDisplay.compat, (*&display.glCapabilities).compatible)))
{
wglShareLists(oglSystem.glrc, oglDisplay.glrc);
wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
}
else
ReleaseDC(display.window, oglDisplay.hdc);
- #elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
- #else
+#elif defined(__unix__) || defined(__APPLE__)
+# if defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__ODROID__)
+ result = true;
+# else
XVisualInfo * visualInfo = ((XWindowData)display.windowDriverData).visual;
/*
#if defined(__APPLE__)
// visualInfo = oglSystem.visualInfo;
//#endif
*/
+#if !defined(__APPLE__)
+ oglDisplay.compat = true;
+ oglDisplay.version = 4;
+#endif
+
if(visualInfo)
{
//printf("visualInfo is not null\n");
glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
result = true;
}
- #endif
- #endif
+# endif
+#endif
}
#if defined(__WIN32__) || defined(USEPBUFFER)
else
{
+ oglDisplay.compat = (*&display.glCapabilities).compatible;
result = true;
wglMakeCurrent(oglSystem.hdc, oglSystem.glrc);
}
#endif
if(result)
{
- ogl_LoadFunctions();
- CheckExtensions(oglSystem);
- vboAvailable = glBindBuffer != null;
- setupDebugging();
- initialDisplaySetup(display);
+#if defined(__EMSCRIPTEN__)
+ emscripten_webgl_make_context_current(oglSystem.glc);
+#endif
+
+#if defined(__WIN32__) || defined(USEPBUFFER)
+ initialDisplaySetup(display, !display.alphaBlend, true);
+#else
+ initialDisplaySetup(display, true, true);
+#endif
}
if(!useSingleGLContext)
result = true;
#endif
}
-
return result;
}
bool DisplaySize(Display display, int width, int height)
{
OGLDisplay oglDisplay = display.driverData;
-
bool result = false;
- //printf("Inside DisplaySize\n");
#if defined(__WIN32__) || defined(USEPBUFFER)
OGLSystem oglSystem = display.displaySystem.driverData;
if(display.alphaBlend)
oglDisplay.pBuffer = wglCreatePbufferARB(oglSystem.hdc, pixelFormat, width, height, attributes);
oglDisplay.hdc = wglGetPbufferDCARB(oglDisplay.pBuffer);
- if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc)))
+ if((oglDisplay.glrc = winCreateContext(oglDisplay.hdc, null, null, oglDisplay.capabilities.compatible)))
{
BITMAPINFO * info;
HDC hdc = GetDC(display.window);
#if defined(__WIN32__)
wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
#elif defined(__unix__) || defined(__APPLE__)
- #if defined(__ANDROID__) || defined(__ODROID__) || defined(__EMSCRIPTEN__)
+ #if defined(__ANDROID__) || defined(__ODROID__)
width = eglWidth;
height = eglHeight;
+ #elif defined(__EMSCRIPTEN__)
+ emscripten_webgl_make_context_current(oglSystem.glc);
#else
glXMakeCurrent(xGlobalDisplay, (GLXDrawable)display.window, oglDisplay.glContext);
#endif
#endif
result = true;
+ SETCAPS(oglDisplay.capabilities);
+
if(display.alphaBlend && result)
- initialDisplaySetup(display);
+ initialDisplaySetup(display, true, false);
if(!result && display.alphaBlend)
{
result = false;
glViewport(0,0,width,height);
- glMatrixMode(MatrixMode::projection);
- glLoadIdentity();
- glOrtho(0,width,height,0,0.0,1.0);
+ GLMatrixMode(MatrixMode::projection);
+ GLLoadIdentity();
+ GLOrtho(0,width,height,0,0.0,1.0);
displayWidth = display.width = width;
displayHeight = display.height = height;
{
oglDisplay.flipBufW = width;
oglDisplay.flipBufH = height;
-#ifdef ES1_1
+#if defined(_GLES) || defined(_GLES2)
result = true;
#else
oglDisplay.flippingBuffer = renew oglDisplay.flippingBuffer ColorAlpha [width * height];
void StartUpdate(Display display)
{
+#if ENABLE_GL_VAO
+ if(glCaps_vao)
+ {
+ OGLDisplay oglDisplay = display.driverData;
+ glBindVertexArray(oglDisplay.vao);
+ }
+#endif
+ GLABBindBuffer(GL_ARRAY_BUFFER, 0);
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#if ENABLE_GL_SHADERS
+ activeProgram = 0;
+#endif
}
void EndUpdate(Display display)
#if defined(__WIN32__) || defined(USEPBUFFER)
OGLDisplay oglDisplay = display.driverData;
#endif
- //Logf("DisplayScreen\n");
#if !defined(__ANDROID__)
/*glFlush();
#if defined(__WIN32__)
//wglSwapLayerBuffers(oglDisplay.hdc,WGL_SWAP_MAIN_PLANE);
SwapBuffers(oglDisplay.hdc);
+ //ecere::sys::Sleep(0.1);
#elif defined(__unix__) || defined(__APPLE__)
#if defined(__ANDROID__) || defined(__ODROID__)
- eglSwapBuffers(eglDisplay, eglSurface);
+ egl_swap_buffers();
#elif defined(__EMSCRIPTEN__)
- glfwSwapBuffers();
#else
glXSwapBuffers(xGlobalDisplay, (GLXDrawable)display.window);
#endif
#endif
}
- //Logf("Out of DisplayScreen\n");
}
void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
{
OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities capabilities = oglSystem.capabilities;
bool result = false;
Bitmap mipMap { };
GLuint glBitmap = 0;
uint w = width, h = height;
- if(oglSystem.pow2textures)
+ if(!capabilities.nonPow2Textures)
{
w = pow2i(w);
h = pow2i(h);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#if !defined(SHADERS)
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+#if ENABLE_GL_FFP
+ if(!capabilities.shaders)
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
#endif
mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
return result;
}
- bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
+ bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps, uint cubeMapFace)
{
bool result = false;
OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities capabilities = oglSystem.capabilities;
Bitmap convBitmap = bitmap;
+ bool oldStyleCubeMap = (cubeMapFace >> 3) != 0;
+ int face = (cubeMapFace & 7) - 1;
if(bitmap.keepData)
{
convBitmap = { };
{
int c, level;
uint w = bitmap.width, h = bitmap.height;
- GLuint glBitmap = 0;
- if(oglSystem.pow2textures)
+ GLuint glBitmap = cubeMapFace && face > 0 ? (GLuint)(uintptr)bitmap.driverData : 0;
+ int target = cubeMapFace ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
+ if(!capabilities.nonPow2Textures)
{
w = pow2i(w);
h = pow2i(h);
// Switch ARGB to RGBA
//if(bitmap.format != pixelFormatRGBA)
{
- for(c=0; c<bitmap.size; c++)
+ int size = convBitmap.stride * convBitmap.height;
+ for(c = 0; c < size; c++)
{
// ((ColorRGBA *)bitmap.picture)[c] = ((ColorAlpha *)bitmap.picture)[c];
// TODO:
}
// convBitmap.pixelFormat = pixelFormat888;
+ if(cubeMapFace && oldStyleCubeMap)
+ {
+ if(face == 0 || face == 1 || face == 4 || face == 5)
+ {
+ uint w = convBitmap.width;
+ uint32 * tmp = new uint [convBitmap.width];
+ int x, y;
+ for(y = 0; y < convBitmap.height; y++)
+ {
+ uint32 * pic = (uint32 *)((byte *)convBitmap.picture + y * w * 4);
+ for(x = 0; x < w; x++)
+ tmp[x] = pic[w-1-x];
+ memcpy(pic, tmp, w*4);
+ }
+ delete tmp;
+ }
+ else if(face == 2 || face == 3)
+ {
+ int y;
+ Bitmap tmp { };
+ tmp.Allocate(null, convBitmap.width, convBitmap.height, 0, convBitmap.pixelFormat, false);
+ for(y = 0; y < convBitmap.height; y++)
+ {
+ memcpy(tmp.picture + convBitmap.width * 4 * y,
+ convBitmap.picture + (convBitmap.height-1-y) * convBitmap.width * 4,
+ convBitmap.width * 4);
+ }
+ memcpy(convBitmap.picture, tmp.picture, convBitmap.sizeBytes);
+ delete tmp;
+ }
+ }
+
glGetError();
- glGenTextures(1, &glBitmap);
+ if(!glBitmap)
+ glGenTextures(1, &glBitmap);
if(glBitmap == 0)
{
//int error = glGetError();
return false;
}
- glBindTexture(GL_TEXTURE_2D, glBitmap);
+ glBindTexture(target, glBitmap);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ //glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ //glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ //glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+#ifndef GL_TEXTURE_WRAP_R
+ #define GL_TEXTURE_WRAP_R 0x8072
+#endif
+
+#if !defined(__EMSCRIPTEN__)
+ if(cubeMapFace)
+ glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+#endif
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
#endif
-#if !defined(SHADERS)
+#if ENABLE_GL_FFP
+ if(!capabilities.shaders)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
#endif
if(mipMap.Allocate(null, w, h, w, convBitmap.pixelFormat, false))
{
Surface mipSurface = mipMap.GetSurface(0,0,null);
+ mipSurface.blend = false;
mipSurface.Filter(convBitmap, 0,0,0,0, w, h, convBitmap.width, convBitmap.height);
delete mipSurface;
}
//int width = 0;
glGetError();
// glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
- glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
+ glTexImage2D(cubeMapFace ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
//printf("Calling glTexImage2D\n");
//glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
//printf("width = %d (Should be %d, %d)\n", width, w, h);
FreeBitmap(displaySystem, bitmap);
else if(oglSystem.loadingFont)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
oglSystem.loadingFont = false;
}
}
bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
{
bool result = false;
+ OGLDisplay oglDisplay = display.driverData;
OGLSurface oglSurface = surface.driverData = OGLSurface { };
-
- //Logf("GetSurface\n");
-
if(oglSurface)
{
+ SETCAPS(oglDisplay.capabilities);
if(displayWidth != display.width || displayHeight != display.height)
{
displayWidth = display.width;
displayHeight = display.height;
glViewport(0,0,display.width,display.height);
- glLoadIdentity();
- glOrtho(0,display.width,display.height,0,0.0,1.0);
+ GLLoadIdentity();
+ GLOrtho(0,display.width,display.height,0,0.0,1.0);
}
surface.offset.x = x;
{
Box box;
- //Logf("Clip\n");
-
if(clip != null)
{
box = clip;
uint row;
glPixelStorei(GL_PACK_ALIGNMENT, 4);
+#if ENABLE_GL_LEGACY
glPixelStorei(GL_PACK_ROW_LENGTH, bitmap.stride);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+#endif
glReadPixels(x,display.height-h-y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, flippingBuffer);
// Need a flip...
{
OGLSurface oglSurface = surface.driverData;
- //Logf("SetForeground\n");
-
oglSurface.foreground[0] = color.color.r/255.0f;
oglSurface.foreground[1] = color.color.g/255.0f;
oglSurface.foreground[2] = color.color.b/255.0f;
{
OGLSurface oglSurface = surface.driverData;
- //Logf("SetBackground\n");
-
oglSurface.background[0] = color.color.r/255.0f;
oglSurface.background[1] = color.color.g/255.0f;
oglSurface.background[2] = color.color.b/255.0f;
void PutPixel(Display display, Surface surface,int x,int y)
{
OGLSurface oglSurface = surface.driverData;
-
- //Logf("PutPixel\n");
-
- glColor4fv(oglSurface.foreground);
- glBegin(GL_POINTS);
+ GLColor4fv(oglSurface.foreground);
+ GLBegin(GL_POINTS);
// glVertex2i(x+surface.offset.x, y+surface.offset.y);
- glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
-
- glEnd();
+ GLVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
+ GLEnd();
}
void DrawLine(Display display, Surface surface, int _x1, int _y1, int _x2, int _y2)
x2 += surface.offset.x;
y2 += surface.offset.y;
- //Logf("Line\n");
-
- glColor4fv(oglSurface.foreground);
- glBegin(GL_LINES);
-#if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
+ GLColor4fv(oglSurface.foreground);
+ GLBegin(GL_LINES);
if(stippleEnabled)
{
- glTexCoord2f(0.5f, 0);
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLTexCoord2f(Max(x2-x1, y2-y1) + 0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
}
else
-#endif
{
/*
- glVertex2i(x1, y1);
- glVertex2i(x2, y2);
+ GLVertex2i(x1, y1);
+ GLVertex2i(x2, y2);
*/
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
}
- glEnd();
+ GLEnd();
}
void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
x2 += surface.offset.x;
y2 += surface.offset.y;
- //Logf("Rectangle\n");
-
- glColor4fv(oglSurface.foreground);
-#if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
+ GLColor4fv(oglSurface.foreground);
if(stippleEnabled)
{
- glBegin(GL_LINES);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glTexCoord2f(y2-y1 + 0.5f, 0);
- glVertex2f(x1 + 0.5f, y2 + 0.5f);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x1 + 0.5f, y2 + 0.5f);
- glTexCoord2f(x2 - x1 + 0.5f, 0);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
- glTexCoord2f(y1 - y2 + 0.5f, 0);
- glVertex2f(x2 + 0.5f, y1 + 0.5f);
-
- glTexCoord2f(0.5f, 0);
- glVertex2f(x2 + 0.5f, y1 + 0.5f);
- glTexCoord2f(x1 - x2 + 0.5f, 0);
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLBegin(GL_LINES);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLTexCoord2f(y2-y1 + 0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y2 + 0.5f);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y2 + 0.5f);
+ GLTexCoord2f(x2 - x1 + 0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLTexCoord2f(y1 - y2 + 0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y1 + 0.5f);
+
+ GLTexCoord2f(0.5f, 0);
+ GLVertex2f(x2 + 0.5f, y1 + 0.5f);
+ GLTexCoord2f(x1 - x2 + 0.5f, 0);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
}
else
-#endif
{
- glBegin(GL_LINE_LOOP);
+ GLBegin(GL_LINE_LOOP);
/*
glVertex2i(x1, y1);
glVertex2i(x1, y2);
glVertex2i(x2, y2);
glVertex2i(x2, y1);
*/
- glVertex2f(x1 + 0.5f, y1 + 0.5f);
- glVertex2f(x1 + 0.5f, y2 + 0.5f);
- glVertex2f(x2 + 0.5f, y2 + 0.5f);
- glVertex2f(x2 + 0.5f, y1 + 0.5f);
+ GLVertex2f(x1 + 0.5f, y1 + 0.5f);
+ GLVertex2f(x1 + 0.5f, y2 + 0.5f);
+ GLVertex2f(x2 + 0.5f, y2 + 0.5f);
+ GLVertex2f(x2 + 0.5f, y1 + 0.5f);
}
- glEnd();
+ GLEnd();
}
void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
{
OGLSurface oglSurface = surface.driverData;
- //Logf("Area\n");
- glColor4fv(oglSurface.background);
+ GLColor4fv(oglSurface.background);
-#ifdef EM_MODE
- glBegin(GL_QUADS);
- glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
- glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
- glVertex2f(x2+surface.offset.x+1, y2+surface.offset.y+1);
- glVertex2f(x2+surface.offset.x+1, y1+surface.offset.y);
- glEnd();
-#else
- glRecti(x1+surface.offset.x, y1+surface.offset.y,
+ GLRecti(x1+surface.offset.x, y1+surface.offset.y,
x2+surface.offset.x + 1, y2+surface.offset.y + 1);
-#endif
/*
- glRectf(x1+surface.offset.x, y1+surface.offset.y,
+ GLRectf(x1+surface.offset.x, y1+surface.offset.y,
x2+surface.offset.x + 1, y2+surface.offset.y + 1);
*/
}
void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
{
OGLSurface oglSurface = surface.driverData;
+ GLuint tex = (GLuint)(uintptr)bitmap.driverData;
+ if(!tex) return;
if(!oglSurface.writingText)
{
// glTranslatef(-0.375f, -0.375f, 0.0f);
GLSetupTexturing(true);
- glColor4fv(oglSurface.bitmapMult);
+ GLColor4fv(oglSurface.bitmapMult);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ GLBegin(GLIMTKMode::quads);
+ }
+ else if(lastBlitTex != tex)
+ {
+ if(lastBlitTex)
+ GLEnd();
+ glBindTexture(GL_TEXTURE_2D, tex);
+ GLBegin(GLIMTKMode::quads);
+ lastBlitTex = tex;
}
- else if(oglSurface.xOffset)
- glTranslated(oglSurface.xOffset / 64.0/*-0.375*/, 0.0, 0.0);
-
- glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
- glBegin(GLIMTKMode::quads);
if(h < 0)
{
- glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
- glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
}
else
{
/*
- glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
- glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
*/
- glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
- glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
- glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
- glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
- glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
- glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
- glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
+ GLVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
+ GLTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
+ GLVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
}
- glEnd();
-
if(!oglSurface.writingText)
{
+ GLEnd();
GLSetupTexturing(false);
-
//glTranslate(0.375, 0.375, 0.0);
}
- else if(oglSurface.xOffset)
- glTranslated(-oglSurface.xOffset / 64.0/*+0.375*/, 0.0, 0.0);
}
void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
GLSetupTexturing(true);
glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
- glColor4fv(oglSurface.bitmapMult);
+ GLColor4fv(oglSurface.bitmapMult);
- glBegin(GLIMTKMode::quads);
+ GLBegin(GLIMTKMode::quads);
if(h < 0)
{
- glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
- glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
+ GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
}
else
{
- glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
- glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
- glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
- glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
+ GLTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
+ GLVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
}
- glEnd();
+ GLEnd();
GLSetupTexturing(false);
void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
{
-#if !defined(EM_MODE)
float s2dw,s2dh,d2sw,d2sh;
//bool flipX = false, flipY = false;
- //Logf("StretchDI\n");
-
if(Sgn(w) != Sgn(sw))
{
w = Abs(w);
if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
-#if !defined(SHADERS)
- glRasterPos2d(dx,dy);
- //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
- glPixelZoom(s2dw, -s2dh);
- glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
+ glRasterPos2d(dx,dy);
+ //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
+ glPixelZoom(s2dw, -s2dh);
+ glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ }
#endif
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
}
-#endif
}
void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
{
-#if !defined(EM_MODE)
- //Logf("BlitDI\n");
-
//Clip against the edges of the source
if(sx<0)
{
if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
-#if !defined(SHADERS)
- glRasterPos2d(dx,dy);
- glPixelZoom(1,-1);
- glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
+ glRasterPos2d(dx,dy);
+ glPixelZoom(1,-1);
+ glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ }
#endif
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
}
-#endif
}
void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
{
- OGLSurface oglSurface = surface.driverData;
- OGLSystem oglSystem = display.displaySystem.driverData;
- oglSystem.loadingFont = true;
+ if(len && text[0] && surface.font)
+ {
+ OGLSurface oglSurface = surface.driverData;
+ OGLSystem oglSystem = display.displaySystem.driverData;
+ oglSystem.loadingFont = true;
+
+ //glTranslated(-0.375, -0.375, 0.0);
- //glTranslated(-0.375, -0.375, 0.0);
+ if(surface.textOpacity)
+ {
+ int w = 0, h, adv = 0;
+ FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
+ w += adv;
+ display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
+ }
- //Logf("Blit\n");
+ oglSurface.writingText = true;
- if(surface.textOpacity)
- {
- int w, h, adv;
- FontExtent(display.displaySystem, surface.font, text, len, &w, &h, 0, null, &adv);
- w += adv;
- display.displaySystem.driver.Area(display, surface,x,y,x+w-1,y+h-1);
- }
+ GLSetupTexturing(true);
- oglSurface.writingText = true;
+ x <<= 6;
+ if(surface.font.outlineSize)
+ {
+ ColorAlpha outlineColor = surface.outlineColor;
+ int fx = x;
+
+ GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
+ oglSurface.writingOutline = true;
+ lastBlitTex = 0;
+ oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &fx, y, prevGlyph, rPrevGlyph, null);
+ if(lastBlitTex) GLEnd();
+ oglSurface.writingOutline = false;
+ }
+ GLColor4fv(oglSurface.foreground);
- GLSetupTexturing(true);
+ lastBlitTex = 0;
+ oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &x, y, prevGlyph, rPrevGlyph, null);
- if(surface.font.outlineSize)
- {
- ColorAlpha outlineColor = surface.outlineColor;
- glColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
- oglSurface.writingOutline = true;
- ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
- oglSurface.writingOutline = false;
- }
- glColor4fv(oglSurface.foreground);
+ if(lastBlitTex) GLEnd();
+ lastBlitTex = 0;
- ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
- oglSurface.writingText = false;
- oglSystem.loadingFont = false;
+ oglSurface.writingText = false;
+ oglSystem.loadingFont = false;
- GLSetupTexturing(false);
+ GLSetupTexturing(false);
- //glTranslated(0.375, 0.375, 0.0);
+ //glTranslated(0.375, 0.375, 0.0);
+ }
}
void TextFont(Display display, Surface surface, Font font)
void LineStipple(Display display, Surface surface, uint32 stipple)
{
- //Logf("Stipple\n");
-
if(stipple)
{
-#if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
- stippleEnabled = true;
- glesLineStipple(1, (uint16)stipple);
-#else
- glLineStipple(1, (uint16)stipple);
- glEnable(GL_LINE_STIPPLE);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ {
+ glLineStipple(1, (uint16)stipple);
+ glEnable(GL_LINE_STIPPLE);
+ }
+ else
#endif
+ {
+ stippleEnabled = true;
+ glsupLineStipple(1, (uint16)stipple);
+ }
}
else
{
-#if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
- stippleEnabled = false;
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(MatrixMode::projection);
- GLSetupTexturing(false); // TODO: Special shading code for stipple?
-#else
- glDisable(GL_LINE_STIPPLE);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ glDisable(GL_LINE_STIPPLE);
+ else
#endif
+ {
+ stippleEnabled = false;
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
+ GLMatrixMode(MatrixMode::projection);
+ GLSetupTexturing(false); // TODO: Special shading code for stipple?
+ }
}
}
+#if ENABLE_GL_FFP
+ void ::disableRemainingTMUs(Display display, int lastTMU)
+ {
+ OGLDisplay oglDisplay = display.driverData;
+ int t;
+ for(t = lastTMU; t < oglDisplay.maxTMU; t++)
+ {
+ glActiveTexture(GL_TEXTURE0 + t);
+ glClientActiveTexture(GL_TEXTURE0 + t);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ GLDisableClientState(TEXCOORDS);
+ }
+ glActiveTexture(GL_TEXTURE0);
+ glClientActiveTexture(GL_TEXTURE0);
+ oglDisplay.maxTMU = lastTMU;
+ }
+#endif
+
#if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
void SetRenderState(Display display, RenderState state, uint value)
{
OGLDisplay oglDisplay = display.driverData;
- //Logf("RenderState\n");
-
switch(state)
{
case antiAlias:
+#ifndef __EMSCRIPTEN__
if(value)
- glEnable(GL_MULTISAMPLE_ARB);
+ glEnable(GL_MULTISAMPLE);
else
- glDisable(GL_MULTISAMPLE_ARB);
+ glDisable(GL_MULTISAMPLE);
+#endif
break;
case fillMode:
-#if !defined(ES1_1)
- glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
+#if ENABLE_GL_LEGACY
+ if(glCaps_legacy)
+ glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
#endif
break;
case depthTest:
break;
case fogColor:
{
-#if !defined(SHADERS)
float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
- glFogfv(GL_FOG_COLOR, (float *)&color);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setFogColor(color[0], color[1], color[2]);
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glFogfv(GL_FOG_COLOR, (float *)&color);
#endif
break;
}
case fogDensity:
-#if !defined(SHADERS)
- glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setFogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
#endif
break;
case blend:
+//#if !defined(__EMSCRIPTEN__)
if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
+//#endif
break;
case ambient:
{
-#if !defined(EM_MODE) && !defined(SHADERS)
- float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+ }
#endif
break;
}
case vSync:
{
#if defined(__WIN32__)
- wglSwapIntervalEXT(value ? 1 : 0);
+ if(wglSwapIntervalEXT)
+ wglSwapIntervalEXT(value ? 1 : 0);
#endif
break;
}
void SetLight(Display display, int id, Light light)
{
-#if !defined(EM_MODE) && !defined(SHADERS)
- //Logf("SetLight\n");
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.setLight(display, id, light);
+#endif
- if(light != null)
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- Object lightObject = light.lightObject;
- float position[4] = { 0, 0, 0, 0 };
- float color[4] = { 0, 0, 0, 1 };
+ if(light != null && !light.flags.off)
+ {
+ Object lightObject = light.lightObject;
+ float position[4] = { 0, 0, 0, 0 };
+ float color[4] = { 0, 0, 0, 1 };
+ Vector3D l;
- glEnable(GL_LIGHT0 + id);
- /*
- glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, (float *)&light.diffuse);
- glLightfv(GL_LIGHT0 + id, GL_AMBIENT, (float *)&light.ambient);
- glLightfv(GL_LIGHT0 + id, GL_SPECULAR,(float *)&light.specular);
- */
+ glEnable(GL_LIGHT0 + id);
- if(!light.multiplier) light.multiplier = 1.0f;
+ if(!light.multiplier) light.multiplier = 1.0f;
- color[0] = light.diffuse.r * light.multiplier;
- color[1] = light.diffuse.g * light.multiplier;
- color[2] = light.diffuse.b * light.multiplier;
- glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
+ GLFlushMatrices();
- color[0] = light.ambient.r * light.multiplier;
- color[1] = light.ambient.g * light.multiplier;
- color[2] = light.ambient.b * light.multiplier;
- glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
- color[0] = light.specular.r * light.multiplier;
- color[1] = light.specular.g * light.multiplier;
- color[2] = light.specular.b * light.multiplier;
- glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
+ color[0] = light.diffuse.r * light.multiplier;
+ color[1] = light.diffuse.g * light.multiplier;
+ color[2] = light.diffuse.b * light.multiplier;
+ glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
- if(lightObject)
- {
- Vector3D positionVector;
- if(light.flags.spot)
+ color[0] = light.ambient.r * light.multiplier;
+ color[1] = light.ambient.g * light.multiplier;
+ color[2] = light.ambient.b * light.multiplier;
+ glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
+
+ color[0] = light.specular.r * light.multiplier;
+ color[1] = light.specular.g * light.multiplier;
+ color[2] = light.specular.b * light.multiplier;
+ glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
+
+ if(lightObject)
{
- if(lightObject.flags.root || !lightObject.parent)
+ // Positional Lights, including Spot Lights (and omni light with flags.spot not set)
+ Matrix * mat = &lightObject.matrix;
+ l = { mat->m[3][0], mat->m[3][1], mat->m[3][2] };
+ if(display.display3D && display.display3D.camera)
+ l.Subtract(l, display.display3D.camera.cPosition);
+
+ position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 1;
+
+ if(light.flags.attenuation)
{
- positionVector = lightObject.transform.position;
- positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
+ glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
+ glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
+ glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
}
else
{
- positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
- if(display.display3D.camera)
- positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
+ glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, 1);
+ glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, 0);
+ glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, 0);
}
- position[3] = 1;
- }
- else
- {
- if(!light.direction.x && !light.direction.y && !light.direction.z)
+
+ if((light.flags.spot && light.fallOff < 360) || (lightObject && (light.direction.x || light.direction.y || light.direction.z)))
{
- Vector3Df vector { 0,0,-1 };
- Matrix mat;
- mat.RotationQuaternion(light.orientation);
- positionVector.MultMatrixf(vector, mat);
+ // Figure out exponent out of the hot spot
+ #define MAXLIGHT 0.9
+ float exponent = light.flags.spot ? (float)(log(MAXLIGHT) / log(cos(light.hotSpot / 2))) : 1;
+ Degrees cutOff = light.flags.spot ? light.fallOff/2 : 90;
+ float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
+
+ glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)cutOff);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
}
else
{
- positionVector = light.direction;
- position[3] = 1;
+ float d[4] = { 0, 0, 1, 0 };
+ glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, d);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, 180);
+ glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, 1);
}
- }
- position[0] = (float)positionVector.x;
- position[1] = (float)positionVector.y;
- position[2] = (float)positionVector.z;
-
- glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
+ /*
+ if(lightObject)
+ {
+ // Display Light Position
+ glDisable(GL_LIGHTING);
+ glDisable(GL_DEPTH_TEST);
+ glColor3f(1,1,1);
+ glPointSize(10);
+ glBegin(GL_POINTS);
+ glVertex3fv(position);
+ glEnd();
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+
+
+ // Display Target
+ if(lightObject.flags.root || !lightObject.parent)
+ {
+ positionVector = light.target.transform.position;
+ positionVector.Subtract(positionVector, display.camera.cPosition);
+ }
+ else
+ {
+ positionVector.MultMatrix(light.target.transform.position,
+ lightObject.light.target.parent.matrix);
+ positionVector.Subtract(positionVector, display.camera.cPosition);
+ }
- /*
- // Display Light Position
- glDisable(GL_LIGHTING);
- glDisable(GL_DEPTH_TEST);
- glColor3f(1,1,1);
- glPointSize(10);
- glBegin(GL_POINTS);
- glVertex3fv(position);
- glEnd();
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
-
-
- // Display Target
- if(lightObject.flags.root || !lightObject.parent)
- {
- positionVector = light.target.transform.position;
- positionVector.Subtract(positionVector, display.camera.cPosition);
+ position[0] = positionVector.x;
+ position[1] = positionVector.y;
+ position[2] = positionVector.z;
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_DEPTH_TEST);
+ glColor3f(1,1,0);
+ glPointSize(10);
+ glBegin(GL_POINTS);
+ glVertex3fv(position);
+ glEnd();
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+ }
+ */
}
else
{
- positionVector.MultMatrix(light.target.transform.position,
- lightObject.light.target.parent.matrix);
- positionVector.Subtract(positionVector, display.camera.cPosition);
- }
-
- position[0] = positionVector.x;
- position[1] = positionVector.y;
- position[2] = positionVector.z;
-
- glDisable(GL_LIGHTING);
- glDisable(GL_DEPTH_TEST);
- glColor3f(1,1,0);
- glPointSize(10);
- glBegin(GL_POINTS);
- glVertex3fv(position);
- glEnd();
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- */
-
- if(light.flags.attenuation)
- {
- glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
- glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
- glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
+ // Directional Light
+ Vector3D vector { 0,0,-1 };
+ Vector3D direction;
+ Matrix mat;
+ mat.RotationQuaternion(light.orientation);
+ direction.MultMatrix(vector, mat);
+ l.Normalize(direction);
+ position[0] = (float)l.x, position[1] = (float)l.y, position[2] = (float)l.z, position[3] = 0;
}
-
- if(light.flags.spot)
+ glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
+ if(display.display3D)
{
- float exponent = 0;
- #define MAXLIGHT 0.9
- float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
- // Figure out exponent out of the hot spot
- exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
-
- glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
- glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
- glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
+ Matrix m;
+ Vector3Df v { position[0], position[1], position[2] };
+ Vector3Df l;
+ float * lp = display.display3D.light0Pos;
+ if(display.display3D.camera)
+ m = display.display3D.camera.viewMatrix;
+ else
+ m.Identity();
+ l.MultMatrix(v, m);
+ lp[0] = l.x;
+ lp[1] =-l.y;
+ lp[2] =-l.z;
+ lp[3] = position[3];
}
}
else
- {
-
- Vector3Df vector { 0,0,-1 };
- Vector3Df direction;
- Matrix mat;
-
- mat.RotationQuaternion(light.orientation);
- direction.MultMatrix(vector, mat);
-
- position[0] = direction.x;
- position[1] = direction.y;
- position[2] = direction.z;
-
- glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
- }
+ glDisable(GL_LIGHT0 + id);
}
- else
- glDisable(GL_LIGHT0 + id);
#endif
}
void SetCamera(Display display, Surface surface, Camera camera)
{
OGLDisplay oglDisplay = display.driverData;
- //Logf("SetCamera\n");
if(surface && camera)
{
// *** ViewPort ***
glViewport(x, y, w, h);
+ GLMatrixMode(MatrixMode::texture);
+ if(!display.display3D.camera)
+ GLPushMatrix();
+ GLLoadIdentity();
+
// *** Projection Matrix ***
- glMatrixMode(MatrixMode::projection);
+ GLMatrixMode(MatrixMode::projection);
if(!display.display3D.camera)
- glPushMatrix();
+ GLPushMatrix();
if(display.display3D.collectingHits)
{
(h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
}
};
- glLoadMatrixd(pickMatrix.array);
+ GLLoadMatrixd(pickMatrix.array);
}
else
- glLoadIdentity();
- glFrustum(
+ GLLoadIdentity();
+ GLFrustum(
(left - origX) * camera.zMin / camera.focalX,
(right - origX) * camera.zMin / camera.focalX,
(bottom - origY) * camera.zMin / camera.focalY,
glDisable(GL_BLEND);
// *** Z Inverted Identity Matrix ***
- glMatrixMode(MatrixMode::modelView);
+ GLMatrixMode(MatrixMode::modelView);
if(!display.display3D.camera)
- glPushMatrix();
+ GLPushMatrix();
- glLoadIdentity();
+ GLLoadIdentity();
- glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
+ GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
// *** View Matrix ***
- glMultMatrixd(camera.viewMatrix.array);
+ GLMultMatrixd(camera.viewMatrix.array);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ defaultShader.select();
+ defaultShader.setCamera(camera);
+ }
+#endif
// *** Lights ***
// ...
glEnable(GL_DEPTH_TEST);
-#if !defined(EM_MODE) && !defined(SHADERS)
- glEnable(GL_LIGHTING);
- glShadeModel(GL_SMOOTH);
+ GLSetupLighting(true);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glShadeModel(GL_SMOOTH);
#endif
glDepthMask((byte)bool::true);
oglDisplay.depthWrite = true;
- glEnable(GL_MULTISAMPLE_ARB);
+#ifndef __EMSCRIPTEN__
+ glEnable(GL_MULTISAMPLE);
+#endif
}
else if(surface && display.display3D.camera)
{
+ nearPlane = 1;
oglDisplay.depthWrite = false;
glViewport(0,0,display.width,display.height);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
- GLSetupTexturing(false);
-#if !defined(EM_MODE) && !defined(SHADERS)
- glDisable(GL_LIGHTING);
- glDisable(GL_FOG);
- glShadeModel(GL_FLAT);
+
+ GLDisableClientState(COLORS);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ GLDisableClientState(TANGENTS1);
+ GLDisableClientState(TANGENTS2);
+ }
+#endif
+ GLDisableClientState(NORMALS);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ GLDisableClientState(LIGHTVECTORS);
#endif
- glEnable(GL_BLEND);
- glDisable(GL_MULTISAMPLE_ARB);
// *** Restore 2D MODELVIEW Matrix ***
- glPopMatrix();
+ GLMatrixMode(MatrixMode::modelView);
+ GLPopMatrix();
+
+ // *** Restore 2D TEXTURE Matrix ***
+ GLMatrixMode(MatrixMode::texture);
+ GLPopMatrix();
// *** Restore 2D PROJECTION Matrix ***
- glMatrixMode(MatrixMode::projection);
- glPopMatrix();
- }
+ GLMatrixMode(MatrixMode::projection);
+ GLPopMatrix();
+
+ // NOTE: We expect the 2D projection matrix to be the active one for GetSurface to call glOrtho()
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ defaultShader.select();
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ disableRemainingTMUs(display, 0);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ #if _GLES
+ glDisable(GL_TEXTURE_GEN_STR);
+ #else
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ #endif
+ }
+#endif
+
+ GLSetupTexturing(false);
+ GLSetupLighting(false);
+ GLSetupFog(false);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ defaultShader.setPerVertexColor(false);
+ defaultShader.setMaterial(null, 0);
+ }
+#endif
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ glShadeModel(GL_FLAT);
+#endif
+ glEnable(GL_BLEND);
+#if !defined(__EMSCRIPTEN__)
+ glDisable(GL_MULTISAMPLE);
+#endif
+ }
}
void ApplyMaterial(Display display, Material material, Mesh mesh)
{
- //Logf("ApplyMaterial\n");
+ Shader shader = material.shader ? material.shader : defaultShader;
+ MaterialFlags flags = material.flags;
+#if ENABLE_GL_FFP
+ static int lastSeparate = 0;
+ int tmu = 0;
+ bool normalMapped = false;
+ OGLMesh oglMesh = mesh ? mesh.data : null;
+#endif
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders && shader)
+ shader.select();
+#endif
// Basic Properties
- if(material.flags.doubleSided)
+ if(flags.doubleSided)
{
-#if !defined(EM_MODE) && !defined(SHADERS)
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !flags.singleSideLight);
#endif
glDisable(GL_CULL_FACE);
}
else
{
-#if !defined(EM_MODE) && !defined(SHADERS)
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
#endif
glEnable(GL_CULL_FACE);
}
-#if !defined(SHADERS)
// Fog
- if(material.flags.noFog)
- glDisable(GL_FOG);
- else
- glEnable(GL_FOG);
+ GLSetupFog(!flags.noFog);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ activeShader.setMaterial(material, mesh.flags);
#endif
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ if(material.bumpMap && mesh.lightVectors)
+ {
+ float color[4] = { 1,1,1,1 };
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ glEnable(GL_TEXTURE_2D);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ if(0) //((DefaultShaderBits)defaultShader.state).debugging)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+ }
+
+ #if _GLES
+ glDisable(GL_TEXTURE_GEN_STR);
+ #else
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ #endif
+ glDisable(GL_LIGHTING);
+ lightingEnabled = false;
+
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
+ if(material.uScale && material.vScale)
+ GLScalef(material.uScale, material.vScale, 1);
+ GLMatrixMode(MatrixMode::modelView);
+
+ if(flags.tile)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu);
+
+ normalMapped = true;
+
+ // Modulate base color
+ if(material.diffuse.r < 1 || material.diffuse.g < 1 || material.diffuse.b < 1)
+ {
+ tmu++;
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ color[0] = material.diffuse.r, color[1] = material.diffuse.g, color[2] = material.diffuse.b, color[3] = 1.0;
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu);
+ }
+
+ // Add ambient light
+ {
+ ColorRGB ambient { material.ambient.r * 0.2f, material.ambient.g * 0.2f, material.ambient.g * 0.2f };
+ if(ambient.r > 0 || ambient.g > 0 || ambient.b > 0)
+ {
+ tmu++;
+ glDisable(GL_TEXTURE_CUBE_MAP);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)material.bumpMap.driverData);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ color[0] = ambient.r, color[1] = ambient.g, color[2] = ambient.b, color[3] = 1.0;
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu);
+ }
+ }
+ }
+ else
+ {
+ GLDisableClientState(LIGHTVECTORS);
+ if(!lightingEnabled)
+ {
+ glEnable(GL_LIGHTING);
+ lightingEnabled = true;
+ }
+ }
+ }
+#endif
// Maps
- if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
+ if(flags.cubeMap || (material.baseMap && (mesh.texCoords || mesh.flags.texCoords1)))
{
Bitmap map = material.baseMap;
- GLSetupTexturing(true);
- glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
+ int diffuseTarget = flags.cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- if(material.uScale && material.vScale)
- glScalef(material.uScale, material.vScale, 1);
- glMatrixMode(MatrixMode::modelView);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glEnable(diffuseTarget);
+ glDisable(flags.cubeMap ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP);
+ }
+#endif
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders && !flags.cubeMap)
+ GLSetupTexturing(true);
+#endif
+
+ glBindTexture(diffuseTarget, (GLuint)(uintptr)map.driverData);
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ /* // This did not have the desired effect with a GL_ALPHA texture
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+ */
+
+ if(flags.cubeMap)
+ {
+ #if _GLES
+ glEnable(GL_TEXTURE_GEN_STR);
+ // GL_OBJECT_LINEAR: No extension support?
+ // glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ #else
+ GLfloat xPlane[] = { 1.0f, 0.0f, 0.0f, 0 };
+ GLfloat yPlane[] = { 0.0f,-1.0f, 0.0f, 0 };
+ GLfloat zPlane[] = { 0.0f, 0.0f,-1.0f, 0 };
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_R, GL_OBJECT_PLANE, zPlane);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, xPlane);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, yPlane);
+
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ #endif
+
+ GLDisableClientState(TEXCOORDS);
+ }
+ else
+ {
+ #if _GLES
+ glDisable(GL_TEXTURE_GEN_STR);
+ #else
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ #endif
- if(material.flags.tile)
+ if(tmu > 1)
+ oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
+ GLEnableClientState(TEXCOORDS);
+ }
+ glClientActiveTexture(GL_TEXTURE0);
+ }
+#endif
+ if(flags.tile)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
else
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
else
+ {
GLSetupTexturing(false);
+ }
-#if defined(EM_MODE) || defined(SHADERS)
- glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
-#else
- if(mesh.flags.colors)
+#if ENABLE_GL_FFP && !defined(_GLES)
+ if(!glCaps_shaders)
{
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
+ int separate = material.flags.separateSpecular ? GL_SEPARATE_SPECULAR_COLOR : GL_SINGLE_COLOR;
+ if(separate != lastSeparate)
+ {
+ GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, separate);
+ lastSeparate = separate;
+ }
}
- else
+#endif
+
+ if((flags.cubeMap && material.baseMap) ||
+ (mesh.texCoords && (material.baseMap || material.bumpMap || material.specularMap || material.reflectMap)))
{
- glDisable(GL_COLOR_MATERIAL);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
+ glActiveTexture(GL_TEXTURE0 + tmu - 1);
+ glClientActiveTexture(GL_TEXTURE0 + tmu - 1);
}
+#endif
+ GLMatrixMode(GL_TEXTURE);
+ GLLoadIdentity();
+ if(material.uScale && material.vScale)
+ GLScalef(material.uScale, material.vScale, 1);
+ GLMatrixMode(MatrixMode::modelView);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
+ glActiveTexture(GL_TEXTURE0);
+ glClientActiveTexture(GL_TEXTURE0);
}
+#endif
}
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
+ if(material.envMap && material.refractiveIndex)
+ {
+ float color[4] = { material.opacity, material.opacity, material.opacity, 1.0 };
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
+ glEnable(GL_TEXTURE_CUBE_MAP);
+ #if _GLES
+ glEnable(GL_TEXTURE_GEN_STR);
+ glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ #else
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ #endif
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ if(normalMapped)
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ else
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ if(!normalMapped)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
+ }
+
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+
+ GLMatrixMode(MatrixMode::texture);
+ {
+ double * s = display.display3D.camera.viewMatrix.array;
+ double k = 2.0;
+ Matrix m
+ { {
+ k*s[0],-k*s[4],-k*s[8], 0,
+ k*s[1],-k*s[5],-k*s[9], 0,
+ k*s[2],-k*s[6],-k*s[10],0,
+ 0,0,0,1
+ } };
+ GLLoadMatrixd(m.array);
+ }
+ GLMatrixMode(MatrixMode::modelView);
+ }
+
+ if(material.envMap && material.reflectivity)
+ {
+ float color[4] = { 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0f - material.reflectivity, 1.0 };
+ glActiveTexture(GL_TEXTURE0 + tmu);
+ glClientActiveTexture(GL_TEXTURE0 + tmu++);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, (GLuint)(uintptr)material.envMap.driverData);
+ glEnable(GL_TEXTURE_CUBE_MAP);
+ #if _GLES
+ glEnable(GL_TEXTURE_GEN_STR);
+ glTexGeni(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ #else
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ #endif
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ if(normalMapped)
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ else
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ if(!normalMapped)
+ {
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
+ }
+
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
+
+ GLMatrixMode(MatrixMode::texture);
+ {
+ double * s = display.display3D.camera.inverseTranspose.array;
+ Matrix m
+ { {
+ s[0],s[1],-s[2],0,
+ s[4],-s[5],-s[6],0,
+ -s[8],s[9],s[10],0,
+ 0,0,0,1
+ } };
+ GLLoadMatrixd(m.array);
+ }
+ GLMatrixMode(MatrixMode::modelView);
+ }
}
+#endif
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
{
- float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
- }
+ disableRemainingTMUs(display, tmu);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
+ if(mesh.flags.colors)
+ {
+ GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ }
+ else
+ {
+ glDisable(GL_COLOR_MATERIAL);
+ {
+ float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
+ }
+ {
+ float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
+ }
+ }
+ if(material.power > 0.1)
+ {
+ float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
+ }
+ else
+ {
+ float color[4] = { 0,0,0,0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
+ }
+ {
+ float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
+ }
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
+ }
#endif
}
OGLMesh oglMesh = mesh.data;
if(oglMesh)
{
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
+
if(!mesh.flags.vertices)
{
oglMesh.vertices.free();
oglMesh.normals.free();
delete mesh.normals;
}
+ if(!mesh.flags.tangents)
+ {
+ oglMesh.tangents.free();
+ delete mesh.tangents;
+ }
+ if(!mesh.flags.lightVectors)
+ {
+ oglMesh.lightVectors.free();
+ delete mesh.lightVectors;
+ }
if(!mesh.flags.texCoords1)
{
oglMesh.texCoords.free();
delete oglMesh;
mesh.data = null;
}
+ SETCAPS(caps);
}
}
else
mesh.normals = new Vector3Df[nVertices];
}
+ if(!mesh.flags.tangents && flags.tangents)
+ {
+ mesh.tangents = new Vector3Df[2*nVertices];
+ }
+ if(!mesh.flags.lightVectors && flags.lightVectors)
+ {
+ mesh.lightVectors = new ColorRGB[nVertices];
+ }
if(!mesh.flags.texCoords1 && flags.texCoords1)
{
mesh.texCoords = new Pointf[nVertices];
{
mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
}
+ if(flags.tangents)
+ {
+ mesh.tangents = renew mesh.tangents Vector3Df[2 * nVertices];
+ }
+ if(flags.lightVectors)
+ {
+ mesh.lightVectors = renew mesh.lightVectors ColorRGB[nVertices];
+ }
}
result = true;
}
void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
{
- OGLMesh oglMesh = mesh.data;
- if(!flags) flags = mesh.flags;
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
- if(vboAvailable)
+ if(glCaps_vertexBuffer)
{
+ OGLMesh oglMesh = mesh.data;
+ if(!flags) flags = mesh.flags;
if(flags.vertices)
- oglMesh.vertices.upload(
- mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices); //, GL_STATIC_DRAW_ARB );
+ oglMesh.vertices.allocate(
+ mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, staticDraw);
if(flags.normals)
- oglMesh.normals.upload(
- mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals); //, GL_STATIC_DRAW_ARB );
+ oglMesh.normals.allocate(
+ mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, staticDraw);
if(flags.texCoords1)
- oglMesh.texCoords.upload(
- mesh.nVertices * sizeof(Pointf), mesh.texCoords); //, GL_STATIC_DRAW_ARB );
+ oglMesh.texCoords.allocate(
+ mesh.nVertices * sizeof(Pointf), mesh.texCoords, staticDraw);
if(flags.colors)
- oglMesh.colors.upload(
- mesh.nVertices * sizeof(ColorRGBAf), mesh.colors); //, GL_STATIC_DRAW_ARB );
+ oglMesh.colors.allocate(
+ mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, staticDraw);
+
+ if(flags.tangents)
+ oglMesh.tangents.allocate(mesh.nVertices * 2*sizeof(Vector3Df), mesh.tangents, staticDraw);
+
+ if(flags.lightVectors)
+ oglMesh.lightVectors.allocate(mesh.nVertices * sizeof(ColorRGB), mesh.lightVectors, staticDraw);
}
+ SETCAPS(caps);
}
bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
void FreeIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
{
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
+
if(oglIndices)
{
oglIndices.buffer.free();
delete oglIndices.indices;
delete oglIndices;
}
+ SETCAPS(caps);
}
void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
void UnlockIndices(DisplaySystem displaySystem, OGLIndices oglIndices, bool indices32bit, int nIndices)
{
- if(vboAvailable)
+ OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
+ SETCAPS(oglSystem.capabilities);
+
+ if(glCaps_vertexBuffer)
{
-#ifdef ES1_1
- if(indices32bit)
+ if(!glCaps_intAndDouble && indices32bit)
{
if(!oglIndices.buffer.buffer)
glGenBuffers(1, &oglIndices.buffer.buffer);
if(glabCurElementBuffer != oglIndices.buffer.buffer)
GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oglIndices.buffer.buffer);
- glimtkBufferDatai(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * nIndices, oglIndices.indices, GL_STATIC_DRAW_ARB);
+
+ {
+ uint * pointer = (uint *)oglIndices.indices;
+ int i;
+ uint16 * b;
+ if(nIndices > oglSystem.shortBDSize)
+ {
+ oglSystem.shortBDSize = nIndices;
+ oglSystem.shortBDBuffer = renew oglSystem.shortBDBuffer uint16[oglSystem.shortBDSize];
+ }
+ b = oglSystem.shortBDBuffer;
+ for(i = 0; i < nIndices; i++)
+ b[i] = (uint16)pointer[i];
+
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(uint16), b, GL_STATIC_DRAW);
+ }
}
else
-#endif
- oglIndices.buffer.upload(
- nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
- oglIndices.indices); //GL_STATIC_DRAW_ARB);
+ oglIndices.buffer.allocate(
+ nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
+ oglIndices.indices, staticDraw);
}
+ SETCAPS(caps);
}
uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
void SelectMesh(Display display, Mesh mesh)
{
- //Logf("SelectMesh\n");
-
#if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
-
#if defined(__WIN32__)
if(glUnlockArraysEXT)
#endif
- if(!vboAvailable && display.display3D.mesh)
+ if(!glCaps_vertexBuffer && display.display3D.mesh)
glUnlockArraysEXT();
-
#endif
if(mesh)
{
OGLMesh oglMesh = mesh.data;
// *** Vertex Stream ***
- glEnableClientState(GL_VERTEX_ARRAY);
+ GLEnableClientState(VERTICES);
if(!display.display3D.collectingHits && oglMesh)
{
oglMesh.vertices.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, oglMesh.vertices.buffer ? null : (double *)mesh.vertices);
// *** Normals Stream ***
if(mesh.normals || mesh.flags.normals)
{
- glEnableClientState(GL_NORMAL_ARRAY);
+ GLEnableClientState(NORMALS);
oglMesh.normals.use(normal, 3, GL_FLOAT, 0, oglMesh.normals.buffer ? null : mesh.normals);
}
else
- glDisableClientState(GL_NORMAL_ARRAY);
+ GLDisableClientState(NORMALS);
+
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ // *** Tangents Stream ***
+ if(mesh.tangents || mesh.flags.tangents)
+ {
+ GLEnableClientState(TANGENTS1);
+ GLEnableClientState(TANGENTS2);
+ oglMesh.tangents.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? null : mesh.tangents);
+ oglMesh.tangents.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, oglMesh.tangents.buffer ? (void *)sizeof(Vector3Df) : mesh.tangents+1);
+ }
+ else
+ {
+ GLDisableClientState(TANGENTS1);
+ GLDisableClientState(TANGENTS2);
+ }
+ }
+#endif
// *** Texture Coordinates Stream ***
if(mesh.texCoords || mesh.flags.texCoords1)
{
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ GLEnableClientState(TEXCOORDS);
oglMesh.texCoords.use(texCoord, 2, GL_FLOAT, 0, oglMesh.texCoords.buffer ? null : mesh.texCoords);
}
else
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ GLDisableClientState(TEXCOORDS);
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ // *** Normal Map Aligned Light Vector ***
+ if(mesh.lightVectors || mesh.flags.lightVectors)
+ {
+ GLEnableClientState(LIGHTVECTORS);
+ oglMesh.lightVectors.use(lightVector, 3, GL_FLOAT, 0, oglMesh.lightVectors.buffer ? null : mesh.lightVectors);
+ }
+ else
+ GLDisableClientState(LIGHTVECTORS);
+ }
+ else
+#endif
// *** Color Stream ***
if(mesh.colors || mesh.flags.colors)
{
- glEnableClientState(GL_COLOR_ARRAY);
+ GLEnableClientState(COLORS);
oglMesh.colors.use(color, 4, GL_FLOAT, 0, oglMesh.colors.buffer ? null : mesh.colors);
}
else
- glDisableClientState(GL_COLOR_ARRAY);
+ GLDisableClientState(COLORS);
}
else
{
noAB.use(vertex, 3, (mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT), 0, (double *)mesh.vertices);
if((mesh.normals || mesh.flags.normals) && !display.display3D.collectingHits)
{
- glEnableClientState(GL_NORMAL_ARRAY);
+ GLEnableClientState(NORMALS);
noAB.use(normal, 3, GL_FLOAT, 0, mesh.normals);
}
else
- glDisableClientState(GL_NORMAL_ARRAY);
+ GLDisableClientState(NORMALS);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ if((mesh.tangents || mesh.flags.tangents) && !display.display3D.collectingHits)
+ {
+ GLEnableClientState(TANGENTS1);
+ GLEnableClientState(TANGENTS2);
+ noAB.use(tangent1, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents);
+ noAB.use(tangent2, 3, GL_FLOAT, sizeof(Vector3Df)*2, mesh.tangents+1);
+ }
+ else
+ {
+ GLDisableClientState(TANGENTS1);
+ GLDisableClientState(TANGENTS2);
+ }
+ }
+#endif
+
if((mesh.texCoords || mesh.flags.texCoords1) && !display.display3D.collectingHits)
{
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ GLEnableClientState(TEXCOORDS);
noAB.use(texCoord, 2, GL_FLOAT, 0, mesh.texCoords);
}
else
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ GLDisableClientState(TEXCOORDS);
+
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ if((mesh.lightVectors || mesh.flags.lightVectors) && !display.display3D.collectingHits)
+ {
+ GLEnableClientState(LIGHTVECTORS);
+ noAB.use(lightVector, 3, GL_FLOAT, sizeof(ColorRGB), mesh.lightVectors);
+ }
+ else
+ GLDisableClientState(LIGHTVECTORS);
+ }
+ else
+#endif
if((mesh.colors || mesh.flags.colors) && !display.display3D.collectingHits)
{
- glEnableClientState(GL_COLOR_ARRAY);
+ GLEnableClientState(COLORS);
noAB.use(color, 4, GL_FLOAT, 0, mesh.colors);
}
else
- glDisableClientState(GL_COLOR_ARRAY);
+ GLDisableClientState(COLORS);
}
#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__ODROID__) && !defined(__EMSCRIPTEN__)
#if defined(__WIN32__)
if(glLockArraysEXT)
#endif
- if(!vboAvailable)
+ if(!glCaps_vertexBuffer)
glLockArraysEXT(0, mesh.nVertices);
-
#endif
}
}
void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
{
- //Logf("DrawPrimitives\n");
-
if(primitive->type.vertexRange)
- glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
+ {
+ GLFlushMatrices();
+ glDrawArrays(getPrimitiveType(primitive->type.primitiveType), primitive->first, primitive->nVertices);
+ }
else
{
- // *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
- // HACK TO SPEED THINGS UP...
-#ifndef __ANDROID__
- /*GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
+ OGLIndices oglIndices = primitive->data;
+ GLEAB eab = ((!display.display3D.collectingHits && oglIndices && glCaps_vertexBuffer) ? oglIndices.buffer : noEAB);
+ if(!glCaps_intAndDouble && !glCaps_vertexBuffer && primitive->type.indices32bit)
{
- int c;
- glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
- if(primitive->data)
- {
- OGLIndices oglIndices = primitive->data;
- MeshFeatures flags = mesh.flags;
- for(c = 0; c<primitive->nIndices; c++)
- {
- uint16 index = ((uint16 *) oglIndices.indices)[c];
- if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
- if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
- if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
- glVertex3fv((float *)&mesh.vertices[index]);
- }
- }
- glEnd();
+ uint16 * temp = new uint16[primitive->nIndices];
+ uint32 * src = (uint32 *)(oglIndices ? oglIndices.indices : primitive->indices);
+ int i;
+ for(i = 0; i < primitive->nIndices; i++)
+ temp[i] = (uint16)src[i];
+ eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices, GL_UNSIGNED_SHORT, temp);
+ delete temp;
}
- else*/
-#endif
-
- {
- OGLIndices oglIndices = primitive->data;
- GLEAB eab = ((!display.display3D.collectingHits && oglIndices) ? oglIndices.buffer : noEAB);
-
- eab.draw(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
+ else
+ eab.draw(getPrimitiveType(primitive->type.primitiveType), primitive->nIndices,
primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
eab.buffer ? 0 : (oglIndices ? oglIndices.indices : primitive->indices));
- GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
}
void PushMatrix(Display display)
{
- glPushMatrix();
+ GLPushMatrix();
}
void PopMatrix(Display display, bool setMatrix)
{
- glPopMatrix();
+ GLPopMatrix();
}
void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
if(viewSpace)
{
- glLoadIdentity();
- glScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
+ GLLoadIdentity();
+ GLScaled(1.0/nearPlane, 1.0/nearPlane, -1.0/nearPlane);
}
else if(camera)
{
- glTranslated(
+ GLTranslated(
matrix.m[3][0] - camera.cPosition.x,
matrix.m[3][1] - camera.cPosition.y,
matrix.m[3][2] - camera.cPosition.z);
}
else
- glTranslated(
+ GLTranslated(
matrix.m[3][0],
matrix.m[3][1],
matrix.m[3][2]);
matrix.m[3][1] = 0;
matrix.m[3][2] = 0;
- glMultMatrixd(matrix.array);
+ GLMultMatrixd(matrix.array);
}
#endif
}
#elif defined(__ANDROID__) || defined(__ODROID__)
return eglContext;
#elif defined(__EMSCRIPTEN__)
+ OGLSystem system = displaySystem.driverData;
+ return (void *)system.glc;
#else
OGLSystem system = displaySystem.driverData;
return system.glContext;