Draw triangle back faces like the front, unless we draw them in red.
The configuration option "draw back faces in red" aids debugging, in that it allows to visually identify a non-watertight mesh. When it is disabled, or when the mesh is transparent, we used to not draw them at all before this commit; after, they are drawn just like the front faces. This has two consequences: 1. Inner surfaces of non-watertight meshes are not see-through anymore. That used to be the behavior in version 2.0, and it was accidentally broken in 2.1. 2. Transparent meshes look *much* better. 3. Solids made from a union of a non-transparent and a transparent one look sensibly at all. This commit also updates the OpenGL 1 renderer to let it render such meshes correctly.single-window
parent
c8ff17f4a2
commit
73844f7202
|
@ -476,6 +476,8 @@ void Group::DrawMesh(DrawMeshAs how, Canvas *canvas) {
|
||||||
fillBack.layer = fillFront.layer;
|
fillBack.layer = fillFront.layer;
|
||||||
fillBack.color = RgbaColor::FromFloat(1.0f, 0.1f, 0.1f);
|
fillBack.color = RgbaColor::FromFloat(1.0f, 0.1f, 0.1f);
|
||||||
hcfBack = canvas->GetFill(fillBack);
|
hcfBack = canvas->GetFill(fillBack);
|
||||||
|
} else {
|
||||||
|
hcfBack = hcfFront;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the shaded solid into the depth buffer for hidden line removal,
|
// Draw the shaded solid into the depth buffer for hidden line removal,
|
||||||
|
|
|
@ -600,30 +600,40 @@ void OpenGl1Renderer::DrawPolygon(const SPolygon &p, hFill hcf) {
|
||||||
void OpenGl1Renderer::DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) {
|
void OpenGl1Renderer::DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) {
|
||||||
UnSelectPrimitive();
|
UnSelectPrimitive();
|
||||||
|
|
||||||
Fill *frontFill = SelectFill(hcfFront);
|
RgbaColor frontColor = {},
|
||||||
ssglMaterialRGBA(GL_FRONT, frontFill->color);
|
backColor = {};
|
||||||
|
|
||||||
|
Fill *frontFill = SelectFill(hcfFront);
|
||||||
|
frontColor = frontFill->color;
|
||||||
|
|
||||||
|
ssglMaterialRGBA(GL_FRONT, frontFill->color);
|
||||||
if(hcfBack.v != 0) {
|
if(hcfBack.v != 0) {
|
||||||
Fill *backFill = fills.FindById(hcfBack);
|
Fill *backFill = fills.FindById(hcfBack);
|
||||||
|
backColor = backFill->color;
|
||||||
ssassert(frontFill->layer == backFill->layer &&
|
ssassert(frontFill->layer == backFill->layer &&
|
||||||
frontFill->zIndex == backFill->zIndex,
|
frontFill->zIndex == backFill->zIndex,
|
||||||
"frontFill and backFill should belong to the same depth range");
|
"frontFill and backFill should belong to the same depth range");
|
||||||
ssassert(frontFill->pattern == backFill->pattern,
|
ssassert(frontFill->pattern == backFill->pattern,
|
||||||
"frontFill and backFill should have the same pattern");
|
"frontFill and backFill should have the same pattern");
|
||||||
ssglMaterialRGBA(GL_BACK, backFill->color);
|
|
||||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
|
||||||
|
ssglMaterialRGBA(GL_BACK, backFill->color);
|
||||||
} else {
|
} else {
|
||||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbaColor frontColor = {};
|
RgbaColor triangleColor = {};
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
for(const STriangle &tr : m.l) {
|
for(const STriangle &tr : m.l) {
|
||||||
if(frontFill->color.IsEmpty()) {
|
if(frontColor.IsEmpty() || backColor.IsEmpty()) {
|
||||||
if(frontColor.IsEmpty() || !frontColor.Equals(tr.meta.color)) {
|
if(triangleColor.IsEmpty() || !triangleColor.Equals(tr.meta.color)) {
|
||||||
frontColor = tr.meta.color;
|
triangleColor = tr.meta.color;
|
||||||
ssglMaterialRGBA(GL_FRONT, frontColor);
|
if(frontColor.IsEmpty()) {
|
||||||
|
ssglMaterialRGBA(GL_FRONT, triangleColor);
|
||||||
|
}
|
||||||
|
if(backColor.IsEmpty()) {
|
||||||
|
ssglMaterialRGBA(GL_BACK, triangleColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,6 +724,11 @@ void OpenGl1Renderer::UpdateProjection(bool flip) {
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, clp, 1);
|
0, 0, clp, 1);
|
||||||
glMultMatrixd(mat);
|
glMultMatrixd(mat);
|
||||||
|
|
||||||
|
// If we flip the framebuffer, then we also flip the handedness
|
||||||
|
// of the coordinate system, and so the face winding order.
|
||||||
|
glFrontFace(flip ? GL_CW : GL_CCW);
|
||||||
|
|
||||||
// Before that, we apply the rotation
|
// Before that, we apply the rotation
|
||||||
Vector projRight = camera.projRight,
|
Vector projRight = camera.projRight,
|
||||||
projUp = camera.projUp,
|
projUp = camera.projUp,
|
||||||
|
@ -723,6 +738,7 @@ void OpenGl1Renderer::UpdateProjection(bool flip) {
|
||||||
n.x, n.y, n.z, 0,
|
n.x, n.y, n.z, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
glMultMatrixd(mat);
|
glMultMatrixd(mat);
|
||||||
|
|
||||||
// And before that, the translation
|
// And before that, the translation
|
||||||
Vector offset = camera.offset;
|
Vector offset = camera.offset;
|
||||||
MakeMatrix(mat, 1, 0, 0, offset.x,
|
MakeMatrix(mat, 1, 0, 0, offset.x,
|
||||||
|
|
Loading…
Reference in New Issue