namespace gfx;
+#if (defined(ECERE_VANILLA) || defined(ECERE_ONEDRIVER)) && defined(__WIN32__)
+#define ECERE_NOTRUETYPE
+#endif
+
import "System"
import "Color"
import "LFBDisplayDriver"
+// TOFIX: Temporary until we pass Display instead of DisplaySystem to FontExtent
+#if defined(__WIN32__) && !defined(ECERE_NOTRUETYPE)
+import "GDIDisplayDriver"
+#endif
+
#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
import "Camera"
import "Plane"
public enum RenderState { fillMode = 1, depthTest, depthWrite, fogDensity, fogColor, blend, ambient, alphaWrite, antiAlias, vSync };
+public union RenderStateFloat { float f; uint ui; };
+
public enum FillModeValue { solid, wireframe };
public class DisplayFlags
public bool bold:1, italic:1, underline:1;
};
-static void DummyFunction()
+__attribute__((unused)) static void DummyFunction()
{
- Mutex mutex { };
+#if !defined(__EMSCRIPTEN__)
+ Mutex { };
+#endif
}
public class DisplayDriver
{
public:
- class_data char * name;
+ class_data const char * name;
class_data bool textMode;
class_data bool printer;
class_data DisplaySystem displaySystem;
get { return class_data(displaySystem); }
};
- class_property char * name
+ class_property const char * name
{
set { class_data(name) = value; }
get { return class_data(name); }
virtual void ::Scroll(Display, Box, int, int, Extent);
virtual void ::Update(Display, Box);
virtual void ::EndUpdate(Display);
-
+
// Allocate/free a bitmap
virtual bool ::AllocateBitmap(DisplaySystem, Bitmap, int, int, int, PixelFormat, bool);
virtual void ::FreeBitmap(DisplaySystem, Bitmap);
// Grab from the screen
virtual bool ::GrabScreen(Display, Bitmap, int, int, unsigned int, unsigned int);
-
+
// Converts a bitmap format
virtual bool ::ConvertBitmap(DisplaySystem, Bitmap, PixelFormat, ColorAlpha *);
virtual bool ::MakeDDBitmap(DisplaySystem, Bitmap, bool);
// Font loading
- virtual Font ::LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags);
+ virtual Font ::LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags);
virtual void ::UnloadFont(DisplaySystem, Font);
// 2D Drawing
virtual void ::FilterDI(Display, Surface, Bitmap, int, int, int, int, int, int, int,int);
virtual void ::TextFont(Display, Surface, Font);
virtual void ::TextOpacity(Display, Surface, bool);
- virtual void ::WriteText(Display, Surface, int, int, char *, int);
- virtual void ::TextExtent(Display, Surface, char *, int, int *, int *);
- virtual void ::FontExtent(DisplaySystem, Font, char *, int, int *, int *);
+ virtual void ::WriteText(Display, Surface, int, int, const char *, int);
+ virtual void ::TextExtent(Display, Surface, const char *, int, int *, int *);
+ virtual void ::FontExtent(DisplaySystem, Font, const char *, int, int *, int *);
virtual void ::DrawingChar(Display, Surface, char);
virtual void ::NextPage(Display);
#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
virtual void ::SetRenderState(Display, RenderState, uint);
virtual void ::SetLight(Display, int, Light);
virtual void ::SetCamera(Display, Surface, Camera);
- virtual bool ::AllocateMesh(DisplaySystem, Mesh);
+ virtual bool ::AllocateMesh(DisplaySystem, Mesh, MeshFeatures, int nVertices);
virtual void ::FreeMesh(DisplaySystem, Mesh);
virtual bool ::LockMesh(DisplaySystem, Mesh, MeshFeatures flags);
virtual void ::UnlockMesh(DisplaySystem, Mesh, MeshFeatures flags);
public enum Alignment { left, right, center };
public enum ClearType { colorBuffer, depthBuffer, colorAndDepth };
-subclass(DisplayDriver) GetDisplayDriver(char * driverName)
-{
- if(driverName)
- {
- OldLink link;
- for(link = class(DisplayDriver).derivatives.first; link; link = link.next)
- {
- subclass(DisplayDriver) displayDriver = link.data;
- if(displayDriver && displayDriver.name && !strcmp(displayDriver.name, driverName))
- return displayDriver;
- }
- }
- return null;
-}
-
-DisplaySystem GetDisplaySystem(char * driverName)
-{
- subclass(DisplayDriver) displayDriver = GetDisplayDriver(driverName);
- return displayDriver ? displayDriver.displaySystem : null;
-}
-
define textCellW = 8;
define textCellH = 16;
};
public enum Resolution : int
{
- resText80x25, res320x200, res320x240, res320x400, res360x480, res400x256, res400x300, res512x256, res512x384,
+ resText80x25, res320x200, res320x240, res320x400, res360x480, res400x256, res400x300, res512x256, res512x384,
res640x200, res640x350, res640x400, res640x480, res720x348, res800x600, res856x480, res960x720, res1024x768,
res1152x864, res1280x1024, res1600x1200, res768x480
};
Mesh mesh = object.mesh;
Matrix * matrix = &object.matrix;
int v;
- float a = poly2.plane.a, b = poly2.plane.b, c = poly2.plane.c, d = poly2.plane.d;
+ double a = poly2.plane.a, b = poly2.plane.b, c = poly2.plane.c, d = poly2.plane.d;
if(d < 0)
{
a*=-1;
d = - (a * poly2.middle.x + b * poly2.middle.y + c * poly2.middle.z);
}
- for(v = 0; v < primitive->nIndices; v++)
+ for(v = 0; v < primitive->nIndices; v++)
{
double surface;
Vector3Df * local = &mesh.vertices[primitive->indices[v]];
surface = a * vertex.x + b * vertex.y + c * vertex.z + d;
- if(surface < EPSILON)
+ if(surface < EPSILON)
{
result = false;
break;
return result;
}
- int SurfaceInside(SortPrimitive poly2)
+ bool SurfaceInside(SortPrimitive poly2)
{
bool result = true;
Mesh mesh = poly2.object.mesh;
Matrix * matrix = &poly2.object.matrix;
int v;
- float a = plane.a, b = plane.b, c = plane.c, d = plane.d;
+ double a = plane.a, b = plane.b, c = plane.c, d = plane.d;
if(d < 0)
{
a*=-1;
c*=-1;
d = - (a * middle.x + b * middle.y + c * middle.z);
}
-
- for(v = 0; v < primitive->nIndices; v++)
+
+ for(v = 0; v < primitive->nIndices; v++)
{
double surface;
Vector3Df * local = &mesh.vertices[primitive->indices[v]];
Vector3Df vertex;
- vertex.Transform(local, matrix);
+ vertex.MultMatrix(local, matrix);
surface = a * vertex.x + b * vertex.y + c * vertex.z + d;
if(surface > -EPSILON)
return result;
}
- void FontExtent(Font font, char * text, int len, int * width, int * height)
+ void FontExtent(Font font, const char * text, int len, int * width, int * height)
{
- DisplaySystem::FontExtent(this ? displaySystem : null, font, text, len, width, height);
+ // Fix for OnLoadGraphics time alpha blended window text extent on GDI
+#if defined(__WIN32__) && !defined(ECERE_NOTRUETYPE)
+ if(this && alphaBlend && pixelFormat == pixelFormat888 &&
+ displaySystem.driver == class(GDIDisplayDriver))
+ {
+ Surface s = GetSurface(0,0,null);
+ if(s)
+ {
+ s.font = font;
+ s.TextExtent(text, len, width, height);
+ delete s;
+ }
+ }
+ else
+#endif
+ // TODO: Should really pass display here...
+ DisplaySystem::FontExtent(this ? displaySystem : null, font, text, len, width, height);
}
void SetPalette(ColorAlpha * palette, bool colorMatch)
{
displaySystem.driver.SetPalette(this, palette, colorMatch);
}
-
+
void RestorePalette(void)
{
- displaySystem.driver.RestorePalette(this);
+ displaySystem.driver.RestorePalette(this);
}
bool Lock(bool render)
Log(" ");
Logf("Locking (%d)\n", current+1);
*/
-
+
// TOCHECK: Why is displaySystem null with GISDesigner?
result = displaySystem && displaySystem.Lock();
if(result && render)
{
+#if !defined(__EMSCRIPTEN__)
mutex.Wait();
+#endif
if(!current)
result = displaySystem.driver.Lock(this);
current--;
/*{
int c;
-
+
for(c = 0; c<current; c++)
Log(" ");
Logf("Unlocking (%d)\n", current);
*/
if(!current && displaySystem)
displaySystem.driver.Unlock(this);
+#if !defined(__EMSCRIPTEN__)
mutex.Release();
+#endif
}
if(displaySystem)
displaySystem.Unlock();
{
if(!display3D.selection)
displaySystem.driver.SelectMesh(this, null);
-
+
display3D.material = null;
display3D.mesh = null;
}
double r = camera.origin.x - (display3D.pickX + display3D.pickWidth/2.0f);
double t = (display3D.pickY - display3D.pickHeight/2.0f) - camera.origin.y;
double b = (display3D.pickY + display3D.pickHeight/2.0f) - camera.origin.y;
-
+
fovLeft = atan(l / camera.focalX);
fovRight = atan(r / camera.focalX);
fovTop = atan(t / camera.focalY);
fovBottom = atan(b / camera.focalY);
-
+
// --- Left ---
quat.Yaw(fovLeft - Pi/2);
quat.ToDirection(normal);
Matrix matrix;
Matrix inverse, inverseTranspose;
int c;
-
+
if(object.flags.viewSpace)
matrix = object.matrix;
else
- {
+ {
Camera camera = display3D.camera;
Matrix temp = object.matrix;
temp.m[3][0] -= camera.cPosition.x;
sort->middle.MultMatrix(triangle->middle, matrix);
sort->middle.z *= -1;
// sort->plane.MultMatrix(triangle->plane, inverseTranspose);
- sort->plane.d = plane->a * inverseTranspose.m[0][3] +
+ sort->plane.d = plane->a * inverseTranspose.m[0][3] +
plane->b * inverseTranspose.m[1][3] +
- plane->c * inverseTranspose.m[2][3] +
+ plane->c * inverseTranspose.m[2][3] +
plane->d * inverseTranspose.m[3][3];
}
}
planes = object.flags.viewSpace ? display3D.viewPickingPlanes : display3D.worldPickingPlanes;
else
planes = object.flags.viewSpace ? camera.viewClippingPlanes : camera.worldClippingPlanes;
-
+
visible = object.InsideFrustum(planes);
if(visible || display3D.pickingPlanes)
property FillModeValue fillMode { set { displaySystem.driver.SetRenderState(this, fillMode, value); } };
property bool depthTest { set { displaySystem.driver.SetRenderState(this, depthTest, value); } };
property bool depthWrite { set { displaySystem.driver.SetRenderState(this, depthWrite, value); } };
- property float fogDensity { set { displaySystem.driver.SetRenderState(this, fogDensity, *(uint *)(void *)&value); } };
+ property float fogDensity { set { displaySystem.driver.SetRenderState(this, fogDensity, RenderStateFloat { value }.ui); } };
property Color fogColor { set { displaySystem.driver.SetRenderState(this, fogColor, value); } };
property bool blend { set { displaySystem.driver.SetRenderState(this, blend, value); } };
property Color ambient { set { displaySystem.driver.SetRenderState(this, ambient, value); } };
property void * systemWindow { get { return window; } };
property DisplaySystem displaySystem { get { return displaySystem; } };
+ int width, height;
+ void * driverData;
+
private:
DisplaySystem displaySystem;
void * window;
- public int width, height;
-
+
+#if !defined(__EMSCRIPTEN__)
Mutex mutex { };
+#endif
int current;
- public void * driverData;
#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
Display3D display3D;
#endif
};
#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
-private class Display3D
+private class Display3D : struct
{
// 3D Display
int nTriangles;
if(object.flags.light && !object.light.flags.off)
display.SetLight(id++, object.light);
-
+
for(child = object.children.first; child; child = child.next)
{
id = _SetLights(display, child, id);
- }
+ }
}
return id;
}
int c = 0;
int nIndex = 1, nPoints = 1;
int offset = 0;
- bool result = false;
+ bool result = false;
Vector3D * points = this.points;
Vector3D * newPoints = this.newPoints;
byte * goodPoints = this.goodPoints;
int strip = 1;
Vector3Df tmp;
bool i32bit = primitive.type.indices32bit;
- uint32 * indices32 = primitive.indices;
+ uint32 * indices32 = primitive.indices32;
uint16 * indices16 = primitive.indices;
-
+
switch(primitive.type.primitiveType)
{
case triangles: nIndex = 3; nPoints = 3; break;
points[1] = { (double)tmp.x, (double)tmp.y, (double)tmp.z };
break;
}
-
+
for(c = offset; c<nVertices; c += nIndex)
{
bool outside = false;
}
}
- for(p = 0; p < 6; p++)
+ for(p = 0; p < 6; p++)
{
Plane * plane = &planes[p];
int i;
int numGoodPoints = 0;
-
+
memset(goodPoints, 0, n);
- for(i = 0; i < n; i++)
+ for(i = 0; i < n; i++)
{
double dot = plane->normal.DotProduct(points[i]);
double distance = dot + plane->d;
}
else
{
- Line edge;
+ Line edge;
int next;
if(lastGood == -1)
Vector3Df min { MAXFLOAT, MAXFLOAT, MAXFLOAT };
Vector3Df max { -MAXFLOAT, -MAXFLOAT, -MAXFLOAT };
int v;
+ bool ix32 = primitive->type.indices32bit;
if(object != sort->object)
{
object = sort->object;
if(object.flags.viewSpace)
matrix = object.matrix;
else
- {
+ {
Camera camera = this.camera;
Matrix temp = object.matrix;
temp.m[3][0] -= camera.cPosition.x;
}
}
- for(v = 0; v<primitive->nIndices; v++)
+ for(v = 0; v<primitive->nIndices; v++)
{
- Vector3Df * local = &mesh.vertices[primitive->indices[v]];
+ Vector3Df * local = &mesh.vertices[ix32 ? primitive->indices32[v] : primitive->indices[v]];
Vector3Df vertex;
vertex.MultMatrix(local, &matrix);
Logf("Triangle %d (%s):\n", c, primitive->material->name);
- for(v = 0; v<primitive->nIndices; v++)
+ for(v = 0; v<primitive->nIndices; v++)
{
Vector3Df * local = &mesh.vertices[primitive->indices[v]];
Vector3Df vertex;
Logf("Triangle %d (%s):\n", c, primitive->material->name);
- for(v = 0; v<primitive->nIndices; v++)
+ for(v = 0; v<primitive->nIndices; v++)
{
Vector3Df * local = &mesh.vertices[primitive->indices[v]];
Vector3Df vertex;
//exit(0);
/*
- If all five tests fail for a particular Q,
- then P might obscure Q. Now Q must be tested.
- First, the algorithm checks if Q has been "marked."
- If Q is marked, then Q was "moved around" in the list
- during a previous iteration of the loop. The algorithm
- only allows a polygon to be moved once, to avoid the possibility
- of infinite loops. If Q is not marked, it is tested to see
- if it might obscure P. If Q cannot obscure P, then Q is possibly
- behind P and so it is good candidate to be drawn next.
- Therefore, the algorithm "abandons" the current P (that is, it
- stops testing Q's against the current P) and moves the current
+ If all five tests fail for a particular Q,
+ then P might obscure Q. Now Q must be tested.
+ First, the algorithm checks if Q has been "marked."
+ If Q is marked, then Q was "moved around" in the list
+ during a previous iteration of the loop. The algorithm
+ only allows a polygon to be moved once, to avoid the possibility
+ of infinite loops. If Q is not marked, it is tested to see
+ if it might obscure P. If Q cannot obscure P, then Q is possibly
+ behind P and so it is good candidate to be drawn next.
+ Therefore, the algorithm "abandons" the current P (that is, it
+ stops testing Q's against the current P) and moves the current
Q to the end of the list to become the next P.
*/
/*
}
}
}
- */
- /*
+
{
int p;
for(p = 0; p<nTriangles; p++)
}
}
}
- }*/
- /*
+ }
+
{
int p;
for(p = nTriangles-1; p>=0; p--)
}
}
}
- }*/
+ }
+
- /*
{
- for(c=0; c<nTriangles; c++)
+ for(c=0; c<nTriangles; c++)
{
int b;
SortPrimitive * poly1 = &triangles[c];
- // for(b=0; b<nTriangles; b++)
- //for(b=c+1; b<nTriangles; b++)
+ // for(b=0; b<nTriangles; b++)
+ //for(b=c+1; b<nTriangles; b++)
b = c+1;
if(b<this.nTriangles)
{
}
}
}
- */
+ */
+
}
};
#endif
-bool IsDriverTextMode(char * driverName)
+bool IsDriverTextMode(const char * driverName)
{
subclass(DisplayDriver) driver = GetDisplayDriver(driverName);
return driver ? driver.textMode : false;
}
-bool IsDriverPrinter(char * driverName)
+bool IsDriverPrinter(const char * driverName)
{
subclass(DisplayDriver) driver = GetDisplayDriver(driverName);
return driver ? driver.printer : false;
}
return best;
}
+
+// had to move this here due to compiler ordering issue for "get property" symbol
+subclass(DisplayDriver) GetDisplayDriver(const char * driverName)
+{
+ if(driverName)
+ {
+ OldLink link;
+ for(link = class(DisplayDriver).derivatives.first; link; link = link.next)
+ {
+ subclass(DisplayDriver) displayDriver = link.data;
+ if(displayDriver && displayDriver.name && !strcmp(displayDriver.name, driverName))
+ return displayDriver;
+ }
+ }
+ return null;
+}
+
+DisplaySystem GetDisplaySystem(const char * driverName)
+{
+ subclass(DisplayDriver) displayDriver = GetDisplayDriver(driverName);
+ return displayDriver ? displayDriver.displaySystem : null;
+}