add initial rendertest stuff

includes basic scripts, savefiles and gold images
This commit is contained in:
2023-11-24 11:54:11 -05:00
commit 6c65b1dfac
68 changed files with 10197 additions and 0 deletions

3
.gitattributes vendored Normal file
View File

@@ -0,0 +1,3 @@
*.sav filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text

2
render/Makefile Normal file
View File

@@ -0,0 +1,2 @@
imagecompare: imagecompare.c stb_image.h stb_image_write.h Makefile
${CC} -O3 -ggdb3 -march=native -Wall -Werror -pedantic -lm -o imagecompare imagecompare.c

Binary file not shown.

BIN
render/gold/brush2_01_direct.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
render/gold/brush2_01_full.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
render/gold/brush2_01_ngeom.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush2_01_nshade.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
render/gold/brush_01_direct.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_01_emissive.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_01_full.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_01_indirect.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
render/gold/brush_01_lighting.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_01_ngeom.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_01_nshade.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
render/gold/brush_02_direct.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_02_emissive.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_02_full.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_02_indirect.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
render/gold/brush_02_lighting.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_02_ngeom.png LFS Normal file

Binary file not shown.

BIN
render/gold/brush_02_nshade.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
render/gold/light_01_direct.png LFS Normal file

Binary file not shown.

BIN
render/gold/light_01_emissive.png LFS Normal file

Binary file not shown.

BIN
render/gold/light_01_full.png LFS Normal file

Binary file not shown.

BIN
render/gold/light_01_indirect.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
render/gold/light_01_lighting.png LFS Normal file

Binary file not shown.

BIN
render/gold/light_01_ngeom.png LFS Normal file

Binary file not shown.

BIN
render/gold/light_01_nshade.png LFS Normal file

Binary file not shown.

149
render/imagecompare.c Normal file
View File

@@ -0,0 +1,149 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include <stdio.h>
#include <time.h>
static int clampi(int v, int min, int max) {
return v < min ? min : v > max ? max : v;
}
static uint64_t now( void ) {
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
return tp.tv_nsec + tp.tv_sec * 1000000000ull;
}
typedef struct {
int w, h;
int comp;
unsigned char* data;
} image_t;
static int imageLoad(image_t* img, const char *f) {
img->data = stbi_load(f, &img->w, &img->h, &img->comp, 0);
if (!img->data)
fprintf(stderr, "Unable to load image \"%s\"\n", f);
return !!(img->data);
}
static int imageSave(image_t* img, const char *f) {
const char *const ext = strrchr(f, '.');
if (ext != NULL) {
if (strcmp(ext, ".png") == 0) {
return stbi_write_png(f, img->w, img->h, img->comp, img->data, 0);
} else if (strcmp(ext, ".bmp") == 0) {
return stbi_write_bmp(f, img->w, img->h, img->comp, img->data);
} else if (strcmp(ext, ".tga") == 0) {
return stbi_write_tga(f, img->w, img->h, img->comp, img->data);
} else if (strcmp(ext, ".jpg") ==0 || strcmp(ext, ".jpeg") == 0) {
return stbi_write_jpg(f, img->w, img->h, img->comp, img->data, 90);
}
}
return stbi_write_png(f, img->w, img->h, img->comp, img->data, 0);
}
/* LOL no need to clear anything
static void imageFree(image_t *img) {
if (img->data)
stbi_image_free(img->data);
}
*/
int main(int argc, char *argv[]) {
if (argc < 4) {
fprintf(stderr, "Usage: %s infile1 infile2 out_diff.png\n", argv[0]);
return 1;
}
const uint64_t start_ns = now();
image_t a, b;
if (!imageLoad(&a, argv[1]))
return 1;
if (!imageLoad(&b, argv[2]))
return 1;
if (a.w != b.w || a.h != b.h || a.comp != b.comp) {
fprintf(stderr, "Images metadata doesn't match: %s:%dx%d(%d) %s:%dx%d(%d)\n",
argv[1], a.w, a.h, a.comp,
argv[2], b.w, b.h, b.comp);
return 1;
}
image_t diff = {
.w = a.w,
.h = a.h,
.comp = a.comp,
.data = malloc(a.w * a.h * a.comp),
};
const uint64_t loaded_ns = now();
const unsigned char* ap = a.data, *bp = b.data;
unsigned char* dp = diff.data;
uint32_t diff_sum = 0;
for (int y = 0; y < a.h; ++y) {
for (int x = 0; x < a.w; ++x) {
const uint8_t ar = *(ap++);
const uint8_t ag = *(ap++);
const uint8_t ab = *(ap++);
const uint8_t br = *(bp++);
const uint8_t bg = *(bp++);
const uint8_t bb = *(bp++);
uint8_t dr = abs((int)ar-br);
uint8_t dg = abs((int)ag-bg);
uint8_t db = abs((int)ab-bb);
const int dsum = dr + dg + db;
if (dsum) {
const int maxd = 255+255+255;
const int threshold = maxd * 1 / 100;
const int t = clampi(dsum * 255 / threshold, 0, 255);
dr = t;
dg = 255 - t;
db = 0;
}
*(dp++) = dr;
*(dp++) = dg;
*(dp++) = db;
const int diff = dr + dg + db;
diff_sum += diff;
}
}
const uint64_t diffd_ns = now();
const uint32_t total = a.w * a.h * a.comp * 256;
const float diff_pct_threshold = 1.f;
const float diff_pct = diff_sum * 100.f / total;
const int over = diff_pct_threshold < diff_pct;
fprintf(stderr, "%s\"%s\" vs \"%s\": %d (%.03f%%)\033[0m\n",
over ? "\033[31mFAIL" : (diff_sum == 0 ? "\033[32m" : ""),
argv[1], argv[2], diff_sum, diff_pct
);
if (!imageSave(&diff, argv[3]))
return 1;
const uint64_t end_ns = now();
#define MS(t) ((t)/1e6)
fprintf(stderr, "loading: %.03fms, diffing: %.03fms, saving: %.03fms; total: %.03fms\n",
MS(loaded_ns - start_ns), MS(diffd_ns - loaded_ns), MS(end_ns - diffd_ns), MS(end_ns - start_ns));
return over;
}

BIN
render/maps/test_brush.bsp LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,2 @@
+0~gymlight 200 190 130 11000
+0~FIFTS_LGHT4 160 170 220 1000

BIN
render/maps/test_brush2.bsp LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,7 @@
+0~gymlight 200 190 130 11000
//halflife.wad
TOXICGRN 0 255 0 300
!TOXICGRN 0 255 0 300
GLASSGREEN 0 255 0 300
SCROLLTOXIC 0 255 0 300

BIN
render/maps/test_light.bsp LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,18 @@
+0~gymlight 200 190 130 11000
debug_rad 255 0 0 1024
~SPOTRED 255 26 29 1024
~SPOTGREEN 60 255 125 1024
~LIGHT3B 155 155 235 2000
// debug light
DEBUG_L_10 255 0 0 10
DEBUG_L_50 255 0 0 50
DEBUG_L_100 255 0 0 100
DEBUG_L_500 255 0 0 500
DEBUG_L_1000 255 0 0 1000
DEBUG_L_5000 255 0 0 5000
DEBUG_L_10000 255 0 0 10000
DEBUG_L_50000 255 0 0 50000
DEBUG_L_100000 255 0 0 100000
TECH_LITE1 255 235 160 60000

59
render/rendertest.py Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env python3
saves = [
'brush2_01',
'brush_01',
'brush_02',
'c0a0d_emissive',
'light_01',
]
displays = {
'full': '',
'basecolor': 'basecolor',
'emissive': 'emissive',
'nshade': 'nshade',
'ngeom': 'ngeom',
'lighting': 'lighting',
'direct': 'direct',
'indirect': 'indirect',
'indirect_specular': 'indirect_spec',
'indirect_diffuse': 'indirect_diff',
}
import argparse
parser = argparse.ArgumentParser(description='Generate scripts and makefiles for rendertest')
parser.add_argument('--script', '-s', type=argparse.FileType('w'), help='Console script for generating images')
args = parser.parse_args()
def make_script(file):
header = '''sv_cheats 1
developer 0
m_ignore 1
cl_showfps 0
scr_conspeed 100000
con_notifytime 0
hud_draw 0
r_speeds 0
rt_debug_fixed_random_seed 31337
'''
file.write(header)
for save in saves:
screenshot_base = 'rendertest/'
file.write(f'load rendertest_{save}\n')
file.write(f'wait 4; echo DONE WAIT4; playersonly; wait 11\n')
# for i in range(13):
# file.write(f'echo FRAME {i+4}; wait 1;\n')
for name, display in displays.items():
file.write(f'rt_debug_display_only "{display}"; screenshot {screenshot_base}{save}_{name}.tga; wait 1\n')
file.write('\n')
file.write('quit\n')
if args.script:
print(f'Generating script {args.script.name}')
make_script(args.script)

72
render/rendertest.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
set -eu
# Exec this script from the directory with xash3d executable
TEST_ROOT="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
WORKDIR="$TEST_ROOT/work"
IMAGE_COMPARE="$TEST_ROOT/imagecompare"
compile() {
pushd "$TEST_ROOT"
make
./rendertest.py -s rendertest.script
popd
}
prepare() {
mkdir -p "$WORKDIR"
cp -av "$TEST_ROOT/maps" "valve/"
cp -av "$TEST_ROOT/save" "valve/"
cp -av "$TEST_ROOT/rendertest.script" "./"
}
generate() {
time RADV_PERFTEST=rt LD_LIBRARY_PATH=. \
./xash3d -ref vk -nowriteconfig -nosound \
-width 1280 -height 800 \
+exec "rendertest.script"
# valve/rendertest now contains lots of images
}
compare() {
for i in $TEST_ROOT/gold/*.png
do
BASE="$(basename "$i" .png)"
"$IMAGE_COMPARE" \
"$i" \
"valve/rendertest/$BASE.tga" \
"$WORKDIR/${BASE}_diff.tga" \
|| echo "FAILED: $BASE"
convert \
\( "$i" -bordercolor gold -border 2x2 \
-gravity SouthWest -font Impact -pointsize 24 -fill gold -stroke black -annotate 0 'GOLD' \) \
\( "valve/rendertest/$BASE.tga" -bordercolor white -border 2x2 \
-fill white -annotate 0 'TEST' \) \
-loop 0 -set delay 25 "$WORKDIR/${BASE}_flip.gif"
done
}
convert_png() {
pushd "valve/rendertest"
for i in *tga
do
BASE="$(basename "$i" .tga)"
convert "$i" "$BASE".png
done
popd
}
run() {
prepare
time generate
time compare
}
time "$@"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

7987
render/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

1724
render/stb_image_write.h Normal file

File diff suppressed because it is too large Load Diff