import "glab"
import "immediate"
import "matrixStack"
-import "shading"
+import "defaultShader"
namespace gfx::drivers;
{
#if ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_texturing(enable);
+ defaultShader.texturing(enable);
#endif
#if ENABLE_GL_FFP
{
#if ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_fog(enable);
+ defaultShader.fog(enable);
#endif
#if ENABLE_GL_FFP
lightingEnabled = enable;
#if ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_lighting(enable);
+ defaultShader.lighting(enable);
#endif
#if ENABLE_GL_FFP
/*static */GLuint lastBlitTex;
+Shader activeShader;
+
static int displayWidth, displayHeight;
#define GL_CLAMP_TO_EDGE 0x812F
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
-
- GLCapabilities capabilities, originalCapabilities;
- bool compat;
- int version;
-
- ColorAlpha * flippingBuffer;
- int flipBufH, flipBufW;
- bool depthWrite;
- int x, y;
- uint vao;
};
class OGLSystem : struct
{
int maxTextureSize;
bool loadingFont;
-#if ENABLE_GL_SHADERS
- int shadingProgram;
- int vertexShader;
- int fragmentShader;
-#endif
#if defined(__WIN32__)
PIXELFORMATDESCRIPTOR pfd;
int format;
{
GLAB vertices;
GLAB normals;
+ GLAB tangents;
+ GLAB lightVectors;
GLAB texCoords;
GLAB texCoords2;
GLAB colors;
{
GLCapabilities capabilities;
#if !defined(_GLES2)
- const char * extensions = (canCheckExtensions && oglDisplay.compat) ? (const char *)glGetString(GL_EXTENSIONS) : null;
+ const char * extensions = (canCheckExtensions && (!oglDisplay || oglDisplay.compat)) ? (const char *)glGetString(GL_EXTENSIONS) : null;
#endif
#ifdef DIAGNOSTICS
printf("extensions: %s\n", extensions);
vao = glBindVertexArray != null && !oglDisplay.compat;
#endif
#if ENABLE_GL_FBO
- shaders = glBindFramebuffer != null;
+ frameBuffer = glBindFramebuffer != null;
#endif
vertexBuffer = glBindBuffer != null;
// mapBuffer = glMapBuffer != null;
}
#if ENABLE_GL_SHADERS
- if(oglSystem.shadingProgram)
- glDeleteProgram(oglSystem.shadingProgram);
- if(oglSystem.fragmentShader)
- glDeleteShader(oglSystem.fragmentShader);
- if(oglSystem.vertexShader)
- glDeleteShader(oglSystem.vertexShader);
+ defaultShader.free();
+ activeShader = null;
#endif
delete oglSystem.shortBDBuffer;
XFree(oglSystem.visualInfo);
#endif
}
+ if(oglSystem.glContext)
+ glXDestroyContext(xGlobalDisplay, oglSystem.glContext);
if(oglSystem.glxDrawable)
{
if(loadExtensions && ogl_LoadFunctions() == ogl_LOAD_FAILED)
PrintLn("ogl_LoadFunctions() failed!");
CheckCapabilities(oglSystem, oglDisplay, canCheckExtensions);
- #ifdef GL_DEBUGGING
- if(oglDisplay.capabilities.debug)
- setupDebugging();
- #else
- oglDisplay.capabilities.debug = false;
- #endif
#endif
{
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)
{
glDisableClientState(GL_COLOR_ARRAY);
}
#endif
- loadShaders(display.displaySystem, "<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
+ defaultShader.select();
}
#if ENABLE_GL_LEGACY
else
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
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
#endif
GLABBindBuffer(GL_ARRAY_BUFFER, 0);
GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#if ENABLE_GL_SHADERS
+ activeProgram = 0;
+#endif
}
void EndUpdate(Display display)
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;
+ 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);
// 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(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ //glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ //glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#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(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;
}
}
void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
{
- if(len && text[0])
+ if(len && text[0] && surface.font)
{
OGLSurface oglSurface = surface.driverData;
OGLSystem oglSystem = display.displaySystem.driverData;
GLSetupTexturing(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;
- ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
+ 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);
lastBlitTex = 0;
- ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len, prevGlyph, rPrevGlyph);
+ oglSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &x, y, prevGlyph, rPrevGlyph, null);
+
if(lastBlitTex) GLEnd();
lastBlitTex = 0;
}
}
}
+#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)
float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
#if ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_fogColor(color[0], color[1], color[2]);
+ defaultShader.setFogColor(color[0], color[1], color[2]);
#endif
#if ENABLE_GL_FFP
case fogDensity:
#if ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_fogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
+ defaultShader.setFogDensity((float)(RenderStateFloat { ui = value }.f * nearPlane));
#endif
#if ENABLE_GL_FFP
{
#if ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_setGlobalAmbient(((Color)value).r / 255.0f, ((Color)value).g / 255.0f, ((Color)value).b / 255.0f, 1.0f);
+ 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 ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_setLight(display, id, light);
+ defaultShader.setLight(display, id, light);
#endif
#if ENABLE_GL_FFP
if(!light.multiplier) light.multiplier = 1.0f;
+ GLFlushMatrices();
+
color[0] = light.diffuse.r * light.multiplier;
color[1] = light.diffuse.g * light.multiplier;
color[2] = light.diffuse.b * light.multiplier;
// 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.camera)
+ 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;
- glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
if(light.flags.attenuation)
{
glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
}
+ else
+ {
+ glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, 1);
+ glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, 0);
+ glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, 0);
+ }
if((light.flags.spot && light.fallOff < 360) || (lightObject && (light.direction.x || light.direction.y || light.direction.z)))
{
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;
- glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
+ }
+ glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
+ if(display.display3D)
+ {
+ 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
// *** ViewPort ***
glViewport(x, y, w, h);
+ GLMatrixMode(MatrixMode::texture);
+ if(!display.display3D.camera)
+ GLPushMatrix();
+ GLLoadIdentity();
+
// *** Projection Matrix ***
GLMatrixMode(MatrixMode::projection);
if(!display.display3D.camera)
// *** View Matrix ***
GLMultMatrixd(camera.viewMatrix.array);
+#if ENABLE_GL_SHADERS
+ if(glCaps_shaders)
+ {
+ defaultShader.select();
+ defaultShader.setCamera(camera);
+ }
+#endif
+
// *** Lights ***
// ...
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
+ 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
+
+ // *** Restore 2D MODELVIEW Matrix ***
+ GLMatrixMode(MatrixMode::modelView);
+ GLPopMatrix();
+
+ // *** Restore 2D TEXTURE Matrix ***
+ GLMatrixMode(MatrixMode::texture);
+ GLPopMatrix();
+
+ // *** Restore 2D PROJECTION Matrix ***
+ 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);
- GLDisableClientState(COLORS);
-
#if ENABLE_GL_SHADERS
if(glCaps_shaders)
- shader_setPerVertexColor(false);
+ {
+ defaultShader.setPerVertexColor(false);
+ defaultShader.setMaterial(null, 0);
+ }
#endif
#if ENABLE_GL_FFP
#if !defined(__EMSCRIPTEN__)
glDisable(GL_MULTISAMPLE);
#endif
-
- // *** Restore 2D MODELVIEW Matrix ***
- GLPopMatrix();
-
- // *** Restore 2D PROJECTION Matrix ***
- GLMatrixMode(MatrixMode::projection);
- GLPopMatrix();
}
-
}
void ApplyMaterial(Display display, Material material, Mesh mesh)
{
+ 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 ENABLE_GL_FFP
if(!glCaps_shaders)
- GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
+ GLLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !flags.singleSideLight);
#endif
glDisable(GL_CULL_FACE);
}
}
// Fog
- GLSetupFog(!material.flags.noFog);
+ 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;
+
+#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(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(diffuseTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+ else
+ {
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(diffuseTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+ }
+ else
+ {
+ GLSetupTexturing(false);
+ }
+
+#if ENABLE_GL_FFP && !defined(_GLES)
+ if(!glCaps_shaders)
+ {
+ int separate = material.flags.separateSpecular ? GL_SEPARATE_SPECULAR_COLOR : GL_SINGLE_COLOR;
+ if(separate != lastSeparate)
+ {
+ GLLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, separate);
+ lastSeparate = separate;
+ }
+ }
+#endif
+ if((flags.cubeMap && material.baseMap) ||
+ (mesh.texCoords && (material.baseMap || material.bumpMap || material.specularMap || material.reflectMap)))
+ {
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ 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)
+ {
+ glActiveTexture(GL_TEXTURE0);
+ glClientActiveTexture(GL_TEXTURE0);
+ }
+#endif
+ }
- if(material.flags.tile)
+#if ENABLE_GL_FFP
+ if(!glCaps_shaders)
+ {
+ if(material.envMap && material.refractiveIndex)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ 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);
}
- else
+
+ if(material.envMap && material.reflectivity)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ 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);
}
}
- else
- GLSetupTexturing(false);
-
-#if ENABLE_GL_SHADERS
- if(glCaps_shaders)
- shader_setMaterial(material, mesh.flags.colors);
#endif
#if ENABLE_GL_FFP
if(!glCaps_shaders)
{
+ disableRemainingTMUs(display, tmu);
+
if(mesh.flags.colors)
{
GLColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
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
if(oglMesh)
{
OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
SETCAPS(oglSystem.capabilities);
+
if(!mesh.flags.vertices)
{
- oglMesh.vertices.free(glCaps_vertexBuffer);
+ oglMesh.vertices.free();
delete mesh.vertices;
}
if(!mesh.flags.normals)
{
- oglMesh.normals.free(glCaps_vertexBuffer);
+ 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(glCaps_vertexBuffer);
+ oglMesh.texCoords.free();
delete mesh.texCoords;
}
if(!mesh.flags.texCoords2)
{
- oglMesh.texCoords2.free(glCaps_vertexBuffer);
+ oglMesh.texCoords2.free();
// delete mesh.texCoords2;
}
if(!mesh.flags.colors)
{
- oglMesh.colors.free(glCaps_vertexBuffer);
+ oglMesh.colors.free();
delete mesh.colors;
}
if(!mesh.flags)
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)
{
OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
SETCAPS(oglSystem.capabilities);
+
if(glCaps_vertexBuffer)
{
OGLMesh oglMesh = mesh.data;
if(flags.colors)
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(glCaps_vertexBuffer);
+ 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)
{
OGLSystem oglSystem = displaySystem.driverData;
+ GLCapabilities caps = glCaps;
SETCAPS(oglSystem.capabilities);
+
if(glCaps_vertexBuffer)
{
if(!glCaps_intAndDouble && indices32bit)
nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
oglIndices.indices, staticDraw);
}
+ SETCAPS(caps);
}
uint16 * LockIndices(DisplaySystem displaySystem, OGLIndices oglIndices)
else
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)
{
else
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)
{
}
else
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(TEXCOORDS);
}
else
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(COLORS);