add initial rendertest stuff

includes basic scripts, savefiles and gold images
This commit is contained in:
Ivan Avdeev 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

BIN
render/gold/brush2_01_basecolor.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_direct.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_emissive.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_full.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_indirect.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_indirect_diffuse.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_indirect_specular.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_lighting.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_ngeom.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush2_01_nshade.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_basecolor.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_direct.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_emissive.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_full.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_indirect.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_indirect_diffuse.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_indirect_specular.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_lighting.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_ngeom.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_01_nshade.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_basecolor.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_direct.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_emissive.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_full.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_indirect.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_indirect_diffuse.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_indirect_specular.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_lighting.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_ngeom.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/brush_02_nshade.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_basecolor.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_direct.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_emissive.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_full.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_indirect.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_indirect_diffuse.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_indirect_specular.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_lighting.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_ngeom.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/c0a0d_emissive_nshade.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_basecolor.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_direct.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_emissive.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_full.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_indirect.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_indirect_diffuse.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_indirect_specular.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_lighting.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_ngeom.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/gold/light_01_nshade.png (Stored with Git 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 (Stored with Git 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 (Stored with Git 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 (Stored with Git 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 "$@"

BIN
render/save/rendertest_brush2_01.sav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/save/rendertest_brush_01.sav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/save/rendertest_brush_02.sav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/save/rendertest_c0a0d_emissive.sav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
render/save/rendertest_light_01.sav (Stored with Git LFS) Normal file

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