Skip to content

Commit c1a2458

Browse files
committed
tinydisplay: Fix assorted depth-related issues:
- M_always depth test wasn't implemented but M_none was - framebuffer_copy_to_ram didn't work for the depth buffer - the clear depth value was being ignored - depth range on DisplayRegion wasn't being honored
1 parent 300090e commit c1a2458

File tree

2 files changed

+80
-32
lines changed

2 files changed

+80
-32
lines changed

panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {

panda/src/tinydisplay/zbuffer.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ ZB_clear_viewport(ZBuffer * zb, int clear_z, ZPOINT z, int clear_color, PIXEL co
420420
if (clear_z) {
421421
zz = zb->zbuf + xmin + ymin * zb->xsize;
422422
for (y = 0; y < ysize; ++y) {
423-
memset(zz, 0, xsize * sizeof(ZPOINT));
423+
memset_l(zz, z, xsize);
424424
zz += zb->xsize;
425425
}
426426
}

0 commit comments

Comments
 (0)