}
#endif
+static GLuint lastBlitTex;
+
static int displayWidth, displayHeight;
#define GL_CLAMP_TO_EDGE 0x812F
GLXDrawable glxDrawable;
#endif
GLCapabilities capabilities;
+
+ // Buffer Data
+ uint16 *shortBDBuffer;
+ uint shortBDSize;
};
class OGLSurface : struct
glDeleteShader(oglSystem.vertexShader);
#endif
+ delete oglSystem.shortBDBuffer;
glimtkTerminate();
#if defined(__WIN32__)
#if ENABLE_GL_SHADERS
if(glcaps_shaders)
+ {
+#if ENABLE_GL_LEGACY
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+#endif
loadShaders(display.displaySystem, "<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
+ }
#if ENABLE_GL_LEGACY
else
{
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);
+ 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);
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)
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])
+ {
+ 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);
- }
+ 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);
+ }
- oglSurface.writingText = true;
+ oglSurface.writingText = true;
- GLSetupTexturing(true);
+ GLSetupTexturing(true);
- if(surface.font.outlineSize)
- {
- ColorAlpha outlineColor = surface.outlineColor;
- GLColor4ub(outlineColor.color.r, outlineColor.color.g, outlineColor.color.b, outlineColor.a);
- oglSurface.writingOutline = true;
+ if(surface.font.outlineSize)
+ {
+ ColorAlpha outlineColor = surface.outlineColor;
+ 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);
+ 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.writingOutline = false;
- }
- GLColor4fv(oglSurface.foreground);
+ if(lastBlitTex) GLEnd();
- ((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)
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);
+ 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);
+ 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);
+ oglMesh.texCoords.allocate(
+ mesh.nVertices * sizeof(Pointf), mesh.texCoords, staticDraw);
if(flags.colors)
- oglMesh.colors.upload(
- mesh.nVertices * sizeof(ColorRGBAf), mesh.colors);
+ oglMesh.colors.allocate(
+ mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, staticDraw);
}
}
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);
+
+ {
+ 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(
+ oglIndices.buffer.allocate(
nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
- oglIndices.indices);
+ oglIndices.indices, staticDraw);
}
}
// Kept public for now
-// NOTE: Don't call if without vertexBuffer
public void GLABDeleteBuffers(int count, GLAB * buffers)
{
- int i;
- for(i = 0; i < count; i++)
+ if(glcaps_vertexBuffer)
{
- uint buffer = buffers[i].buffer;
- if(buffer)
+ int i;
+ for(i = 0; i < count; i++)
{
- if(buffer == glabCurArrayBuffer)
- GLABBindBuffer(GL_ARRAY_BUFFER, 0);
- else if(buffer == glabCurElementBuffer)
- GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ uint buffer = buffers[i].buffer;
+ if(buffer)
+ {
+ if(buffer == glabCurArrayBuffer)
+ GLABBindBuffer(GL_ARRAY_BUFFER, 0);
+ else if(buffer == glabCurElementBuffer)
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
}
+ if(count && buffers[0].buffer)
+ glDeleteBuffers(count, (GLuint *)buffers);
}
- if(count && buffers[0].buffer)
- glDeleteBuffers(count, (GLuint *)buffers);
}
// NOTE: Don't call if without vertexBuffer
void GLABBindBuffer(int target, uint buffer)
{
- glBindBuffer(target, buffer);
- if(target == GL_ARRAY_BUFFER)
- glabCurArrayBuffer = buffer;
- else if(target == GL_ELEMENT_ARRAY_BUFFER)
- glabCurElementBuffer = buffer;
+ if(glcaps_vertexBuffer)
+ {
+ glBindBuffer(target, buffer);
+ if(target == GL_ARRAY_BUFFER)
+ glabCurArrayBuffer = buffer;
+ else if(target == GL_ELEMENT_ARRAY_BUFFER)
+ glabCurElementBuffer = buffer;
+ }
}
public enum GLBufferContents { vertex, normal, texCoord, color };
+public enum GLBufferUsage { staticDraw, dynamicDraw, streamDraw };
+
+static GLint bufferUsages[] = { GL_DYNAMIC_DRAW, GL_STATIC_DRAW, GL_STREAM_DRAW };
+
public define noAB = GLAB { 0 };
uint glabCurArrayBuffer;
+static short *shortVPBuffer = null;
+static uint shortVPSize = 0;
+
+void glabTerminate()
+{
+ shortVPSize = 0;
+ delete shortVPBuffer;
+}
+
public struct GLAB
{
uint buffer;
- void upload(uint size, void * data)
+ void allocate(uint size, void * data, GLBufferUsage usage)
{
- if(this != null && data)
+ if(this != null)
{
if(glcaps_vertexBuffer)
{
glGenBuffers(1, &buffer);
if(glabCurArrayBuffer != buffer)
GLABBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); //GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, size, data, bufferUsages[usage]);
}
else
buffer = 1;
}
}
+ void upload(uint offset, uint size, void * data)
+ {
+ if(this != null && glcaps_vertexBuffer)
+ {
+ if(glabCurArrayBuffer != buffer)
+ GLABBindBuffer(GL_ARRAY_BUFFER, buffer);
+ glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);
+ }
+ }
+
void free()
{
if(this != null && buffer)
if(!glcaps_shaders)
switch(contents)
{
- case normal: glNormalPointer(type, stride, pointer); break;
- case vertex: glVertexPointer(n, type, stride, pointer); break;
- case texCoord: glTexCoordPointer(n, type, stride, pointer); break;
- case color: glColorPointer(n, type, stride, pointer); break;
+ case normal: glNormalPointer (type, stride, pointer); break;
+ case vertex: glVertexPointer (n, type, stride, pointer); break;
+ case texCoord: glTexCoordPointer (n, type, stride, pointer); break;
+ case color: glColorPointer (n, type, stride, pointer); break;
}
#endif
}
if(glabCurArrayBuffer != ((this != null) ? buffer : 0) && glcaps_vertexBuffer)
GLABBindBuffer(GL_ARRAY_BUFFER, ((this != null) ? buffer : 0));
if(type == GL_INT)
- glimtkVertexPointeri(n, stride, pointer, count);
+ {
+ if(pointer)
+ {
+ int i;
+ if(count*n > shortVPSize)
+ {
+ shortVPSize = count*n;
+ shortVPBuffer = renew shortVPBuffer short[shortVPSize];
+ }
+ for(i = 0; i < count*n; i++)
+ shortVPBuffer[i] = (short)pointer[i];
+
+ GLVertexPointer(n, GL_SHORT, stride, shortVPBuffer);
+ }
+ else
+ GLVertexPointer(n, GL_SHORT, stride, 0);
+ }
else if(type == GL_DOUBLE)
{
#if ENABLE_GL_SHADERS
{
uint buffer;
- void upload(uint size, void * data)
+ void allocate(uint size, void * data, GLBufferUsage usage)
{
- if(this != null && data)
+ if(this != null)
{
if(glcaps_vertexBuffer)
{
if(glcaps_vertexBuffer && glabCurElementBuffer != buffer)
GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
if(size)
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); //GL_DYNAMIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, bufferUsages[usage]);
else
;
}
}
}
+ void upload(uint offset, uint size, void * data)
+ {
+ if(this != null && glcaps_vertexBuffer)
+ {
+ if(glabCurArrayBuffer != buffer)
+ GLABBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
+ glBufferSubData(buffer, offset, size, data);
+ }
+ }
+
void free()
{
if(this != null && buffer)
};
static int beginCount;
-static int vertexCount;
-static int normalCount;
-static float *vertexPointer;
-static float *normalPointer;
static GLIMTKMode beginMode = unset;
-static uint beginBufferSize, normalBufferSize;
-static int numVertexCoords = 2;
static bool vertexColorValues = false;
-static int vertexStride = 4;
-static int vertexOffset = 2;
+static int numCoords = 2; // Number of coordinates per vertex
+static int vertexOffset = 2; // Offset of vertex info
+
+static struct FloatGLAB : GLAB
+{
+ uint count; // Count of vertices
+ uint size; // Size in vertices
+ int stride; // Number of floats per vertex
+ float * pointer;
+ uint bufSize; // Size in bytes of VBO
+
+ static inline float * ensure(uint extraVertices)
+ {
+ if(count + extraVertices >= size)
+ {
+ size = size ? (size + size/2) : Max(count + extraVertices, 6);
+ pointer = renew pointer float[size * stride];
+ }
+ return pointer + count * stride;
+ }
+
+ static inline void upload()
+ {
+ uint bufSize = count * stride * sizeof(float);
+ if(bufSize > this.bufSize)
+ {
+ this.bufSize = bufSize;
+ GLAB::allocate(bufSize, null, dynamicDraw);
+ }
+ GLAB::upload(0, bufSize, verticesBuf.pointer);
+ }
+
+ static inline void free()
+ {
+ bufSize = 0;
+ count = 0;
+ size = 0;
+ delete pointer;
+ GLAB::free();
+ }
+};
+
+FloatGLAB verticesBuf { stride = 4 };
+FloatGLAB normalsBuf { stride = 3 };
+
+void glimtkTerminate()
+{
+ verticesBuf.free();
+ normalsBuf.free();
+}
public void glimtkRecti(int a, int b, int c, int d)
{
public void glimtkBegin(GLIMTKMode mode)
{
beginMode = mode;
- beginCount = 0;
- vertexCount = 0;
vertexColorValues = false;
+ beginCount = 0;
vertexOffset = 2;
- vertexStride = 4;
- numVertexCoords = 2;
- if(!vertexPointer)
- {
- normalBufferSize = beginBufferSize = 1024; // default number of vertices
- vertexPointer = new float[beginBufferSize * vertexStride];
- normalPointer = new float[normalBufferSize * 3];
- }
+ verticesBuf.count = 0;
+ verticesBuf.stride = 4;
+ numCoords = 2;
}
public void glimtkTexCoord2f(float x, float y)
{
- int count = vertexCount;
-
- if(vertexCount + numVertexCoords > beginBufferSize)
- {
- beginBufferSize = beginBufferSize + beginBufferSize/2;
- vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
- }
-
- vertexPointer[count*vertexStride ] = x;
- vertexPointer[count*vertexStride+1] = y;
- count++;
-
- if(beginMode == quads && ((beginCount % 4) == 3))
+ int stride = verticesBuf.stride;
+ bool quadsAdd = beginMode == quads && !glcaps_quads && ((beginCount % 4) == 3);
+ float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1);
+ buf[0] = x;
+ buf[1] = y;
+ buf += stride;
+ if(quadsAdd)
{
- vertexPointer[count*vertexStride ] = vertexPointer[(count-4)*vertexStride];
- vertexPointer[count*vertexStride+1] = vertexPointer[(count-4)*vertexStride+1];
- count++;
- vertexPointer[count*vertexStride ] = vertexPointer[(count-3)*vertexStride];
- vertexPointer[count*vertexStride+1] = vertexPointer[(count-3)*vertexStride+1];
- count++;
+ buf[0] = buf[-4*stride];
+ buf[1] = buf[-4*stride+1];
+ buf += stride;
+ buf[0] = buf[-3*stride];
+ buf[1] = buf[-3*stride+1];
+ buf += stride;
}
}
+
public void glimtkTexCoord2i(int x, int y) { glimtkTexCoord2f((float)x, (float)y); }
public void glimtkTexCoord2d(double x, double y) { glimtkTexCoord2f((float)x, (float)y); }
public void glimtkTexCoord2fv(float * a) { glimtkTexCoord2f(a[0], a[1]); }
public void glimtkVertex2f(float x, float y)
{
- numVertexCoords = 2;
- vertexStride = vertexOffset + numVertexCoords;
-
- if(vertexCount + 4 > beginBufferSize)
- {
- beginBufferSize = beginBufferSize + beginBufferSize/2;
- vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
- }
-
- vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
- vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = y;
- vertexCount++;
-
- if(beginMode == quads && ((beginCount % 4) == 3))
+ numCoords = 2;
+ verticesBuf.stride = vertexOffset + numCoords;
{
- vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
- vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset + 1];
- vertexCount++;
- vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
- vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset + 1];
- vertexCount++;
+ int stride = verticesBuf.stride;
+ bool quadsAdd = beginMode == quads && !glcaps_quads && ((beginCount % 4) == 3);
+ float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
+ buf[0] = x;
+ buf[1] = y;
+ verticesBuf.count++;
+ if(quadsAdd)
+ {
+ buf += stride;
+ buf[0] = buf[-4*stride];
+ buf[1] = buf[-4*stride+1];
+ buf += stride;
+ buf[0] = buf[-3*stride];
+ buf[1] = buf[-3*stride+1];
+ verticesBuf.count+=2;
+ }
}
beginCount++;
}
public void glimtkVertex2i(int x, int y) { glimtkVertex2f((float)x, (float)y); }
public void glimtkVertex2d(double x, double y) { glimtkVertex2f((float)x, (float)y); }
-GLAB streamVecAB, streamNorAB;
-
-public void glimtkEnd()
-{
- GLIMTKMode mode = beginMode;
- if(mode == quads) mode = triangles;
- else if(mode == polygon) mode = triangleFan;
-
- GLEnableClientState(TEXCOORDS);
-
- if(glcaps_vertexBuffer)
- {
- streamVecAB.upload(vertexStride * sizeof(float) * vertexCount, vertexPointer);
- streamVecAB.use(texCoord, 2, GL_FLOAT, vertexStride * sizeof(float), 0);
- }
- else
- noAB.use(texCoord, 2, GL_FLOAT, vertexStride * sizeof(float), vertexPointer);
-
- if(vertexColorValues)
- {
- GLEnableClientState(COLORS);
- if(glcaps_vertexBuffer)
- streamVecAB.use(color, 4, GL_FLOAT, vertexStride * sizeof(float), (void *)(2 * sizeof(float)));
- else
- noAB.use(color, 4, GL_FLOAT, vertexStride * sizeof(float), vertexPointer + 2);
-
-#if ENABLE_GL_SHADERS
- if(glcaps_shaders)
- shader_setPerVertexColor(true);
-#endif
- }
-
- if(glcaps_vertexBuffer)
- streamVecAB.use(vertex, numVertexCoords, GL_FLOAT, vertexStride * sizeof(float), (void *)(vertexOffset * sizeof(float)));
- else
- noAB.use(vertex, numVertexCoords, GL_FLOAT, vertexStride * sizeof(float), vertexPointer + vertexOffset);
-
- if(normalCount && normalCount == vertexCount)
- {
- GLEnableClientState(NORMALS);
- if(glcaps_vertexBuffer)
- {
- streamNorAB.upload(3*sizeof(float) * vertexCount, normalPointer);
- streamNorAB.use(normal, 3, GL_FLOAT, 3*sizeof(float), 0);
- }
- else
- noAB.use(normal, 3, GL_FLOAT, 3*sizeof(float),normalPointer);
- }
-
- GLFlushMatrices();
- glDrawArrays(mode, 0, vertexCount);
-
- if(normalCount)
- GLDisableClientState(NORMALS);
- if(vertexColorValues)
- {
- GLDisableClientState(COLORS);
-
-#if ENABLE_GL_SHADERS
- if(glcaps_shaders)
- shader_setPerVertexColor(false);
-#endif
-
- }
- GLDisableClientState(TEXCOORDS);
-
- normalCount = 0;
- vertexColorValues = false;
- numVertexCoords = 2;
- beginMode = unset;
-}
-
-// Vertex Pointer
-static float *floatVPBuffer = null;
-static short *shortVPBuffer = null;
-static unsigned int shortVPSize = 0, floatVPSize = 0;
-
-// Buffer Data
-static unsigned short *shortBDBuffer = null;
-static unsigned int shortBDSize = 0;
-
-public void glimtkVertexPointeri(int numCoords, int stride, int *pointer, int numVertices)
-{
- if(pointer)
- {
- int i;
- if(numVertices*numCoords > shortVPSize)
- {
- shortVPSize = numVertices*numCoords;
- shortVPBuffer = renew shortVPBuffer short[shortVPSize];
- }
- for(i = 0; i < numVertices*numCoords; i++)
- shortVPBuffer[i] = (short)pointer[i];
-
- GLVertexPointer(numCoords, GL_SHORT, stride, shortVPBuffer);
- }
- else
- GLVertexPointer(numCoords, GL_SHORT, stride, 0);
-}
-
-public void glimtkVertexPointerd(int numCoords, int stride, double *pointer, int numVertices)
+public void glimtkVertex3f( float x, float y, float z )
{
- if(pointer)
+ numCoords = 3;
+ verticesBuf.stride = vertexOffset + numCoords;
{
- int i;
- if(numVertices*numCoords > floatVPSize)
+ int stride = verticesBuf.stride;
+ bool quadsAdd = beginMode == quads && !glcaps_quads && ((beginCount % 4) == 3);
+ float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
+ buf[0] = x;
+ buf[1] = y;
+ buf[2] = z;
+ verticesBuf.count++;
+ if(quadsAdd)
{
- floatVPSize = numVertices*numCoords;
- floatVPBuffer = renew floatVPBuffer float[floatVPSize];
+ buf += stride;
+ buf[0] = buf[-4*stride];
+ buf[1] = buf[-4*stride+1];
+ buf[2] = buf[-4*stride+2];
+ buf += stride;
+ buf[0] = buf[-3*stride];
+ buf[1] = buf[-3*stride+1];
+ buf[2] = buf[-3*stride+2];
+ verticesBuf.count+=2;
}
- for(i = 0; i < numVertices*numCoords; i++)
- floatVPBuffer[i] = (float)pointer[i];
- GLVertexPointer(numCoords, GL_FLOAT, stride, floatVPBuffer);
}
- else
- GLVertexPointer(numCoords, GL_FLOAT, stride, 0);
-}
-
-public void glimtkTexReuseIntVP(int numCoords)
-{
- GLTexCoordPointer(numCoords, GL_SHORT, 0, floatVPBuffer);
+ beginCount++;
}
-public void glimtkTexReuseDoubleVP(int numCoords)
-{
- GLTexCoordPointer(numCoords, GL_FLOAT, 0, floatVPBuffer);
-}
+public void glimtkVertex3d( double x, double y, double z ) { glimtkVertex3f((float)x, (float)y, (float)z); }
+public void glimtkVertex3fv( float* coords ) { glimtkVertex3f(coords[0], coords[1], coords[2]); }
+public void glimtkVertex3dv( double* coords ) { glimtkVertex3f((float)coords[0], (float)coords[1], (float)coords[2]); }
public void glimtkColor4f(float r, float g, float b, float a)
{
if(beginMode != unset)
{
- int count = vertexCount;
-
+ // Called within glBegin()/glEnd()
vertexColorValues = true;
vertexOffset = 6;
- vertexStride = vertexOffset + numVertexCoords;
-
- if(vertexCount + vertexStride > beginBufferSize)
+ verticesBuf.stride = vertexOffset + numCoords;
{
- beginBufferSize = beginBufferSize + beginBufferSize/2;
- vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
- }
-
- vertexPointer[count*vertexStride + 2] = r;
- vertexPointer[count*vertexStride + 3] = g;
- vertexPointer[count*vertexStride + 4] = b;
- vertexPointer[count*vertexStride + 5] = a;
- count++;
+ int stride = verticesBuf.stride;
+ bool quadsAdd = beginMode == quads && !glcaps_quads && ((beginCount % 4) == 3);
+ float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + 2;
+ buf[0] = r, buf[1] = g, buf[2] = b, buf[3] = a;
- if(beginMode == quads && ((beginCount % 4) == 3))
- {
- vertexPointer[count*vertexStride + 2] = vertexPointer[(count-4) * vertexStride + 2];
- vertexPointer[count*vertexStride + 3] = vertexPointer[(count-4) * vertexStride + 3];
- vertexPointer[count*vertexStride + 4] = vertexPointer[(count-4) * vertexStride + 4];
- vertexPointer[count*vertexStride + 5] = vertexPointer[(count-4) * vertexStride + 5];
- count++;
- vertexPointer[count*vertexStride + 2] = vertexPointer[(count-3) * vertexStride + 2];
- vertexPointer[count*vertexStride + 3] = vertexPointer[(count-3) * vertexStride + 3];
- vertexPointer[count*vertexStride + 4] = vertexPointer[(count-3) * vertexStride + 4];
- vertexPointer[count*vertexStride + 5] = vertexPointer[(count-3) * vertexStride + 5];
- count++;
+ if(quadsAdd)
+ {
+ buf += stride;
+ buf[0] = buf[-4*stride];
+ buf[1] = buf[-4*stride+1];
+ buf[2] = buf[-4*stride+2];
+ buf[3] = buf[-4*stride+3];
+ buf += stride;
+ buf[0] = buf[-3*stride];
+ buf[1] = buf[-3*stride+1];
+ buf[2] = buf[-3*stride+2];
+ buf[3] = buf[-3*stride+3];
+ }
}
}
else
}
}
-public void glimtkColor3f( float r, float g, float b )
-{
- glimtkColor4f(r, g, b, 1.0f);
-}
-
-public void glimtkColor4ub(byte r, byte g, byte b, byte a)
-{
- glimtkColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
-}
+public void glimtkColor3f( float r, float g, float b ) { glimtkColor4f(r, g, b, 1.0f); }
+public void glimtkColor4ub(byte r, byte g, byte b, byte a) { glimtkColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f); }
+public void glimtkColor4fv(float * a) { glimtkColor4f(a[0], a[1], a[2], a[3]); }
-public void glimtkColor4fv(float * a)
-{
- glimtkColor4f(a[0], a[1], a[2], a[3]);
-}
-public void glimtkBufferDatad(int target, int size, void * data, int usage)
+public void glimtkNormal3f(float x, float y, float z)
{
- int numElems = size/sizeof(double);
- double * dblPtr = (double *)data;
- int i;
- if (numElems > floatVPSize)
+ normalsBuf.count = verticesBuf.count;
{
- floatVPSize = numElems;
- floatVPBuffer = renew floatVPBuffer float[floatVPSize];
- }
- for (i=0; i< numElems; i++)
- floatVPBuffer[i] = (float)dblPtr[i];
+ int stride = normalsBuf.stride;
+ bool quadsAdd = beginMode == quads && !glcaps_quads && ((beginCount % 4) == 3);
+ float * buf = normalsBuf.ensure(quadsAdd ? 3 : 1) + 2;
- glBufferData(target, numElems*sizeof(float), floatVPBuffer, usage);
-}
+ buf[0] = x, buf[1] = y, buf[2] = z;
+ normalsBuf.count++;
-public void glimtkBufferDatai(int target, int size, void * data, int usage)
-{
- int numElems = size/sizeof(unsigned int);
- unsigned int * pointer = (unsigned int *)data;
- int i;
- if (numElems > shortBDSize)
- {
- shortBDSize = numElems;
- shortBDBuffer = renew shortBDBuffer uint16[shortBDSize];
+ if(quadsAdd)
+ {
+ buf[0] = buf[-4*stride];
+ buf[1] = buf[-4*stride+1];
+ buf[2] = buf[-4*stride+2];
+ buf += stride;
+ buf[0] = buf[-3*stride];
+ buf[1] = buf[-3*stride+1];
+ buf[2] = buf[-3*stride+2];
+ normalsBuf.count += 2;
+ }
}
- for (i=0; i< numElems; i++)
- shortBDBuffer[i] = (unsigned short)pointer[i];
-
- glBufferData(target, numElems*sizeof(unsigned short), shortBDBuffer, usage);
}
+public void glimtkNormal3d(double x, double y, double z) { glimtkNormal3f((float)x, (float)y, (float)z); }
+public void glimtkNormal3fv(float * coords) { glimtkNormal3f(coords[0], coords[1], coords[2]); }
+public void glimtkNormal3fd(double * coords) { glimtkNormal3f((float)coords[0], (float)coords[1], (float)coords[2]); }
-public void glimtkVertex3f( float x, float y, float z )
-{
- numVertexCoords = 3;
- vertexStride = vertexOffset + numVertexCoords;
- if(vertexCount + vertexStride > beginBufferSize)
+public void glimtkEnd()
+{
+ GLIMTKMode mode = beginMode;
+ if(!glcaps_quads)
{
- beginBufferSize = beginBufferSize + beginBufferSize/2;
- vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
+ if(mode == quads) mode = triangles;
+ else if(mode == polygon) mode = triangleFan;
}
- vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
- vertexPointer[vertexCount*vertexStride+vertexOffset+1] = y;
- vertexPointer[vertexCount*vertexStride+vertexOffset+2] = z;
- vertexCount++;
+ GLEnableClientState(TEXCOORDS);
- if(beginMode == quads && ((beginCount % 4) == 3))
+ if(glcaps_vertexBuffer)
{
- vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
- vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+1];
- vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+2];
- vertexCount++;
- vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
- vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+1];
- vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+2];
- vertexCount++;
+ verticesBuf.upload();
+ verticesBuf.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), 0);
}
- beginCount++;
-}
-
-public void glimtkVertex3d( double x, double y, double z ) { glimtkVertex3f((float)x, (float)y, (float)z); }
-public void glimtkVertex3fv( float* coords ) { glimtkVertex3f(coords[0], coords[1], coords[2]); }
-public void glimtkVertex3dv( double* coords ) { glimtkVertex3f((float)coords[0], (float)coords[1], (float)coords[2]); }
+ else
+ noAB.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer);
-public void glimtkNormal3f(float x, float y, float z)
-{
- normalCount = vertexCount;
- if(vertexCount + 4 > normalBufferSize)
+ if(vertexColorValues)
{
- normalBufferSize = normalBufferSize + normalBufferSize/2;
- normalPointer = renew normalPointer float[normalBufferSize * 2];
+ GLEnableClientState(COLORS);
+ if(glcaps_vertexBuffer)
+ verticesBuf.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(2 * sizeof(float)));
+ else
+ noAB.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + 2);
+
+#if ENABLE_GL_SHADERS
+ if(glcaps_shaders)
+ shader_setPerVertexColor(true);
+#endif
}
- normalPointer[normalCount*3+0] = x;
- normalPointer[normalCount*3+1] = y;
- normalPointer[normalCount*3+2] = z;
- normalCount++;
+ if(glcaps_vertexBuffer)
+ verticesBuf.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(vertexOffset * sizeof(float)));
+ else
+ noAB.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + vertexOffset);
- if(beginMode == quads && ((beginCount % 4) == 3))
+ if(normalsBuf.count && normalsBuf.count == verticesBuf.count)
{
- normalPointer[normalCount*3+0] = normalPointer[(normalCount-4)*3+0];
- normalPointer[normalCount*3+1] = normalPointer[(normalCount-4)*3+1];
- normalPointer[normalCount*3+2] = normalPointer[(normalCount-4)*3+2];
- normalCount++;
- normalPointer[normalCount*3+0] = normalPointer[(normalCount-3)*3+0];
- normalPointer[normalCount*3+1] = normalPointer[(normalCount-3)*3+1];
- normalPointer[normalCount*3+2] = normalPointer[(normalCount-3)*3+2];
- normalCount++;
+ GLEnableClientState(NORMALS);
+ if(glcaps_vertexBuffer)
+ {
+ normalsBuf.upload();
+ normalsBuf.use(normal, 3, GL_FLOAT, 3*sizeof(float), 0);
+ }
+ else
+ noAB.use(normal, 3, GL_FLOAT, 3*sizeof(float),normalsBuf.pointer);
}
-}
-public void glimtkNormal3fd(double x, double y, double z) { glimtkNormal3f((float)x, (float)y, (float)z); }
-public void glimtkNormal3fv(float * coords) { glimtkNormal3f(coords[0], coords[1], coords[2]); }
-public void glimtkTerminate()
-{
- delete vertexPointer;
- delete normalPointer;
- beginBufferSize = 0;
+ GLFlushMatrices();
+ glDrawArrays(mode, 0, verticesBuf.count);
+
+ if(normalsBuf.count)
+ GLDisableClientState(NORMALS);
+ if(vertexColorValues)
+ {
+ GLDisableClientState(COLORS);
- delete floatVPBuffer;
- shortVPSize = 0;
+#if ENABLE_GL_SHADERS
+ if(glcaps_shaders)
+ shader_setPerVertexColor(false);
+#endif
- delete shortVPBuffer;
- floatVPSize = 0;
+ }
+ GLDisableClientState(TEXCOORDS);
- delete shortBDBuffer;
- shortBDSize = 0;
+ normalsBuf.count = 0;
+ vertexColorValues = false;
+ numCoords = 2;
+ beginMode = unset;
}