diff --git a/.github/workflows/screenshot.yml b/.github/workflows/screenshot.yml new file mode 100644 index 0000000..5a9df8d --- /dev/null +++ b/.github/workflows/screenshot.yml @@ -0,0 +1,36 @@ +name: Screenshot Test + +on: + push: + branches: [ "fix/tessellation-artifacts" ] + +jobs: + test-and-screenshot: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: sudo apt update && sudo apt install --fix-missing cmake gcc gfortran libx11-dev libglu1-mesa-dev libmotif-dev tcsh libxaw7-dev libglew-dev libdlm-dev libgl2ps-dev libpng-dev xvfb imagemagick + + - name: Build + run: | + make config + make build + + - name: Run test_f3 and capture screenshot + run: | + Xvfb :99 -screen 0 1024x768x24 & + export DISPLAY=:99 + sleep 2 + ./build/test_f/test_f3 & + TEST_PID=$! + sleep 5 + import -window root test_f3_output.png + kill $TEST_PID + + - name: Upload Screenshot Artifact + uses: actions/upload-artifact@v4 + with: + name: test_f3-screenshot + path: test_f3_output.png diff --git a/src/libphigs/f_binding/fb_extel.c b/src/libphigs/f_binding/fb_extel.c index f08ef51..a7a2454 100644 --- a/src/libphigs/f_binding/fb_extel.c +++ b/src/libphigs/f_binding/fb_extel.c @@ -884,3 +884,38 @@ FTN_SUBROUTINE(psmcv3)( spacelist.half_spaces = &list[0]; pset_model_clip_vol3(iop, spacelist); } + +/******************************************************************************* + * psbici + * + * DESCR: set back interior colour index + * RETURNS: N/A + */ +FTN_SUBROUTINE(psbici)( + FTN_INTEGER(coli) + ) +{ + Pint colr_ind = FTN_INTEGER_GET(coli); +#ifdef DEBUG + printf("DEBUG: pset back interior color index set to %d\n", colr_ind); +#endif + pset_back_int_colr_ind(colr_ind); +} + +/******************************************************************************* + * psbisi + * + * DESCR: set back interior style index + * RETURNS: N/A + */ +FTN_SUBROUTINE(psbisi)( + FTN_INTEGER(stylei) + ) +{ + Pint style_ind = FTN_INTEGER_GET(stylei); +#ifdef DEBUG + printf("DEBUG: pset back interior style index set to %d\n", style_ind); +#endif + pset_back_int_style_ind(style_ind); +} + diff --git a/src/libphigs/wsgl/wsgl_tess.c b/src/libphigs/wsgl/wsgl_tess.c index a1455a5..2c2fbf5 100644 --- a/src/libphigs/wsgl/wsgl_tess.c +++ b/src/libphigs/wsgl/wsgl_tess.c @@ -26,6 +26,10 @@ static void CALLBACK tessEndCB() { glEnd(); } +static void CALLBACK tessEdgeFlagCB(GLboolean flag) { + glEdgeFlag(flag); +} + static void CALLBACK tessVertexCB(void *data) { Wsgl_tess_vertex *v = (Wsgl_tess_vertex *)data; if (v->has_norm) { @@ -83,6 +87,9 @@ void wsgl_draw_tess_polygon(Wsgl_tess_vertex *vertices, int num_vertices, int re int normal_indices[MAX_VERTICES]; int n_vertices = 0; int n_normals = 0; + GLboolean orig_depth_mask; + GLfloat cur_color[4]; + int has_transparency = 0; tess = gluNewTess(); if (!tess) return; @@ -92,6 +99,25 @@ void wsgl_draw_tess_polygon(Wsgl_tess_vertex *vertices, int num_vertices, int re gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK *)())tessVertexCB); gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK *)())tessErrorCB); gluTessCallback(tess, GLU_TESS_COMBINE, (void (CALLBACK *)())tessCombineCB); + gluTessCallback(tess, GLU_TESS_EDGE_FLAG, (void (CALLBACK *)())tessEdgeFlagCB); + + /* Determine if depth writing should be disabled for order-independent transparency */ + glGetBooleanv(GL_DEPTH_WRITEMASK, &orig_depth_mask); + + if (num_vertices > 0 && vertices[0].apply_cb) { + if (vertices[0].colr_type == PMODEL_RGBA && vertices[0].colr.direct.rgba.alpha < 1.0f) { + has_transparency = 1; + } + } else { + glGetFloatv(GL_CURRENT_COLOR, cur_color); + if (cur_color[3] < 1.0f) { + has_transparency = 1; + } + } + + if (has_transparency && orig_depth_mask == GL_TRUE) { + glDepthMask(GL_FALSE); + } gluTessBeginPolygon(tess, NULL); gluTessBeginContour(tess); @@ -115,6 +141,13 @@ void wsgl_draw_tess_polygon(Wsgl_tess_vertex *vertices, int num_vertices, int re gluTessEndPolygon(tess); gluDeleteTess(tess); + /* Restore default edge flag state for subsequent rendering */ + glEdgeFlag(GL_TRUE); + + if (has_transparency && orig_depth_mask == GL_TRUE) { + glDepthMask(GL_TRUE); + } + if (record_geom_flag && n_vertices > 0) { wsgl_add_geometry(GEOM_FACE, vertex_indices, normal_indices, n_vertices); }