@@ -229,10 +229,9 @@ clear(DrawableRegion *clearable) {
229229 }
230230
231231 bool clear_z = false ;
232- int z = 0 ;
232+ ZPOINT z = 0 ;
233233 if (clearable->get_clear_depth_active ()) {
234- // We ignore the specified depth clear value, since we don't support
235- // alternate depth compare functions anyway.
234+ z = (ZPOINT)((1 .0f - clearable->get_clear_depth ()) * (1 << ZB_Z_BITS));
236235 clear_z = true ;
237236 }
238237
@@ -280,6 +279,18 @@ prepare_display_region(DisplayRegionPipelineReader *dr) {
280279 _c->viewport .ysize = ysize;
281280 set_scissor (0 .0f , 1 .0f , 0 .0f , 1 .0f );
282281
282+ PN_stdfloat dr_near = 0 .0f ;
283+ PN_stdfloat dr_far = 1 .0f ;
284+ dr->get_depth_range (dr_near, dr_far);
285+
286+ if (dr_near == 0 .0f && dr_far == 1 .0f ) {
287+ _c->has_zrange = false ;
288+ } else {
289+ _c->has_zrange = true ;
290+ _c->zmin = dr_near;
291+ _c->zrange = dr_far - dr_near;
292+ }
293+
283294 nassertv (xmin >= 0 && xmin < _c->zb ->xsize &&
284295 ymin >= 0 && ymin < _c->zb ->ysize &&
285296 xmin + xsize >= 0 && xmin + xsize <= _c->zb ->xsize &&
@@ -875,7 +886,8 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
875886 int depth_test_state = 1 ; // zless
876887 _c->depth_test = 1 ; // set this for ZB_line
877888 const DepthTestAttrib *target_depth_test = DCAST (DepthTestAttrib, _target_rs->get_attrib_def (DepthTestAttrib::get_class_slot ()));
878- if (target_depth_test->get_mode () == DepthTestAttrib::M_none) {
889+ if (target_depth_test->get_mode () == DepthTestAttrib::M_none ||
890+ target_depth_test->get_mode () == DepthTestAttrib::M_always) {
879891 depth_test_state = 0 ; // zless
880892 _c->depth_test = 0 ;
881893 }
@@ -1415,10 +1427,17 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z,
14151427 z_size = 1 ;
14161428 }
14171429
1418- Texture::ComponentType component_type = Texture::T_unsigned_byte;
1419- Texture::Format format = Texture::F_rgba;
1420- if (_current_properties->get_srgb_color ()) {
1421- format = Texture::F_srgb_alpha;
1430+ Texture::ComponentType component_type;
1431+ Texture::Format format;
1432+ if (rb._buffer_type & RenderBuffer::T_depth) {
1433+ component_type = Texture::T_unsigned_int;
1434+ format = Texture::F_depth_component;
1435+ } else {
1436+ component_type = Texture::T_unsigned_byte;
1437+ format = Texture::F_rgba;
1438+ if (_current_properties->get_srgb_color ()) {
1439+ format = Texture::F_srgb_alpha;
1440+ }
14221441 }
14231442
14241443 if (tex->get_x_size () != w || tex->get_y_size () != h ||
@@ -1445,32 +1464,53 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z,
14451464 }
14461465 }
14471466
1448- PIXEL *ip = (PIXEL *)(image_ptr + image_size);
1449- PIXEL *fo = _c->zb ->pbuf + xo + yo * _c->zb ->linesize / PSZB;
1450- for (int y = 0 ; y < h; ++y) {
1451- ip -= w;
1467+ if (rb._buffer_type & RenderBuffer::T_depth) {
1468+ size_t dst_stride = tex->get_x_size ();
1469+ unsigned int *dst = (unsigned int *)(image_ptr + image_size);
1470+ size_t src_stride = _c->zb ->xsize ;
1471+ ZPOINT *src = _c->zb ->zbuf + xo + src_stride * yo;
1472+
1473+ for (int y = 0 ; y < h; ++y) {
1474+ dst -= dst_stride;
1475+ for (int x = 0 ; x < w; ++x) {
1476+ ZPOINT z = src[x];
1477+ if (z == 0 ) {
1478+ z = 0xFFFFFFFF ;
1479+ } else {
1480+ z = (1 << ZB_Z_BITS) - z;
1481+ z = z << (32 - ZB_Z_BITS);
1482+ }
1483+ dst[x] = z;
1484+ }
1485+ }
1486+ } else {
1487+ PIXEL *ip = (PIXEL *)(image_ptr + image_size);
1488+ PIXEL *fo = _c->zb ->pbuf + xo + yo * _c->zb ->linesize / PSZB;
1489+ for (int y = 0 ; y < h; ++y) {
1490+ ip -= w;
14521491#ifndef WORDS_BIGENDIAN
1453- // On a little-endian machine, we can copy the whole row at a time.
1454- memcpy (ip, fo, w * PSZB);
1492+ // On a little-endian machine, we can copy the whole row at a time.
1493+ memcpy (ip, fo, w * PSZB);
14551494#else
1456- // On a big-endian machine, we have to reverse the color-component order.
1457- const char *source = (const char *)fo;
1458- const char *stop = (const char *)fo + w * PSZB;
1459- char *dest = (char *)ip;
1460- while (source < stop) {
1461- char b = source[0 ];
1462- char g = source[1 ];
1463- char r = source[2 ];
1464- char a = source[3 ];
1465- dest[0 ] = a;
1466- dest[1 ] = r;
1467- dest[2 ] = g;
1468- dest[3 ] = b;
1469- dest += 4 ;
1470- source += 4 ;
1471- }
1495+ // On a big-endian machine, we have to reverse the color-component order.
1496+ const char *source = (const char *)fo;
1497+ const char *stop = (const char *)fo + w * PSZB;
1498+ char *dest = (char *)ip;
1499+ while (source < stop) {
1500+ char b = source[0 ];
1501+ char g = source[1 ];
1502+ char r = source[2 ];
1503+ char a = source[3 ];
1504+ dest[0 ] = a;
1505+ dest[1 ] = r;
1506+ dest[2 ] = g;
1507+ dest[3 ] = b;
1508+ dest += 4 ;
1509+ source += 4 ;
1510+ }
14721511#endif
1473- fo += _c->zb ->linesize / PSZB;
1512+ fo += _c->zb ->linesize / PSZB;
1513+ }
14741514 }
14751515
14761516 if (request != nullptr ) {
@@ -2075,8 +2115,16 @@ do_issue_depth_offset() {
20752115 int offset = target_depth_offset->get_offset ();
20762116 _c->zbias = offset;
20772117
2118+ PN_stdfloat dr_near = 0 .0f ;
2119+ PN_stdfloat dr_far = 1 .0f ;
2120+ if (_current_display_region != nullptr ) {
2121+ _current_display_region->get_depth_range (dr_near, dr_far);
2122+ }
2123+
20782124 PN_stdfloat min_value = target_depth_offset->get_min_value ();
20792125 PN_stdfloat max_value = target_depth_offset->get_max_value ();
2126+ min_value = dr_far * min_value + dr_near * (1 - min_value);
2127+ max_value = dr_far * max_value + dr_near * (1 - max_value);
20802128 if (min_value == 0 .0f && max_value == 1 .0f ) {
20812129 _c->has_zrange = false ;
20822130 } else {
0 commit comments