add initial rendertest stuff
includes basic scripts, savefiles and gold images
This commit is contained in:
@@ -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
|
||||
@@ -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.
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.
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.
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.
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.
Binary file not shown.
@@ -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
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
+0~gymlight 200 190 130 11000
|
||||
+0~FIFTS_LGHT4 160 170 220 1000
|
||||
BIN
Binary file not shown.
@@ -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
Binary file not shown.
@@ -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
|
||||
Executable
+59
@@ -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)
|
||||
Executable
+72
@@ -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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user