mirror of
https://github.com/ioquake/ioq3.git
synced 2025-05-30 00:20:59 +00:00
Merge 15ff484715
into 10afd421f2
This commit is contained in:
commit
3af3f55b65
165 changed files with 110423 additions and 1 deletions
136
Makefile
136
Makefile
|
@ -46,6 +46,9 @@ endif
|
|||
ifndef BUILD_RENDERER_OPENGL2
|
||||
BUILD_RENDERER_OPENGL2=
|
||||
endif
|
||||
ifndef BUILD_RENDERER_VULKAN
|
||||
BUILD_RENDERER_VULKAN=
|
||||
endif
|
||||
ifndef BUILD_AUTOUPDATER # DON'T build unless you mean to!
|
||||
BUILD_AUTOUPDATER=0
|
||||
endif
|
||||
|
@ -264,6 +267,7 @@ SDIR=$(MOUNT_DIR)/server
|
|||
RCOMMONDIR=$(MOUNT_DIR)/renderercommon
|
||||
RGL1DIR=$(MOUNT_DIR)/renderergl1
|
||||
RGL2DIR=$(MOUNT_DIR)/renderergl2
|
||||
RVULKANDIR=$(MOUNT_DIR)/renderervk
|
||||
CMDIR=$(MOUNT_DIR)/qcommon
|
||||
SDLDIR=$(MOUNT_DIR)/sdl
|
||||
ASMDIR=$(MOUNT_DIR)/asm
|
||||
|
@ -1168,6 +1172,9 @@ ifneq ($(BUILD_CLIENT),0)
|
|||
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||
TARGETS += $(B)/renderer_opengl2_$(SHLIBNAME)
|
||||
endif
|
||||
ifneq ($(BUILD_RENDERER_VULKAN),0)
|
||||
TARGETS += $(B)/renderer_vulkan_$(SHLIBNAME)
|
||||
endif
|
||||
else
|
||||
ifneq ($(BUILD_RENDERER_OPENGL1),0)
|
||||
TARGETS += $(B)/$(CLIENTBIN)$(FULLBINEXT)
|
||||
|
@ -1175,6 +1182,9 @@ ifneq ($(BUILD_CLIENT),0)
|
|||
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||
TARGETS += $(B)/$(CLIENTBIN)_opengl2$(FULLBINEXT)
|
||||
endif
|
||||
ifneq ($(BUILD_RENDERER_VULKAN),0)
|
||||
TARGETS += $(B)/$(CLIENTBIN)_vulkan$(FULLBINEXT)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -1642,6 +1652,7 @@ makedirs:
|
|||
@$(MKDIR) $(B)/renderergl1
|
||||
@$(MKDIR) $(B)/renderergl2
|
||||
@$(MKDIR) $(B)/renderergl2/glsl
|
||||
@$(MKDIR) $(B)/renderervk
|
||||
@$(MKDIR) $(B)/ded
|
||||
@$(MKDIR) $(B)/$(BASEGAME)/cgame
|
||||
@$(MKDIR) $(B)/$(BASEGAME)/game
|
||||
|
@ -1997,6 +2008,88 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
Q3VKOBJ = \
|
||||
$(B)/renderervk/matrix_multiplication.o \
|
||||
$(B)/renderervk/tr_globals.o \
|
||||
$(B)/renderervk/tr_cvar.o \
|
||||
$(B)/renderervk/tr_animation.o \
|
||||
$(B)/renderervk/tr_bsp.o \
|
||||
$(B)/renderervk/tr_cmds.o \
|
||||
$(B)/renderervk/tr_curve.o \
|
||||
$(B)/renderervk/tr_fonts.o \
|
||||
$(B)/renderervk/tr_image.o \
|
||||
$(B)/renderervk/R_FindShader.o \
|
||||
$(B)/renderervk/R_ListShader.o \
|
||||
$(B)/renderervk/R_ImageProcess.o \
|
||||
$(B)/renderervk/tr_init.o \
|
||||
$(B)/renderervk/tr_light.o \
|
||||
$(B)/renderervk/tr_main.o \
|
||||
$(B)/renderervk/tr_marks.o \
|
||||
$(B)/renderervk/tr_mesh.o \
|
||||
$(B)/renderervk/tr_model.o \
|
||||
$(B)/renderervk/tr_model_iqm.o \
|
||||
$(B)/renderervk/RE_RegisterModel.o \
|
||||
$(B)/renderervk/R_ModelBounds.o \
|
||||
$(B)/renderervk/R_LoadMD3.o \
|
||||
$(B)/renderervk/R_LoadMDR.o \
|
||||
$(B)/renderervk/R_LerpTag.o \
|
||||
$(B)/renderervk/tr_noise.o \
|
||||
$(B)/renderervk/tr_scene.o \
|
||||
$(B)/renderervk/tr_shade.o \
|
||||
$(B)/renderervk/tr_shade_calc.o \
|
||||
$(B)/renderervk/tr_shader.o \
|
||||
$(B)/renderervk/tr_shadows.o \
|
||||
$(B)/renderervk/tr_sky.o \
|
||||
$(B)/renderervk/tr_surface.o \
|
||||
$(B)/renderervk/tr_flares.o \
|
||||
$(B)/renderervk/tr_fog.o \
|
||||
$(B)/renderervk/tr_world.o \
|
||||
$(B)/renderervk/vk_instance.o \
|
||||
$(B)/renderervk/vk_init.o \
|
||||
$(B)/renderervk/vk_cmd.o \
|
||||
$(B)/renderervk/vk_image.o \
|
||||
$(B)/renderervk/vk_image_sampler2.o \
|
||||
$(B)/renderervk/vk_pipelines.o \
|
||||
$(B)/renderervk/vk_frame.o \
|
||||
$(B)/renderervk/vk_swapchain.o \
|
||||
$(B)/renderervk/vk_screenshot.o \
|
||||
$(B)/renderervk/vk_shade_geometry.o \
|
||||
$(B)/renderervk/vk_depth_attachment.o \
|
||||
\
|
||||
$(B)/renderervk/vk_shaders.o \
|
||||
$(B)/renderervk/multi_texture_clipping_plane_vert.o \
|
||||
$(B)/renderervk/multi_texture_frag.o \
|
||||
$(B)/renderervk/multi_texture_vert.o \
|
||||
$(B)/renderervk/single_texture_clipping_plane_vert.o \
|
||||
$(B)/renderervk/single_texture_frag.o \
|
||||
$(B)/renderervk/single_texture_vert.o \
|
||||
\
|
||||
$(B)/renderervk/R_StretchRaw.o \
|
||||
$(B)/renderervk/R_DebugGraphics.o \
|
||||
$(B)/renderervk/RB_ShowImages.o \
|
||||
$(B)/renderervk/RB_DrawNormals.o \
|
||||
$(B)/renderervk/RB_DrawTris.o \
|
||||
$(B)/renderervk/RB_SurfaceAnim.o \
|
||||
$(B)/renderervk/tr_backend.o \
|
||||
$(B)/renderervk/tr_Cull.o \
|
||||
$(B)/renderervk/glConfig.o \
|
||||
$(B)/renderervk/R_Parser.o \
|
||||
$(B)/renderervk/R_PortalPlane.o \
|
||||
$(B)/renderervk/R_PrintMat.o \
|
||||
\
|
||||
$(B)/renderervk/R_LoadImage2.o \
|
||||
$(B)/renderervk/R_LoadImage.o \
|
||||
$(B)/renderervk/R_ImageJPG.o \
|
||||
$(B)/renderervk/R_ImageTGA.o \
|
||||
$(B)/renderervk/R_ImagePNG.o \
|
||||
$(B)/renderervk/R_ImageBMP.o \
|
||||
$(B)/renderervk/R_ImagePCX.o \
|
||||
\
|
||||
$(B)/renderervk/ref_import.o \
|
||||
$(B)/renderervk/render_export.o \
|
||||
\
|
||||
$(B)/renderervk/vk_create_window_SDL.o
|
||||
|
||||
Q3R2OBJ = \
|
||||
$(B)/renderergl2/tr_animation.o \
|
||||
$(B)/renderergl2/tr_backend.o \
|
||||
|
@ -2116,6 +2209,11 @@ ifneq ($(USE_RENDERER_DLOPEN), 0)
|
|||
$(B)/renderergl1/puff.o \
|
||||
$(B)/renderergl1/q_math.o \
|
||||
$(B)/renderergl1/tr_subs.o
|
||||
|
||||
Q3VKOBJ += \
|
||||
$(B)/renderergl1/q_shared.o \
|
||||
$(B)/renderergl1/puff.o \
|
||||
$(B)/renderergl1/q_math.o
|
||||
endif
|
||||
|
||||
ifneq ($(USE_INTERNAL_JPEG),0)
|
||||
|
@ -2426,6 +2524,11 @@ $(B)/renderer_opengl2_$(SHLIBNAME): $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ)
|
|||
$(echo_cmd) "LD $@"
|
||||
$(Q)$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) \
|
||||
$(THREAD_LIBS) $(LIBSDLMAIN) $(RENDERER_LIBS) $(LIBS)
|
||||
|
||||
$(B)/renderer_vulkan_$(SHLIBNAME): $(Q3VKOBJ) $(JPGOBJ)
|
||||
$(echo_cmd) "LD $@"
|
||||
$(Q)$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(Q3VKOBJ) $(JPGOBJ) \
|
||||
$(THREAD_LIBS) $(LIBSDLMAIN) $(RENDERER_LIBS) $(LIBS)
|
||||
else
|
||||
$(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(Q3ROBJ) $(JPGOBJ) $(LIBSDLMAIN)
|
||||
$(echo_cmd) "LD $@"
|
||||
|
@ -2438,6 +2541,12 @@ $(B)/$(CLIENTBIN)_opengl2$(FULLBINEXT): $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(J
|
|||
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
|
||||
-o $@ $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) \
|
||||
$(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
|
||||
|
||||
$(B)/$(CLIENTBIN)_vulkan$(FULLBINEXT): $(Q3OBJ) $(Q3VKOBJ) $(JPGOBJ) $(LIBSDLMAIN)
|
||||
$(echo_cmd) "LD $@"
|
||||
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
|
||||
-o $@ $(Q3OBJ) $(Q3VKOBJ) $(JPGOBJ) \
|
||||
$(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
|
||||
endif
|
||||
|
||||
ifneq ($(strip $(LIBSDLMAIN)),)
|
||||
|
@ -2967,6 +3076,24 @@ $(B)/renderergl2/%.o: $(RCOMMONDIR)/%.c
|
|||
$(B)/renderergl2/%.o: $(RGL2DIR)/%.c
|
||||
$(DO_REF_CC)
|
||||
|
||||
$(B)/renderervk/%.o: $(CMDIR)/%.c
|
||||
$(DO_REF_CC)
|
||||
|
||||
$(B)/renderervk/%.o: $(SDLDIR)/%.c
|
||||
$(DO_REF_CC)
|
||||
|
||||
$(B)/renderervk/%.o: $(JPDIR)/%.c
|
||||
$(DO_REF_CC)
|
||||
|
||||
$(B)/renderervk/%.o: $(RCOMMONDIR)/%.c
|
||||
$(DO_REF_CC)
|
||||
|
||||
$(B)/renderervk/%.o: $(RVULKANDIR)/%.c
|
||||
$(DO_REF_CC)
|
||||
|
||||
$(B)/renderervk/%.o: $(MOUNT_DIR)/renderervk/shaders/Compiled/%.c
|
||||
$(DO_REF_CC)
|
||||
|
||||
|
||||
$(B)/ded/%.o: $(ASMDIR)/%.s
|
||||
$(DO_AS)
|
||||
|
@ -3104,7 +3231,7 @@ $(B)/$(CLIENTBIN)-config.json: $(WEBDIR)/client-config.json
|
|||
# MISC
|
||||
#############################################################################
|
||||
|
||||
OBJ = $(Q3OBJ) $(Q3ROBJ) $(Q3R2OBJ) $(Q3DOBJ) $(JPGOBJ) \
|
||||
OBJ = $(Q3OBJ) $(Q3ROBJ) $(Q3R2OBJ) $(Q3VKOBJ) $(Q3DOBJ) $(JPGOBJ) \
|
||||
$(MPGOBJ) $(Q3GOBJ) $(Q3CGOBJ) $(MPCGOBJ) $(Q3UIOBJ) $(MPUIOBJ) \
|
||||
$(MPGVMOBJ) $(Q3GVMOBJ) $(Q3CGVMOBJ) $(MPCGVMOBJ) $(Q3UIVMOBJ) $(MPUIVMOBJ)
|
||||
TOOLSOBJ = $(LBURGOBJ) $(Q3CPPOBJ) $(Q3RCCOBJ) $(Q3LCCOBJ) $(Q3ASMOBJ)
|
||||
|
@ -3131,6 +3258,9 @@ ifneq ($(BUILD_CLIENT),0)
|
|||
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/renderer_opengl2_$(SHLIBNAME) $(COPYBINDIR)/renderer_opengl2_$(SHLIBNAME)
|
||||
endif
|
||||
ifneq ($(BUILD_RENDERER_VULKAN),0)
|
||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/renderer_vulkan_$(SHLIBNAME) $(COPYBINDIR)/renderer_vulkan_$(SHLIBNAME)
|
||||
endif
|
||||
else
|
||||
ifneq ($(BUILD_RENDERER_OPENGL1),0)
|
||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/$(CLIENTBIN)$(FULLBINEXT) $(COPYBINDIR)/$(CLIENTBIN)$(FULLBINEXT)
|
||||
|
@ -3138,6 +3268,9 @@ ifneq ($(BUILD_CLIENT),0)
|
|||
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/$(CLIENTBIN)_opengl2$(FULLBINEXT) $(COPYBINDIR)/$(CLIENTBIN)_opengl2$(FULLBINEXT)
|
||||
endif
|
||||
ifneq ($(BUILD_RENDERER_VULKAN),0)
|
||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/$(CLIENTBIN)_vulkan$(FULLBINEXT) $(COPYBINDIR)/$(CLIENTBIN)_vulkan$(FULLBINEXT)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -3185,6 +3318,7 @@ clean2:
|
|||
@rm -f $(OBJ_D_FILES)
|
||||
@rm -f $(STRINGOBJ)
|
||||
@rm -f $(TARGETS)
|
||||
@rm -rf $(Q3VKOBJ)
|
||||
@rm -f $(GENERATEDTARGETS)
|
||||
|
||||
toolsclean: toolsclean-debug toolsclean-release
|
||||
|
|
|
@ -147,6 +147,7 @@ Makefile.local:
|
|||
USE_RENDERER_DLOPEN - build and use the renderer in a library
|
||||
BUILD_RENDERER_OPENGL1 build the opengl1 client / renderer library
|
||||
BUILD_RENDERER_OPENGL2 build the opengl2 client / renderer library
|
||||
BUILD_RENDERER_VULKAN build the vulkan client / renderer library
|
||||
USE_YACC - use yacc to update code/tools/lcc/lburg/gram.c
|
||||
BASEGAME - rename 'baseq3'
|
||||
BASEGAME_CFLAGS - custom CFLAGS for basegame
|
||||
|
@ -199,6 +200,12 @@ set using command line arguments:
|
|||
ioquake3 +set cl_renderer opengl2 +set r_preferOpenGLES 1
|
||||
|
||||
|
||||
# Vulkan support
|
||||
|
||||
The vulkan rendender can be enabled by:
|
||||
|
||||
ioquake3 +set cl_renderer vulkan
|
||||
|
||||
# Console
|
||||
|
||||
## New cvars
|
||||
|
|
43
code/renderervk/RB_DrawNormals.c
Normal file
43
code/renderervk/RB_DrawNormals.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "tr_backend.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
#include "tr_globals.h"
|
||||
#include "vk_pipelines.h"
|
||||
|
||||
/*
|
||||
================
|
||||
Draws vertex normals for debugging
|
||||
================
|
||||
*/
|
||||
void RB_DrawNormals (shaderCommands_t* pTess, int numVertexes )
|
||||
{
|
||||
// VULKAN
|
||||
// int numVertexes = tess.numVertexes;
|
||||
vec4_t xyz[SHADER_MAX_VERTEXES];
|
||||
memcpy(xyz, pTess->xyz, numVertexes * sizeof(vec4_t));
|
||||
|
||||
memset(pTess->svars.colors, tr.identityLightByte, SHADER_MAX_VERTEXES * sizeof(color4ub_t));
|
||||
|
||||
int i = 0;
|
||||
while (i < numVertexes)
|
||||
{
|
||||
int count = numVertexes - i;
|
||||
if (count >= SHADER_MAX_VERTEXES/2 - 1)
|
||||
count = SHADER_MAX_VERTEXES/2 - 1;
|
||||
|
||||
int k;
|
||||
for (k = 0; k < count; k++)
|
||||
{
|
||||
VectorCopy(xyz[i + k], pTess->xyz[2*k]);
|
||||
VectorMA(xyz[i + k], 2, pTess->normal[i + k], pTess->xyz[2*k + 1]);
|
||||
}
|
||||
pTess->numVertexes = 2 * count;
|
||||
pTess->numIndexes = 0;
|
||||
|
||||
vk_UploadXYZI(pTess->xyz, pTess->numVertexes, NULL, 0);
|
||||
|
||||
updateMVP(backEnd.viewParms.isPortal, backEnd.projection2D, getptr_modelview_matrix());
|
||||
vk_shade_geometry(g_stdPipelines.normals_debug_pipeline, VK_FALSE, DEPTH_RANGE_ZERO, VK_FALSE);
|
||||
|
||||
i += count;
|
||||
}
|
||||
}
|
8
code/renderervk/RB_DrawNormals.h
Normal file
8
code/renderervk/RB_DrawNormals.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef RB_SHOW_NORMALS_H_
|
||||
#define RB_SHOW_NORMALS_H_
|
||||
|
||||
struct shaderCommands_s;
|
||||
|
||||
void RB_DrawNormals (struct shaderCommands_s* input , int numVertexes );
|
||||
|
||||
#endif
|
30
code/renderervk/RB_DrawTris.c
Normal file
30
code/renderervk/RB_DrawTris.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include "RB_DrawTris.h"
|
||||
#include "tr_globals.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
#include "vk_pipelines.h"
|
||||
#include "tr_backend.h"
|
||||
/*
|
||||
================
|
||||
Draws triangle outlines for debugging
|
||||
================
|
||||
*/
|
||||
void RB_DrawTris (shaderCommands_t * pInput)
|
||||
{
|
||||
if (vk.features.fillModeNonSolid == VK_FALSE) {
|
||||
static qboolean printed = qfalse;
|
||||
if (!printed) {
|
||||
ri.Printf(PRINT_WARNING, "RB_ShowTris: fillModeNonSolid not supported.\n");
|
||||
printed = qtrue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
updateCurDescriptor( tr.whiteImage->descriptor_set, 0);
|
||||
|
||||
// VULKAN
|
||||
|
||||
memset(pInput->svars.colors, 255, pInput->numVertexes * 4 );
|
||||
VkPipeline pipeline = backEnd.viewParms.isMirror ? g_stdPipelines.tris_mirror_debug_pipeline : g_stdPipelines.tris_debug_pipeline;
|
||||
vk_shade_geometry(pipeline, VK_FALSE, DEPTH_RANGE_ZERO, VK_TRUE);
|
||||
}
|
7
code/renderervk/RB_DrawTris.h
Normal file
7
code/renderervk/RB_DrawTris.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef RB_DRAWTRIS_H_
|
||||
#define RB_DRAWTRIS_H_
|
||||
struct shaderCommands_s;
|
||||
|
||||
void RB_DrawTris (struct shaderCommands_s *input);
|
||||
|
||||
#endif
|
85
code/renderervk/RB_ShowImages.c
Normal file
85
code/renderervk/RB_ShowImages.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "tr_backend.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
#include "vk_pipelines.h"
|
||||
#include "glConfig.h"
|
||||
|
||||
/*
|
||||
===============
|
||||
Draw all the images to the screen, on top of whatever was there.
|
||||
This is used to test for texture thrashing.
|
||||
|
||||
Also called by RE_EndRegistration
|
||||
===============
|
||||
*/
|
||||
// TODO: move glConfig retated stuff to glConfig.c,
|
||||
|
||||
|
||||
void RB_ShowImages(image_t ** const pImg, unsigned int N)
|
||||
{
|
||||
|
||||
backEnd.projection2D = qtrue;
|
||||
|
||||
const float black[4] = {0, 0, 0, 1};
|
||||
vk_clearColorAttachments(black);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
R_GetWinResolution(&width, &height);
|
||||
|
||||
const float w = width / 20;
|
||||
const float h = height / 15;
|
||||
|
||||
|
||||
tess.numIndexes = 6;
|
||||
tess.numVertexes = 4;
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < N; ++i)
|
||||
{
|
||||
//image_t* image = tr.images[i];
|
||||
float x = i % 20 * w;
|
||||
float y = i / 20 * h;
|
||||
|
||||
tess.indexes[0] = 0;
|
||||
tess.indexes[1] = 1;
|
||||
tess.indexes[2] = 2;
|
||||
tess.indexes[3] = 0;
|
||||
tess.indexes[4] = 2;
|
||||
tess.indexes[5] = 3;
|
||||
|
||||
tess.xyz[0][0] = x;
|
||||
tess.xyz[0][1] = y;
|
||||
|
||||
tess.xyz[1][0] = x + w;
|
||||
tess.xyz[1][1] = y;
|
||||
|
||||
tess.xyz[2][0] = x + w;
|
||||
tess.xyz[2][1] = y + h;
|
||||
|
||||
tess.xyz[3][0] = x;
|
||||
tess.xyz[3][1] = y + h;
|
||||
|
||||
tess.svars.texcoords[0][0][0] = 0;
|
||||
tess.svars.texcoords[0][0][1] = 0;
|
||||
tess.svars.texcoords[0][1][0] = 1;
|
||||
tess.svars.texcoords[0][1][1] = 0;
|
||||
tess.svars.texcoords[0][2][0] = 1;
|
||||
tess.svars.texcoords[0][2][1] = 1;
|
||||
tess.svars.texcoords[0][3][0] = 0;
|
||||
tess.svars.texcoords[0][3][1] = 1;
|
||||
|
||||
memset( tess.svars.colors, 255, tess.numVertexes * 4 );
|
||||
|
||||
updateCurDescriptor( pImg[i]->descriptor_set, 0);
|
||||
|
||||
vk_UploadXYZI(tess.xyz, 4, tess.indexes, 6);
|
||||
|
||||
// updateMVP(backEnd.viewParms.isPortal, backEnd.projection2D, getptr_modelview_matrix());
|
||||
updateMVP( 0 , 1, getptr_modelview_matrix());
|
||||
|
||||
vk_shade_geometry(g_stdPipelines.images_debug_pipeline, VK_FALSE, DEPTH_RANGE_NORMAL, VK_TRUE);
|
||||
}
|
||||
tess.numIndexes = 0;
|
||||
tess.numVertexes = 0;
|
||||
}
|
6
code/renderervk/RB_ShowImages.h
Normal file
6
code/renderervk/RB_ShowImages.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef RB_SHOW_IMAGES_H_
|
||||
#define RB_SHOW_IMAGES_H_
|
||||
|
||||
void RB_ShowImages(image_t ** const pImg, unsigned int N);
|
||||
|
||||
#endif
|
137
code/renderervk/RB_SurfaceAnim.c
Normal file
137
code/renderervk/RB_SurfaceAnim.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "tr_globals.h"
|
||||
#include "RB_SurfaceAnim.h"
|
||||
#include "tr_backend.h"
|
||||
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface )
|
||||
{
|
||||
int j, k;
|
||||
float backlerp;
|
||||
|
||||
mdrBone_t bones[MDR_MAX_BONES], *bonePtr;
|
||||
|
||||
|
||||
// don't lerp if lerping off, or this is the only frame, or the last frame...
|
||||
if (backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame)
|
||||
{
|
||||
backlerp = 0; // if backlerp is 0, lerping is off and frontlerp is never used
|
||||
}
|
||||
else
|
||||
{
|
||||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
}
|
||||
|
||||
mdrHeader_t* header = (mdrHeader_t *)((unsigned char *)surface + surface->ofsHeader);
|
||||
|
||||
int frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
mdrFrame_t* frame = (mdrFrame_t *)((byte *)header + header->ofsFrames + backEnd.currentEntity->e.frame * frameSize );
|
||||
|
||||
mdrFrame_t* oldFrame = (mdrFrame_t *)((byte *)header + header->ofsFrames + backEnd.currentEntity->e.oldframe * frameSize );
|
||||
|
||||
RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles * 3 );
|
||||
|
||||
int* triangles = (int *) ((byte *)surface + surface->ofsTriangles);
|
||||
int indexes = surface->numTriangles * 3;
|
||||
int baseIndex = tess.numIndexes;
|
||||
int baseVertex = tess.numVertexes;
|
||||
|
||||
// Set up all triangles.
|
||||
for (j = 0 ; j < indexes ; j++)
|
||||
{
|
||||
tess.indexes[baseIndex + j] = baseVertex + triangles[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
|
||||
//
|
||||
// lerp all the needed bones
|
||||
//
|
||||
if ( !backlerp )
|
||||
{
|
||||
// no lerping needed
|
||||
bonePtr = frame->bones;
|
||||
}
|
||||
else
|
||||
{
|
||||
bonePtr = bones;
|
||||
int nBones = header->numBones;
|
||||
int n;
|
||||
float tmp;
|
||||
for ( n = 0 ; n < nBones; n++ )
|
||||
{
|
||||
tmp = frame->bones[n].matrix[0][0];
|
||||
bones[n].matrix[0][0] = tmp + backlerp * (oldFrame->bones[n].matrix[0][0] - tmp);
|
||||
tmp = frame->bones[n].matrix[0][1];
|
||||
bones[n].matrix[0][1] = tmp + backlerp * (oldFrame->bones[n].matrix[0][1] - tmp);
|
||||
tmp = frame->bones[n].matrix[0][2];
|
||||
bones[n].matrix[0][2] = tmp + backlerp * (oldFrame->bones[n].matrix[0][2] - tmp);
|
||||
tmp = frame->bones[n].matrix[0][3];
|
||||
bones[n].matrix[0][3] = tmp + backlerp * (oldFrame->bones[n].matrix[0][3] - tmp);
|
||||
|
||||
tmp = frame->bones[n].matrix[1][0];
|
||||
bones[n].matrix[1][0] = tmp + backlerp * (oldFrame->bones[n].matrix[1][0] - tmp);
|
||||
tmp = frame->bones[n].matrix[1][1];
|
||||
bones[n].matrix[1][1] = tmp + backlerp * (oldFrame->bones[n].matrix[1][1] - tmp);
|
||||
tmp = frame->bones[n].matrix[1][2];
|
||||
bones[n].matrix[1][2] = tmp + backlerp * (oldFrame->bones[n].matrix[1][2] - tmp);
|
||||
tmp = frame->bones[n].matrix[1][3];
|
||||
bones[n].matrix[1][3] = tmp + backlerp * (oldFrame->bones[n].matrix[1][3] - tmp);
|
||||
|
||||
tmp = frame->bones[n].matrix[2][0];
|
||||
bones[n].matrix[2][0] = tmp + backlerp * (oldFrame->bones[n].matrix[2][0] - tmp);
|
||||
tmp = frame->bones[n].matrix[2][1];
|
||||
bones[n].matrix[2][1] = tmp + backlerp * (oldFrame->bones[n].matrix[2][1] - tmp);
|
||||
tmp = frame->bones[n].matrix[2][2];
|
||||
bones[n].matrix[2][2] = tmp + backlerp * (oldFrame->bones[n].matrix[2][2] - tmp);
|
||||
tmp = frame->bones[n].matrix[2][3];
|
||||
bones[n].matrix[2][3] = tmp + backlerp * (oldFrame->bones[n].matrix[2][3] - tmp);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// deform the vertexes by the lerped bones
|
||||
//
|
||||
mdrVertex_t* v = (mdrVertex_t *) ((unsigned char *)surface + surface->ofsVerts);
|
||||
int numVerts = surface->numVerts;
|
||||
for( j = 0; j < numVerts; j++ )
|
||||
{
|
||||
float tempVert[3] = {0, 0, 0};
|
||||
float tempNormal[3] = {0, 0, 0};
|
||||
|
||||
mdrWeight_t *w = v->weights;
|
||||
|
||||
for ( k = 0 ; k < v->numWeights ; k++, w++ )
|
||||
{
|
||||
mdrBone_t* bone = bonePtr + w->boneIndex;
|
||||
|
||||
tempVert[0] += w->boneWeight * ( DotProduct( bone->matrix[0], w->offset ) + bone->matrix[0][3] );
|
||||
tempVert[1] += w->boneWeight * ( DotProduct( bone->matrix[1], w->offset ) + bone->matrix[1][3] );
|
||||
tempVert[2] += w->boneWeight * ( DotProduct( bone->matrix[2], w->offset ) + bone->matrix[2][3] );
|
||||
|
||||
tempNormal[0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal );
|
||||
tempNormal[1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal );
|
||||
tempNormal[2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal );
|
||||
}
|
||||
|
||||
tess.xyz[baseVertex + j][0] = tempVert[0];
|
||||
tess.xyz[baseVertex + j][1] = tempVert[1];
|
||||
tess.xyz[baseVertex + j][2] = tempVert[2];
|
||||
|
||||
tess.normal[baseVertex + j][0] = tempNormal[0];
|
||||
tess.normal[baseVertex + j][1] = tempNormal[1];
|
||||
tess.normal[baseVertex + j][2] = tempNormal[2];
|
||||
|
||||
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
|
||||
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
|
||||
|
||||
//supress GGC strict-alisaing warnning
|
||||
{
|
||||
mdrWeight_t* pTmp = &v->weights[v->numWeights];
|
||||
v = (mdrVertex_t *) pTmp;
|
||||
}
|
||||
}
|
||||
|
||||
tess.numVertexes += surface->numVerts;
|
||||
}
|
5
code/renderervk/RB_SurfaceAnim.h
Normal file
5
code/renderervk/RB_SurfaceAnim.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef RB_SURFACEANIM_H
|
||||
#define RB_SURFACEANIM_H
|
||||
#include "tr_model.h"
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface );
|
||||
#endif
|
148
code/renderervk/README.md
Normal file
148
code/renderervk/README.md
Normal file
|
@ -0,0 +1,148 @@
|
|||
# vulkan backend info
|
||||
* codes in this dir is "borrow" from https://github.com/kennyalive/Quake-III-Arena-Kenny-Edition, I convert cpp to c so that it can compile.
|
||||
|
||||
* vulkan forder is copied form vulkan sdk, not all items in it is used, it need clean.
|
||||
|
||||
* I am a naive programmer, need help, doc and instructions.
|
||||
|
||||
|
||||
# Rendering
|
||||
|
||||
## General setup.
|
||||
|
||||
Single command buffer that records all the commands. Single render pass which specifies color and depth-stencil attachment.
|
||||
Stencil buffer is used to render Q3's stencil shadows (cg\_shadows=2).
|
||||
|
||||
## Geometry.
|
||||
Quake 3 renderer prepares geometry data for each draw call in tess.xyz and tess.indexes arrays.
|
||||
OpenGL backend calls qglDrawElements to feed this geometry to the GPU.
|
||||
Vulkan backend appends this data to geometry buffers that are bound to host visible memory chunk.
|
||||
At the end of the frame when command buffer is submitted to the queue the geometry buffers contain all the geometry data to render the frame.
|
||||
Typically up to 500Kb of vertex data is copied to the vertex buffer and up to 100Kb of index data is copied to the index buffer per frame.
|
||||
|
||||
## Descriptor sets.
|
||||
For each image used by the renderer separate descriptor set is created.
|
||||
Each descriptor set contains single descriptor (combined image sampler).
|
||||
For each draw call either one or two (if lightmap is available) descriptor sets are bound.
|
||||
Descriptor sets are updated only once during initialization.
|
||||
There are no descriptor set updates during frame.
|
||||
|
||||
## Per-primitive uniform data.
|
||||
Vulkan guarantees that minimum size of push constants range is at least 128 bytes.
|
||||
To render ordinary view we use 64 bytes to specify mvp transform.
|
||||
For portaled/mirrored views additional 64 byte are used to specify eye transform and clipping plane.
|
||||
|
||||
Pipeline layout. 2 sets + 128 bytes push constant range.
|
||||
|
||||
## Pipelines.
|
||||
Standard pipelines are created when renderer starts.
|
||||
They are used for skybox rendering, fog/dynamic light effects, shadow volumes and various debug features.
|
||||
Map specific pipelines are created as part of parsing Q3 shaders and are created during map load.
|
||||
For each Q3 shader we create three pipelines: one pipeline to render regular view and two additional pipelines for portal and mirror views.
|
||||
|
||||
## Shaders.
|
||||
Emulate corresponding fixed-function functionality.
|
||||
Vertex shaders are boring with the only thing to mention that for portaled/mirrored views
|
||||
we additionally compute distance to the clipping plane.
|
||||
Fragment shaders do one or two texture lookups and modulate the results by the color.
|
||||
|
||||
## Draw calls.
|
||||
vkCmdDrawIndexed is used to draw geometry in most cases. Additionally there are few debug features that use vkCmdDraw to convey unindexed vertexes.
|
||||
|
||||
## Code
|
||||
vk.h provides interface that brings Vulkan support to Q3 renderer.
|
||||
The interface is quite concise and consists of a dozen of functions that can be divided into 3 categories:
|
||||
initialization functions, resource management functions and rendering setup functions.
|
||||
|
||||
### Initialization:
|
||||
|
||||
* vk\_initialize : initialize Vulkan backend
|
||||
* vk\_shutdown : shutdown Vulkan backend
|
||||
|
||||
### Resource management:
|
||||
|
||||
* images: vk\_create\_image/vk\_upload\_image\_data
|
||||
|
||||
* descriptor sets: vk\_update\_descriptor\_set
|
||||
|
||||
* samplers: vk\_find\_sampler
|
||||
|
||||
* pipelines: vk\_find\_pipeline
|
||||
|
||||
### Rendering setup:
|
||||
|
||||
* vk\_clear\_attachments : clears framebuffer¡¯s attachments.
|
||||
|
||||
* vk\_bind\_geometry : is called when we start drawing new geometry.
|
||||
|
||||
* vk\_shade\_geometry : is called to shade geometry specified with vk\_bind\_geometry. Can be called multiple times for Q3's multi-stage shaders.
|
||||
|
||||
* vk\_begin\_frame/vk\_end\_frame : frame setup.
|
||||
|
||||
* vk\_read\_pixels : takes a screenshot.
|
||||
|
||||
|
||||
### about turn the intensity/gamma of the drawing wondow
|
||||
|
||||
* use r\_gamma in the pulldown window, which nonlinearly correct the image before the uploading to GPU.
|
||||
`\r_gamma 1.5` then `vid_restart`
|
||||
|
||||
* you can also use r\_intensity which turn the intensity linearly.
|
||||
```
|
||||
# 1.5 ~ 2.0 give acceptable result
|
||||
$ \r_intensity 1.8
|
||||
$ \vid_restart
|
||||
```
|
||||
|
||||
* but why, because original gamma setting program turn the light by setting entire destop window.
|
||||
which works on newer computer on the market
|
||||
but not works on some machine. it is buggy and embarrasing when program abnormal quit or stall.
|
||||
|
||||
### new cmd
|
||||
|
||||
* pipelineList: list the pipeline we have created;
|
||||
* gpuMem: image memmory allocated on GPU;
|
||||
* printOR: print the value of backend.or;
|
||||
* displayResoList: list of the display resolution you monitor supported
|
||||
For example:
|
||||
```
|
||||
$ \displayResoList
|
||||
|
||||
Mode 0: 320x240
|
||||
Mode 1: 400x300
|
||||
Mode 2: 512x384
|
||||
Mode 3: 640x480 (480p)
|
||||
Mode 4: 800x600
|
||||
Mode 5: 960x720
|
||||
Mode 6: 1024x768
|
||||
Mode 7: 1152x864
|
||||
Mode 8: 1280x1024
|
||||
Mode 9: 1600x1200
|
||||
Mode 10: 2048x1536
|
||||
Mode 11: 856x480
|
||||
Mode 12: 1280x720 (720p)
|
||||
Mode 13: 1280x768
|
||||
Mode 14: 1280x800
|
||||
Mode 15: 1280x960
|
||||
Mode 16: 1360x768
|
||||
Mode 17: 1366x768
|
||||
Mode 18: 1360x1024
|
||||
Mode 19: 1400x1050
|
||||
Mode 20: 1400x900
|
||||
Mode 21: 1600x900
|
||||
Mode 22: 1680x1050
|
||||
Mode 23: 1920x1080 (1080p)
|
||||
Mode 24: 1920x1200
|
||||
Mode 25: 1920x1440
|
||||
Mode 26: 2560x1080
|
||||
Mode 27: 2560x1600
|
||||
Mode 28: 3840x2160 (4K)
|
||||
|
||||
$ \r_mode 12
|
||||
$ \vid_restart
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TODO:
|
||||
* get cpu, gpu, memory usage
|
142
code/renderervk/RE_RegisterModel.c
Normal file
142
code/renderervk/RE_RegisterModel.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
#include "tr_local.h"
|
||||
#include "tr_model.h"
|
||||
#include "tr_globals.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *ext;
|
||||
qhandle_t (* ModelLoader)( const char * , model_t * );
|
||||
} modelExtToLoaderMap_t;
|
||||
|
||||
// Note that the ordering indicates the order of preference used
|
||||
// when there are multiple models of different formats available
|
||||
static const modelExtToLoaderMap_t modelLoaders[ ] =
|
||||
{
|
||||
{ "md3", R_RegisterMD3 },
|
||||
{ "mdr", R_RegisterMDR },
|
||||
{ "iqm", R_RegisterIQM }
|
||||
};
|
||||
|
||||
static const uint32_t numModelLoaders = ARRAY_LEN(modelLoaders);
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
Loads in a model for the given name
|
||||
|
||||
Zero will be returned if the model fails to load.
|
||||
An entry will be retained for failed models as an
|
||||
optimization to prevent disk rescanning if they are
|
||||
asked for again.
|
||||
====================
|
||||
*/
|
||||
qhandle_t RE_RegisterModel( const char *name )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "RegisterModel: %s. \n", name);
|
||||
|
||||
qboolean orgNameFailed = qfalse;
|
||||
int orgLoader = -1;
|
||||
|
||||
if ( !name || !name[0] ) {
|
||||
ri.Printf( PRINT_WARNING, "RE_RegisterModel: NULL name\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
ri.Printf( PRINT_WARNING, "Model name exceeds MAX_QPATH\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// search the currently loaded models
|
||||
//
|
||||
qhandle_t hModel;
|
||||
|
||||
for ( hModel = 1; hModel < tr.numModels; hModel++ )
|
||||
{
|
||||
if ( 0 == strcmp( tr.models[hModel]->name, name ) )
|
||||
{
|
||||
if( tr.models[hModel]->type == MOD_BAD )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "tr.models[%d]->type = MOD_BAD \n", hModel);
|
||||
return 0;
|
||||
}
|
||||
return hModel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// allocate a new model_t
|
||||
ri.Printf( PRINT_ALL, "Allocate Memory for %s. \n", name);
|
||||
|
||||
model_t* mod = ri.Hunk_Alloc( sizeof( model_t ), h_low );
|
||||
|
||||
// only set the name after the model has been successfully loaded
|
||||
strncpy(mod->name, name, MAX_QPATH);
|
||||
mod->index = tr.numModels;
|
||||
mod->type = MOD_BAD;
|
||||
mod->numLods = 0;
|
||||
|
||||
tr.models[tr.numModels] = mod;
|
||||
|
||||
if ( ++tr.numModels > MAX_MOD_KNOWN )
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterModel: MAX_MOD_KNOWN.\n");
|
||||
}
|
||||
|
||||
// load the files
|
||||
|
||||
const char* dot = strrchr(name, '.');
|
||||
|
||||
if(dot != NULL)
|
||||
{
|
||||
if( (dot[1] == 'm') && (dot[2] == 'd') && (dot[3] == '3') )
|
||||
{
|
||||
hModel = R_RegisterMD3(name, mod);
|
||||
}
|
||||
else if( (dot[1] == 'm') && (dot[2] == 'd') && (dot[3] == 'r') )
|
||||
{
|
||||
hModel = R_RegisterMDR(name, mod);
|
||||
}
|
||||
else if( (dot[1] == 'i') && (dot[2] == 'q') && (dot[3] == 'm') )
|
||||
{
|
||||
hModel = R_RegisterIQM(name, mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, " %s format not support now. \n ", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "RegisterModel: %s without extention. "
|
||||
" Try and find a suitable match using all the model formats supported\n", name);
|
||||
|
||||
uint32_t i;
|
||||
for( i = 0; i < numModelLoaders; i++ )
|
||||
{
|
||||
if (i == orgLoader)
|
||||
continue;
|
||||
|
||||
char altName[ MAX_QPATH * 2 ] = {0};
|
||||
snprintf( altName, sizeof (altName), "%s.%s", name, modelLoaders[ i ].ext );
|
||||
|
||||
// Load
|
||||
hModel = modelLoaders[ i ].ModelLoader( altName, mod );
|
||||
|
||||
if( hModel )
|
||||
{
|
||||
if( orgNameFailed )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "WARNING: %s not present, using %s instead\n",
|
||||
name, altName );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hModel;
|
||||
}
|
109
code/renderervk/R_DebugGraphics.c
Normal file
109
code/renderervk/R_DebugGraphics.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
#include "tr_globals.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
#include "vk_instance.h"
|
||||
#include "vk_image.h"
|
||||
#include "vk_pipelines.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "tr_backend.h"
|
||||
#include "ref_import.h"
|
||||
#include "matrix_multiplication.h"
|
||||
|
||||
|
||||
void R_DebugPolygon( int color, int numPoints, float *points )
|
||||
{
|
||||
if (numPoints < 3 || numPoints >= SHADER_MAX_VERTEXES/2)
|
||||
return;
|
||||
int i;
|
||||
// In Vulkan we don't have GL_POLYGON + GLS_POLYMODE_LINE equivalent,
|
||||
// so we use lines to draw polygon outlines.This approach has additional
|
||||
// implication that we need to do manual backface culling to reject outlines
|
||||
// that belong to back facing polygons. The code assumes that polygons are convex.
|
||||
|
||||
// Backface culling.
|
||||
float pa[3], pb[3], p[3];
|
||||
|
||||
|
||||
const float* m = getptr_modelview_matrix();
|
||||
|
||||
// transform to eye space
|
||||
Vec3Transform(points, m, pa);
|
||||
Vec3Transform(&points[3], m, pb);
|
||||
VectorSubtract(pb, pa, p);
|
||||
|
||||
float n[3];
|
||||
for (i = 2; i < numPoints; i++)
|
||||
{
|
||||
Vec3Transform(&points[3*i], m, pb);
|
||||
float q[3];
|
||||
VectorSubtract(pb, pa, q);
|
||||
CrossProduct(q, p, n);
|
||||
if (VectorLength(n) > 1e-5)
|
||||
break;
|
||||
}
|
||||
if (DotProduct(n, pa) >= 0)
|
||||
return; // discard backfacing polygon
|
||||
|
||||
// Solid shade.
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
VectorCopy(&points[3*i], tess.xyz[i]);
|
||||
|
||||
tess.svars.colors[i][0] = (color&1) ? 255 : 0;
|
||||
tess.svars.colors[i][1] = (color&2) ? 255 : 0;
|
||||
tess.svars.colors[i][2] = (color&4) ? 255 : 0;
|
||||
tess.svars.colors[i][3] = 255;
|
||||
}
|
||||
tess.numVertexes = numPoints;
|
||||
|
||||
tess.numIndexes = 0;
|
||||
for (i = 1; i < numPoints - 1; i++)
|
||||
{
|
||||
tess.indexes[tess.numIndexes + 0] = 0;
|
||||
tess.indexes[tess.numIndexes + 1] = i;
|
||||
tess.indexes[tess.numIndexes + 2] = i + 1;
|
||||
tess.numIndexes += 3;
|
||||
}
|
||||
|
||||
vk_UploadXYZI(tess.xyz, tess.numVertexes, tess.indexes, tess.numIndexes);
|
||||
|
||||
updateMVP(backEnd.viewParms.isPortal, backEnd.projection2D, getptr_modelview_matrix());
|
||||
|
||||
vk_shade_geometry(g_stdPipelines.surface_debug_pipeline_solid, VK_FALSE, DEPTH_RANGE_NORMAL, VK_TRUE);
|
||||
|
||||
|
||||
// Outline.
|
||||
memset(tess.svars.colors, tr.identityLightByte, numPoints * 2 * sizeof(color4ub_t));
|
||||
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
VectorCopy(&points[3*i], tess.xyz[2*i]);
|
||||
VectorCopy(&points[3*((i + 1) % numPoints)], tess.xyz[2*i + 1]);
|
||||
}
|
||||
tess.numVertexes = numPoints * 2;
|
||||
tess.numIndexes = 0;
|
||||
|
||||
vk_UploadXYZI(tess.xyz, tess.numVertexes, tess.indexes, 0);
|
||||
|
||||
updateMVP(backEnd.viewParms.isPortal, backEnd.projection2D, getptr_modelview_matrix());
|
||||
vk_shade_geometry(g_stdPipelines.surface_debug_pipeline_outline, VK_FALSE, DEPTH_RANGE_ZERO, VK_FALSE);
|
||||
|
||||
tess.numVertexes = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
R_DebugGraphics
|
||||
|
||||
Visualization aid for movement clipping debugging
|
||||
====================
|
||||
*/
|
||||
void R_DebugGraphics( void )
|
||||
{
|
||||
// the render thread can't make callbacks to the main thread
|
||||
if ( tr.registered ) {
|
||||
R_IssueRenderCommands( qfalse );
|
||||
}
|
||||
|
||||
updateCurDescriptor( tr.whiteImage->descriptor_set, 0);
|
||||
ri.CM_DrawDebugSurface( R_DebugPolygon );
|
||||
}
|
5
code/renderervk/R_DebugGraphics.h
Normal file
5
code/renderervk/R_DebugGraphics.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef R_DEBUG_GRAPHICS_H_
|
||||
#define R_DEBUG_GRAPHICS_H_
|
||||
|
||||
void R_DebugGraphics(void);
|
||||
#endif
|
678
code/renderervk/R_FindShader.c
Normal file
678
code/renderervk/R_FindShader.c
Normal file
|
@ -0,0 +1,678 @@
|
|||
#include "tr_local.h"
|
||||
#include "vk_image.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
#include "R_PrintMat.h"
|
||||
#include "R_Parser.h"
|
||||
#include "tr_globals.h"
|
||||
#include "tr_shader.h"
|
||||
|
||||
|
||||
#define MAX_SHADERTEXT_HASH 2048
|
||||
static char** shaderTextHashTable[MAX_SHADERTEXT_HASH] ={ 0 };
|
||||
|
||||
#define FILE_HASH_SIZE 1024
|
||||
static shader_t* hashTable[FILE_HASH_SIZE] = {0};
|
||||
|
||||
|
||||
static char *s_shaderText = NULL;
|
||||
|
||||
/*
|
||||
================
|
||||
return a hash value for the filename
|
||||
================
|
||||
*/
|
||||
static int generateHashValue( const char *fname, const int size )
|
||||
{
|
||||
int i = 0;
|
||||
long hash = 0;
|
||||
|
||||
while (fname[i] != '\0')
|
||||
{
|
||||
char letter = tolower(fname[i]);
|
||||
if (letter =='.') break; // don't include extension
|
||||
if (letter =='\\') letter = '/'; // damn path names
|
||||
if (letter == PATH_SEP) letter = '/'; // damn path names
|
||||
hash+=(long)(letter)*(i+119);
|
||||
i++;
|
||||
}
|
||||
hash = (hash ^ (hash >> 10) ^ (hash >> 20));
|
||||
hash &= (size-1);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void R_ClearShaderHashTable()
|
||||
{
|
||||
memset(hashTable, 0, sizeof(hashTable));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
FindShaderInShaderText
|
||||
|
||||
Scans the combined text description of all the shader files for the given
|
||||
shader name. If found, it will return a valid shader, return NULL if not found.
|
||||
=====================
|
||||
*/
|
||||
static char* FindShaderInShaderText( const char *shadername )
|
||||
{
|
||||
|
||||
// ri.Printf( PRINT_ALL, "FindShaderInShaderText: %s\n", shadername);
|
||||
|
||||
int hash = generateHashValue(shadername, MAX_SHADERTEXT_HASH);
|
||||
|
||||
int i;
|
||||
for (i = 0; shaderTextHashTable[hash][i]; i++)
|
||||
{
|
||||
char* p = shaderTextHashTable[hash][i];
|
||||
char* token = R_ParseExt(&p, qtrue);
|
||||
if ( !Q_stricmp( token, shadername ) )
|
||||
{
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
char* p = s_shaderText;
|
||||
|
||||
if ( !p ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// look for label
|
||||
while ( 1 )
|
||||
{
|
||||
char* token = R_ParseExt( &p, qtrue );
|
||||
|
||||
if( token[0] == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( token, shadername ) )
|
||||
{
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// skip the definition, tr_common
|
||||
// -> R_SkipBracedSection ?
|
||||
SkipBracedSection( &p , 0);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_FindShader
|
||||
|
||||
Will always return a valid shader, but it might be the
|
||||
default shader if the real one can't be found.
|
||||
|
||||
In the interest of not requiring an explicit shader text entry to
|
||||
be defined for every single image used in the game, three default
|
||||
shader behaviors can be auto-created for any image:
|
||||
|
||||
If lightmapIndex == LIGHTMAP_NONE, then the image will have
|
||||
dynamic diffuse lighting applied to it, as apropriate for most
|
||||
entity skin surfaces.
|
||||
|
||||
If lightmapIndex == LIGHTMAP_2D, then the image will be used
|
||||
for 2D rendering unless an explicit shader is found
|
||||
|
||||
If lightmapIndex == LIGHTMAP_BY_VERTEX, then the image will use
|
||||
the vertex rgba modulate values, as apropriate for misc_model
|
||||
pre-lit surfaces.
|
||||
|
||||
Other lightmapIndex values will have a lightmap stage created
|
||||
and src*dest blending applied with the texture, as apropriate for
|
||||
most world construction surfaces.
|
||||
|
||||
===============
|
||||
*/
|
||||
|
||||
extern void setDefaultShader(void);
|
||||
|
||||
|
||||
shader_t* R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImage )
|
||||
{
|
||||
char strippedName[MAX_QPATH] = {0};
|
||||
|
||||
if ( name == NULL )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "Find Shader: name = NULL\n");
|
||||
return tr.defaultShader;
|
||||
}
|
||||
|
||||
|
||||
// use (fullbright) vertex lighting if the bsp file doesn't have lightmaps
|
||||
if ( (lightmapIndex >= 0) && (lightmapIndex >= tr.numLightmaps) )
|
||||
{
|
||||
lightmapIndex = LIGHTMAP_BY_VERTEX;
|
||||
}
|
||||
else if ( lightmapIndex < LIGHTMAP_2D )
|
||||
{
|
||||
// negative lightmap indexes cause stray pointers (think tr.lightmaps[lightmapIndex])
|
||||
ri.Printf( PRINT_WARNING, "WARNING: shader '%s' has invalid lightmap index of %d\n", name, lightmapIndex );
|
||||
lightmapIndex = LIGHTMAP_BY_VERTEX;
|
||||
}
|
||||
|
||||
|
||||
R_StripExtension(name, strippedName, sizeof(strippedName));
|
||||
|
||||
int hash = generateHashValue(strippedName, FILE_HASH_SIZE);
|
||||
|
||||
//
|
||||
// see if the shader is already loaded
|
||||
//
|
||||
{
|
||||
shader_t* sh = hashTable[hash];
|
||||
while ( sh )
|
||||
{
|
||||
// NOTE: if there was no shader or image available with the name strippedName
|
||||
// then a default shader is created with lightmapIndex == LIGHTMAP_NONE, so we
|
||||
// have to check all default shaders otherwise for every call to R_findShader
|
||||
// with that same strippedName a new default shader is created.
|
||||
if ( ( 0 == Q_stricmp(sh->name, strippedName) ) && (sh->lightmapIndex == lightmapIndex || sh->defaultShader) )
|
||||
{
|
||||
// match found
|
||||
return sh;
|
||||
}
|
||||
|
||||
sh = sh->next;
|
||||
}
|
||||
}
|
||||
|
||||
R_SetTheShader( strippedName, lightmapIndex );
|
||||
|
||||
//
|
||||
// attempt to define shader from an explicit parameter file
|
||||
//
|
||||
{
|
||||
char* shaderText = FindShaderInShaderText( strippedName );
|
||||
if ( shaderText )
|
||||
{
|
||||
// enable this when building a pak file to get a global list
|
||||
// of all explicit shaders
|
||||
if ( r_printShaders->integer ) {
|
||||
ri.Printf( PRINT_ALL, "*SHADER* %s\n", name );
|
||||
}
|
||||
|
||||
if ( !ParseShader( &shaderText ) )
|
||||
{
|
||||
// had errors, so use default shader
|
||||
R_SetDefaultShader( );
|
||||
ri.Printf( PRINT_WARNING, "ParseShader: %s had errors\n", strippedName );
|
||||
}
|
||||
|
||||
return FinishShader();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if not defined in the in-memory shader descriptions,
|
||||
// look for a single supported image file
|
||||
|
||||
/*
|
||||
char fileName[128] = {0};
|
||||
{
|
||||
qboolean ptExist = qfalse;
|
||||
int i = 0;
|
||||
|
||||
while(name[i] != '\0')
|
||||
{
|
||||
fileName[i] = name[i];
|
||||
if(fileName[i] == '.')
|
||||
{
|
||||
ptExist = qtrue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// if path doesn't have an extension, then append
|
||||
// the specified one (which should include the .)
|
||||
|
||||
if(ptExist == qtrue)
|
||||
fileName[i] = '\0';
|
||||
else
|
||||
{
|
||||
fileName[i++] = '.';
|
||||
fileName[i++] = 't';
|
||||
fileName[i++] = 'g';
|
||||
fileName[i++] = 'a';
|
||||
fileName[i] = '\0';
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
image_t* image = R_FindImageFile( name, mipRawImage, mipRawImage, mipRawImage ? GL_REPEAT : GL_CLAMP );
|
||||
|
||||
if(image != NULL)
|
||||
{
|
||||
// create the default shading commands
|
||||
R_CreateDefaultShadingCmds(name, image);
|
||||
}
|
||||
else
|
||||
{
|
||||
setDefaultShader();
|
||||
}
|
||||
|
||||
|
||||
return FinishShader();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
This is the exported shader entry point for the rest of the system
|
||||
It will always return an index that will be valid.
|
||||
|
||||
This should really only be used for explicit shaders, because there is no
|
||||
way to ask for different implicit lighting modes (vertex, lightmap, etc)
|
||||
====================
|
||||
*/
|
||||
qhandle_t RE_RegisterShader( const char *name )
|
||||
{
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
ri.Printf(PRINT_ALL, "Shader name exceeds MAX_QPATH\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
shader_t* sh = R_FindShader( name, LIGHTMAP_2D, qtrue );
|
||||
|
||||
// we want to return 0 if the shader failed to
|
||||
// load for some reason, but R_FindShader should
|
||||
// still keep a name allocated for it, so if
|
||||
// something calls RE_RegisterShader again with
|
||||
// the same name, we don't try looking for it again
|
||||
if ( sh->defaultShader ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sh->index;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
RE_RegisterShaderNoMip
|
||||
|
||||
For menu graphics that should never be picmiped
|
||||
====================
|
||||
*/
|
||||
qhandle_t RE_RegisterShaderNoMip( const char *name )
|
||||
{
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
ri.Printf(PRINT_ALL, "Shader name exceeds MAX_QPATH\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
shader_t* sh = R_FindShader( name, LIGHTMAP_2D, qfalse );
|
||||
|
||||
// we want to return 0 if the shader failed to
|
||||
// load for some reason, but R_FindShader should
|
||||
// still keep a name allocated for it, so if
|
||||
// something calls RE_RegisterShader again with
|
||||
// the same name, we don't try looking for it again
|
||||
if ( sh->defaultShader ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sh->index;
|
||||
}
|
||||
|
||||
|
||||
qhandle_t R_RegisterShaderFromImage(const char *name, int lightmapIndex, image_t *image, qboolean mipRawImage)
|
||||
{
|
||||
|
||||
int hash = generateHashValue(name, FILE_HASH_SIZE);
|
||||
|
||||
//
|
||||
// see if the shader is already loaded
|
||||
//
|
||||
shader_t* sh = hashTable[hash];
|
||||
while(sh)
|
||||
{
|
||||
// NOTE: if there was no shader or image available with the name strippedName
|
||||
// then a default shader is created with lightmapIndex == LIGHTMAP_NONE, so we
|
||||
// have to check all default shaders otherwise for every call to R_FindShader
|
||||
// with that same strippedName a new default shader is created.
|
||||
if ( (sh->lightmapIndex == lightmapIndex || sh->defaultShader) &&
|
||||
// index by name
|
||||
!Q_stricmp(sh->name, name)) {
|
||||
// match found
|
||||
return sh->index;
|
||||
}
|
||||
|
||||
sh = sh->next;
|
||||
}
|
||||
|
||||
|
||||
R_SetTheShader( name, lightmapIndex );
|
||||
|
||||
|
||||
//
|
||||
// create the default shading commands
|
||||
//
|
||||
R_CreateDefaultShadingCmds(name, image);
|
||||
|
||||
sh = FinishShader();
|
||||
return sh->index;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
ScanAndLoadShaderFiles
|
||||
|
||||
Finds and loads all .shader files, combining them into
|
||||
a single large text block that can be scanned for shader names
|
||||
=====================
|
||||
*/
|
||||
|
||||
static void BuildSingleLargeBuffer(char* buffers[], const int nShaderFiles, const int sum)
|
||||
{
|
||||
// build single large buffer
|
||||
s_shaderText = ri.Hunk_Alloc( sum + nShaderFiles*2, h_low );
|
||||
s_shaderText[ 0 ] = '\0';
|
||||
|
||||
char* textEnd = s_shaderText;
|
||||
int n = nShaderFiles - 1;
|
||||
// free in reverse order, so the temp files are all dumped
|
||||
for ( n = nShaderFiles - 1; n >= 0 ; n-- )
|
||||
{
|
||||
if ( buffers[n] )
|
||||
{
|
||||
strcat( textEnd, buffers[n] );
|
||||
strcat( textEnd, "\n" );
|
||||
|
||||
textEnd += strlen(buffers[n]) + 1;
|
||||
|
||||
ri.FS_FreeFile( buffers[n] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Shader_DoSimpleCheck(char* name, char* p)
|
||||
{
|
||||
char* pBuf = p;
|
||||
|
||||
R_BeginParseSession(name);
|
||||
|
||||
while(1)
|
||||
{
|
||||
char* token = R_ParseExt(&p, qtrue);
|
||||
if(0 == *token)
|
||||
break;
|
||||
char shaderName[64]={0};
|
||||
strncpy(shaderName, token, sizeof(shaderName));
|
||||
|
||||
int shaderLine = R_GetCurrentParseLine();
|
||||
|
||||
token = R_ParseExt(&p, qtrue);
|
||||
if(token[0] != '{' || token[1] != '\0')
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "WARNING: Ignoring shader file %s. Shader \"%s\" on line %d missing opening brace",
|
||||
name, shaderName, shaderLine);
|
||||
if (token[0])
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, " (found \"%s\" on line %d)", token, R_GetCurrentParseLine());
|
||||
}
|
||||
ri.Printf(PRINT_WARNING, ".\n");
|
||||
ri.FS_FreeFile(pBuf);
|
||||
pBuf = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!SkipBracedSection(&p, 1))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "WARNING: Ignoring shader file %s. Shader \"%s\" on line %d missing closing brace.\n",
|
||||
name, shaderName, shaderLine);
|
||||
ri.FS_FreeFile(pBuf);
|
||||
pBuf = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void SetShaderTextHashTableSizes( void )
|
||||
{
|
||||
int shaderTextHashTableSizes[MAX_SHADERTEXT_HASH];
|
||||
memset(shaderTextHashTableSizes, 0, sizeof(shaderTextHashTableSizes));
|
||||
|
||||
int size = 0;
|
||||
|
||||
char* p = s_shaderText;
|
||||
// look for shader names
|
||||
while ( 1 )
|
||||
{
|
||||
char* token = R_ParseExt( &p, qtrue );
|
||||
if ( token[0] == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
int hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
|
||||
shaderTextHashTableSizes[hash]++;
|
||||
size++;
|
||||
SkipBracedSection(&p, 0);
|
||||
}
|
||||
|
||||
size += MAX_SHADERTEXT_HASH;
|
||||
|
||||
|
||||
char* hashMem = (char*)ri.Hunk_Alloc( size * sizeof(char *), h_low );
|
||||
|
||||
int i;
|
||||
for (i = 0; i < MAX_SHADERTEXT_HASH; i++)
|
||||
{
|
||||
shaderTextHashTable[i] = (char **) hashMem;
|
||||
hashMem += (shaderTextHashTableSizes[i] + 1) * sizeof(char *);
|
||||
}
|
||||
|
||||
memset(shaderTextHashTableSizes, 0, sizeof(shaderTextHashTableSizes));
|
||||
|
||||
p = s_shaderText;
|
||||
// look for shader names
|
||||
while ( 1 )
|
||||
{
|
||||
char* oldp = p;
|
||||
char* token = R_ParseExt( &p, qtrue );
|
||||
|
||||
if ( token[0] == 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
int hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
|
||||
shaderTextHashTable[hash][shaderTextHashTableSizes[hash]++] = oldp;
|
||||
|
||||
SkipBracedSection(&p, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define MAX_SHADER_FILES 4096
|
||||
void ScanAndLoadShaderFiles( void )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "ScanAndLoadShaderFiles\n" );
|
||||
|
||||
char *buffers[MAX_SHADER_FILES] = {0};
|
||||
int numShaderFiles = 0;
|
||||
|
||||
|
||||
// scan for shader files
|
||||
char** shaderFiles = ri.FS_ListFiles( "scripts", ".shader", &numShaderFiles );
|
||||
|
||||
if ( !shaderFiles || !numShaderFiles )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: no shader files found\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( numShaderFiles > MAX_SHADER_FILES ) {
|
||||
numShaderFiles = MAX_SHADER_FILES;
|
||||
ri.Printf( PRINT_WARNING, "numShaderFiles > MAX_SHADER_FILES\n" );
|
||||
}
|
||||
|
||||
// load and parse shader files
|
||||
long sum = 0;
|
||||
int i;
|
||||
for ( i = 0; i < numShaderFiles; i++ )
|
||||
{
|
||||
char filename[128] = {0};
|
||||
|
||||
snprintf( filename, sizeof( filename ), "scripts/%s", shaderFiles[i] );
|
||||
ri.Printf( PRINT_ALL, "...loading '%s'\n", filename );
|
||||
long summand = ri.FS_ReadFile( filename, (void**)&buffers[i] );
|
||||
|
||||
if ( !buffers[i] )
|
||||
ri.Error( ERR_DROP, "Couldn't load %s", filename );
|
||||
|
||||
// Do a simple check on the shader structure in that file
|
||||
// to make sure one bad shader file cannot fuck up all other shaders.
|
||||
Shader_DoSimpleCheck(filename, buffers[i]);
|
||||
|
||||
if (buffers[i])
|
||||
sum += summand;
|
||||
}
|
||||
|
||||
// build single large buffer
|
||||
BuildSingleLargeBuffer(buffers, numShaderFiles, sum);
|
||||
|
||||
R_Compress( s_shaderText );
|
||||
|
||||
|
||||
// free up memory
|
||||
ri.FS_FreeFileList( shaderFiles );
|
||||
|
||||
|
||||
SetShaderTextHashTableSizes();
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
RE_RegisterShader
|
||||
|
||||
This is the exported shader entry point for the rest of the system
|
||||
It will always return an index that will be valid.
|
||||
|
||||
This should really only be used for explicit shaders, because there is no
|
||||
way to ask for different implicit lighting modes (vertex, lightmap, etc)
|
||||
====================
|
||||
*/
|
||||
|
||||
void RE_RemapShader(const char *shaderName, const char *newShaderName, const char *timeOffset)
|
||||
{
|
||||
|
||||
shader_t* sh2 = tr.defaultShader;
|
||||
|
||||
//R_FindShaderByName( newShaderName );
|
||||
{
|
||||
char strippedName2[MAX_QPATH];
|
||||
R_StripExtension( newShaderName, strippedName2, sizeof(strippedName2) );
|
||||
|
||||
int hash2 = generateHashValue(strippedName2, FILE_HASH_SIZE);
|
||||
|
||||
// see if the shader is already loaded
|
||||
shader_t* pSh = hashTable[hash2];
|
||||
|
||||
while ( pSh )
|
||||
{
|
||||
// NOTE: if there was no shader or image available with the name strippedName
|
||||
// then a default shader is created with lightmapIndex == LIGHTMAP_NONE, so we
|
||||
// have to check all default shaders otherwise for every call to R_findShader
|
||||
// with that same strippedName a new default shader is created.
|
||||
if (Q_stricmp(pSh->name, strippedName2) == 0)
|
||||
{
|
||||
// match found
|
||||
sh2 = pSh;
|
||||
break;
|
||||
}
|
||||
pSh=pSh->next;
|
||||
}
|
||||
|
||||
if (sh2 == tr.defaultShader)
|
||||
{
|
||||
qhandle_t h;
|
||||
//h = RE_RegisterShaderLightMap(newShaderName, 0);
|
||||
|
||||
pSh = R_FindShader( newShaderName, 0, qtrue );
|
||||
|
||||
if ( pSh->defaultShader )
|
||||
{
|
||||
h = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = pSh->index;
|
||||
}
|
||||
|
||||
sh2 = R_GetShaderByHandle(h);
|
||||
|
||||
if( (sh2 == tr.defaultShader) || (sh2 == NULL) )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: R_RemapShader: shader %s not found\n", newShaderName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char strippedName[MAX_QPATH];
|
||||
R_StripExtension(shaderName, strippedName, sizeof(strippedName));
|
||||
int hash = generateHashValue(strippedName, FILE_HASH_SIZE);
|
||||
shader_t* sh = hashTable[hash];
|
||||
// remap all the shaders with the given name
|
||||
// even tho they might have different lightmaps
|
||||
|
||||
while( sh )
|
||||
{
|
||||
if (Q_stricmp(sh->name, strippedName) == 0)
|
||||
{
|
||||
if (sh != sh2)
|
||||
{
|
||||
sh->remappedShader = sh2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sh->remappedShader = NULL;
|
||||
}
|
||||
}
|
||||
sh = sh->next;
|
||||
}
|
||||
|
||||
if (timeOffset)
|
||||
{
|
||||
sh2->timeOffset = atof(timeOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void R_UpdateShaderHashTable(shader_t* newShader)
|
||||
{
|
||||
int hash = generateHashValue(newShader->name, FILE_HASH_SIZE);
|
||||
newShader->next = hashTable[hash];
|
||||
hashTable[hash] = newShader;
|
||||
}
|
238
code/renderervk/R_ImageBMP.c
Normal file
238
code/renderervk/R_ImageBMP.c
Normal file
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "ref_import.h"
|
||||
#include "image_loader.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char id[2];
|
||||
unsigned fileSize;
|
||||
unsigned reserved0;
|
||||
unsigned bitmapDataOffset;
|
||||
unsigned bitmapHeaderSize;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned short planes;
|
||||
unsigned short bitsPerPixel;
|
||||
unsigned compression;
|
||||
unsigned bitmapDataSize;
|
||||
unsigned hRes;
|
||||
unsigned vRes;
|
||||
unsigned colors;
|
||||
unsigned importantColors;
|
||||
unsigned char palette[256][4];
|
||||
} BMPHeader_t;
|
||||
|
||||
void R_LoadBMP( const char *name, byte **pic, int *width, int *height )
|
||||
{
|
||||
int columns, rows;
|
||||
unsigned numPixels;
|
||||
byte *pixbuf;
|
||||
int row, column;
|
||||
byte *buf_p;
|
||||
byte *end;
|
||||
|
||||
char * buffer;
|
||||
int length;
|
||||
BMPHeader_t bmpHeader;
|
||||
byte *bmpRGBA;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
if(width)
|
||||
*width = 0;
|
||||
|
||||
if(height)
|
||||
*height = 0;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
length = ri.FS_ReadFile( name, (void**)&buffer );
|
||||
if (!buffer || length < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (length < 54)
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: header too short (%s)", name );
|
||||
}
|
||||
|
||||
buf_p = (unsigned char*)buffer;
|
||||
end = (unsigned char*)buffer + length;
|
||||
|
||||
bmpHeader.id[0] = *buf_p++;
|
||||
bmpHeader.id[1] = *buf_p++;
|
||||
bmpHeader.fileSize = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.reserved0 = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.bitmapDataOffset = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.bitmapHeaderSize = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.width = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.height = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.planes = LittleShort( * ( short * ) buf_p );
|
||||
buf_p += 2;
|
||||
bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
|
||||
buf_p += 2;
|
||||
bmpHeader.compression = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.bitmapDataSize = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.hRes = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.vRes = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.colors = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.importantColors = LittleLong( * ( int * ) buf_p );
|
||||
buf_p += 4;
|
||||
|
||||
if ( bmpHeader.bitsPerPixel == 8 )
|
||||
{
|
||||
if (buf_p + sizeof(bmpHeader.palette) > end)
|
||||
ri.Error( ERR_DROP, "LoadBMP: header too short (%s)", name );
|
||||
|
||||
memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
|
||||
}
|
||||
|
||||
if ((unsigned char*)buffer + bmpHeader.bitmapDataOffset > end)
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: invalid offset value in header (%s)", name );
|
||||
}
|
||||
|
||||
buf_p = (unsigned char*)buffer + bmpHeader.bitmapDataOffset;
|
||||
|
||||
if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: only Windows-style BMP files supported (%s)", name );
|
||||
}
|
||||
if ( bmpHeader.fileSize != length )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: header size does not match file size (%u vs. %u) (%s)", bmpHeader.fileSize, length, name );
|
||||
}
|
||||
if ( bmpHeader.compression != 0 )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: only uncompressed BMP files supported (%s)", name );
|
||||
}
|
||||
if ( bmpHeader.bitsPerPixel < 8 )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: monochrome and 4-bit BMP files not supported (%s)", name );
|
||||
}
|
||||
|
||||
switch ( bmpHeader.bitsPerPixel )
|
||||
{
|
||||
case 8:
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadBMP: illegal pixel_size '%hu' in file '%s'", bmpHeader.bitsPerPixel, name );
|
||||
break;
|
||||
}
|
||||
|
||||
columns = bmpHeader.width;
|
||||
rows = bmpHeader.height;
|
||||
if ( rows < 0 )
|
||||
rows = -rows;
|
||||
numPixels = columns * rows;
|
||||
|
||||
if(columns <= 0 || !rows || numPixels > 0x1FFFFFFF // 4*1FFFFFFF == 0x7FFFFFFC < 0x7FFFFFFF
|
||||
|| ((numPixels * 4) / columns) / 4 != rows)
|
||||
{
|
||||
ri.Error (ERR_DROP, "LoadBMP: %s has an invalid image size", name);
|
||||
}
|
||||
if(buf_p + numPixels*bmpHeader.bitsPerPixel/8 > end)
|
||||
{
|
||||
ri.Error (ERR_DROP, "LoadBMP: file truncated (%s)", name);
|
||||
}
|
||||
|
||||
if ( width )
|
||||
*width = columns;
|
||||
if ( height )
|
||||
*height = rows;
|
||||
|
||||
bmpRGBA = ri.Malloc( numPixels * 4 );
|
||||
*pic = bmpRGBA;
|
||||
|
||||
|
||||
for ( row = rows-1; row >= 0; row-- )
|
||||
{
|
||||
pixbuf = bmpRGBA + row*columns*4;
|
||||
|
||||
for ( column = 0; column < columns; column++ )
|
||||
{
|
||||
unsigned char red, green, blue, alpha;
|
||||
int palIndex;
|
||||
unsigned short shortPixel;
|
||||
|
||||
switch ( bmpHeader.bitsPerPixel )
|
||||
{
|
||||
case 8:
|
||||
palIndex = *buf_p++;
|
||||
*pixbuf++ = bmpHeader.palette[palIndex][2];
|
||||
*pixbuf++ = bmpHeader.palette[palIndex][1];
|
||||
*pixbuf++ = bmpHeader.palette[palIndex][0];
|
||||
*pixbuf++ = 0xff;
|
||||
break;
|
||||
case 16:
|
||||
shortPixel = * ( unsigned short * ) pixbuf;
|
||||
pixbuf += 2;
|
||||
*pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
|
||||
*pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
|
||||
*pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
|
||||
*pixbuf++ = 0xff;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alpha = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alpha;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ri.FS_FreeFile( buffer );
|
||||
|
||||
}
|
473
code/renderervk/R_ImageJPG.c
Normal file
473
code/renderervk/R_ImageJPG.c
Normal file
|
@ -0,0 +1,473 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
#include "tr_local.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
/*
|
||||
* Include file for users of JPEG library.
|
||||
* You will need to have included system headers that define at least
|
||||
* the typedefs FILE and size_t before you can include jpeglib.h.
|
||||
* (stdio.h is sufficient on ANSI-conforming systems.)
|
||||
* You may also wish to include "jerror.h".
|
||||
*/
|
||||
|
||||
#ifdef USE_INTERNAL_JPEG
|
||||
# define JPEG_INTERNALS
|
||||
#endif
|
||||
|
||||
#include <jpeglib.h>
|
||||
|
||||
#ifndef USE_INTERNAL_JPEG
|
||||
# if JPEG_LIB_VERSION < 80 && !defined(MEM_SRCDST_SUPPORTED)
|
||||
# error Need system libjpeg >= 80 or jpeg_mem_ support
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Catching errors, as done in libjpeg's example.c */
|
||||
typedef struct q_jpeg_error_mgr_s
|
||||
{
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
} q_jpeg_error_mgr_t;
|
||||
|
||||
static void R_JPGErrorExit(j_common_ptr cinfo)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
/* cinfo->err really points to a q_jpeg_error_mgr_s struct, so coerce pointer */
|
||||
q_jpeg_error_mgr_t *jerr = (q_jpeg_error_mgr_t *)cinfo->err;
|
||||
|
||||
(*cinfo->err->format_message) (cinfo, buffer);
|
||||
|
||||
ri.Printf(PRINT_ALL, "Error: %s", buffer);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
longjmp(jerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
static void R_JPGOutputMessage(j_common_ptr cinfo)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
/* Create the message */
|
||||
(*cinfo->err->format_message) (cinfo, buffer);
|
||||
|
||||
/* Send it to stderr, adding a newline */
|
||||
ri.Printf(PRINT_ALL, "%s\n", buffer);
|
||||
}
|
||||
|
||||
void R_LoadJPG(const char *filename, unsigned char **pic, int *width, int *height)
|
||||
{
|
||||
/* This struct contains the JPEG decompression parameters and pointers to
|
||||
* working space (which is allocated as needed by the JPEG library).
|
||||
*/
|
||||
struct jpeg_decompress_struct cinfo = {NULL};
|
||||
/* We use our private extension JPEG error handler.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
/* This struct represents a JPEG error handler. It is declared separately
|
||||
* because applications often want to supply a specialized error handler
|
||||
* (see the second half of this file for an example). But here we just
|
||||
* take the easy way out and use the standard error handler, which will
|
||||
* print a message on stderr and call exit() if compression fails.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
q_jpeg_error_mgr_t jerr;
|
||||
/* More stuff */
|
||||
JSAMPARRAY buffer; /* Output row buffer */
|
||||
unsigned int row_stride; /* physical row width in output buffer */
|
||||
unsigned int pixelcount, memcount;
|
||||
unsigned int sindex, dindex;
|
||||
byte *out;
|
||||
int len;
|
||||
char * fbuffer;
|
||||
byte *buf;
|
||||
|
||||
/* In this example we want to open the input file before doing anything else,
|
||||
* so that the setjmp() error recovery below can assume the file is open.
|
||||
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
|
||||
* requires it in order to read binary files.
|
||||
*/
|
||||
|
||||
len = ri.FS_ReadFile ( filename, (void**)&fbuffer);
|
||||
if (!fbuffer || len < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Step 1: allocate and initialize JPEG decompression object */
|
||||
|
||||
/* We have to set up the error handler first, in case the initialization
|
||||
* step fails. (Unlikely, but it could happen if you are out of memory.)
|
||||
* This routine fills in the contents of struct jerr, and returns jerr's
|
||||
* address which we place into the link field in cinfo.
|
||||
*/
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
cinfo.err->error_exit = R_JPGErrorExit;
|
||||
cinfo.err->output_message = R_JPGOutputMessage;
|
||||
|
||||
/* Establish the setjmp return context for R_JPGErrorExit to use. */
|
||||
if (setjmp(jerr.setjmp_buffer))
|
||||
{
|
||||
/* If we get here, the JPEG code has signaled an error.
|
||||
* We need to clean up the JPEG object, close the input file, and return.
|
||||
*/
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
ri.FS_FreeFile(fbuffer);
|
||||
|
||||
/* Append the filename to the error for easier debugging */
|
||||
ri.Printf(PRINT_ALL, ", loading file %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now we can initialize the JPEG decompression object. */
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
/* Step 2: specify data source (eg, a file) */
|
||||
|
||||
jpeg_mem_src(&cinfo, (unsigned char*)fbuffer, len);
|
||||
|
||||
/* Step 3: read file parameters with jpeg_read_header() */
|
||||
|
||||
(void) jpeg_read_header(&cinfo, TRUE);
|
||||
/* We can ignore the return value from jpeg_read_header since
|
||||
* (a) suspension is not possible with the stdio data source, and
|
||||
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
|
||||
* See libjpeg.doc for more info.
|
||||
*/
|
||||
|
||||
/* Step 4: set parameters for decompression */
|
||||
|
||||
/*
|
||||
* Make sure it always converts images to RGB color space. This will
|
||||
* automatically convert 8-bit greyscale images to RGB as well.
|
||||
*/
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
|
||||
/* Step 5: Start decompressor */
|
||||
|
||||
(void) jpeg_start_decompress(&cinfo);
|
||||
/* We can ignore the return value since suspension is not possible
|
||||
* with the stdio data source.
|
||||
*/
|
||||
|
||||
/* We may need to do some setup of our own at this point before reading
|
||||
* the data. After jpeg_start_decompress() we have the correct scaled
|
||||
* output image dimensions available, as well as the output colormap
|
||||
* if we asked for color quantization.
|
||||
* In this example, we need to make an output work buffer of the right size.
|
||||
*/
|
||||
/* JSAMPLEs per row in output buffer */
|
||||
|
||||
pixelcount = cinfo.output_width * cinfo.output_height;
|
||||
|
||||
if(!cinfo.output_width || !cinfo.output_height
|
||||
|| ((pixelcount * 4) / cinfo.output_width) / 4 != cinfo.output_height
|
||||
|| pixelcount > 0x1FFFFFFF || cinfo.output_components != 3
|
||||
)
|
||||
{
|
||||
// Free the memory to make sure we don't leak memory
|
||||
ri.FS_FreeFile (fbuffer);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
ri.Error(ERR_DROP, "LoadJPG: %s has an invalid image format: %dx%d*4=%d, components: %d", filename,
|
||||
cinfo.output_width, cinfo.output_height, pixelcount * 4, cinfo.output_components);
|
||||
}
|
||||
|
||||
memcount = pixelcount * 4;
|
||||
row_stride = cinfo.output_width * cinfo.output_components;
|
||||
|
||||
out = ri.Malloc(memcount);
|
||||
|
||||
*width = cinfo.output_width;
|
||||
*height = cinfo.output_height;
|
||||
|
||||
/* Step 6: while (scan lines remain to be read) */
|
||||
/* jpeg_read_scanlines(...); */
|
||||
|
||||
/* Here we use the library's state variable cinfo.output_scanline as the
|
||||
* loop counter, so that we don't have to keep track ourselves.
|
||||
*/
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
/* jpeg_read_scanlines expects an array of pointers to scanlines.
|
||||
* Here the array is only one element long, but you could ask for
|
||||
* more than one scanline at a time if that's more convenient.
|
||||
*/
|
||||
buf = ((out+(row_stride*cinfo.output_scanline)));
|
||||
buffer = &buf;
|
||||
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
|
||||
}
|
||||
|
||||
buf = out;
|
||||
|
||||
// Expand from RGB to RGBA
|
||||
sindex = pixelcount * cinfo.output_components;
|
||||
dindex = memcount;
|
||||
|
||||
do
|
||||
{
|
||||
buf[--dindex] = 255;
|
||||
buf[--dindex] = buf[--sindex];
|
||||
buf[--dindex] = buf[--sindex];
|
||||
buf[--dindex] = buf[--sindex];
|
||||
} while(sindex);
|
||||
|
||||
*pic = out;
|
||||
|
||||
/* Step 7: Finish decompression */
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
/* We can ignore the return value since suspension is not possible
|
||||
* with the stdio data source.
|
||||
*/
|
||||
|
||||
/* Step 8: Release JPEG decompression object */
|
||||
|
||||
/* This is an important step since it will release a good deal of memory. */
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
/* After finish_decompress, we can close the input file.
|
||||
* Here we postpone it until after no more JPEG errors are possible,
|
||||
* so as to simplify the setjmp error logic above. (Actually, I don't
|
||||
* think that jpeg_destroy can do an error exit, but why assume anything...)
|
||||
*/
|
||||
ri.FS_FreeFile (fbuffer);
|
||||
|
||||
/* At this point you may want to check to see whether any corrupt-data
|
||||
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
|
||||
*/
|
||||
|
||||
/* And we're done! */
|
||||
}
|
||||
|
||||
|
||||
/* Expanded data destination object for stdio output */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_destination_mgr pub; /* public fields */
|
||||
|
||||
byte* outfile; /* target stream */
|
||||
int size;
|
||||
} my_destination_mgr;
|
||||
|
||||
typedef my_destination_mgr * my_dest_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize destination --- called by jpeg_start_compress
|
||||
* before any data is actually written.
|
||||
*/
|
||||
|
||||
static void
|
||||
init_destination (j_compress_ptr cinfo)
|
||||
{
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
|
||||
dest->pub.next_output_byte = dest->outfile;
|
||||
dest->pub.free_in_buffer = dest->size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty the output buffer --- called whenever buffer fills up.
|
||||
*
|
||||
* In typical applications, this should write the entire output buffer
|
||||
* (ignoring the current state of next_output_byte & free_in_buffer),
|
||||
* reset the pointer & count to the start of the buffer, and return TRUE
|
||||
* indicating that the buffer has been dumped.
|
||||
*
|
||||
* In applications that need to be able to suspend compression due to output
|
||||
* overrun, a FALSE return indicates that the buffer cannot be emptied now.
|
||||
* In this situation, the compressor will return to its caller (possibly with
|
||||
* an indication that it has not accepted all the supplied scanlines). The
|
||||
* application should resume compression after it has made more room in the
|
||||
* output buffer. Note that there are substantial restrictions on the use of
|
||||
* suspension --- see the documentation.
|
||||
*
|
||||
* When suspending, the compressor will back up to a convenient restart point
|
||||
* (typically the start of the current MCU). next_output_byte & free_in_buffer
|
||||
* indicate where the restart point will be if the current call returns FALSE.
|
||||
* Data beyond this point will be regenerated after resumption, so do not
|
||||
* write it out when emptying the buffer externally.
|
||||
*/
|
||||
|
||||
static boolean
|
||||
empty_output_buffer (j_compress_ptr cinfo)
|
||||
{
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
|
||||
jpeg_destroy_compress(cinfo);
|
||||
|
||||
// Make crash fatal or we would probably leak memory.
|
||||
ri.Error(ERR_FATAL, "Output buffer for encoded JPEG image has insufficient size of %d bytes",
|
||||
dest->size);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Terminate destination --- called by jpeg_finish_compress
|
||||
* after all data has been written. Usually needs to flush buffer.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
static void term_destination(j_compress_ptr cinfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for output to a stdio stream.
|
||||
* The caller must have already opened the stream, and is responsible
|
||||
* for closing it after finishing compression.
|
||||
*/
|
||||
|
||||
static void
|
||||
jpegDest (j_compress_ptr cinfo, byte* outfile, int size)
|
||||
{
|
||||
my_dest_ptr dest;
|
||||
|
||||
/* The destination object is made permanent so that multiple JPEG images
|
||||
* can be written to the same file without re-executing jpeg_stdio_dest.
|
||||
* This makes it dangerous to use this manager and a different destination
|
||||
* manager serially with the same JPEG object, because their private object
|
||||
* sizes may be different. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
sizeof(my_destination_mgr));
|
||||
}
|
||||
|
||||
dest = (my_dest_ptr) cinfo->dest;
|
||||
dest->pub.init_destination = init_destination;
|
||||
dest->pub.empty_output_buffer = empty_output_buffer;
|
||||
dest->pub.term_destination = term_destination;
|
||||
dest->outfile = outfile;
|
||||
dest->size = size;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SaveJPGToBuffer
|
||||
|
||||
Encodes JPEG from image in image_buffer and writes to buffer.
|
||||
Expects RGB input data
|
||||
=================
|
||||
*/
|
||||
size_t RE_SaveJPGToBuffer(byte *buffer, size_t bufSize, int quality,
|
||||
int image_width, int image_height, byte *image_buffer, int padding)
|
||||
{
|
||||
struct jpeg_compress_struct cinfo;
|
||||
q_jpeg_error_mgr_t jerr;
|
||||
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
||||
my_dest_ptr dest;
|
||||
int row_stride; /* physical row width in image buffer */
|
||||
size_t outcount;
|
||||
|
||||
/* Step 1: allocate and initialize JPEG compression object */
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
cinfo.err->error_exit = R_JPGErrorExit;
|
||||
cinfo.err->output_message = R_JPGOutputMessage;
|
||||
|
||||
/* Establish the setjmp return context for R_JPGErrorExit to use. */
|
||||
if (setjmp(jerr.setjmp_buffer))
|
||||
{
|
||||
/* If we get here, the JPEG code has signaled an error.
|
||||
* We need to clean up the JPEG object and return.
|
||||
*/
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
ri.Printf(PRINT_ALL, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now we can initialize the JPEG compression object. */
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
/* Step 2: specify data destination (eg, a file) */
|
||||
/* Note: steps 2 and 3 can be done in either order. */
|
||||
jpegDest(&cinfo, buffer, bufSize);
|
||||
|
||||
/* Step 3: set parameters for compression */
|
||||
cinfo.image_width = image_width; /* image width and height, in pixels */
|
||||
cinfo.image_height = image_height;
|
||||
cinfo.input_components = 3; /* # of color components per pixel */
|
||||
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
|
||||
/* If quality is set high, disable chroma subsampling */
|
||||
if (quality >= 85) {
|
||||
cinfo.comp_info[0].h_samp_factor = 1;
|
||||
cinfo.comp_info[0].v_samp_factor = 1;
|
||||
}
|
||||
|
||||
/* Step 4: Start compressor */
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
/* Step 5: while (scan lines remain to be written) */
|
||||
/* jpeg_write_scanlines(...); */
|
||||
row_stride = image_width * cinfo.input_components + padding; /* JSAMPLEs per row in image_buffer */
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height) {
|
||||
/* jpeg_write_scanlines expects an array of pointers to scanlines.
|
||||
* Here the array is only one element long, but you could pass
|
||||
* more than one scanline at a time if that's more convenient.
|
||||
*/
|
||||
row_pointer[0] = &image_buffer[((cinfo.image_height-1)*row_stride)-cinfo.next_scanline * row_stride];
|
||||
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
}
|
||||
|
||||
/* Step 6: Finish compression */
|
||||
jpeg_finish_compress(&cinfo);
|
||||
|
||||
dest = (my_dest_ptr) cinfo.dest;
|
||||
outcount = dest->size - dest->pub.free_in_buffer;
|
||||
|
||||
/* Step 7: release JPEG compression object */
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
/* And we're done! */
|
||||
return outcount;
|
||||
}
|
||||
|
||||
void RE_SaveJPG(char * filename, int quality, int image_width, int image_height, byte *image_buffer, int padding)
|
||||
{
|
||||
byte *out;
|
||||
size_t bufSize;
|
||||
|
||||
bufSize = image_width * image_height * 3;
|
||||
out = ri.Hunk_AllocateTempMemory(bufSize);
|
||||
|
||||
bufSize = RE_SaveJPGToBuffer(out, bufSize, quality, image_width, image_height, image_buffer, padding);
|
||||
ri.FS_WriteFile(filename, out, bufSize);
|
||||
|
||||
ri.Hunk_FreeTempMemory(out);
|
||||
}
|
7
code/renderervk/R_ImageJPG.h
Normal file
7
code/renderervk/R_ImageJPG.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef R_IMAGEJPG_H_
|
||||
#define R_IMAGEJPG_H_
|
||||
|
||||
void RE_SaveJPG(char * filename, int quality, int image_width, int image_height, unsigned char *image_buffer, int padding);
|
||||
size_t RE_SaveJPGToBuffer(unsigned char *buffer, size_t bufSize, int quality, int image_width, int image_height, unsigned char *image_buffer, int padding);
|
||||
|
||||
#endif
|
170
code/renderervk/R_ImagePCX.c
Normal file
170
code/renderervk/R_ImagePCX.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
2008 Ludwig Nussel
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "ref_import.h"
|
||||
#include "image_loader.h"
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
PCX files are used for 8 bit images
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
unsigned short hscreensize, vscreensize;
|
||||
char filler[54];
|
||||
char data[];
|
||||
} pcx_t;
|
||||
|
||||
void R_LoadPCX ( const char *filename, byte **pic, int *width, int *height)
|
||||
{
|
||||
char* raw;
|
||||
unsigned char dataByte = 0, runLength = 0;
|
||||
unsigned char *out, *pix;
|
||||
unsigned short w, h;
|
||||
unsigned char *pic8;
|
||||
unsigned char *palette;
|
||||
int i;
|
||||
unsigned size = 0;
|
||||
|
||||
if (width)
|
||||
*width = 0;
|
||||
if (height)
|
||||
*height = 0;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
int len = ri.FS_ReadFile( filename, (void**)&raw );
|
||||
if (!raw || len < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((unsigned)len < sizeof(pcx_t))
|
||||
{
|
||||
ri.Printf (PRINT_ALL, "PCX truncated: %s\n", filename);
|
||||
ri.FS_FreeFile (raw);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
pcx_t* pcx = (pcx_t *)raw;
|
||||
unsigned char* end = (unsigned char*)raw+len;
|
||||
|
||||
w = LittleShort(pcx->xmax)+1;
|
||||
h = LittleShort(pcx->ymax)+1;
|
||||
size = w*h;
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->color_planes != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| w >= 1024
|
||||
|| h >= 1024)
|
||||
{
|
||||
ri.Printf (PRINT_ALL, "Bad or unsupported pcx file %s (%dx%d@%d)\n", filename, w, h, pcx->bits_per_pixel);
|
||||
return;
|
||||
}
|
||||
|
||||
pix = pic8 = ri.Malloc ( size );
|
||||
|
||||
raw = pcx->data;
|
||||
// FIXME: should use bytes_per_line but original q3 didn't do that either
|
||||
while(pix < pic8+size)
|
||||
{
|
||||
if(runLength > 0) {
|
||||
*pix++ = dataByte;
|
||||
--runLength;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((unsigned char*)raw+1 > end)
|
||||
break;
|
||||
dataByte = *raw++;
|
||||
|
||||
if((dataByte & 0xC0) == 0xC0)
|
||||
{
|
||||
if((unsigned char*)raw+1 > end)
|
||||
break;
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = *raw++;
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
}
|
||||
|
||||
if(pix < pic8+size)
|
||||
{
|
||||
ri.Printf (PRINT_ALL, "PCX file truncated: %s\n", filename);
|
||||
ri.FS_FreeFile (pcx);
|
||||
ri.Free (pic8);
|
||||
}
|
||||
|
||||
if ((byte*)raw-(byte*)pcx >= end - (byte*)769 || end[-769] != 0x0c)
|
||||
{
|
||||
ri.Printf (PRINT_ALL, "PCX missing palette: %s\n", filename);
|
||||
ri.FS_FreeFile (pcx);
|
||||
ri.Free (pic8);
|
||||
return;
|
||||
}
|
||||
|
||||
palette = end-768;
|
||||
|
||||
pix = out = ri.Malloc(4 * size );
|
||||
for (i = 0 ; i < size ; i++)
|
||||
{
|
||||
unsigned char p = pic8[i];
|
||||
pix[0] = palette[p*3];
|
||||
pix[1] = palette[p*3 + 1];
|
||||
pix[2] = palette[p*3 + 2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = w;
|
||||
if (height)
|
||||
*height = h;
|
||||
|
||||
*pic = out;
|
||||
|
||||
ri.FS_FreeFile (pcx);
|
||||
ri.Free (pic8);
|
||||
}
|
2483
code/renderervk/R_ImagePNG.c
Normal file
2483
code/renderervk/R_ImagePNG.c
Normal file
File diff suppressed because it is too large
Load diff
534
code/renderervk/R_ImageProcess.c
Normal file
534
code/renderervk/R_ImageProcess.c
Normal file
|
@ -0,0 +1,534 @@
|
|||
#include "tr_cvar.h"
|
||||
#include "ref_import.h"
|
||||
#include "vk_image.h"
|
||||
#include "R_ImageProcess.h"
|
||||
|
||||
|
||||
static unsigned char s_intensitytable[256];
|
||||
static unsigned char s_gammatable[256];
|
||||
|
||||
/*
|
||||
void R_GammaCorrect(unsigned char* buffer, const unsigned int Size)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for( i = 0; i < Size; i++ )
|
||||
{
|
||||
buffer[i] = s_gammatable[buffer[i]];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void R_SetColorMappings( void )
|
||||
{
|
||||
int i, j;
|
||||
int inf;
|
||||
int shift = 0;
|
||||
|
||||
for (i = 0; i < 255; i++)
|
||||
{
|
||||
s_intensitytable[i] = s_gammatable[i] = i;
|
||||
}
|
||||
|
||||
float g = r_gamma->value;
|
||||
|
||||
for ( i = 0; i < 256; i++ ) {
|
||||
if ( g == 1 ) {
|
||||
inf = i;
|
||||
} else {
|
||||
inf = 255 * pow ( i/255.0f, 1.0f / g ) + 0.5f;
|
||||
}
|
||||
inf <<= shift;
|
||||
if (inf < 0) {
|
||||
inf = 0;
|
||||
}
|
||||
else if (inf > 255) {
|
||||
inf = 255;
|
||||
}
|
||||
s_gammatable[i] = inf;
|
||||
}
|
||||
|
||||
|
||||
if ( r_intensity->value <= 1 ) {
|
||||
ri.Cvar_Set( "r_intensity", "1" );
|
||||
}
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
j = i * r_intensity->value;
|
||||
if (j > 255) {
|
||||
j = 255;
|
||||
}
|
||||
s_intensitytable[i] = j;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Scale up the pixel values in a texture to increase the lighting range
|
||||
================
|
||||
*/
|
||||
void R_LightScaleTexture (unsigned char* dst, unsigned char* in, unsigned int nBytes)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if ( 0 )
|
||||
{
|
||||
for (i=0; i<nBytes; i+=4)
|
||||
{
|
||||
unsigned int n1 = i + 1;
|
||||
unsigned int n2 = i + 2;
|
||||
unsigned int n3 = i + 3;
|
||||
|
||||
dst[i] = s_gammatable[in[i]];
|
||||
dst[n1] = s_gammatable[in[n1]];
|
||||
dst[n2] = s_gammatable[in[n2]];
|
||||
dst[n3] = in[n3];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<nBytes; i+=4)
|
||||
{
|
||||
unsigned int n1 = i + 1;
|
||||
unsigned int n2 = i + 2;
|
||||
unsigned int n3 = i + 3;
|
||||
|
||||
dst[i] = s_gammatable[s_intensitytable[in[i]]];
|
||||
dst[n1] = s_gammatable[s_intensitytable[in[n1]]];
|
||||
dst[n2] = s_gammatable[s_intensitytable[in[n2]]];
|
||||
dst[n3] = in[n3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MIP maps
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// In computer graphics, mipmaps (also MIP maps) or pyramids are pre-calculated,
|
||||
// optimized sequences of images, each of which is a progressively lower resolution
|
||||
// representation of the same image. The height and width of each image, or level,
|
||||
// in the mipmap is a power of two smaller than the previous level.
|
||||
// Mipmaps do not have to be square. They are intended to increase rendering speed
|
||||
// and reduce aliasing artifacts.
|
||||
// A high-resolution mipmap image is used for high-density samples, such as for
|
||||
// objects close to the camera. Lower-resolution images are used as the object
|
||||
// appears farther away.
|
||||
// This is a more efficient way of downfiltering (minifying) a texture than
|
||||
// sampling all texels in the original texture that would contribute to a
|
||||
// screen pixel; it is faster to take a constant number of samples from the
|
||||
// appropriately downfiltered textures. Mipmaps are widely used in 3D computer games.
|
||||
|
||||
// The letters "MIP" in the name are an acronym of the Latin phrase multum in parvo,
|
||||
// meaning "much in little".Since mipmaps, by definition, are pre-allocated,
|
||||
// additional storage space is required to take advantage of them.
|
||||
// Mipmap textures are used in 3D scenes to decrease the time required to
|
||||
// render a scene. They also improve the scene's realism.
|
||||
|
||||
// mip-mapping of 1/3 more memory per texture.
|
||||
|
||||
/*
|
||||
==================
|
||||
R_BlendOverTexture
|
||||
|
||||
Apply a color blend over a set of pixels
|
||||
==================
|
||||
*/
|
||||
void R_BlendOverTexture(unsigned char* data, const uint32_t pixelCount, uint32_t l)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
static const unsigned char mipBlendColors[16][4] =
|
||||
{
|
||||
{0,0,0,0},
|
||||
{255,0,0,128},
|
||||
{0,255,0,128},
|
||||
{0,0,255,128},
|
||||
{255,0,0,128},
|
||||
{0,255,0,128},
|
||||
{0,0,255,128},
|
||||
{255,0,0,128},
|
||||
{0,255,0,128},
|
||||
{0,0,255,128},
|
||||
{255,0,0,128},
|
||||
{0,255,0,128},
|
||||
{0,0,255,128},
|
||||
{255,0,0,128},
|
||||
{0,255,0,128},
|
||||
{0,0,255,128},
|
||||
};
|
||||
|
||||
const unsigned int alpha = mipBlendColors[l][3];
|
||||
const unsigned int inverseAlpha = 255 - alpha;
|
||||
|
||||
const unsigned int bR = mipBlendColors[l][0] * alpha;
|
||||
const unsigned int bG = mipBlendColors[l][1] * alpha;
|
||||
const unsigned int bB = mipBlendColors[l][2] * alpha;
|
||||
|
||||
for ( i = 0; i < pixelCount; i++, data+=4 )
|
||||
{
|
||||
data[0] = ( data[0] * inverseAlpha + bR ) >> 9;
|
||||
data[1] = ( data[1] * inverseAlpha + bG ) >> 9;
|
||||
data[2] = ( data[2] * inverseAlpha + bB ) >> 9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_MipMap
|
||||
|
||||
Operates in place, quartering the size of the texture, no error checking
|
||||
================
|
||||
*/
|
||||
void R_MipMap(const unsigned char* in, uint32_t width, uint32_t height, unsigned char* out)
|
||||
{
|
||||
|
||||
if ( (width == 1) && (height == 1) )
|
||||
{
|
||||
out[0] = in[0];
|
||||
return;
|
||||
}
|
||||
uint32_t i;
|
||||
|
||||
const unsigned int row = width * 4;
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
|
||||
if ( (width == 0) || (height == 0) )
|
||||
{
|
||||
width += height; // get largest
|
||||
for (i=0; i<width; i++, out+=4, in+=8 )
|
||||
{
|
||||
out[0] = ( in[0] + in[4] )>>1;
|
||||
out[1] = ( in[1] + in[5] )>>1;
|
||||
out[2] = ( in[2] + in[6] )>>1;
|
||||
out[3] = ( in[3] + in[7] )>>1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<height; i++, in+=row)
|
||||
{
|
||||
uint32_t j;
|
||||
for (j=0; j<width; j++, out+=4, in+=8)
|
||||
{
|
||||
out[0] = (in[0] + in[4] + in[row+0] + in[row+4])>>2;
|
||||
out[1] = (in[1] + in[5] + in[row+1] + in[row+5])>>2;
|
||||
out[2] = (in[2] + in[6] + in[row+2] + in[row+6])>>2;
|
||||
out[3] = (in[3] + in[7] + in[row+3] + in[row+7])>>2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_MipMap2
|
||||
|
||||
Operates in place, quartering the size of the texture
|
||||
Proper linear filter, no error checking
|
||||
================
|
||||
*/
|
||||
void R_MipMap2(const unsigned char* in, uint32_t inWidth, uint32_t inHeight, unsigned char* out)
|
||||
{
|
||||
|
||||
int i, j;
|
||||
|
||||
if ( (inWidth == 1) && (inHeight == 1) )
|
||||
{
|
||||
out[0] = in[0];
|
||||
return;
|
||||
}
|
||||
//ri.Printf (PRINT_ALL, "\n---R_MipMap2---\n");
|
||||
// Not run time funs, can be used for best view effects
|
||||
|
||||
unsigned int outWidth = inWidth >> 1;
|
||||
unsigned int outHeight = inHeight >> 1;
|
||||
unsigned int nBytes = outWidth * outHeight * 4;
|
||||
|
||||
unsigned char * temp = (unsigned char *)malloc( nBytes );
|
||||
|
||||
const unsigned int inWidthMask = inWidth - 1;
|
||||
const unsigned int inHeightMask = inHeight - 1;
|
||||
|
||||
for ( i = 0 ; i < outHeight ; i++ )
|
||||
{
|
||||
for ( j = 0 ; j < outWidth ; j++ )
|
||||
{
|
||||
unsigned int outIndex = i * outWidth + j;
|
||||
unsigned int k;
|
||||
for ( k = 0 ; k < 4 ; k++ )
|
||||
{
|
||||
unsigned int r0 = ((i*2-1) & inHeightMask) * inWidth;
|
||||
unsigned int r1 = ((i*2 ) & inHeightMask) * inWidth;
|
||||
unsigned int r2 = ((i*2+1) & inHeightMask) * inWidth;
|
||||
unsigned int r3 = ((i*2+2) & inHeightMask) * inWidth;
|
||||
|
||||
unsigned int c0 = ((j*2-1) & inWidthMask);
|
||||
unsigned int c1 = ((j*2 ) & inWidthMask);
|
||||
unsigned int c2 = ((j*2+1) & inWidthMask);
|
||||
unsigned int c3 = ((j*2+2) & inWidthMask);
|
||||
|
||||
|
||||
unsigned int total =
|
||||
1 * in[(r0 + c0) * 4 + k] +
|
||||
2 * in[(r0 + c1) * 4 + k] +
|
||||
2 * in[(r0 + c2) * 4 + k] +
|
||||
1 * in[(r0 + c3) * 4 + k] +
|
||||
|
||||
2 * in[(r1 + c0) * 4 + k] +
|
||||
4 * in[(r1 + c1) * 4 + k] +
|
||||
4 * in[(r1 + c2) * 4 + k] +
|
||||
2 * in[(r1 + c3) * 4 + k] +
|
||||
|
||||
2 * in[(r2 + c0) * 4 + k] +
|
||||
4 * in[(r2 + c1) * 4 + k] +
|
||||
4 * in[(r2 + c2) * 4 + k] +
|
||||
2 * in[(r2 + c3) * 4 + k] +
|
||||
|
||||
1 * in[(r3 + c0) * 4 + k] +
|
||||
2 * in[(r3 + c1) * 4 + k] +
|
||||
2 * in[(r3 + c2) * 4 + k] +
|
||||
1 * in[(r3 + c3) * 4 + k] ;
|
||||
|
||||
temp[4*outIndex + k] = total / 36;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy( out, temp, nBytes );
|
||||
free( temp );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
|
||||
Used to resample images in a more general than quartering fashion.
|
||||
|
||||
This will only be filtered properly if the resampled size
|
||||
is greater than half the original size.
|
||||
|
||||
If a larger shrinking is needed, use the mipmap function before or after.
|
||||
================
|
||||
*/
|
||||
|
||||
void ResampleTexture(unsigned char * pOut, const unsigned int inwidth, const unsigned int inheight,
|
||||
const unsigned char *pIn, const unsigned int outwidth, const unsigned int outheight)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int p1[2048], p2[2048];
|
||||
|
||||
// printf("inwidth: %d \t outwidth: %d \n", inwidth, outwidth);
|
||||
|
||||
unsigned int fracstep = (inwidth << 16)/outwidth;
|
||||
|
||||
unsigned int frac1 = fracstep>>2;
|
||||
unsigned int frac2 = 3*(fracstep>>2);
|
||||
|
||||
for(i=0; i<outwidth; i++)
|
||||
{
|
||||
p1[i] = 4*(frac1>>16);
|
||||
frac1 += fracstep;
|
||||
|
||||
p2[i] = 4*(frac2>>16);
|
||||
frac2 += fracstep;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<outheight; i++)
|
||||
{
|
||||
const unsigned char* inrow1 = pIn + 4 * inwidth * (unsigned int)((i+0.25)*inheight/outheight);
|
||||
const unsigned char* inrow2 = pIn + 4 * inwidth * (unsigned int)((i+0.75)*inheight/outheight);
|
||||
//const unsigned char* inrow1 = pIn + inwidth * (unsigned int)((4*i+1)*inheight/outheight);
|
||||
//const unsigned char* inrow2 = pIn + inwidth * (unsigned int)((4*i+3)*inheight/outheight);
|
||||
|
||||
|
||||
// printf("inrow1: %d \t inrow2: %d \n",
|
||||
// 4 * (unsigned int)((i+0.25)*inheight/outheight),
|
||||
// 4 * (unsigned int)((i+0.75)*inheight/outheight)
|
||||
// );
|
||||
|
||||
for (j=0; j<outwidth; j++)
|
||||
{
|
||||
const unsigned char* pix1 = inrow1 + p1[j];
|
||||
const unsigned char* pix2 = inrow1 + p2[j];
|
||||
const unsigned char* pix3 = inrow2 + p1[j];
|
||||
const unsigned char* pix4 = inrow2 + p2[j];
|
||||
|
||||
unsigned char* pCurPix = pOut + j*4;
|
||||
|
||||
pCurPix[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
|
||||
pCurPix[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
|
||||
pCurPix[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
|
||||
pCurPix[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2;
|
||||
}
|
||||
|
||||
pOut += outwidth*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GetScaledDimension(const unsigned int width, const unsigned int height, unsigned int * const outW, unsigned int * const outH, int isPicMip)
|
||||
{
|
||||
const unsigned int max_texture_size = 2048;
|
||||
|
||||
unsigned int scaled_width, scaled_height;
|
||||
|
||||
for(scaled_width = max_texture_size; scaled_width > width; scaled_width>>=1)
|
||||
;
|
||||
|
||||
for (scaled_height = max_texture_size; scaled_height > height; scaled_height>>=1)
|
||||
;
|
||||
|
||||
// perform optional picmip operation
|
||||
if ( isPicMip )
|
||||
{
|
||||
scaled_width >>= r_picmip->integer;
|
||||
scaled_height >>= r_picmip->integer;
|
||||
}
|
||||
|
||||
// clamp to minimum size
|
||||
if (scaled_width == 0) {
|
||||
scaled_width = 1;
|
||||
}
|
||||
if (scaled_height == 0) {
|
||||
scaled_height = 1;
|
||||
}
|
||||
|
||||
*outW = scaled_width;
|
||||
*outH = scaled_height;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DEBUG HELPER FUNCTIONAS ...
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void imsave(char *fileName, unsigned char* buffer2, unsigned int width, unsigned int height);
|
||||
void fsWriteFile( const char *qpath, const void *buffer, int size );
|
||||
|
||||
|
||||
void fsWriteFile( const char *qpath, const void *buffer, int size )
|
||||
{
|
||||
|
||||
unsigned char* buf = (unsigned char *)buffer;
|
||||
|
||||
FILE * f = fopen( qpath, "wb" );
|
||||
if ( !f )
|
||||
{
|
||||
fprintf(stderr, "Failed to open %s\n", qpath );
|
||||
return;
|
||||
}
|
||||
|
||||
int remaining = size;
|
||||
int tries = 0;
|
||||
int block = 0;
|
||||
int written = 0;
|
||||
|
||||
while (remaining)
|
||||
{
|
||||
block = remaining;
|
||||
written = fwrite (buf, 1, block, f);
|
||||
if (written == 0)
|
||||
{
|
||||
if (!tries)
|
||||
{
|
||||
tries = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "FS_Write: 0 bytes written\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (written == -1)
|
||||
{
|
||||
fprintf(stderr, "FS_Write: -1 bytes written\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
remaining -= written;
|
||||
buf += written;
|
||||
}
|
||||
|
||||
//FS_Write( buffer, size, f );
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
void imsave(char *fileName, unsigned char* buffer2, unsigned int width, unsigned int height)
|
||||
{
|
||||
|
||||
const unsigned int cnPixels = width * height;
|
||||
|
||||
unsigned char* buffer = (unsigned char*) malloc( cnPixels * 3 + 18);
|
||||
|
||||
memset (buffer, 0, 18);
|
||||
buffer[2] = 2; // uncompressed type
|
||||
buffer[12] = width & 255;
|
||||
buffer[13] = width >> 8;
|
||||
buffer[14] = height & 255;
|
||||
buffer[15] = height >> 8;
|
||||
buffer[16] = 24; // pixel size
|
||||
|
||||
unsigned char* buffer_ptr = buffer + 18;
|
||||
unsigned char* buffer2_ptr = buffer2;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < cnPixels; i++)
|
||||
{
|
||||
buffer_ptr[0] = buffer2_ptr[0];
|
||||
buffer_ptr[1] = buffer2_ptr[1];
|
||||
buffer_ptr[2] = buffer2_ptr[2];
|
||||
buffer_ptr += 3;
|
||||
buffer2_ptr += 4;
|
||||
}
|
||||
|
||||
|
||||
// swap rgb to bgr
|
||||
const unsigned int c = 18 + width * height * 3;
|
||||
for (i=18; i<c; i+=3)
|
||||
{
|
||||
unsigned char temp = buffer[i];
|
||||
buffer[i] = buffer[i+2];
|
||||
buffer[i+2] = temp;
|
||||
}
|
||||
|
||||
|
||||
fsWriteFile( fileName, buffer, c );
|
||||
|
||||
free( buffer );
|
||||
|
||||
ri.Printf( PRINT_ALL, "imsave: %s\n", fileName );
|
||||
}
|
||||
|
||||
|
||||
void DEBUG_resample(const char *name, unsigned char* data, unsigned char* pBuffer,
|
||||
unsigned int width, unsigned int height, unsigned int scaled_width, unsigned int scaled_height)
|
||||
{
|
||||
const char *slash = strrchr(name, '/');
|
||||
|
||||
char tmpName[128] = {0};
|
||||
char tmpName2[128] = "resampled_";
|
||||
|
||||
strcpy(tmpName, slash+1);
|
||||
strcat(tmpName2, tmpName);
|
||||
|
||||
imsave(tmpName , data, width, height);
|
||||
imsave(tmpName2, pBuffer, scaled_width, scaled_height);
|
||||
|
||||
ri.Printf( PRINT_ALL, "tmpName: %s\n", tmpName);
|
||||
ri.Printf( PRINT_ALL, "tmpName2: %s\n", tmpName2);
|
||||
|
||||
ri.Printf( PRINT_ALL, "DEBUG_resample, inwidth: %d, inheight: %d, outwidth: %d, outheight: %d\n",
|
||||
width, height, scaled_width, scaled_height );
|
||||
}
|
15
code/renderervk/R_ImageProcess.h
Normal file
15
code/renderervk/R_ImageProcess.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef R_IMAGE_PROCESS_H_
|
||||
#define R_IMAHE_PROCESS_H_
|
||||
|
||||
void GetScaledDimension(const unsigned int width, const unsigned int height, unsigned int * const outW, unsigned int * const outH, int isPicMip);
|
||||
|
||||
void R_SetColorMappings( void );
|
||||
void R_LightScaleTexture (unsigned char* dst, unsigned char* in, unsigned int nBytes);
|
||||
void ResampleTexture(unsigned char *pOut, const unsigned int inwidth, const unsigned int inheight,
|
||||
const unsigned char *pIn, const unsigned int outwidth, const unsigned int outheight);
|
||||
void R_BlendOverTexture(unsigned char* data, const uint32_t pixelCount, const uint32_t l);
|
||||
//void R_GammaCorrect(unsigned char* buffer, const unsigned int Size);
|
||||
void R_MipMap(const unsigned char* in, uint32_t width, uint32_t height, unsigned char* out);
|
||||
void R_MipMap2(const unsigned char* in, uint32_t inWidth, uint32_t inHeight, unsigned char* out);
|
||||
|
||||
#endif
|
321
code/renderervk/R_ImageTGA.c
Normal file
321
code/renderervk/R_ImageTGA.c
Normal file
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "ref_import.h"
|
||||
#include "image_loader.h"
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
TGA files are used for 24/32 bit images
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
typedef struct _TargaHeader {
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
} TargaHeader;
|
||||
|
||||
void R_LoadTGA ( const char *name, unsigned char** pic, int *width, int *height)
|
||||
{
|
||||
unsigned columns, rows, numPixels;
|
||||
unsigned char *pixbuf;
|
||||
int row, column;
|
||||
unsigned char *buf_p;
|
||||
unsigned char *end;
|
||||
char * buffer;
|
||||
TargaHeader targa_header;
|
||||
unsigned char *targa_rgba;
|
||||
int length;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
if(width)
|
||||
*width = 0;
|
||||
if(height)
|
||||
*height = 0;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
length = ri.FS_ReadFile ( name, (void**)&buffer);
|
||||
if (!buffer || length < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(length < 18)
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadTGA: header too short (%s)", name );
|
||||
}
|
||||
|
||||
buf_p = (unsigned char*)buffer;
|
||||
end = (unsigned char*)buffer + length;
|
||||
|
||||
targa_header.id_length = buf_p[0];
|
||||
targa_header.colormap_type = buf_p[1];
|
||||
targa_header.image_type = buf_p[2];
|
||||
|
||||
memcpy(&targa_header.colormap_index, &buf_p[3], 2);
|
||||
memcpy(&targa_header.colormap_length, &buf_p[5], 2);
|
||||
targa_header.colormap_size = buf_p[7];
|
||||
memcpy(&targa_header.x_origin, &buf_p[8], 2);
|
||||
memcpy(&targa_header.y_origin, &buf_p[10], 2);
|
||||
memcpy(&targa_header.width, &buf_p[12], 2);
|
||||
memcpy(&targa_header.height, &buf_p[14], 2);
|
||||
targa_header.pixel_size = buf_p[16];
|
||||
targa_header.attributes = buf_p[17];
|
||||
|
||||
targa_header.colormap_index = LittleShort(targa_header.colormap_index);
|
||||
targa_header.colormap_length = LittleShort(targa_header.colormap_length);
|
||||
targa_header.x_origin = LittleShort(targa_header.x_origin);
|
||||
targa_header.y_origin = LittleShort(targa_header.y_origin);
|
||||
targa_header.width = LittleShort(targa_header.width);
|
||||
targa_header.height = LittleShort(targa_header.height);
|
||||
|
||||
buf_p += 18;
|
||||
|
||||
if (targa_header.image_type!=2
|
||||
&& targa_header.image_type!=10
|
||||
&& targa_header.image_type != 3 )
|
||||
{
|
||||
// leilei - made these far less fatal and more informative
|
||||
ri.Printf( PRINT_WARNING, "LoadTGA: '%s' Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n", name);
|
||||
//ri.Error (ERR_DROP, "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported");
|
||||
return;
|
||||
}
|
||||
|
||||
else if ( targa_header.colormap_type != 0 )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "LoadTGA: '%s' colormaps not supported\n", name);
|
||||
|
||||
//ri.Error( ERR_DROP, "LoadTGA: colormaps not supported" );
|
||||
return;
|
||||
}
|
||||
|
||||
else if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "LoadTGA: '%s' Only 32 or 24 bit images supported (no colormaps)\n", name);
|
||||
// ri.Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)");
|
||||
return;
|
||||
}
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
numPixels = columns * rows * 4;
|
||||
|
||||
if(!columns || !rows || numPixels > 0x7FFFFFFF || numPixels / columns / 4 != rows)
|
||||
{
|
||||
ri.Error (ERR_DROP, "LoadTGA: %s has an invalid image size", name);
|
||||
}
|
||||
|
||||
|
||||
targa_rgba = ri.Malloc (numPixels);
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
{
|
||||
if (buf_p + targa_header.id_length > end)
|
||||
ri.Error( ERR_DROP, "LoadTGA: header too short (%s)", name );
|
||||
|
||||
buf_p += targa_header.id_length; // skip TARGA image comment
|
||||
}
|
||||
|
||||
if ( targa_header.image_type==2 || targa_header.image_type == 3 )
|
||||
{
|
||||
if(buf_p + columns*rows*targa_header.pixel_size/8 > end)
|
||||
{
|
||||
ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)", name);
|
||||
}
|
||||
|
||||
// Uncompressed RGB or gray scale image
|
||||
for(row=rows-1; row>=0; row--)
|
||||
{
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; column++)
|
||||
{
|
||||
unsigned char red,green,blue,alphabyte;
|
||||
switch (targa_header.pixel_size)
|
||||
{
|
||||
|
||||
case 8:
|
||||
blue = *buf_p++;
|
||||
green = blue;
|
||||
red = blue;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type==10) { // Runlength encoded RGB images
|
||||
unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
|
||||
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; ) {
|
||||
if(buf_p + 1 > end)
|
||||
ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)", name);
|
||||
packetHeader= *buf_p++;
|
||||
packetSize = 1 + (packetHeader & 0x7f);
|
||||
if (packetHeader & 0x80) { // run-length packet
|
||||
if(buf_p + targa_header.pixel_size/8 > end)
|
||||
ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)", name);
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
|
||||
for(j=0;j<packetSize;j++) {
|
||||
*pixbuf++=red;
|
||||
*pixbuf++=green;
|
||||
*pixbuf++=blue;
|
||||
*pixbuf++=alphabyte;
|
||||
column++;
|
||||
if (column==columns) { // run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // non run-length packet
|
||||
|
||||
if(buf_p + targa_header.pixel_size/8*packetSize > end)
|
||||
ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)", name);
|
||||
for(j=0;j<packetSize;j++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
column++;
|
||||
if (column==columns) { // pixel packet run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TTimo: this is the chunk of code to ensure a behavior that meets TGA specs
|
||||
// bit 5 set => top-down
|
||||
if (targa_header.attributes & 0x20) {
|
||||
unsigned char *flip = (unsigned char*)malloc (columns*4);
|
||||
unsigned char *src, *dst;
|
||||
|
||||
for (row = 0; row < rows/2; row++) {
|
||||
src = targa_rgba + row * 4 * columns;
|
||||
dst = targa_rgba + (rows - row - 1) * 4 * columns;
|
||||
|
||||
memcpy (flip, src, columns*4);
|
||||
memcpy (src, dst, columns*4);
|
||||
memcpy (dst, flip, columns*4);
|
||||
}
|
||||
free (flip);
|
||||
}
|
||||
#endif
|
||||
// instead we just print a warning
|
||||
if (targa_header.attributes & 0x20) {
|
||||
ri.Printf( PRINT_WARNING, "WARNING: '%s' TGA file header declares top-down image, ignoring\n", name);
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = columns;
|
||||
if (height)
|
||||
*height = rows;
|
||||
|
||||
*pic = targa_rgba;
|
||||
|
||||
ri.FS_FreeFile (buffer);
|
||||
}
|
177
code/renderervk/R_LerpTag.c
Normal file
177
code/renderervk/R_LerpTag.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
#include "tr_local.h"
|
||||
#include "tr_model.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
static md3Tag_t *R_GetTag( md3Header_t *mod, int frame, const char *tagName ) {
|
||||
md3Tag_t *tag;
|
||||
int i;
|
||||
|
||||
if ( frame >= mod->numFrames ) {
|
||||
// it is possible to have a bad frame while changing models, so don't error
|
||||
frame = mod->numFrames - 1;
|
||||
}
|
||||
|
||||
tag = (md3Tag_t *)((byte *)mod + mod->ofsTags) + frame * mod->numTags;
|
||||
for ( i = 0 ; i < mod->numTags ; i++, tag++ ) {
|
||||
if ( !strcmp( tag->name, tagName ) ) {
|
||||
return tag; // found it
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static md3Tag_t *R_GetAnimTag( mdrHeader_t *mod, int framenum, const char *tagName, md3Tag_t * dest)
|
||||
{
|
||||
int i, j, k;
|
||||
int frameSize;
|
||||
mdrFrame_t *frame;
|
||||
mdrTag_t *tag;
|
||||
|
||||
if ( framenum >= mod->numFrames )
|
||||
{
|
||||
// it is possible to have a bad frame while changing models, so don't error
|
||||
framenum = mod->numFrames - 1;
|
||||
}
|
||||
|
||||
tag = (mdrTag_t *)((byte *)mod + mod->ofsTags);
|
||||
for ( i = 0 ; i < mod->numTags ; i++, tag++ )
|
||||
{
|
||||
if ( !strcmp( tag->name, tagName ) )
|
||||
{
|
||||
Q_strncpyz(dest->name, tag->name, sizeof(dest->name));
|
||||
|
||||
// uncompressed model...
|
||||
//
|
||||
frameSize = (intptr_t)( &((mdrFrame_t *)0)->bones[ mod->numBones ] );
|
||||
frame = (mdrFrame_t *)((byte *)mod + mod->ofsFrames + framenum * frameSize );
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
dest->axis[j][k]=frame->bones[tag->boneIndex].matrix[k][j];
|
||||
}
|
||||
|
||||
dest->origin[0]=frame->bones[tag->boneIndex].matrix[0][3];
|
||||
dest->origin[1]=frame->bones[tag->boneIndex].matrix[1][3];
|
||||
dest->origin[2]=frame->bones[tag->boneIndex].matrix[2][3];
|
||||
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) {
|
||||
out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3];
|
||||
out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7];
|
||||
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
|
||||
float backlerp, float *mat ) {
|
||||
float *mat1;
|
||||
int i;
|
||||
|
||||
ComputePoseMats( data, frame, oldframe, backlerp, mat );
|
||||
|
||||
for( i = 0; i < data->num_joints; i++ ) {
|
||||
float outmat[12];
|
||||
mat1 = mat + 12 * i;
|
||||
|
||||
memcpy(outmat, mat1, sizeof(outmat));
|
||||
|
||||
Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int R_IQMLerpTag( orientation_t *tag, iqmData_t *data,
|
||||
int startFrame, int endFrame,
|
||||
float frac, const char *tagName ) {
|
||||
float jointMats[IQM_MAX_JOINTS * 12];
|
||||
int joint;
|
||||
char *names = data->names;
|
||||
|
||||
// get joint number by reading the joint names
|
||||
for( joint = 0; joint < data->num_joints; joint++ ) {
|
||||
if( !strcmp( tagName, names ) )
|
||||
break;
|
||||
names += strlen( names ) + 1;
|
||||
}
|
||||
if( joint >= data->num_joints ) {
|
||||
memset(tag, 0, sizeof(orientation_t));
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
ComputeJointMats( data, startFrame, endFrame, frac, jointMats );
|
||||
|
||||
tag->axis[0][0] = jointMats[12 * joint + 0];
|
||||
tag->axis[1][0] = jointMats[12 * joint + 1];
|
||||
tag->axis[2][0] = jointMats[12 * joint + 2];
|
||||
tag->origin[0] = jointMats[12 * joint + 3];
|
||||
tag->axis[0][1] = jointMats[12 * joint + 4];
|
||||
tag->axis[1][1] = jointMats[12 * joint + 5];
|
||||
tag->axis[2][1] = jointMats[12 * joint + 6];
|
||||
tag->origin[1] = jointMats[12 * joint + 7];
|
||||
tag->axis[0][2] = jointMats[12 * joint + 8];
|
||||
tag->axis[1][2] = jointMats[12 * joint + 9];
|
||||
tag->axis[2][2] = jointMats[12 * joint + 10];
|
||||
tag->origin[2] = jointMats[12 * joint + 11];
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
int RE_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame,
|
||||
float frac, const char *tagName )
|
||||
{
|
||||
|
||||
// ri.Printf(PRINT_ALL, "R_LerpTag\n");
|
||||
|
||||
md3Tag_t *start, *end;
|
||||
md3Tag_t start_space, end_space;
|
||||
model_t* model = R_GetModelByHandle( handle );
|
||||
if ( !model->md3[0] )
|
||||
{
|
||||
if(model->type == MOD_MDR)
|
||||
{
|
||||
start = R_GetAnimTag((mdrHeader_t *) model->modelData, startFrame, tagName, &start_space);
|
||||
end = R_GetAnimTag((mdrHeader_t *) model->modelData, endFrame, tagName, &end_space);
|
||||
}
|
||||
else if( model->type == MOD_IQM ) {
|
||||
return R_IQMLerpTag( tag, model->modelData,
|
||||
startFrame, endFrame,
|
||||
frac, tagName );
|
||||
} else {
|
||||
start = end = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
start = R_GetTag( model->md3[0], startFrame, tagName );
|
||||
end = R_GetTag( model->md3[0], endFrame, tagName );
|
||||
}
|
||||
|
||||
if ( !start || !end ) {
|
||||
memset(tag, 0, sizeof(orientation_t));
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
uint32_t i;
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
tag->origin[i] = start->origin[i] + (end->origin[i] - start->origin[i]) * frac;
|
||||
tag->axis[0][i] = start->axis[0][i] + (end->axis[0][i] - start->axis[0][i]) * frac;
|
||||
tag->axis[1][i] = start->axis[1][i] + (end->axis[1][i] - start->axis[1][i]) * frac;
|
||||
tag->axis[2][i] = start->axis[2][i] + (end->axis[2][i] - start->axis[2][i]) * frac;
|
||||
}
|
||||
VectorNormalize( tag->axis[0] );
|
||||
VectorNormalize( tag->axis[1] );
|
||||
VectorNormalize( tag->axis[2] );
|
||||
return qtrue;
|
||||
}
|
64
code/renderervk/R_ListShader.c
Normal file
64
code/renderervk/R_ListShader.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "tr_globals.h"
|
||||
#include "tr_shader.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
/*
|
||||
===============
|
||||
Dump information on all valid shaders to the console
|
||||
A second parameter will cause it to print in sorted order
|
||||
===============
|
||||
*/
|
||||
void R_ShaderList_f (void)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
shader_t* pShader;
|
||||
|
||||
ri.Printf (PRINT_ALL, "-----------------------\n");
|
||||
|
||||
for ( i = 0 ; i < tr.numShaders ; i++ )
|
||||
{
|
||||
if ( ri.Cmd_Argc() > 1 )
|
||||
pShader = tr.sortedShaders[i];
|
||||
else
|
||||
pShader = tr.shaders[i];
|
||||
|
||||
ri.Printf( PRINT_ALL, "%i ", pShader->numUnfoggedPasses );
|
||||
|
||||
if (pShader->lightmapIndex >= 0 )
|
||||
ri.Printf (PRINT_ALL, "L ");
|
||||
else
|
||||
ri.Printf (PRINT_ALL, " ");
|
||||
|
||||
|
||||
if ( pShader->multitextureEnv == GL_ADD )
|
||||
ri.Printf( PRINT_ALL, "MT(a) " );
|
||||
else if ( pShader->multitextureEnv == GL_MODULATE )
|
||||
ri.Printf( PRINT_ALL, "MT(m) " );
|
||||
else
|
||||
ri.Printf( PRINT_ALL, " " );
|
||||
|
||||
|
||||
if ( pShader->explicitlyDefined )
|
||||
ri.Printf( PRINT_ALL, "E " );
|
||||
else
|
||||
ri.Printf( PRINT_ALL, " " );
|
||||
|
||||
|
||||
if ( !pShader->isSky )
|
||||
ri.Printf( PRINT_ALL, "gen " );
|
||||
else
|
||||
ri.Printf( PRINT_ALL, "sky " );
|
||||
|
||||
|
||||
if ( pShader->defaultShader )
|
||||
ri.Printf (PRINT_ALL, ": %s (DEFAULTED)\n", pShader->name);
|
||||
else
|
||||
ri.Printf (PRINT_ALL, ": %s\n", pShader->name);
|
||||
|
||||
count++;
|
||||
}
|
||||
ri.Printf (PRINT_ALL, "%i total shaders\n", count);
|
||||
ri.Printf (PRINT_ALL, "------------------\n");
|
||||
}
|
||||
|
128
code/renderervk/R_LoadImage.c
Normal file
128
code/renderervk/R_LoadImage.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include "tr_local.h"
|
||||
#include "ref_import.h"
|
||||
#include "image_loader.h"
|
||||
|
||||
// Description: Loads any of the supported image types into
|
||||
// a cannonical 32 bit format.
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *ext;
|
||||
void (*ImageLoader)( const char *, unsigned char **, int *, int * );
|
||||
} imageExtToLoaderMap_t;
|
||||
|
||||
// Note that the ordering indicates the order of preference used
|
||||
// when there are multiple images of different formats available
|
||||
const static imageExtToLoaderMap_t imageLoaders[6] =
|
||||
{
|
||||
{ "tga", R_LoadTGA },
|
||||
{ "jpg", R_LoadJPG },
|
||||
{ "jpeg", R_LoadJPG },
|
||||
{ "png", R_LoadPNG },
|
||||
{ "pcx", R_LoadPCX },
|
||||
{ "bmp", R_LoadBMP }
|
||||
};
|
||||
|
||||
const static int numImageLoaders = 6;
|
||||
|
||||
|
||||
void R_LoadImage(const char *name, unsigned char **pic, int *width, int *height )
|
||||
{
|
||||
int orgLoader = -1;
|
||||
int i;
|
||||
char localName[ 128 ] = {0};
|
||||
//int len = strlen(name);
|
||||
|
||||
const char* pSrc = name;
|
||||
char* pDst = localName;
|
||||
//char* dot = NULL;
|
||||
char* pExt = NULL;
|
||||
//char* slash = NULL;
|
||||
|
||||
*pic = NULL;
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
|
||||
|
||||
char c;
|
||||
|
||||
// copy name to localName
|
||||
while( (c = *pDst++ = *pSrc++) )
|
||||
{
|
||||
|
||||
if(c == '.')
|
||||
pExt = pDst;
|
||||
// else if(c == '/')
|
||||
// slash = pDst-1;
|
||||
}
|
||||
|
||||
if( pExt != NULL )
|
||||
{
|
||||
// Look for the correct loader and use it
|
||||
for( i = 0; i < numImageLoaders; i++ )
|
||||
{
|
||||
if( !Q_stricmp( pExt, imageLoaders[ i ].ext ) )
|
||||
{
|
||||
orgLoader = i;
|
||||
|
||||
// Load
|
||||
imageLoaders[ i ].ImageLoader( localName, pic, width, height );
|
||||
if( *pic != NULL )
|
||||
{
|
||||
// Something loaded
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loader failed, most likely because the file isn't there;
|
||||
// Try and find a suitable match using all the image formats supported
|
||||
|
||||
for( i = 0; i < numImageLoaders; i++ )
|
||||
{
|
||||
if (i == orgLoader)
|
||||
continue;
|
||||
|
||||
strcpy(pExt, imageLoaders[ i ].ext);
|
||||
|
||||
// Load
|
||||
imageLoaders[ i ].ImageLoader( localName, pic, width, height );
|
||||
|
||||
if( *pic != NULL )
|
||||
{
|
||||
// Something loaded
|
||||
//ri.Printf( PRINT_WARNING, "%s not present, using %s instead\n", name, localName );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ri.Printf( PRINT_WARNING, "%s not present\n", localName );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Try and find a suitable match using all the image formats supported
|
||||
*(pDst-1) = '.';
|
||||
|
||||
for( i = 0; i < numImageLoaders; i++ )
|
||||
{
|
||||
strcpy(pDst, imageLoaders[ i ].ext);
|
||||
// Load
|
||||
imageLoaders[ i ].ImageLoader( localName, pic, width, height );
|
||||
|
||||
if( *pic != NULL )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "%s without a extension, using %s instead. \n",
|
||||
name, localName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ri.Printf( PRINT_WARNING, "%s not present.\n", name);
|
||||
|
||||
// try again without the extension
|
||||
|
||||
}
|
728
code/renderervk/R_LoadImage2.c
Normal file
728
code/renderervk/R_LoadImage2.c
Normal file
|
@ -0,0 +1,728 @@
|
|||
#include "tr_local.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
static void* q3_stbi_malloc(size_t size) {
|
||||
return ri.Malloc((int)size);
|
||||
}
|
||||
static void q3_stbi_free(void* p) {
|
||||
ri.Free(p);
|
||||
}
|
||||
static void* q3_stbi_realloc(void* p, size_t old_size, size_t new_size) {
|
||||
if (p == NULL)
|
||||
return q3_stbi_malloc(new_size);
|
||||
|
||||
void* p_new;
|
||||
if (old_size < new_size) {
|
||||
p_new = q3_stbi_malloc(new_size);
|
||||
memcpy(p_new, p, old_size);
|
||||
q3_stbi_free(p);
|
||||
} else {
|
||||
p_new = p;
|
||||
}
|
||||
return p_new;
|
||||
}
|
||||
#define STBI_MALLOC q3_stbi_malloc
|
||||
#define STBI_FREE q3_stbi_free
|
||||
#define STBI_REALLOC_SIZED q3_stbi_realloc
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
|
||||
|
||||
static void LoadTGA( const char* name, unsigned char** pic, uint32_t* width, uint32_t* height);
|
||||
static void LoadBMP( const char* name, unsigned char** pic, uint32_t* width, uint32_t* height);
|
||||
static void LoadJPG( const char* name, unsigned char** pic, uint32_t* width, uint32_t* height);
|
||||
static void LoadPCX32 ( const char* filename, unsigned char** pic, uint32_t* width, uint32_t* height);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Loads any of the supported image types into a cannonical 32 bit format.
|
||||
*/
|
||||
void R_LoadImage2(const char *name, unsigned char **pic, uint32_t* width, uint32_t* height)
|
||||
{
|
||||
|
||||
const int len = (int)strlen(name);
|
||||
if (len<5)
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "R_LoadImage2: try to loading %s ? \n", name );
|
||||
return;
|
||||
}
|
||||
|
||||
// point to '.', .jped are assume not exist
|
||||
const char* const pPnt = (char*)name + len - 4;
|
||||
|
||||
if(pPnt[0] == '.')
|
||||
{ // have a extension
|
||||
if( ( (pPnt[1] == 't') && (pPnt[2] == 'g') && (pPnt[3] == 'a') ) ||
|
||||
( (pPnt[1] == 'T') && (pPnt[2] == 'G') && (pPnt[3] == 'A') ) )
|
||||
{
|
||||
LoadTGA( name, pic, width, height );
|
||||
|
||||
if (NULL == *pic)
|
||||
{
|
||||
// try jpg in place of tga
|
||||
char altname[128] = {0};
|
||||
strncpy( altname, name, 128 );
|
||||
char* pt = altname + len - 4;
|
||||
|
||||
pt[1] = 'j';
|
||||
pt[2] = 'p';
|
||||
pt[3] = 'g';
|
||||
|
||||
LoadJPG( altname, pic, width, height );
|
||||
}
|
||||
}
|
||||
else if ( ( (pPnt[1] == 'j') && (pPnt[2] == 'p') && (pPnt[3] == 'g') ) ||
|
||||
( (pPnt[1] == 'J') && (pPnt[2] == 'P') && (pPnt[3] == 'G') ) )
|
||||
{
|
||||
LoadJPG( name, pic, width, height );
|
||||
}
|
||||
else if ( ( (pPnt[1] == 'b') && (pPnt[2] == 'm') && (pPnt[3] == 'p') ) ||
|
||||
( (pPnt[1] == 'B') && (pPnt[2] == 'M') && (pPnt[3] == 'P') ) )
|
||||
|
||||
{
|
||||
LoadBMP( name, pic, width, height );
|
||||
}
|
||||
else if ( ( (pPnt[1] == 'p') && (pPnt[2] == 'c') && (pPnt[3] == 'x') ) ||
|
||||
( (pPnt[1] == 'P') && (pPnt[2] == 'C') && (pPnt[3] == 'X') ) )
|
||||
{
|
||||
LoadPCX32( name, pic, width, height );
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // without a extension
|
||||
// Try and find a suitable match using all the image formats supported
|
||||
char altname[128] = {0};
|
||||
strcpy( altname, name );
|
||||
char* pt = altname + len;
|
||||
pt[0] = '.';
|
||||
pt[1] = 't';
|
||||
pt[2] = 'g';
|
||||
pt[3] = 'a';
|
||||
pt[4] = '\0';
|
||||
|
||||
LoadTGA( altname, pic, width, height );
|
||||
|
||||
if (NULL == *pic)
|
||||
{
|
||||
// try jpg in place of tga
|
||||
pt[0] = '.';
|
||||
pt[1] = 'j';
|
||||
pt[2] = 'p';
|
||||
pt[3] = 'g';
|
||||
pt[4] = '\0';
|
||||
|
||||
LoadJPG( altname, pic, width, height );
|
||||
}
|
||||
|
||||
if( *pic == NULL )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "%s not present.\n", name);
|
||||
}
|
||||
// else
|
||||
// ri.Printf( PRINT_ALL, "%s without a extension, using %s instead. \n", name, altname);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ====================================== //
|
||||
// ====================================== //
|
||||
|
||||
typedef struct _TargaHeader {
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
} TargaHeader;
|
||||
|
||||
|
||||
|
||||
static void LoadTGA( const char* name, unsigned char** pic, uint32_t* width, uint32_t* height)
|
||||
{
|
||||
int columns, rows, numPixels;
|
||||
unsigned char* pixbuf;
|
||||
int row, column;
|
||||
|
||||
char* buffer;
|
||||
TargaHeader targa_header;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
ri.FS_ReadFile(name, (void**)&buffer);
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
char* buf_p = buffer;
|
||||
|
||||
targa_header.id_length = *buf_p++;
|
||||
targa_header.colormap_type = *buf_p++;
|
||||
targa_header.image_type = *buf_p++;
|
||||
|
||||
targa_header.colormap_index = LittleShort ( *(short *)buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.colormap_length = LittleShort ( *(short *)buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.colormap_size = *buf_p++;
|
||||
targa_header.x_origin = LittleShort ( *(short *)buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.y_origin = LittleShort ( *(short *)buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.width = LittleShort ( *(short *)buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.height = LittleShort ( *(short *)buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.pixel_size = *buf_p++;
|
||||
targa_header.attributes = *buf_p++;
|
||||
|
||||
if (targa_header.image_type!=2
|
||||
&& targa_header.image_type!=10
|
||||
&& targa_header.image_type != 3 )
|
||||
{
|
||||
ri.Error (ERR_DROP, "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
|
||||
}
|
||||
|
||||
if ( targa_header.colormap_type != 0 )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadTGA: colormaps not supported\n" );
|
||||
}
|
||||
|
||||
if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
|
||||
{
|
||||
ri.Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
|
||||
}
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
numPixels = columns * rows;
|
||||
|
||||
if (width)
|
||||
*width = columns;
|
||||
if (height)
|
||||
*height = rows;
|
||||
|
||||
unsigned char* targa_rgba = (unsigned char*) ri.Malloc (numPixels*4);
|
||||
*pic = targa_rgba;
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
buf_p += targa_header.id_length; // skip TARGA image comment
|
||||
|
||||
if ( targa_header.image_type==2 || targa_header.image_type == 3 )
|
||||
{
|
||||
// Uncompressed RGB or gray scale image
|
||||
for(row=rows-1; row>=0; row--)
|
||||
{
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; column++)
|
||||
{
|
||||
unsigned char red,green,blue,alphabyte;
|
||||
switch (targa_header.pixel_size)
|
||||
{
|
||||
|
||||
case 8:
|
||||
blue = *buf_p++;
|
||||
green = blue;
|
||||
red = blue;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type==10) { // Runlength encoded RGB images
|
||||
unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
|
||||
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
alphabyte = 0xff;
|
||||
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; ) {
|
||||
packetHeader= *buf_p++;
|
||||
packetSize = 1 + (packetHeader & 0x7f);
|
||||
if (packetHeader & 0x80) { // run-length packet
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
|
||||
for(j=0;j<packetSize;j++) {
|
||||
*pixbuf++=red;
|
||||
*pixbuf++=green;
|
||||
*pixbuf++=blue;
|
||||
*pixbuf++=alphabyte;
|
||||
column++;
|
||||
if (column==columns) { // run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // non run-length packet
|
||||
for(j=0;j<packetSize;j++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
column++;
|
||||
if (column==columns) { // pixel packet run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TTimo: this is the chunk of code to ensure a behavior that meets TGA specs
|
||||
// bk0101024 - fix from Leonardo
|
||||
// bit 5 set => top-down
|
||||
if (targa_header.attributes & 0x20) {
|
||||
unsigned char *flip = (unsigned char*)malloc (columns*4);
|
||||
unsigned char *src, *dst;
|
||||
|
||||
for (row = 0; row < rows/2; row++) {
|
||||
src = targa_rgba + row * 4 * columns;
|
||||
dst = targa_rgba + (rows - row - 1) * 4 * columns;
|
||||
|
||||
memcpy (flip, src, columns*4);
|
||||
memcpy (src, dst, columns*4);
|
||||
memcpy (dst, flip, columns*4);
|
||||
}
|
||||
free (flip);
|
||||
}
|
||||
#endif
|
||||
// instead we just print a warning
|
||||
if (targa_header.attributes & 0x20) {
|
||||
ri.Printf( PRINT_WARNING, "WARNING: '%s' TGA file header declares top-down image, ignoring\n", name);
|
||||
}
|
||||
|
||||
ri.FS_FreeFile (buffer);
|
||||
}
|
||||
|
||||
|
||||
static void LoadJPG( const char* name, unsigned char** pic, uint32_t* width, uint32_t* height)
|
||||
{
|
||||
char* fbuffer;
|
||||
int len = ri.FS_ReadFile(name, (void**)&fbuffer);
|
||||
if (!fbuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
int components;
|
||||
*pic = stbi_load_from_memory((unsigned char*)fbuffer, len, (int*)width, (int*)height, &components, STBI_rgb_alpha);
|
||||
if (*pic == NULL) {
|
||||
ri.FS_FreeFile(fbuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
// clear all the alphas to 255
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char* buf = *pic;
|
||||
|
||||
unsigned int nBytes = 4 * (*width) * (*height);
|
||||
for (i = 3; i < nBytes; i += 4)
|
||||
{
|
||||
buf[i] = 255;
|
||||
}
|
||||
}
|
||||
ri.FS_FreeFile(fbuffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
BMP LOADING
|
||||
|
||||
=========================================================
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char id[2];
|
||||
unsigned long fileSize;
|
||||
unsigned long reserved0;
|
||||
unsigned long bitmapDataOffset;
|
||||
unsigned long bitmapHeaderSize;
|
||||
unsigned long width;
|
||||
unsigned long height;
|
||||
unsigned short planes;
|
||||
unsigned short bitsPerPixel;
|
||||
unsigned long compression;
|
||||
unsigned long bitmapDataSize;
|
||||
unsigned long hRes;
|
||||
unsigned long vRes;
|
||||
unsigned long colors;
|
||||
unsigned long importantColors;
|
||||
unsigned char palette[256][4];
|
||||
} BMPHeader_t;
|
||||
|
||||
|
||||
|
||||
|
||||
static void LoadBMP( const char *name, unsigned char **pic, uint32_t *width, uint32_t *height )
|
||||
{
|
||||
int columns, rows, numPixels;
|
||||
unsigned char *pixbuf;
|
||||
int row, column;
|
||||
char* buf_p;
|
||||
char* buffer;
|
||||
|
||||
int length;
|
||||
BMPHeader_t bmpHeader;
|
||||
unsigned char *bmpRGBA;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
length = ri.FS_ReadFile(name, (void**)&buffer);
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf_p = buffer;
|
||||
|
||||
bmpHeader.id[0] = *buf_p++;
|
||||
bmpHeader.id[1] = *buf_p++;
|
||||
bmpHeader.fileSize = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.width = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.height = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.planes = LittleShort( * ( short * ) buf_p );
|
||||
buf_p += 2;
|
||||
bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
|
||||
buf_p += 2;
|
||||
bmpHeader.compression = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.hRes = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.vRes = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.colors = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
bmpHeader.importantColors = LittleLong( * ( long * ) buf_p );
|
||||
buf_p += 4;
|
||||
|
||||
memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
|
||||
|
||||
if ( bmpHeader.bitsPerPixel == 8 )
|
||||
buf_p += 1024;
|
||||
|
||||
if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: only Windows-style BMP files supported (%s)\n", name );
|
||||
}
|
||||
if ( bmpHeader.fileSize != length )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: header size does not match file size (%ld vs. %d) (%s)\n", bmpHeader.fileSize, length, name );
|
||||
}
|
||||
if ( bmpHeader.compression != 0 )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: only uncompressed BMP files supported (%s)\n", name );
|
||||
}
|
||||
if ( bmpHeader.bitsPerPixel < 8 )
|
||||
{
|
||||
ri.Error( ERR_DROP, "LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name );
|
||||
}
|
||||
|
||||
columns = bmpHeader.width;
|
||||
rows = bmpHeader.height;
|
||||
if ( rows < 0 )
|
||||
rows = -rows;
|
||||
numPixels = columns * rows;
|
||||
|
||||
if ( width )
|
||||
*width = columns;
|
||||
if ( height )
|
||||
*height = rows;
|
||||
|
||||
bmpRGBA = (unsigned char*) ri.Malloc( numPixels * 4 );
|
||||
*pic = bmpRGBA;
|
||||
|
||||
|
||||
for ( row = rows-1; row >= 0; row-- )
|
||||
{
|
||||
pixbuf = bmpRGBA + row*columns*4;
|
||||
|
||||
for ( column = 0; column < columns; column++ )
|
||||
{
|
||||
unsigned char red, green, blue, alpha;
|
||||
int palIndex;
|
||||
unsigned short shortPixel;
|
||||
|
||||
switch ( bmpHeader.bitsPerPixel )
|
||||
{
|
||||
case 8:
|
||||
palIndex = *buf_p++;
|
||||
*pixbuf++ = bmpHeader.palette[palIndex][2];
|
||||
*pixbuf++ = bmpHeader.palette[palIndex][1];
|
||||
*pixbuf++ = bmpHeader.palette[palIndex][0];
|
||||
*pixbuf++ = 0xff;
|
||||
break;
|
||||
case 16:
|
||||
shortPixel = * ( unsigned short * ) pixbuf;
|
||||
pixbuf += 2;
|
||||
*pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
|
||||
*pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
|
||||
*pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
|
||||
*pixbuf++ = 0xff;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alpha = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alpha;
|
||||
break;
|
||||
default:
|
||||
ri.Error( ERR_DROP, "LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ri.FS_FreeFile( buffer );
|
||||
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
char data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
static void LoadPCX ( const char *filename, unsigned char **pic, unsigned char **palette, uint32_t *width, uint32_t *height)
|
||||
{
|
||||
char* raw;
|
||||
pcx_t *pcx;
|
||||
int x, y;
|
||||
int len;
|
||||
int dataByte, runLength;
|
||||
unsigned char *out, *pix;
|
||||
int xmax, ymax;
|
||||
|
||||
*pic = NULL;
|
||||
*palette = NULL;
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
len = ri.FS_ReadFile(filename, (void**)&raw);
|
||||
if (!raw) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
pcx = (pcx_t *)raw;
|
||||
raw = &pcx->data;
|
||||
|
||||
xmax = LittleShort(pcx->xmax);
|
||||
ymax = LittleShort(pcx->ymax);
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| xmax >= 1024
|
||||
|| ymax >= 1024)
|
||||
{
|
||||
ri.Printf (PRINT_ALL, "Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax);
|
||||
return;
|
||||
}
|
||||
|
||||
out = (unsigned char*) ri.Malloc ( (ymax+1) * (xmax+1) );
|
||||
|
||||
*pic = out;
|
||||
|
||||
pix = out;
|
||||
|
||||
if (palette)
|
||||
{
|
||||
*palette = (unsigned char*) ri.Malloc(768);
|
||||
memcpy (*palette, (unsigned char *)pcx + len - 768, 768);
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = xmax+1;
|
||||
if (height)
|
||||
*height = ymax+1;
|
||||
// FIXME: use bytes_per_line here?
|
||||
|
||||
for (y=0 ; y<=ymax ; y++, pix += xmax+1)
|
||||
{
|
||||
for (x=0 ; x<=xmax ; )
|
||||
{
|
||||
dataByte = *raw++;
|
||||
|
||||
if((dataByte & 0xC0) == 0xC0)
|
||||
{
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = *raw++;
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
|
||||
while(runLength-- > 0)
|
||||
pix[x++] = dataByte;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( raw - (char *)pcx > len)
|
||||
{
|
||||
ri.Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename);
|
||||
ri.Free (*pic);
|
||||
*pic = NULL;
|
||||
}
|
||||
|
||||
ri.FS_FreeFile (pcx);
|
||||
}
|
||||
|
||||
|
||||
static void LoadPCX32 ( const char *filename, unsigned char **pic, uint32_t *width, uint32_t *height)
|
||||
{
|
||||
unsigned char *palette;
|
||||
unsigned char *pic8;
|
||||
int i, c, p;
|
||||
unsigned char *pic32;
|
||||
|
||||
LoadPCX (filename, &pic8, &palette, width, height);
|
||||
if (!pic8) {
|
||||
*pic = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
c = (*width) * (*height);
|
||||
pic32 = *pic = (unsigned char*) ri.Malloc(4 * c );
|
||||
for (i = 0 ; i < c ; i++) {
|
||||
p = pic8[i];
|
||||
pic32[0] = palette[p*3];
|
||||
pic32[1] = palette[p*3 + 1];
|
||||
pic32[2] = palette[p*3 + 2];
|
||||
pic32[3] = 255;
|
||||
pic32 += 4;
|
||||
}
|
||||
|
||||
ri.Free (pic8);
|
||||
ri.Free (palette);
|
||||
}
|
270
code/renderervk/R_LoadMD3.c
Normal file
270
code/renderervk/R_LoadMD3.c
Normal file
|
@ -0,0 +1,270 @@
|
|||
|
||||
#include "tr_local.h"
|
||||
#include "tr_model.h"
|
||||
#include "ref_import.h"
|
||||
#include "tr_shader.h"
|
||||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
|
||||
static qboolean R_LoadMD3 (model_t *mod, int lod, void *buffer, const char *mod_name )
|
||||
{
|
||||
int i, j;
|
||||
md3Header_t *pinmodel;
|
||||
md3Frame_t *frame;
|
||||
md3Surface_t *surf;
|
||||
md3Shader_t *shader;
|
||||
md3Triangle_t *tri;
|
||||
md3St_t *st;
|
||||
md3XyzNormal_t *xyz;
|
||||
md3Tag_t *tag;
|
||||
int version;
|
||||
int size;
|
||||
|
||||
pinmodel = (md3Header_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
if (version != MD3_VERSION) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD3: %s has wrong version (%i should be %i)\n",
|
||||
mod_name, version, MD3_VERSION);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
mod->type = MOD_MESH;
|
||||
size = LittleLong(pinmodel->ofsEnd);
|
||||
mod->dataSize += size;
|
||||
mod->md3[lod] = ri.Hunk_Alloc( size, h_low );
|
||||
|
||||
memcpy (mod->md3[lod], buffer, LittleLong(pinmodel->ofsEnd) );
|
||||
|
||||
LL(mod->md3[lod]->ident);
|
||||
LL(mod->md3[lod]->version);
|
||||
LL(mod->md3[lod]->numFrames);
|
||||
LL(mod->md3[lod]->numTags);
|
||||
LL(mod->md3[lod]->numSurfaces);
|
||||
LL(mod->md3[lod]->ofsFrames);
|
||||
LL(mod->md3[lod]->ofsTags);
|
||||
LL(mod->md3[lod]->ofsSurfaces);
|
||||
LL(mod->md3[lod]->ofsEnd);
|
||||
|
||||
if ( mod->md3[lod]->numFrames < 1 ) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD3: %s has no frames\n", mod_name );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// swap all the frames
|
||||
frame = (md3Frame_t *) ( (byte *)mod->md3[lod] + mod->md3[lod]->ofsFrames );
|
||||
for ( i = 0 ; i < mod->md3[lod]->numFrames ; i++, frame++) {
|
||||
frame->radius = LittleFloat( frame->radius );
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
|
||||
frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
|
||||
frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
|
||||
}
|
||||
}
|
||||
|
||||
// swap all the tags
|
||||
tag = (md3Tag_t *) ( (byte *)mod->md3[lod] + mod->md3[lod]->ofsTags );
|
||||
for ( i = 0 ; i < mod->md3[lod]->numTags * mod->md3[lod]->numFrames ; i++, tag++) {
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
tag->origin[j] = LittleFloat( tag->origin[j] );
|
||||
tag->axis[0][j] = LittleFloat( tag->axis[0][j] );
|
||||
tag->axis[1][j] = LittleFloat( tag->axis[1][j] );
|
||||
tag->axis[2][j] = LittleFloat( tag->axis[2][j] );
|
||||
}
|
||||
}
|
||||
|
||||
// swap all the surfaces
|
||||
surf = (md3Surface_t *) ( (byte *)mod->md3[lod] + mod->md3[lod]->ofsSurfaces );
|
||||
for ( i = 0 ; i < mod->md3[lod]->numSurfaces ; i++) {
|
||||
|
||||
LL(surf->ident);
|
||||
LL(surf->flags);
|
||||
LL(surf->numFrames);
|
||||
LL(surf->numShaders);
|
||||
LL(surf->numTriangles);
|
||||
LL(surf->ofsTriangles);
|
||||
LL(surf->numVerts);
|
||||
LL(surf->ofsShaders);
|
||||
LL(surf->ofsSt);
|
||||
LL(surf->ofsXyzNormals);
|
||||
LL(surf->ofsEnd);
|
||||
|
||||
if ( surf->numVerts >= SHADER_MAX_VERTEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD3: %s has more than %i verts on %s (%i).\n",
|
||||
mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numVerts );
|
||||
return qfalse;
|
||||
}
|
||||
if ( surf->numTriangles*3 >= SHADER_MAX_INDEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD3: %s has more than %i triangles on %s (%i).\n",
|
||||
mod_name, ( SHADER_MAX_INDEXES / 3 ) - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numTriangles );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// change to surface identifier
|
||||
surf->ident = SF_MD3;
|
||||
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surf->name );
|
||||
|
||||
// strip off a trailing _1 or _2
|
||||
// this is a crutch for q3data being a mess
|
||||
j = strlen( surf->name );
|
||||
if ( j > 2 && surf->name[j-2] == '_' ) {
|
||||
surf->name[j-2] = 0;
|
||||
}
|
||||
|
||||
// register the shaders
|
||||
shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
|
||||
for ( j = 0 ; j < surf->numShaders ; j++, shader++ ) {
|
||||
shader_t* sh = R_FindShader( shader->name, LIGHTMAP_NONE, qtrue );
|
||||
|
||||
if ( sh->defaultShader ) {
|
||||
shader->shaderIndex = 0;
|
||||
} else {
|
||||
shader->shaderIndex = sh->index;
|
||||
}
|
||||
}
|
||||
|
||||
// swap all the triangles
|
||||
tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
|
||||
for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
|
||||
LL(tri->indexes[0]);
|
||||
LL(tri->indexes[1]);
|
||||
LL(tri->indexes[2]);
|
||||
}
|
||||
|
||||
// swap all the ST
|
||||
st = (md3St_t *) ( (byte *)surf + surf->ofsSt );
|
||||
for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
|
||||
st->st[0] = LittleFloat( st->st[0] );
|
||||
st->st[1] = LittleFloat( st->st[1] );
|
||||
}
|
||||
|
||||
// swap all the XyzNormals
|
||||
xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals );
|
||||
for ( j = 0 ; j < surf->numVerts * surf->numFrames ; j++, xyz++ )
|
||||
{
|
||||
xyz->xyz[0] = LittleShort( xyz->xyz[0] );
|
||||
xyz->xyz[1] = LittleShort( xyz->xyz[1] );
|
||||
xyz->xyz[2] = LittleShort( xyz->xyz[2] );
|
||||
|
||||
xyz->normal = LittleShort( xyz->normal );
|
||||
}
|
||||
|
||||
|
||||
// find the next surface
|
||||
surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
qhandle_t R_RegisterMD3(const char* name, model_t* mod)
|
||||
{
|
||||
|
||||
char* buf;
|
||||
int numLoaded = 0;
|
||||
|
||||
ri.FS_ReadFile( name, (void**)&buf );
|
||||
|
||||
if( NULL != buf)
|
||||
{
|
||||
qboolean loaded = qfalse;
|
||||
|
||||
#if defined( Q3_BIG_ENDIAN )
|
||||
int ident = LittleLong(*(int *)buf);
|
||||
#else
|
||||
int ident = *(int *)buf;
|
||||
#endif
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, 0, buf, name);
|
||||
else
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
|
||||
ri.FS_FreeFile(buf);
|
||||
|
||||
if(loaded)
|
||||
{
|
||||
mod->numLods++;
|
||||
numLoaded++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_RegisterMD3: couldn't load %s\n", name);
|
||||
|
||||
mod->type = MOD_BAD;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_RegisterMD3: failed loading %s from disk. \n", name);
|
||||
}
|
||||
|
||||
|
||||
char filename[MAX_QPATH] = {0};
|
||||
strcpy(filename, name);
|
||||
char* const dot = strrchr(filename, '.');
|
||||
*dot = 0;
|
||||
|
||||
uint32_t lod;
|
||||
for (lod = 1; lod < MD3_MAX_LODS; lod++)
|
||||
{
|
||||
qboolean loaded = qfalse;
|
||||
|
||||
char namebuf[MAX_QPATH+20] = {0};
|
||||
snprintf(namebuf, sizeof(namebuf), "%s_%d.md3", filename, lod);
|
||||
|
||||
ri.FS_ReadFile( namebuf, (void**)&buf );
|
||||
if(!buf)
|
||||
continue;
|
||||
|
||||
#if defined( Q3_BIG_ENDIAN )
|
||||
int ident = LittleLong(*(int *)buf);
|
||||
#else
|
||||
int ident = *(int *)buf;
|
||||
#endif
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf, name);
|
||||
else
|
||||
ri.Printf(PRINT_WARNING, "R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
|
||||
ri.FS_FreeFile(buf);
|
||||
|
||||
if(loaded)
|
||||
{
|
||||
mod->numLods++;
|
||||
numLoaded++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(numLoaded)
|
||||
return mod->index;
|
||||
else
|
||||
ri.Printf(PRINT_WARNING, "R_RegisterMD3: couldn't load %s\n", name);
|
||||
|
||||
|
||||
/*
|
||||
if(numLoaded)
|
||||
{
|
||||
// duplicate into higher lod spots that weren't loaded,
|
||||
// in case the user changes r_lodbias on the fly
|
||||
for(lod--; lod >= 0; lod--)
|
||||
{
|
||||
mod->numLods++;
|
||||
mod->md3[lod] = mod->md3[lod + 1];
|
||||
}
|
||||
|
||||
return mod->index;
|
||||
}
|
||||
*/
|
||||
|
||||
mod->type = MOD_BAD;
|
||||
return 0;
|
||||
}
|
527
code/renderervk/R_LoadMDR.c
Normal file
527
code/renderervk/R_LoadMDR.c
Normal file
|
@ -0,0 +1,527 @@
|
|||
#include "tr_local.h"
|
||||
#include "tr_model.h"
|
||||
#include "ref_import.h"
|
||||
#include "tr_shader.h"
|
||||
|
||||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
UNCOMPRESSING BONES
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
#define MC_BITS_X (16)
|
||||
#define MC_BITS_Y (16)
|
||||
#define MC_BITS_Z (16)
|
||||
#define MC_BITS_VECT (16)
|
||||
|
||||
#define MC_SCALE_X (1.0f/64)
|
||||
#define MC_SCALE_Y (1.0f/64)
|
||||
#define MC_SCALE_Z (1.0f/64)
|
||||
|
||||
#define MC_MASK_X ((1<<(MC_BITS_X))-1)
|
||||
#define MC_MASK_Y ((1<<(MC_BITS_Y))-1)
|
||||
#define MC_MASK_Z ((1<<(MC_BITS_Z))-1)
|
||||
#define MC_MASK_VECT ((1<<(MC_BITS_VECT))-1)
|
||||
|
||||
#define MC_SCALE_VECT (1.0f/(float)((1<<(MC_BITS_VECT-1))-2))
|
||||
|
||||
#define MC_POS_X (0)
|
||||
#define MC_SHIFT_X (0)
|
||||
|
||||
#define MC_POS_Y ((((MC_BITS_X))/8))
|
||||
#define MC_SHIFT_Y ((((MC_BITS_X)%8)))
|
||||
|
||||
#define MC_POS_Z ((((MC_BITS_X+MC_BITS_Y))/8))
|
||||
#define MC_SHIFT_Z ((((MC_BITS_X+MC_BITS_Y)%8)))
|
||||
|
||||
#define MC_POS_V11 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z))/8))
|
||||
#define MC_SHIFT_V11 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z)%8)))
|
||||
|
||||
#define MC_POS_V12 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT))/8))
|
||||
#define MC_SHIFT_V12 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT)%8)))
|
||||
|
||||
#define MC_POS_V13 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*2))/8))
|
||||
#define MC_SHIFT_V13 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*2)%8)))
|
||||
|
||||
#define MC_POS_V21 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*3))/8))
|
||||
#define MC_SHIFT_V21 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*3)%8)))
|
||||
|
||||
#define MC_POS_V22 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*4))/8))
|
||||
#define MC_SHIFT_V22 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*4)%8)))
|
||||
|
||||
#define MC_POS_V23 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*5))/8))
|
||||
#define MC_SHIFT_V23 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*5)%8)))
|
||||
|
||||
#define MC_POS_V31 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*6))/8))
|
||||
#define MC_SHIFT_V31 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*6)%8)))
|
||||
|
||||
#define MC_POS_V32 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*7))/8))
|
||||
#define MC_SHIFT_V32 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*7)%8)))
|
||||
|
||||
#define MC_POS_V33 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*8))/8))
|
||||
#define MC_SHIFT_V33 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*8)%8)))
|
||||
|
||||
void MC_UnCompress(float mat[3][4], const unsigned char* comp)
|
||||
{
|
||||
int val;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[0];
|
||||
val-=1<<(MC_BITS_X-1);
|
||||
mat[0][3]=((float)(val))*MC_SCALE_X;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[1];
|
||||
val-=1<<(MC_BITS_Y-1);
|
||||
mat[1][3]=((float)(val))*MC_SCALE_Y;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[2];
|
||||
val-=1<<(MC_BITS_Z-1);
|
||||
mat[2][3]=((float)(val))*MC_SCALE_Z;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[3];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[0][0]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[4];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[0][1]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[5];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[0][2]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
|
||||
val=(int)((unsigned short *)(comp))[6];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[1][0]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[7];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[1][1]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[8];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[1][2]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
|
||||
val=(int)((unsigned short *)(comp))[9];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[2][0]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[10];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[2][1]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[11];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[2][2]=((float)(val))*MC_SCALE_VECT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char *mod_name )
|
||||
{
|
||||
int i, j, k, l;
|
||||
mdrHeader_t *pinmodel, *mdr;
|
||||
mdrFrame_t *frame;
|
||||
mdrLOD_t *lod, *curlod;
|
||||
mdrSurface_t *surf, *cursurf;
|
||||
mdrTriangle_t *tri, *curtri;
|
||||
mdrVertex_t *v, *curv;
|
||||
mdrWeight_t *weight, *curweight;
|
||||
mdrTag_t *tag, *curtag;
|
||||
int size;
|
||||
shader_t *sh;
|
||||
|
||||
pinmodel = (mdrHeader_t *)buffer;
|
||||
|
||||
pinmodel->version = LittleLong(pinmodel->version);
|
||||
if (pinmodel->version != MDR_VERSION)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has wrong version (%i should be %i)\n", mod_name, pinmodel->version, MDR_VERSION);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
size = LittleLong(pinmodel->ofsEnd);
|
||||
|
||||
if(size > filesize)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: Header of %s is broken. Wrong filesize declared!\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
mod->type = MOD_MDR;
|
||||
|
||||
LL(pinmodel->numFrames);
|
||||
LL(pinmodel->numBones);
|
||||
LL(pinmodel->ofsFrames);
|
||||
|
||||
// This is a model that uses some type of compressed Bones. We don't want to uncompress every bone for each rendered frame
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target mdr.
|
||||
if(pinmodel->ofsFrames < 0)
|
||||
{
|
||||
// mdrFrame_t is larger than mdrCompFrame_t:
|
||||
size += pinmodel->numFrames * sizeof(frame->name);
|
||||
// now add enough space for the uncompressed bones.
|
||||
size += pinmodel->numFrames * pinmodel->numBones * ((sizeof(mdrBone_t) - sizeof(mdrCompBone_t)));
|
||||
}
|
||||
|
||||
// simple bounds check
|
||||
if(pinmodel->numBones < 0 ||
|
||||
sizeof(*mdr) + pinmodel->numFrames * (sizeof(*frame) + (pinmodel->numBones - 1) * sizeof(*frame->bones)) > size)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
mod->dataSize += size;
|
||||
mod->modelData = mdr = ri.Hunk_Alloc( size, h_low );
|
||||
|
||||
// Copy all the values over from the file and fix endian issues in the process, if necessary.
|
||||
|
||||
mdr->ident = LittleLong(pinmodel->ident);
|
||||
mdr->version = pinmodel->version; // Don't need to swap byte order on this one, we already did above.
|
||||
Q_strncpyz(mdr->name, pinmodel->name, sizeof(mdr->name));
|
||||
mdr->numFrames = pinmodel->numFrames;
|
||||
mdr->numBones = pinmodel->numBones;
|
||||
mdr->numLODs = LittleLong(pinmodel->numLODs);
|
||||
mdr->numTags = LittleLong(pinmodel->numTags);
|
||||
// We don't care about the other offset values, we'll generate them ourselves while loading.
|
||||
|
||||
mod->numLods = mdr->numLODs;
|
||||
|
||||
if ( mdr->numFrames < 1 )
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has no frames\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/* The first frame will be put into the first free space after the header */
|
||||
frame = (mdrFrame_t *)(mdr + 1);
|
||||
mdr->ofsFrames = (int)((byte *) frame - (byte *) mdr);
|
||||
|
||||
if (pinmodel->ofsFrames < 0)
|
||||
{
|
||||
mdrCompFrame_t *cframe;
|
||||
|
||||
// compressed model...
|
||||
cframe = (mdrCompFrame_t *)((byte *) pinmodel - pinmodel->ofsFrames);
|
||||
|
||||
for(i = 0; i < mdr->numFrames; i++)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
frame->bounds[0][j] = LittleFloat(cframe->bounds[0][j]);
|
||||
frame->bounds[1][j] = LittleFloat(cframe->bounds[1][j]);
|
||||
frame->localOrigin[j] = LittleFloat(cframe->localOrigin[j]);
|
||||
}
|
||||
|
||||
frame->radius = LittleFloat(cframe->radius);
|
||||
frame->name[0] = '\0'; // No name supplied in the compressed version.
|
||||
|
||||
for(j = 0; j < mdr->numBones; j++)
|
||||
{
|
||||
#if defined( Q3_BIG_ENDIAN )
|
||||
for(k = 0; k < (sizeof(cframe->bones[j].Comp) / 2); k++)
|
||||
{
|
||||
// Do swapping for the uncompressing functions. They seem to use shorts
|
||||
// values only, so I assume this will work. Never tested it on other
|
||||
// platforms, though.
|
||||
|
||||
((unsigned short *)(cframe->bones[j].Comp))[k] =
|
||||
LittleShort( ((unsigned short *)(cframe->bones[j].Comp))[k] );
|
||||
}
|
||||
#endif
|
||||
/* Now do the actual uncompressing */
|
||||
MC_UnCompress(frame->bones[j].matrix, cframe->bones[j].Comp);
|
||||
}
|
||||
|
||||
// Next Frame...
|
||||
// cframe = (mdrCompFrame_t *) &cframe->bones[j];
|
||||
// frame = (mdrFrame_t *) &frame->bones[j];
|
||||
// this suppress GCC strict-aliasing warning
|
||||
{
|
||||
// Next Frame...
|
||||
mdrCompBone_t *p = &(cframe->bones[j]);
|
||||
cframe = (mdrCompFrame_t *) p;
|
||||
}
|
||||
|
||||
{
|
||||
mdrBone_t *p = &frame->bones[j];
|
||||
frame = (mdrFrame_t *) p;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mdrFrame_t *curframe;
|
||||
|
||||
// uncompressed model...
|
||||
//
|
||||
|
||||
curframe = (mdrFrame_t *)((byte *) pinmodel + pinmodel->ofsFrames);
|
||||
|
||||
// swap all the frames
|
||||
for ( i = 0 ; i < mdr->numFrames ; i++)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
frame->bounds[0][j] = LittleFloat(curframe->bounds[0][j]);
|
||||
frame->bounds[1][j] = LittleFloat(curframe->bounds[1][j]);
|
||||
frame->localOrigin[j] = LittleFloat(curframe->localOrigin[j]);
|
||||
}
|
||||
|
||||
frame->radius = LittleFloat(curframe->radius);
|
||||
Q_strncpyz(frame->name, curframe->name, sizeof(frame->name));
|
||||
|
||||
// suppress GCC strict-aliasing warning
|
||||
#if defined( Q3_BIG_ENDIAN )
|
||||
for (j = 0; j < (int) (mdr->numBones * sizeof(mdrBone_t) / 4); j++)
|
||||
{
|
||||
((float *)frame->bones)[j]=FloatSwap(&((float *)curframe->bones)[j]);
|
||||
}
|
||||
#else
|
||||
for (j = 0; j < mdr->numBones; j++)
|
||||
{
|
||||
frame->bones[j] = curframe->bones[j];
|
||||
}
|
||||
#endif
|
||||
|
||||
//curframe = (mdrFrame_t *) &curframe->bones[mdr->numBones];
|
||||
//frame = (mdrFrame_t *) &frame->bones[mdr->numBones];
|
||||
// suppress GCC strict-aliasing warning
|
||||
{
|
||||
mdrBone_t* p = &curframe->bones[mdr->numBones];
|
||||
curframe = (mdrFrame_t *) p;
|
||||
}
|
||||
|
||||
{
|
||||
mdrBone_t* p = &frame->bones[mdr->numBones];
|
||||
frame = (mdrFrame_t *) p;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// frame should now point to the first free address after all frames.
|
||||
lod = (mdrLOD_t *) frame;
|
||||
mdr->ofsLODs = (int) ((byte *) lod - (byte *)mdr);
|
||||
|
||||
curlod = (mdrLOD_t *)((byte *) pinmodel + LittleLong(pinmodel->ofsLODs));
|
||||
|
||||
// swap all the LOD's
|
||||
for ( l = 0 ; l < mdr->numLODs ; l++)
|
||||
{
|
||||
// simple bounds check
|
||||
if((byte *) (lod + 1) > (byte *) mdr + size)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
lod->numSurfaces = LittleLong(curlod->numSurfaces);
|
||||
|
||||
// swap all the surfaces
|
||||
surf = (mdrSurface_t *) (lod + 1);
|
||||
lod->ofsSurfaces = (int)((byte *) surf - (byte *) lod);
|
||||
cursurf = (mdrSurface_t *) ((byte *)curlod + LittleLong(curlod->ofsSurfaces));
|
||||
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++)
|
||||
{
|
||||
// simple bounds check
|
||||
if((byte *) (surf + 1) > (byte *) mdr + size)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// first do some copying stuff
|
||||
|
||||
surf->ident = SF_MDR;
|
||||
Q_strncpyz(surf->name, cursurf->name, sizeof(surf->name));
|
||||
Q_strncpyz(surf->shader, cursurf->shader, sizeof(surf->shader));
|
||||
|
||||
surf->ofsHeader = (byte *) mdr - (byte *) surf;
|
||||
|
||||
surf->numVerts = LittleLong(cursurf->numVerts);
|
||||
surf->numTriangles = LittleLong(cursurf->numTriangles);
|
||||
// numBoneReferences and BoneReferences generally seem to be unused
|
||||
|
||||
// now do the checks that may fail.
|
||||
if ( surf->numVerts >= SHADER_MAX_VERTEXES )
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has more than %i verts on %s (%i).\n",
|
||||
mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numVerts );
|
||||
return qfalse;
|
||||
}
|
||||
if ( surf->numTriangles*3 >= SHADER_MAX_INDEXES )
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has more than %i triangles on %s (%i).\n",
|
||||
mod_name, ( SHADER_MAX_INDEXES / 3 ) - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numTriangles );
|
||||
return qfalse;
|
||||
}
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surf->name );
|
||||
|
||||
// register the shaders
|
||||
sh = R_FindShader(surf->shader, LIGHTMAP_NONE, qtrue);
|
||||
if ( sh->defaultShader ) {
|
||||
surf->shaderIndex = 0;
|
||||
} else {
|
||||
surf->shaderIndex = sh->index;
|
||||
}
|
||||
|
||||
// now copy the vertexes.
|
||||
v = (mdrVertex_t *) (surf + 1);
|
||||
surf->ofsVerts = (int)((byte *) v - (byte *) surf);
|
||||
curv = (mdrVertex_t *) ((byte *)cursurf + LittleLong(cursurf->ofsVerts));
|
||||
|
||||
for(j = 0; j < surf->numVerts; j++)
|
||||
{
|
||||
LL(curv->numWeights);
|
||||
|
||||
// simple bounds check
|
||||
if(curv->numWeights < 0 || (byte *) (v + 1) + (curv->numWeights - 1) * sizeof(*weight) > (byte *) mdr + size)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
v->normal[0] = LittleFloat(curv->normal[0]);
|
||||
v->normal[1] = LittleFloat(curv->normal[1]);
|
||||
v->normal[2] = LittleFloat(curv->normal[2]);
|
||||
|
||||
v->texCoords[0] = LittleFloat(curv->texCoords[0]);
|
||||
v->texCoords[1] = LittleFloat(curv->texCoords[1]);
|
||||
|
||||
v->numWeights = curv->numWeights;
|
||||
weight = &v->weights[0];
|
||||
curweight = &curv->weights[0];
|
||||
|
||||
// Now copy all the weights
|
||||
for(k = 0; k < v->numWeights; k++)
|
||||
{
|
||||
weight->boneIndex = LittleLong(curweight->boneIndex);
|
||||
weight->boneWeight = LittleFloat(curweight->boneWeight);
|
||||
|
||||
weight->offset[0] = LittleFloat(curweight->offset[0]);
|
||||
weight->offset[1] = LittleFloat(curweight->offset[1]);
|
||||
weight->offset[2] = LittleFloat(curweight->offset[2]);
|
||||
|
||||
weight++;
|
||||
curweight++;
|
||||
}
|
||||
|
||||
v = (mdrVertex_t *) weight;
|
||||
curv = (mdrVertex_t *) curweight;
|
||||
}
|
||||
|
||||
// we know the offset to the triangles now:
|
||||
tri = (mdrTriangle_t *) v;
|
||||
surf->ofsTriangles = (int)((byte *) tri - (byte *) surf);
|
||||
curtri = (mdrTriangle_t *)((byte *) cursurf + LittleLong(cursurf->ofsTriangles));
|
||||
|
||||
// simple bounds check
|
||||
if(surf->numTriangles < 0 || (byte *) (tri + surf->numTriangles) > (byte *) mdr + size)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
for(j = 0; j < surf->numTriangles; j++)
|
||||
{
|
||||
tri->indexes[0] = LittleLong(curtri->indexes[0]);
|
||||
tri->indexes[1] = LittleLong(curtri->indexes[1]);
|
||||
tri->indexes[2] = LittleLong(curtri->indexes[2]);
|
||||
|
||||
tri++;
|
||||
curtri++;
|
||||
}
|
||||
|
||||
// tri now points to the end of the surface.
|
||||
surf->ofsEnd = (byte *) tri - (byte *) surf;
|
||||
surf = (mdrSurface_t *) tri;
|
||||
|
||||
// find the next surface.
|
||||
cursurf = (mdrSurface_t *) ((byte *) cursurf + LittleLong(cursurf->ofsEnd));
|
||||
}
|
||||
|
||||
// surf points to the next lod now.
|
||||
lod->ofsEnd = (int)((byte *) surf - (byte *) lod);
|
||||
lod = (mdrLOD_t *) surf;
|
||||
|
||||
// find the next LOD.
|
||||
curlod = (mdrLOD_t *)((byte *) curlod + LittleLong(curlod->ofsEnd));
|
||||
}
|
||||
|
||||
// lod points to the first tag now, so update the offset too.
|
||||
tag = (mdrTag_t *) lod;
|
||||
mdr->ofsTags = (int)((byte *) tag - (byte *) mdr);
|
||||
curtag = (mdrTag_t *) ((byte *)pinmodel + LittleLong(pinmodel->ofsTags));
|
||||
|
||||
// simple bounds check
|
||||
if(mdr->numTags < 0 || (byte *) (tag + mdr->numTags) > (byte *) mdr + size)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < mdr->numTags ; i++)
|
||||
{
|
||||
tag->boneIndex = LittleLong(curtag->boneIndex);
|
||||
Q_strncpyz(tag->name, curtag->name, sizeof(tag->name));
|
||||
|
||||
tag++;
|
||||
curtag++;
|
||||
}
|
||||
|
||||
// And finally we know the real offset to the end.
|
||||
mdr->ofsEnd = (int)((byte *) tag - (byte *) mdr);
|
||||
|
||||
// phew! we're done.
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
qhandle_t R_RegisterMDR(const char *name, model_t *mod)
|
||||
{
|
||||
|
||||
char* buf;
|
||||
|
||||
qboolean loaded = qfalse;
|
||||
int filesize = ri.FS_ReadFile(name, (void**)&buf);
|
||||
if(!buf)
|
||||
{
|
||||
mod->type = MOD_BAD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined( Q3_BIG_ENDIAN )
|
||||
int ident = LittleLong(*(int *)buf);
|
||||
#else
|
||||
int ident = *(int *)buf;
|
||||
#endif
|
||||
|
||||
|
||||
if(ident == MDR_IDENT)
|
||||
loaded = R_LoadMDR(mod, buf, filesize, name);
|
||||
|
||||
ri.FS_FreeFile(buf);
|
||||
|
||||
if(!loaded)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMDR: couldn't load mdr file %s\n", name);
|
||||
mod->type = MOD_BAD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mod->index;
|
||||
}
|
48
code/renderervk/R_ModelBounds.c
Normal file
48
code/renderervk/R_ModelBounds.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include "tr_local.h"
|
||||
#include "tr_model.h"
|
||||
|
||||
|
||||
void RE_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs )
|
||||
{
|
||||
model_t* model = R_GetModelByHandle( handle );
|
||||
|
||||
if(model->type == MOD_BRUSH)
|
||||
{
|
||||
VectorCopy( model->bmodel->bounds[0], mins );
|
||||
VectorCopy( model->bmodel->bounds[1], maxs );
|
||||
return;
|
||||
}
|
||||
else if (model->type == MOD_MESH)
|
||||
{
|
||||
md3Header_t* header = model->md3[0];
|
||||
md3Frame_t* frame = (md3Frame_t *) ((unsigned char *)header + header->ofsFrames);
|
||||
|
||||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
return;
|
||||
}
|
||||
else if (model->type == MOD_MDR)
|
||||
{
|
||||
mdrHeader_t* header = (mdrHeader_t *)model->modelData;
|
||||
mdrFrame_t* frame = (mdrFrame_t *) ((unsigned char *)header + header->ofsFrames);
|
||||
|
||||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
}
|
||||
else if(model->type == MOD_IQM)
|
||||
{
|
||||
iqmData_t* iqmData = model->modelData;
|
||||
|
||||
if(iqmData->bounds)
|
||||
{
|
||||
VectorCopy(iqmData->bounds, mins);
|
||||
VectorCopy(iqmData->bounds + 3, maxs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( mins );
|
||||
VectorClear( maxs );
|
||||
}
|
253
code/renderervk/R_Parser.c
Normal file
253
code/renderervk/R_Parser.c
Normal file
|
@ -0,0 +1,253 @@
|
|||
#include "tr_local.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
PARSING
|
||||
|
||||
split those parsing functions from q_shared.c
|
||||
I want the render part standalone, dont fuck up with game part.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
static char r_parsename[512];
|
||||
static int r_lines;
|
||||
static int r_tokenline;
|
||||
|
||||
void R_BeginParseSession(const char* name)
|
||||
{
|
||||
r_lines = 1;
|
||||
r_tokenline = 0;
|
||||
snprintf(r_parsename, sizeof(r_parsename), "%s", name);
|
||||
}
|
||||
|
||||
int R_GetCurrentParseLine( void )
|
||||
{
|
||||
if ( r_tokenline )
|
||||
{
|
||||
return r_tokenline;
|
||||
}
|
||||
|
||||
return r_lines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int R_Compress( char *data_p )
|
||||
{
|
||||
qboolean newline = qfalse;
|
||||
qboolean whitespace = qfalse;
|
||||
|
||||
char* in = data_p;
|
||||
char* out = data_p;
|
||||
|
||||
if (in)
|
||||
{
|
||||
int c;
|
||||
while ((c = *in) != 0)
|
||||
{
|
||||
// skip double slash comments
|
||||
if ( c == '/' && in[1] == '/' )
|
||||
{
|
||||
while (*in && *in != '\n') {
|
||||
in++;
|
||||
}
|
||||
// skip /* */ comments
|
||||
}
|
||||
else if ( c == '/' && in[1] == '*' ) {
|
||||
while ( *in && ( *in != '*' || in[1] != '/' ) )
|
||||
in++;
|
||||
if ( *in )
|
||||
in += 2;
|
||||
// record when we hit a newline
|
||||
}
|
||||
else if ( c == '\n' || c == '\r' ) {
|
||||
newline = qtrue;
|
||||
in++;
|
||||
// record when we hit whitespace
|
||||
}
|
||||
else if ( (c == ' ') || (c == '\t') )
|
||||
{
|
||||
whitespace = qtrue;
|
||||
in++;
|
||||
// an actual token
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we have a pending newline, emit it (and it counts as whitespace)
|
||||
if (newline)
|
||||
{
|
||||
*out++ = '\n';
|
||||
newline = qfalse;
|
||||
whitespace = qfalse;
|
||||
}
|
||||
if (whitespace)
|
||||
{
|
||||
*out++ = ' ';
|
||||
whitespace = qfalse;
|
||||
}
|
||||
|
||||
// copy quoted strings unmolested
|
||||
if (c == '"') {
|
||||
*out++ = c;
|
||||
in++;
|
||||
while (1) {
|
||||
c = *in;
|
||||
if (c && c != '"') {
|
||||
*out++ = c;
|
||||
in++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == '"') {
|
||||
*out++ = c;
|
||||
in++;
|
||||
}
|
||||
} else {
|
||||
*out = c;
|
||||
out++;
|
||||
in++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*out = 0;
|
||||
}
|
||||
return out - data_p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
Parse a token out of a string
|
||||
Will never return NULL, just empty strings
|
||||
|
||||
If "allowLineBreaks" is qtrue then an empty
|
||||
string will be returned if the next token is a newline.
|
||||
==============
|
||||
*/
|
||||
char* R_ParseExt(char** data_p, qboolean allowLineBreaks)
|
||||
{
|
||||
|
||||
unsigned int len = 0;
|
||||
char *data = *data_p;
|
||||
|
||||
unsigned char c;
|
||||
static char r_token[512] = {0};
|
||||
r_token[0] = 0;
|
||||
r_tokenline = 0;
|
||||
|
||||
// make sure incoming data is valid
|
||||
if( !data )
|
||||
{
|
||||
*data_p = NULL;
|
||||
return r_token;
|
||||
}
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
// skip whitespace
|
||||
//data = SkipWhitespace( data, &hasNewLines );
|
||||
|
||||
while( (c = *data) <= ' ')
|
||||
{
|
||||
if( c == '\n' )
|
||||
{
|
||||
r_lines++;
|
||||
if( allowLineBreaks == qfalse )
|
||||
{
|
||||
*data_p = data;
|
||||
return r_token;
|
||||
}
|
||||
}
|
||||
else if( c == 0 )
|
||||
{
|
||||
*data_p = NULL;
|
||||
return r_token;
|
||||
}
|
||||
|
||||
data++;
|
||||
}
|
||||
|
||||
// skip double slash comments
|
||||
if(data[0] == '/')
|
||||
{
|
||||
if(data[1] == '/')
|
||||
{
|
||||
data += 2;
|
||||
while (*data && (*data != '\n'))
|
||||
{
|
||||
data++;
|
||||
}
|
||||
}
|
||||
else if( data[1] == '*' )
|
||||
{ // skip /* */ comments
|
||||
data += 2;
|
||||
// Assuming /* and */ occurs in pairs.
|
||||
while( (data[0] != '*') || (data[1] != '/') )
|
||||
{
|
||||
if ( data[0] == '\n' )
|
||||
{
|
||||
r_lines++;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
data += 2;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// token starts on this line
|
||||
r_tokenline = r_lines;
|
||||
|
||||
// handle quoted strings
|
||||
if (c == '\"')
|
||||
{
|
||||
data++;
|
||||
while (1)
|
||||
{
|
||||
c = *data++;
|
||||
if (c == '\"' || !c)
|
||||
{
|
||||
r_token[len] = 0;
|
||||
*data_p = data;
|
||||
return r_token;
|
||||
}
|
||||
else if ( c == '\n' )
|
||||
{
|
||||
r_lines++;
|
||||
}
|
||||
|
||||
if (len < MAX_TOKEN_CHARS - 1)
|
||||
{
|
||||
r_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse a regular word
|
||||
do
|
||||
{
|
||||
if (len < MAX_TOKEN_CHARS - 1)
|
||||
{
|
||||
r_token[len++] = c;
|
||||
}
|
||||
|
||||
c = *(++data);
|
||||
} while(c > ' ');
|
||||
|
||||
r_token[len] = 0;
|
||||
|
||||
*data_p = data;
|
||||
return r_token;
|
||||
}
|
10
code/renderervk/R_Parser.h
Normal file
10
code/renderervk/R_Parser.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef R_PARSER_H_
|
||||
#define R_PARSER_H_
|
||||
|
||||
char* R_ParseExt(char** data_p, qboolean allowLineBreaks);
|
||||
int R_Compress( char *data_p );
|
||||
int R_GetCurrentParseLine( void );
|
||||
void R_BeginParseSession(const char* name);
|
||||
|
||||
|
||||
#endif
|
31
code/renderervk/R_PortalPlane.c
Normal file
31
code/renderervk/R_PortalPlane.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "R_PortalPlane.h"
|
||||
|
||||
static struct rplane_s g_portalPlane; // clip anything behind this if mirroring
|
||||
|
||||
inline static float DotProduct( const float v1[3], const float v2[3] )
|
||||
{
|
||||
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
|
||||
}
|
||||
|
||||
|
||||
void R_SetupPortalPlane(const float axis[3][3], const float origin[3])
|
||||
{
|
||||
// VectorSubtract( vec3_origin, pCamera->axis[0], g_portalPlane.normal );
|
||||
// g_portalPlane.dist = DotProduct( pCamera->origin, g_portalPlane.normal );
|
||||
|
||||
g_portalPlane.normal[0] = - axis[0][0];
|
||||
g_portalPlane.normal[1] = - axis[0][1];
|
||||
g_portalPlane.normal[2] = - axis[0][2];
|
||||
g_portalPlane.dist = - origin[0] * axis[0][0]
|
||||
- origin[1] * axis[0][1]
|
||||
- origin[2] * axis[0][2];
|
||||
}
|
||||
|
||||
|
||||
void R_TransformPlane(const float R[3][3], const float T[3], struct rplane_s* pDstPlane)
|
||||
{
|
||||
pDstPlane->normal[0] = DotProduct (R[0], g_portalPlane.normal);
|
||||
pDstPlane->normal[1] = DotProduct (R[1], g_portalPlane.normal);
|
||||
pDstPlane->normal[2] = DotProduct (R[2], g_portalPlane.normal);
|
||||
pDstPlane->dist = DotProduct (T, g_portalPlane.normal) - g_portalPlane.dist;
|
||||
}
|
16
code/renderervk/R_PortalPlane.h
Normal file
16
code/renderervk/R_PortalPlane.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef R_PORTAL_PLANE_H_
|
||||
#define R_PORTAL_PLANE_H_
|
||||
|
||||
|
||||
struct rplane_s {
|
||||
float normal[3];
|
||||
float dist;
|
||||
};
|
||||
|
||||
// extern struct rplane_s g_portalPlane; // clip anything behind this if mirroring
|
||||
|
||||
|
||||
void R_SetupPortalPlane(const float axis[3][3], const float origin[3]);
|
||||
void R_TransformPlane(const float R[3][3], const float T[3], struct rplane_s* pDstPlane);
|
||||
|
||||
#endif
|
42
code/renderervk/R_PrintMat.c
Normal file
42
code/renderervk/R_PrintMat.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "R_PrintMat.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
|
||||
/*
|
||||
* ===============================================================================
|
||||
* Filename: R_PrintMat.h
|
||||
*
|
||||
* Description: print matrix values or buffer in easier way for debug
|
||||
* Author: SuiJingfeng, 18949883232@163.com
|
||||
* ===============================================================================
|
||||
*/
|
||||
|
||||
void printMat1x3f(const char* name, const float src[3])
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "\n float %s[3] = {%f, %f, %f};\n",
|
||||
name, src[0], src[1], src[2]);
|
||||
}
|
||||
|
||||
void printMat1x4f(const char* name, const float src[4])
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "\n float %s[4] = {%f, %f, %f, %f};\n",
|
||||
name, src[0], src[1], src[2], src[3]);
|
||||
}
|
||||
|
||||
void printMat3x3f(const char* name, const float src[3][3])
|
||||
{
|
||||
ri.Printf(PRINT_ALL,
|
||||
"\n float %s[3][3] = {\n%f, %f, %f, \n%f, %f, %f, \n%f, %f, %f };\n", name,
|
||||
src[0][0], src[0][1], src[0][2],
|
||||
src[1][0], src[1][1], src[1][2],
|
||||
src[2][0], src[2][1], src[2][2]);
|
||||
}
|
||||
|
||||
void printMat4x4f(const char* name, const float src[16])
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "\n float %s[16] = {\n %f, %f, %f, %f,\n %f, %f, %f, %f, \n %f, %f, %f, %f, \n %f, %f, %f, %f};\n", name,
|
||||
src[0], src[1], src[2], src[3], src[4], src[5], src[6], src[7],
|
||||
src[8], src[9], src[10], src[11], src[12], src[13], src[14], src[15] );
|
||||
}
|
21
code/renderervk/R_PrintMat.h
Normal file
21
code/renderervk/R_PrintMat.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* ==================================================================================
|
||||
*
|
||||
* Filename: R_PrintMat.h
|
||||
*
|
||||
* Description: print matrix values for debug
|
||||
* Author: Sui Jingfeng (), 18949883232@163.com
|
||||
* ==================================================================================
|
||||
*/
|
||||
|
||||
#ifndef R_PRINT_MAT_H_
|
||||
#define R_PRINT_MAT_H_
|
||||
|
||||
// data print helper
|
||||
void printMat1x3f(const char* name, const float src[3]);
|
||||
void printMat1x4f(const char* name, const float src[4]);
|
||||
void printMat3x3f(const char* name, const float src[3][3]);
|
||||
void printMat4x4f(const char* name, const float src[16]);
|
||||
|
||||
|
||||
#endif
|
43
code/renderervk/R_StretchRaw.c
Normal file
43
code/renderervk/R_StretchRaw.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "ref_import.h"
|
||||
#include "tr_globals.h"
|
||||
|
||||
|
||||
extern void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty);
|
||||
extern void RE_StretchPic ( float x, float y, float w, float h,
|
||||
float s1, float t1, float s2, float t2, qhandle_t hShader );
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
FIXME: not exactly backend
|
||||
Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle.
|
||||
Used for cinematics.
|
||||
=============
|
||||
*/
|
||||
void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const unsigned char *data, int client, qboolean dirty)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure rows and cols are powers of 2
|
||||
for ( i = 0 ; ( 1 << i ) < cols ; i++ )
|
||||
{
|
||||
;
|
||||
}
|
||||
for ( j = 0 ; ( 1 << j ) < rows ; j++ )
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if ( ( 1 << i ) != cols || ( 1 << j ) != rows) {
|
||||
ri.Error (ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows);
|
||||
}
|
||||
|
||||
RE_UploadCinematic(w, h, cols, rows, data, client, dirty);
|
||||
|
||||
tr.cinematicShader->stages[0]->bundle[0].image[0] = tr.scratchImage[client];
|
||||
RE_StretchPic(x, y, w, h, 0.5f / cols, 0.5f / rows, 1.0f - 0.5f / cols, 1.0f - 0.5 / rows, tr.cinematicShader->index);
|
||||
}
|
26
code/renderervk/VKimpl.h
Normal file
26
code/renderervk/VKimpl.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef VKIMPL_H_
|
||||
#define VKIMPL_H_
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
IMPLEMENTATION SPECIFIC FUNCTIONS
|
||||
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
|
||||
#define VK_NO_PROTOTYPES
|
||||
#include "vulkan/vulkan.h"
|
||||
|
||||
void vk_createWindow(void);
|
||||
void vk_destroyWindow(void);
|
||||
|
||||
void vk_getInstanceProcAddrImpl(void);
|
||||
|
||||
void vk_createSurfaceImpl(void);
|
||||
|
||||
void vk_minimizeWindow( void );
|
||||
|
||||
#endif
|
346
code/renderervk/glConfig.c
Normal file
346
code/renderervk/glConfig.c
Normal file
|
@ -0,0 +1,346 @@
|
|||
#include "tr_local.h"
|
||||
#include "ref_import.h"
|
||||
#include "tr_cvar.h"
|
||||
|
||||
#include "../renderercommon/tr_types.h"
|
||||
|
||||
#include "VKimpl.h"
|
||||
#include "vk_instance.h"
|
||||
#include "vk_image.h"
|
||||
// outside of this file shouldn't modify glConfig
|
||||
// I want keep it locally, as it belong to OpenGL, not VulKan
|
||||
// have to use this keep backward Compatibility
|
||||
static glconfig_t glConfig;
|
||||
|
||||
|
||||
static cvar_t* r_customwidth;
|
||||
static cvar_t* r_customheight;
|
||||
static cvar_t* r_customaspect;
|
||||
|
||||
typedef struct vidmode_s
|
||||
{
|
||||
const char *description;
|
||||
int width, height;
|
||||
float pixelAspect; // pixel width / height
|
||||
} vidmode_t;
|
||||
|
||||
|
||||
static const vidmode_t r_vidModes[] =
|
||||
{
|
||||
{ "Mode 0: 320x240", 320, 240, 1 },
|
||||
{ "Mode 1: 400x300", 400, 300, 1 },
|
||||
{ "Mode 2: 512x384", 512, 384, 1 },
|
||||
{ "Mode 3: 640x480 (480p)", 640, 480, 1 },
|
||||
{ "Mode 4: 800x600", 800, 600, 1 },
|
||||
{ "Mode 5: 960x720", 960, 720, 1 },
|
||||
{ "Mode 6: 1024x768", 1024, 768, 1 },
|
||||
{ "Mode 7: 1152x864", 1152, 864, 1 },
|
||||
{ "Mode 8: 1280x1024", 1280, 1024, 1 },
|
||||
{ "Mode 9: 1600x1200", 1600, 1200, 1 },
|
||||
{ "Mode 10: 2048x1536", 2048, 1536, 1 },
|
||||
{ "Mode 11: 856x480", 856, 480, 1 }, // Q3 MODES END HERE AND EXTENDED MODES BEGIN
|
||||
{ "Mode 12: 1280x720 (720p)", 1280, 720, 1 },
|
||||
{ "Mode 13: 1280x768", 1280, 768, 1 },
|
||||
{ "Mode 14: 1280x800", 1280, 800, 1 },
|
||||
{ "Mode 15: 1280x960", 1280, 960, 1 },
|
||||
{ "Mode 16: 1360x768", 1360, 768, 1 },
|
||||
{ "Mode 17: 1366x768", 1366, 768, 1 }, // yes there are some out there on that extra 6
|
||||
{ "Mode 18: 1360x1024", 1360, 1024, 1 },
|
||||
{ "Mode 19: 1400x1050", 1400, 1050, 1 },
|
||||
{ "Mode 20: 1400x900", 1400, 900, 1 },
|
||||
{ "Mode 21: 1600x900", 1600, 900, 1 },
|
||||
{ "Mode 22: 1680x1050", 1680, 1050, 1 },
|
||||
{ "Mode 23: 1920x1080 (1080p)", 1920, 1080, 1 },
|
||||
{ "Mode 24: 1920x1200", 1920, 1200, 1 },
|
||||
{ "Mode 25: 1920x1440", 1920, 1440, 1 },
|
||||
{ "Mode 26: 2560x1080", 2560, 1080, 1 },
|
||||
{ "Mode 27: 2560x1600", 2560, 1600, 1 },
|
||||
{ "Mode 28: 3840x2160 (4K)", 3840, 2160, 1 }
|
||||
};
|
||||
static const int s_numVidModes = 29;
|
||||
|
||||
|
||||
void R_DisplayResolutionList_f( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
ri.Printf( PRINT_ALL, "\n" );
|
||||
for ( i = 0; i < s_numVidModes; i++ )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "%s\n", r_vidModes[i].description );
|
||||
}
|
||||
ri.Printf( PRINT_ALL, "\n" );
|
||||
}
|
||||
|
||||
|
||||
void R_SetWinMode(int mode, unsigned int width, unsigned int height, unsigned int hz)
|
||||
{
|
||||
|
||||
if ( mode < -2 || mode >= s_numVidModes) {
|
||||
mode = 3;
|
||||
}
|
||||
|
||||
if (mode == -2)
|
||||
{
|
||||
// use desktop video resolution
|
||||
glConfig.vidWidth = width;
|
||||
glConfig.vidHeight = height;
|
||||
glConfig.windowAspect = (float)width / (float)height;
|
||||
glConfig.displayFrequency = hz;
|
||||
glConfig.isFullscreen = 1;
|
||||
}
|
||||
else if ( mode == -1 )
|
||||
{
|
||||
glConfig.vidWidth = r_customwidth->integer;
|
||||
glConfig.vidHeight = r_customheight->integer;
|
||||
glConfig.windowAspect = r_customaspect->value;
|
||||
glConfig.displayFrequency = 60;
|
||||
glConfig.isFullscreen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
glConfig.vidWidth = r_vidModes[mode].width;
|
||||
glConfig.vidHeight = r_vidModes[mode].height;
|
||||
glConfig.windowAspect = (float)r_vidModes[mode].width / ( r_vidModes[mode].height * r_vidModes[mode].pixelAspect );
|
||||
glConfig.displayFrequency = 60;
|
||||
glConfig.isFullscreen = 0;
|
||||
|
||||
}
|
||||
|
||||
ri.Printf(PRINT_ALL, " MODE: %d, %d x %d, refresh rate: %dhz\n",
|
||||
mode, glConfig.vidWidth, glConfig.vidHeight, glConfig.displayFrequency);
|
||||
}
|
||||
|
||||
void R_GetWinResolution(int* w, int* h)
|
||||
{
|
||||
*w = glConfig.vidWidth;
|
||||
*h = glConfig.vidHeight;
|
||||
}
|
||||
|
||||
void R_GetWinResolutionF(float* w, float* h)
|
||||
{
|
||||
*w = glConfig.vidWidth;
|
||||
*h = glConfig.vidHeight;
|
||||
}
|
||||
|
||||
void R_InitDisplayResolution( void )
|
||||
{
|
||||
// leilei - -2 is so convenient for modern day PCs
|
||||
r_mode = ri.Cvar_Get( "r_mode", "-2", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_customwidth = ri.Cvar_Get( "r_customwidth", "960", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_customheight = ri.Cvar_Get( "r_customheight", "540", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_customaspect = ri.Cvar_Get( "r_customaspect", "1.78", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
}
|
||||
|
||||
void R_glConfigClear(void)
|
||||
{
|
||||
memset(&glConfig, 0, sizeof(glConfig));
|
||||
}
|
||||
|
||||
|
||||
//IN: a pointer to the glConfig struct
|
||||
void R_GetGlConfig(glconfig_t * const pCfg)
|
||||
{
|
||||
*pCfg = glConfig;
|
||||
}
|
||||
|
||||
|
||||
void R_glConfigInit(void)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "--- R_glConfigInit() ---\n");
|
||||
|
||||
// These values force the UI to disable driver selection
|
||||
glConfig.driverType = GLDRV_ICD;
|
||||
glConfig.hardwareType = GLHW_GENERIC;
|
||||
|
||||
// Only using SDL_SetWindowBrightness to determine if hardware gamma is supported
|
||||
glConfig.deviceSupportsGamma = qtrue;
|
||||
|
||||
glConfig.textureEnvAddAvailable = 0; // not used
|
||||
glConfig.textureCompression = TC_NONE; // not used
|
||||
// init command buffers and SMP
|
||||
glConfig.stereoEnabled = 0;
|
||||
glConfig.smpActive = qfalse; // not used
|
||||
|
||||
// hardcode it
|
||||
glConfig.colorBits = 32;
|
||||
glConfig.depthBits = 24;
|
||||
glConfig.stencilBits = 8;
|
||||
}
|
||||
|
||||
// ==================================================
|
||||
// ==================================================
|
||||
|
||||
static void printDeviceExtensions(void)
|
||||
{
|
||||
uint32_t nDevExts = 0;
|
||||
|
||||
// To query the extensions available to a given physical device
|
||||
VK_CHECK( qvkEnumerateDeviceExtensionProperties( vk.physical_device, NULL, &nDevExts, NULL) );
|
||||
|
||||
assert(nDevExts > 0);
|
||||
|
||||
VkExtensionProperties* pDevExt =
|
||||
(VkExtensionProperties *) malloc(sizeof(VkExtensionProperties) * nDevExts);
|
||||
|
||||
qvkEnumerateDeviceExtensionProperties(
|
||||
vk.physical_device, NULL, &nDevExts, pDevExt);
|
||||
|
||||
|
||||
ri.Printf(PRINT_ALL, "--------- Total %d Device Extension Supported ---------\n", nDevExts);
|
||||
uint32_t i;
|
||||
for (i=0; i<nDevExts; ++i)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, " %s \n", pDevExt[i].extensionName);
|
||||
}
|
||||
ri.Printf(PRINT_ALL, "--------- ----------------------------------- ---------\n");
|
||||
|
||||
free(pDevExt);
|
||||
}
|
||||
|
||||
|
||||
static void printInstanceExtensions(int setting)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
uint32_t nInsExt = 0;
|
||||
// To retrieve a list of supported extensions before creating an instance
|
||||
VK_CHECK( qvkEnumerateInstanceExtensionProperties( NULL, &nInsExt, NULL) );
|
||||
|
||||
assert(nInsExt > 0);
|
||||
|
||||
VkExtensionProperties* pInsExt = (VkExtensionProperties *) malloc(sizeof(VkExtensionProperties) * nInsExt);
|
||||
|
||||
VK_CHECK(qvkEnumerateInstanceExtensionProperties( NULL, &nInsExt, pInsExt));
|
||||
|
||||
ri.Printf(PRINT_ALL, "\n");
|
||||
|
||||
ri.Printf(PRINT_ALL, "----- Total %d Instance Extension Supported -----\n", nInsExt);
|
||||
for (i = 0; i < nInsExt; ++i)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "%s\n", pInsExt[i].extensionName );
|
||||
}
|
||||
ri.Printf(PRINT_ALL, "----- ------------------------------------- -----\n\n");
|
||||
|
||||
// =================================================================
|
||||
|
||||
// we enabled all the instance extenstion, dose this reasonable???
|
||||
// so we copy it to glConfig.ext str,
|
||||
// split it with create instance function so that made it clear and clean
|
||||
if( setting )
|
||||
{
|
||||
uint32_t indicator = 0;
|
||||
|
||||
for (i = 0; i < nInsExt; ++i)
|
||||
{
|
||||
uint32_t len = strlen(pInsExt[i].extensionName);
|
||||
memcpy(glConfig.extensions_string + indicator,
|
||||
pInsExt[i].extensionName, len);
|
||||
indicator += len;
|
||||
glConfig.extensions_string[indicator++] = ' ';
|
||||
}
|
||||
|
||||
free(pInsExt);
|
||||
}
|
||||
// ==================================================================
|
||||
/*
|
||||
uint32_t nDevExts = 0;
|
||||
|
||||
// To query the extensions available to a given physical device
|
||||
VK_CHECK( qvkEnumerateDeviceExtensionProperties( vk.physical_device, NULL, &nDevExts, NULL) );
|
||||
|
||||
assert(nDevExts > 0);
|
||||
|
||||
VkExtensionProperties* pDevExt =
|
||||
(VkExtensionProperties *) malloc(sizeof(VkExtensionProperties) * nDevExts);
|
||||
|
||||
qvkEnumerateDeviceExtensionProperties(
|
||||
vk.physical_device, NULL, &nDevExts, pDevExt);
|
||||
|
||||
|
||||
ri.Printf(PRINT_ALL, "---- Total %d Device Extension Supported ----\n", nDevExts);
|
||||
uint32_t i;
|
||||
for (i=0; i<nDevExts; ++i)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, " %s \n", pDevExt[i].extensionName);
|
||||
}
|
||||
ri.Printf(PRINT_ALL, "---- ----------------------------------- ----\n\n");
|
||||
|
||||
// There much more device extentions, beyound UI driver info can display
|
||||
// and we only use VK_KHR_swapchain for now, so won't copy that,
|
||||
// just print it out.
|
||||
|
||||
for (i = 0; i < nDevExts; ++i)
|
||||
{
|
||||
uint32_t len = strlen(pDevExt[i].extensionName);
|
||||
memcpy(glConfig.extensions_string + indicator, pDevExt[i].extensionName, len);
|
||||
indicator += len;
|
||||
glConfig.extensions_string[indicator++] = ' ';
|
||||
}
|
||||
free(pDevExt);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
void vulkanInfo_f( void )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "\nActive 3D API: Vulkan\n" );
|
||||
|
||||
// To query general properties of physical devices once enumerated
|
||||
VkPhysicalDeviceProperties props;
|
||||
qvkGetPhysicalDeviceProperties(vk.physical_device, &props);
|
||||
|
||||
uint32_t major = VK_VERSION_MAJOR(props.apiVersion);
|
||||
uint32_t minor = VK_VERSION_MINOR(props.apiVersion);
|
||||
uint32_t patch = VK_VERSION_PATCH(props.apiVersion);
|
||||
|
||||
const char* device_type;
|
||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
|
||||
device_type = "INTEGRATED_GPU";
|
||||
else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
device_type = "DISCRETE_GPU";
|
||||
else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)
|
||||
device_type = "VIRTUAL_GPU";
|
||||
else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)
|
||||
device_type = "CPU";
|
||||
else
|
||||
device_type = "Unknown";
|
||||
|
||||
const char* vendor_name = "unknown";
|
||||
if (props.vendorID == 0x1002) {
|
||||
vendor_name = "Advanced Micro Devices, Inc.";
|
||||
} else if (props.vendorID == 0x10DE) {
|
||||
vendor_name = "NVIDIA";
|
||||
} else if (props.vendorID == 0x8086) {
|
||||
vendor_name = "Intel Corporation";
|
||||
}
|
||||
|
||||
ri.Printf(PRINT_ALL, "Vk api version: %d.%d.%d\n", major, minor, patch);
|
||||
ri.Printf(PRINT_ALL, "Vk driver version: %d\n", props.driverVersion);
|
||||
ri.Printf(PRINT_ALL, "Vk vendor id: 0x%X (%s)\n", props.vendorID, vendor_name);
|
||||
ri.Printf(PRINT_ALL, "Vk device id: 0x%X\n", props.deviceID);
|
||||
ri.Printf(PRINT_ALL, "Vk device type: %s\n", device_type);
|
||||
ri.Printf(PRINT_ALL, "Vk device name: %s\n", props.deviceName);
|
||||
|
||||
//
|
||||
char tmpBuf[128] = {0};
|
||||
snprintf(tmpBuf, 128, " Vk api version: %d.%d.%d ", major, minor, patch);
|
||||
strncpy( glConfig.version_string, tmpBuf, sizeof( glConfig.version_string ) );
|
||||
strncpy( glConfig.vendor_string, vendor_name, sizeof( glConfig.vendor_string ) );
|
||||
|
||||
strncpy( glConfig.renderer_string, props.deviceName, sizeof( glConfig.renderer_string ) );
|
||||
if (*glConfig.renderer_string &&
|
||||
glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] == '\n')
|
||||
glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] = 0;
|
||||
|
||||
|
||||
//
|
||||
// Info that for UI display
|
||||
//
|
||||
printInstanceExtensions(1);
|
||||
|
||||
printDeviceExtensions();
|
||||
|
||||
gpuMemUsageInfo_f();
|
||||
}
|
16
code/renderervk/glConfig.h
Normal file
16
code/renderervk/glConfig.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef GL_CONFIGURE_H_
|
||||
#define GL_CONFIGURE_H_
|
||||
|
||||
|
||||
void R_SetWinMode(int mode, unsigned int w, unsigned int h, unsigned int hz);
|
||||
void R_glConfigInit(void);
|
||||
void R_glConfigClear(void);
|
||||
void R_GetWinResolution(int* w, int* h);
|
||||
void R_GetWinResolutionF(float* w, float* h);
|
||||
|
||||
void R_GetGlConfig(glconfig_t * const pOut);
|
||||
void R_DisplayResolutionList_f(void);
|
||||
void R_InitDisplayResolution( void );
|
||||
|
||||
void vulkanInfo_f( void );
|
||||
#endif
|
132
code/renderervk/icon_oa.h
Normal file
132
code/renderervk/icon_oa.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/* GIMP RGBA C-Source image dump (sdl_icon.h) */
|
||||
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[32 * 32 * 4 + 1];
|
||||
} CLIENT_WINDOW_ICON = {
|
||||
32, 32, 4,
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0w\0\0\377w\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0w\0\0\377w\0\0"
|
||||
"\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0w\0\0\377w\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0w\0"
|
||||
"\0\377w\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0w\0\0\377w\0\0\377\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0w\0\0\377w\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210\0\0\377\210\0\0\377"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\210\0\0\377\210\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\210\0\0\377\210\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\231\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210\0\0\377\210\0\0"
|
||||
"\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\231\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\252\0\0"
|
||||
"\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\231\0\0\377\210\0\0\377\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\252\0\0\377\0\0\0\0\273\0\0\377\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\231\0\0\377\231\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\273\0\0\377\314\0\0\377\231\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\231\0\0\377\231\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\231\0\0"
|
||||
"\377\314\0\0\377\0\0\0\0\335\0\0\377\314\0\0\377\231\0\0\377\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\231\0\0\377\231\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\231\0\0\377\314\0\0\377\335"
|
||||
"\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\231\0\0\377\314\0\0\377\335\0\0\377\335"
|
||||
"\0\0\377\273\0\0\377\231\0\0\377\210\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\231\0\0\377\252\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\0\0\377\273\0\0\377\335\0\0\377\335\0\0"
|
||||
"\377\314\0\0\377\231\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\252\0\0\377\314\0\0\377\314\0\0\377\314\0\0\377\314\0\0\377"
|
||||
"\314\0\0\377\314\0\0\377\314\0\0\377\314\0\0\377\0\0\0\0\252\0\0\377\252"
|
||||
"\0\0\377\0\0\0\0\314\0\0\377\314\0\0\377\314\0\0\377\314\0\0\377\314\0\0"
|
||||
"\377\314\0\0\377\314\0\0\377\314\0\0\377\252\0\0\377\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\210\0\0\377\231\0\0\377\273\0\0\377\314\0\0\377\314"
|
||||
"\0\0\377\0\0\0\0\252\0\0\377\252\0\0\377\0\0\0\0\314\0\0\377\314\0\0\377"
|
||||
"\273\0\0\377\231\0\0\377\210\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210\0\0\377"
|
||||
"\273\0\0\377\0\0\0\0\252\0\0\377\252\0\0\377\0\0\0\0\273\0\0\377\210\0\0"
|
||||
"\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0w\0\0\377\273\0\0\377"
|
||||
"\0\0\0\0\231\0\0\377\252\0\0\377\0\0\0\0\273\0\0\377w\0\0\377\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\0\0\377\0\0\0\0\231\0\0"
|
||||
"\377\231\0\0\377\0\0\0\0\252\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\0\0\377\0\0\0\0\210\0\0\377\231\0\0\377"
|
||||
"\0\0\0\0\252\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\231\0\0\377\0\0\0\0\210\0\0\377\210\0\0\377\0\0\0\0\231\0\0"
|
||||
"\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\231"
|
||||
"\0\0\377\0\0\0\0w\0\0\377\210\0\0\377\0\0\0\0\231\0\0\377\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210\0\0\377\0\0\0\0\210"
|
||||
"\0\0\377\210\0\0\377\0\0\0\0\210\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210\0\0\377\0\0\0\0w\0\0\377\210\0\0\377"
|
||||
"\0\0\0\0\210\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0w\0\0\377\0\0\0\0w\0\0\377w\0\0\377\0\0\0\0w\0\0\377\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0w\0\0\377\0\0\0\0"
|
||||
"w\0\0\377w\0\0\377\0\0\0\0w\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0w\0\0\377\0\0\0\0w\0\0\377w\0\0\377\0\0\0\0w\0"
|
||||
"\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0f\0\0\377f\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0f\0\0\377f\0\0\377"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0",
|
||||
};
|
||||
|
20
code/renderervk/image_loader.h
Normal file
20
code/renderervk/image_loader.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef IMAGE_LOADER_H_
|
||||
#define IMAGE_LOADER_H_
|
||||
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
IMAGE LOADERS
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
void R_LoadBMP( const char *name, byte **pic, int *width, int *height );
|
||||
void R_LoadJPG( const char *name, byte **pic, int *width, int *height );
|
||||
void R_LoadPCX( const char *name, byte **pic, int *width, int *height );
|
||||
void R_LoadPNG( const char *name, byte **pic, int *width, int *height );
|
||||
void R_LoadTGA( const char *name, byte **pic, int *width, int *height );
|
||||
|
||||
|
||||
#endif
|
567
code/renderervk/matrix_multiplication.c
Normal file
567
code/renderervk/matrix_multiplication.c
Normal file
|
@ -0,0 +1,567 @@
|
|||
/*
|
||||
* =========================================================================
|
||||
* Filename: matrix_multiplication.c
|
||||
* Description: 4*4 matrix
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
#if defined __x86_64__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ref_import.h"
|
||||
#include "matrix_multiplication.h"
|
||||
|
||||
#define DEG2RAD( a ) ( ( (a) * M_PI ) / 180.0F )
|
||||
|
||||
static const float s_Identity3x3[3][3] = {
|
||||
{ 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 1.0f }
|
||||
};
|
||||
|
||||
static const float s_Identity4x4[16] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
|
||||
void Mat4Copy( const float in[64], float out[16] )
|
||||
{
|
||||
memcpy(out, in, 64);
|
||||
}
|
||||
|
||||
void Mat3x3Copy( float dst[3][3], const float src[3][3] )
|
||||
{
|
||||
memcpy(dst, src, 36);
|
||||
}
|
||||
|
||||
void VectorLerp( float a[3], float b[3], float lerp, float out[3])
|
||||
{
|
||||
out[0] = a[0] + (b[0] - a[0]) * lerp;
|
||||
out[1] = a[1] + (b[1] - a[1]) * lerp;
|
||||
out[2] = a[2] + (b[2] - a[2]) * lerp;
|
||||
}
|
||||
|
||||
void VectorNorm( float v[3] )
|
||||
{
|
||||
float length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||
|
||||
if(length != 0)
|
||||
{
|
||||
/* writing it this way allows gcc to recognize that rsqrt can be used */
|
||||
length = 1.0f / sqrtf (length);
|
||||
v[0] *= length;
|
||||
v[1] *= length;
|
||||
v[2] *= length;
|
||||
}
|
||||
}
|
||||
|
||||
float VectorLen( const float v[3] )
|
||||
{
|
||||
return sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
}
|
||||
|
||||
|
||||
void Mat4Identity( float out[16] )
|
||||
{
|
||||
memcpy(out, s_Identity4x4, 64);
|
||||
}
|
||||
|
||||
void Mat4Translation( float vec[3], float out[16] )
|
||||
{
|
||||
memcpy(out, s_Identity4x4, 64);
|
||||
|
||||
out[12] = vec[0];
|
||||
out[13] = vec[1];
|
||||
out[14] = vec[2];
|
||||
}
|
||||
//
|
||||
// NOTE; out = b * a ???
|
||||
// a, b and c are specified in column-major order
|
||||
//
|
||||
void myGlMultMatrix(const float A[16], const float B[16], float out[16])
|
||||
{
|
||||
int i, j;
|
||||
for ( i = 0 ; i < 4 ; i++ )
|
||||
{
|
||||
for ( j = 0 ; j < 4 ; j++ )
|
||||
{
|
||||
out[ i * 4 + j ] =
|
||||
A [ i * 4 + 0 ] * B [ 0 * 4 + j ]
|
||||
+ A [ i * 4 + 1 ] * B [ 1 * 4 + j ]
|
||||
+ A [ i * 4 + 2 ] * B [ 2 * 4 + j ]
|
||||
+ A [ i * 4 + 3 ] * B [ 3 * 4 + j ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MatrixMultiply4x4(const float A[16], const float B[16], float out[16])
|
||||
{
|
||||
out[0] = A[0]*B[0] + A[1]*B[4] + A[2]*B[8] + A[3]*B[12];
|
||||
out[1] = A[0]*B[1] + A[1]*B[5] + A[2]*B[9] + A[3]*B[13];
|
||||
out[2] = A[0]*B[2] + A[1]*B[6] + A[2]*B[10] + A[3]*B[14];
|
||||
out[3] = A[0]*B[3] + A[1]*B[7] + A[2]*B[11] + A[3]*B[15];
|
||||
|
||||
out[4] = A[4]*B[0] + A[5]*B[4] + A[6]*B[8] + A[7]*B[12];
|
||||
out[5] = A[4]*B[1] + A[5]*B[5] + A[6]*B[9] + A[7]*B[13];
|
||||
out[6] = A[4]*B[2] + A[5]*B[6] + A[6]*B[10] + A[7]*B[14];
|
||||
out[7] = A[4]*B[3] + A[5]*B[7] + A[6]*B[11] + A[7]*B[15];
|
||||
|
||||
out[8] = A[8]*B[0] + A[9]*B[4] + A[10]*B[8] + A[11]*B[12];
|
||||
out[9] = A[8]*B[1] + A[9]*B[5] + A[10]*B[9] + A[11]*B[13];
|
||||
out[10] = A[8]*B[2] + A[9]*B[6] + A[10]*B[10] + A[11]*B[14];
|
||||
out[11] = A[8]*B[3] + A[9]*B[7] + A[10]*B[11] + A[11]*B[15];
|
||||
|
||||
out[12] = A[12]*B[0] + A[13]*B[4] + A[14]*B[8] + A[15]*B[12];
|
||||
out[13] = A[12]*B[1] + A[13]*B[5] + A[14]*B[9] + A[15]*B[13];
|
||||
out[14] = A[12]*B[2] + A[13]*B[6] + A[14]*B[10] + A[15]*B[14];
|
||||
out[15] = A[12]*B[3] + A[13]*B[7] + A[14]*B[11] + A[15]*B[15];
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE; out = B * A in math
|
||||
* a, b and c are specified in column-major order
|
||||
* out must be 16 byte aliagned
|
||||
*/
|
||||
|
||||
void MatrixMultiply4x4_SSE(const float A[16], const float B[16], float out[16])
|
||||
{
|
||||
#if defined __x86_64__
|
||||
__m128 row1 = _mm_load_ps(&B[0]);
|
||||
__m128 row2 = _mm_load_ps(&B[4]);
|
||||
__m128 row3 = _mm_load_ps(&B[8]);
|
||||
__m128 row4 = _mm_load_ps(&B[12]);
|
||||
|
||||
int i;
|
||||
for(i=0; i<4; i++)
|
||||
{
|
||||
__m128 brod1 = _mm_set1_ps(A[4*i ]);
|
||||
__m128 brod2 = _mm_set1_ps(A[4*i + 1]);
|
||||
__m128 brod3 = _mm_set1_ps(A[4*i + 2]);
|
||||
__m128 brod4 = _mm_set1_ps(A[4*i + 3]);
|
||||
|
||||
__m128 row = _mm_add_ps(
|
||||
_mm_add_ps( _mm_mul_ps(brod1, row1), _mm_mul_ps(brod2, row2) ),
|
||||
_mm_add_ps( _mm_mul_ps(brod3, row3), _mm_mul_ps(brod4, row4) )
|
||||
);
|
||||
|
||||
_mm_store_ps(&out[4*i], row);
|
||||
}
|
||||
#else
|
||||
MatrixMultiply4x4( A, B, out);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Mat4Transform( const float in1[16], const float in2[4], float out[4] )
|
||||
{
|
||||
// 16 mult, 12 plus
|
||||
|
||||
float a = in2[0];
|
||||
float b = in2[1];
|
||||
float c = in2[2];
|
||||
float d = in2[3];
|
||||
|
||||
out[0] = in1[0] * a + in1[4] * b + in1[ 8] * c + in1[12] * d;
|
||||
out[1] = in1[1] * a + in1[5] * b + in1[ 9] * c + in1[13] * d;
|
||||
out[2] = in1[2] * a + in1[6] * b + in1[10] * c + in1[14] * d;
|
||||
out[3] = in1[3] * a + in1[7] * b + in1[11] * c + in1[15] * d;
|
||||
}
|
||||
|
||||
|
||||
void Vec3Transform(const float Mat[16], const float v[3], float out[3])
|
||||
{
|
||||
float x = v[0];
|
||||
float y = v[1];
|
||||
float z = v[2];
|
||||
|
||||
out[0] = Mat[0] * x + Mat[4] * y + Mat[ 8] * z + Mat[12];
|
||||
out[1] = Mat[1] * x + Mat[5] * y + Mat[ 9] * z + Mat[13];
|
||||
out[2] = Mat[2] * x + Mat[6] * y + Mat[10] * z + Mat[14];
|
||||
}
|
||||
|
||||
|
||||
// unfortunately, this fun seems not faseter than Mat4Transform
|
||||
// vector1x4 * mat4x4
|
||||
void Mat4x1Transform_SSE( const float A[16], const float x[4], float out[4] )
|
||||
{
|
||||
// 16 mult, 12 plus
|
||||
//out[0] = A[0] * x[0] + A[4] * x[1] + A[ 8] * x[2] + A[12] * x[3];
|
||||
//out[1] = A[1] * x[0] + A[5] * x[1] + A[ 9] * x[2] + A[13] * x[3];
|
||||
//out[2] = A[2] * x[0] + A[6] * x[1] + A[10] * x[2] + A[14] * x[3];
|
||||
//out[3] = A[3] * x[0] + A[7] * x[1] + A[11] * x[2] + A[15] * x[3];
|
||||
|
||||
// 4 mult + 3 plus + 4 broadcast + 8 load (4 _mm_set1_ps + 4 _mm_set1_ps)
|
||||
// + 1 store
|
||||
#if defined __x86_64__
|
||||
__m128 r1 = _mm_mul_ps( _mm_set1_ps(x[0]), _mm_load_ps(A ) );
|
||||
__m128 r2 = _mm_mul_ps( _mm_set1_ps(x[1]), _mm_load_ps(A+4 ) );
|
||||
__m128 r3 = _mm_mul_ps( _mm_set1_ps(x[2]), _mm_load_ps(A+8 ) );
|
||||
__m128 r4 = _mm_mul_ps( _mm_set1_ps(x[3]), _mm_load_ps(A+12) );
|
||||
|
||||
_mm_store_ps(out, _mm_add_ps( _mm_add_ps(r1, r2), _mm_add_ps(r3, r4) ) );
|
||||
#else
|
||||
Mat4Transform(A, x, out);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#define SHUFFLE_PARAM(x, y, z, w) ( x | y<<2 | z<<4 | w<<6 )
|
||||
#define _mm_replicate_x_ps(v) _mm_shuffle_ps(v, v, SHUFFLE_PARAM(0, 0, 0, 0))
|
||||
#define _mm_replicate_y_ps(v) _mm_shuffle_ps(v, v, SHUFFLE_PARAM(1, 1, 1, 1))
|
||||
#define _mm_replicate_z_ps(v) _mm_shuffle_ps(v, v, SHUFFLE_PARAM(2, 2, 2, 2))
|
||||
#define _mm_replicate_w_ps(v) _mm_shuffle_ps(v, v, SHUFFLE_PARAM(3, 3, 3, 3))
|
||||
|
||||
|
||||
void Vec4Transform_SSE( const float A[16], float v[4], float out[4] )
|
||||
{
|
||||
#if defined __x86_64__
|
||||
__m128 x = _mm_load_ps(v);
|
||||
// 16 mult, 12 plus
|
||||
//out[0] = A[0] * x[0] + A[4] * x[1] + A[ 8] * x[2] + A[12] * x[3];
|
||||
//out[1] = A[1] * x[0] + A[5] * x[1] + A[ 9] * x[2] + A[13] * x[3];
|
||||
//out[2] = A[2] * x[0] + A[6] * x[1] + A[10] * x[2] + A[14] * x[3];
|
||||
//out[3] = A[3] * x[0] + A[7] * x[1] + A[11] * x[2] + A[15] * x[3];
|
||||
|
||||
// 4 mult + 3 plus + 4 broadcast + 8 load (4 _mm_set1_ps + 4 _mm_set1_ps)
|
||||
// + 1 store
|
||||
__m128 r1 = _mm_mul_ps( _mm_replicate_x_ps( x ), _mm_load_ps(A) );
|
||||
__m128 r2 = _mm_mul_ps( _mm_replicate_y_ps( x ), _mm_load_ps(A+4) );
|
||||
__m128 r3 = _mm_mul_ps( _mm_replicate_z_ps( x ), _mm_load_ps(A+8) );
|
||||
__m128 r4 = _mm_mul_ps( _mm_replicate_w_ps( x ), _mm_load_ps(A+12) );
|
||||
|
||||
_mm_store_ps(out, _mm_add_ps( _mm_add_ps( r1, r2 ), _mm_add_ps( r3, r4 ) ));
|
||||
#else
|
||||
Mat4Transform(A, v, out);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
void Mat3x3Identity( float pMat[3][3] )
|
||||
{
|
||||
memcpy(pMat, s_Identity3x3, 36);
|
||||
}
|
||||
|
||||
|
||||
void TransformModelToClip( const float src[3], const float* pMatModel, const float* pMatProj, float eye[4], float dst[4])
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < 4 ; i++ )
|
||||
{
|
||||
eye[i] =
|
||||
src[0] * pMatModel[ i + 0 * 4 ] +
|
||||
src[1] * pMatModel[ i + 1 * 4 ] +
|
||||
src[2] * pMatModel[ i + 2 * 4 ] +
|
||||
1 * pMatModel[ i + 3 * 4 ];
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < 4 ; i++ )
|
||||
{
|
||||
dst[i] =
|
||||
eye[0] * pMatProj[ i + 0 * 4 ] +
|
||||
eye[1] * pMatProj[ i + 1 * 4 ] +
|
||||
eye[2] * pMatProj[ i + 2 * 4 ] +
|
||||
eye[3] * pMatProj[ i + 3 * 4 ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void VectorCross( const float v1[3], const float v2[3], float cross[3] )
|
||||
{
|
||||
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||
cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||
cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||
}
|
||||
|
||||
|
||||
// fast vector normalize routine that does not check to make sure
|
||||
// that length != 0, nor does it return length, uses rsqrt approximation
|
||||
void FastNormalize1f(float v[3])
|
||||
{
|
||||
// writing it this way allows gcc to recognize that rsqrt can be used
|
||||
float invLen = 1.0f / sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
|
||||
v[0] = v[0] * invLen;
|
||||
v[1] = v[1] * invLen;
|
||||
v[2] = v[2] * invLen;
|
||||
}
|
||||
|
||||
void FastNormalize2f( const float* v, float* out)
|
||||
{
|
||||
// writing it this way allows gcc to recognize that rsqrt can be used
|
||||
float invLen = 1.0f / sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
|
||||
out[0] = v[0] * invLen;
|
||||
out[1] = v[1] * invLen;
|
||||
out[2] = v[2] * invLen;
|
||||
}
|
||||
|
||||
// use Rodrigue's rotation formula
|
||||
// dir are not assumed to be unit vector
|
||||
void PointRotateAroundVector(float* res, const float* vec, const float* p, const float degrees)
|
||||
{
|
||||
float rad = DEG2RAD( degrees );
|
||||
float cos_th = cos( rad );
|
||||
float sin_th = sin( rad );
|
||||
float k[3];
|
||||
|
||||
// writing it this way allows gcc to recognize that rsqrt can be used
|
||||
float invLen = 1.0f / sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
|
||||
k[0] = vec[0] * invLen;
|
||||
k[1] = vec[1] * invLen;
|
||||
k[2] = vec[2] * invLen;
|
||||
|
||||
float d = (1 - cos_th) * (p[0] * k[0] + p[1] * k[1] + p[2] * k[2]);
|
||||
|
||||
res[0] = sin_th * (k[1]*p[2] - k[2]*p[1]);
|
||||
res[1] = sin_th * (k[2]*p[0] - k[0]*p[2]);
|
||||
res[2] = sin_th * (k[0]*p[1] - k[1]*p[0]);
|
||||
|
||||
res[0] += cos_th * p[0] + d * k[0];
|
||||
res[1] += cos_th * p[1] + d * k[1];
|
||||
res[2] += cos_th * p[2] + d * k[2];
|
||||
}
|
||||
|
||||
// vector k are assumed to be unit
|
||||
void RotateAroundUnitVector(float* res, const float* k, const float* p, const float degrees)
|
||||
{
|
||||
float rad = DEG2RAD( degrees );
|
||||
float cos_th = cos( rad );
|
||||
float sin_th = sin( rad );
|
||||
|
||||
float d = (1 - cos_th) * (p[0] * k[0] + p[1] * k[1] + p[2] * k[2]);
|
||||
|
||||
res[0] = sin_th * (k[1]*p[2] - k[2]*p[1]);
|
||||
res[1] = sin_th * (k[2]*p[0] - k[0]*p[2]);
|
||||
res[2] = sin_th * (k[0]*p[1] - k[1]*p[0]);
|
||||
|
||||
res[0] += cos_th * p[0] + d * k[0];
|
||||
res[1] += cos_th * p[1] + d * k[1];
|
||||
res[2] += cos_th * p[2] + d * k[2];
|
||||
}
|
||||
|
||||
|
||||
// note: vector forward are NOT assumed to be nornalized,
|
||||
// unit: nornalized of forward,
|
||||
// dst: unit vector which perpendicular of forward(src)
|
||||
void VectorPerp( const float src[3], float dst[3] )
|
||||
{
|
||||
float unit[3];
|
||||
|
||||
float sqlen = src[0]*src[0] + src[1]*src[1] + src[2]*src[2];
|
||||
if(0 == sqlen)
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "MakePerpVectors: zero vertor input!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dst[1] = -src[0];
|
||||
dst[2] = src[1];
|
||||
dst[0] = src[2];
|
||||
// this rotate and negate try to make a vector not colinear with the original
|
||||
// actually can not guarantee, for example
|
||||
// forward = (1/sqrt(3), 1/sqrt(3), -1/sqrt(3)),
|
||||
// then right = (-1/sqrt(3), -1/sqrt(3), 1/sqrt(3))
|
||||
|
||||
|
||||
float invLen = 1.0f / sqrtf(sqlen);
|
||||
unit[0] = src[0] * invLen;
|
||||
unit[1] = src[1] * invLen;
|
||||
unit[2] = src[2] * invLen;
|
||||
|
||||
|
||||
float d = DotProduct(unit, dst);
|
||||
dst[0] -= d*unit[0];
|
||||
dst[1] -= d*unit[1];
|
||||
dst[2] -= d*unit[2];
|
||||
|
||||
// normalize the result
|
||||
invLen = 1.0f / sqrtf(dst[0]*dst[0] + dst[1]*dst[1] + dst[2]*dst[2]);
|
||||
|
||||
dst[0] *= invLen;
|
||||
dst[1] *= invLen;
|
||||
dst[2] *= invLen;
|
||||
}
|
||||
|
||||
// Given a normalized forward vector, create two other perpendicular vectors
|
||||
// note: vector forward are NOT assumed to be nornalized,
|
||||
// after this funtion is called , forward are nornalized.
|
||||
// right, up: perpendicular of forward
|
||||
float MakeTwoPerpVectors(const float forward[3], float right[3], float up[3])
|
||||
{
|
||||
|
||||
float sqLen = forward[0]*forward[0]+forward[1]*forward[1]+forward[2]*forward[2];
|
||||
if(sqLen)
|
||||
{
|
||||
float nf[3] = {0, 0, 1};
|
||||
float invLen = 1.0f / sqrtf(sqLen);
|
||||
nf[0] = forward[0] * invLen;
|
||||
nf[1] = forward[1] * invLen;
|
||||
nf[2] = forward[2] * invLen;
|
||||
|
||||
float adjlen = DotProduct(nf, right);
|
||||
|
||||
// this rotate and negate guarantees a vector
|
||||
// not colinear with the original
|
||||
right[0] = forward[2] - adjlen * nf[0];
|
||||
right[1] = -forward[0] - adjlen * nf[1];
|
||||
right[2] = forward[1] - adjlen * nf[2];
|
||||
|
||||
|
||||
invLen = 1.0f/sqrtf(right[0]*right[0]+right[1]*right[1]+right[2]*right[2]);
|
||||
right[0] *= invLen;
|
||||
right[1] *= invLen;
|
||||
right[2] *= invLen;
|
||||
|
||||
// get the up vector with the right hand rules
|
||||
VectorCross(right, nf, up);
|
||||
|
||||
return (sqLen * invLen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void TransformModelToClip_SSE( const float src[3], const float pMatModel[16], const float pMatProj[16], float dst[4] )
|
||||
{
|
||||
#if defined __x86_64__
|
||||
|
||||
float AugSrc[4] = {src[0], src[1], src[2], 1.0f};
|
||||
|
||||
|
||||
__m128 row1 = _mm_load_ps(&pMatProj[0]);
|
||||
__m128 row2 = _mm_load_ps(&pMatProj[4]);
|
||||
__m128 row3 = _mm_load_ps(&pMatProj[8]);
|
||||
__m128 row4 = _mm_load_ps(&pMatProj[12]);
|
||||
|
||||
__m128 res[4];
|
||||
int i;
|
||||
for(i=0; i<4; i++)
|
||||
{
|
||||
__m128 brod1 = _mm_set1_ps(pMatModel[4*i ]);
|
||||
__m128 brod2 = _mm_set1_ps(pMatModel[4*i + 1]);
|
||||
__m128 brod3 = _mm_set1_ps(pMatModel[4*i + 2]);
|
||||
__m128 brod4 = _mm_set1_ps(pMatModel[4*i + 3]);
|
||||
|
||||
__m128 scol = _mm_set1_ps(AugSrc[i]);
|
||||
|
||||
res[i] =_mm_mul_ps( _mm_add_ps(
|
||||
_mm_add_ps( _mm_mul_ps(brod1, row1), _mm_mul_ps(brod2, row2) ),
|
||||
_mm_add_ps( _mm_mul_ps(brod3, row3), _mm_mul_ps(brod4, row4) )
|
||||
), scol);
|
||||
}
|
||||
|
||||
|
||||
_mm_store_ps(dst, _mm_add_ps( _mm_add_ps(res[0], res[1]), _mm_add_ps(res[2], res[3]) ) );
|
||||
#else
|
||||
float eye[4];
|
||||
TransformModelToClip(src, pMatModel, pMatProj, eye, dst );
|
||||
#endif
|
||||
|
||||
|
||||
// print4f("AugSrc", AugSrc);
|
||||
// printMat4x4f("MatModel", pMatModel);
|
||||
// printMat4x4f("MatProj", pMatProj);
|
||||
// MatrixMultiply4x4_SSE(pMatModel, pMatProj, mvp);
|
||||
// Mat4x1Transform_SSE(mvp, AugSrc, dst);
|
||||
// print4f("dst", dst);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
void TransformModelToClip_SSE2( const float x[3], const float pMatModel[16], const float pMatProj[16], float dst[4] )
|
||||
{
|
||||
|
||||
// 7/8 broadcaster, 8 load, 7/8 mult, 6 add
|
||||
|
||||
__m128 row = _mm_add_ps(
|
||||
_mm_add_ps( _mm_mul_ps( _mm_set1_ps(x[0]), _mm_load_ps(pMatModel ) ) ,
|
||||
_mm_mul_ps( _mm_set1_ps(x[1]), _mm_load_ps(pMatModel+4 ) ) )
|
||||
,
|
||||
_mm_add_ps( _mm_mul_ps( _mm_set1_ps(x[2]), _mm_load_ps(pMatModel+8 ) ) ,
|
||||
_mm_load_ps(pMatModel+12) ) );
|
||||
_mm_store_ps(dst, _mm_add_ps(
|
||||
_mm_add_ps( _mm_mul_ps( _mm_set1_ps(row[0]), _mm_load_ps(pMatProj ) ) ,
|
||||
_mm_mul_ps( _mm_set1_ps(row[1]), _mm_load_ps(pMatProj+4 ) ) )
|
||||
,
|
||||
_mm_add_ps( _mm_mul_ps( _mm_set1_ps(row[2]), _mm_load_ps(pMatProj+8 ) ) ,
|
||||
_mm_mul_ps( _mm_set1_ps(row[3]), _mm_load_ps(pMatProj+12) ) ) )
|
||||
);
|
||||
|
||||
|
||||
// _mm_store_ps(dst, row);
|
||||
|
||||
// Mat4x1Transform_SSE(pMatModel, AugSrc, eye);
|
||||
// Mat4x1Transform_SSE(pMatProj, eye, dst);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// ===============================================
|
||||
// not used now
|
||||
// ===============================================
|
||||
|
||||
/*
|
||||
void Mat4SimpleInverse( const float in[16], float out[16])
|
||||
{
|
||||
float v[3];
|
||||
float invSqrLen;
|
||||
|
||||
VectorCopy(in + 0, v);
|
||||
invSqrLen = 1.0f / DotProduct(v, v); VectorScale(v, invSqrLen, v);
|
||||
out[ 0] = v[0]; out[ 4] = v[1]; out[ 8] = v[2]; out[12] = -DotProduct(v, &in[12]);
|
||||
|
||||
VectorCopy(in + 4, v);
|
||||
invSqrLen = 1.0f / DotProduct(v, v); VectorScale(v, invSqrLen, v);
|
||||
out[ 1] = v[0]; out[ 5] = v[1]; out[ 9] = v[2]; out[13] = -DotProduct(v, &in[12]);
|
||||
|
||||
VectorCopy(in + 8, v);
|
||||
invSqrLen = 1.0f / DotProduct(v, v); VectorScale(v, invSqrLen, v);
|
||||
out[ 2] = v[0]; out[ 6] = v[1]; out[10] = v[2]; out[14] = -DotProduct(v, &in[12]);
|
||||
|
||||
out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
void Mat4Dump( const float in[16] )
|
||||
{
|
||||
printf( "%3.5f %3.5f %3.5f %3.5f\n", in[ 0], in[ 4], in[ 8], in[12]);
|
||||
printf( "%3.5f %3.5f %3.5f %3.5f\n", in[ 1], in[ 5], in[ 9], in[13]);
|
||||
printf( "%3.5f %3.5f %3.5f %3.5f\n", in[ 2], in[ 6], in[10], in[14]);
|
||||
printf( "%3.5f %3.5f %3.5f %3.5f\n", in[ 3], in[ 7], in[11], in[15]);
|
||||
}
|
||||
|
||||
void Mat4View(vec3_t axes[3], vec3_t origin, mat4_t out)
|
||||
{
|
||||
out[0] = axes[0][0];
|
||||
out[1] = axes[1][0];
|
||||
out[2] = axes[2][0];
|
||||
out[3] = 0;
|
||||
|
||||
out[4] = axes[0][1];
|
||||
out[5] = axes[1][1];
|
||||
out[6] = axes[2][1];
|
||||
out[7] = 0;
|
||||
|
||||
out[8] = axes[0][2];
|
||||
out[9] = axes[1][2];
|
||||
out[10] = axes[2][2];
|
||||
out[11] = 0;
|
||||
|
||||
out[12] = -DotProduct(origin, axes[0]);
|
||||
out[13] = -DotProduct(origin, axes[1]);
|
||||
out[14] = -DotProduct(origin, axes[2]);
|
||||
out[15] = 1;
|
||||
}
|
||||
*/
|
24
code/renderervk/matrix_multiplication.h
Normal file
24
code/renderervk/matrix_multiplication.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef MATRIX_MULTIPLICATION_H_
|
||||
#define MATRIX_MULTIPLICATION_H_
|
||||
|
||||
|
||||
void Mat4Copy( const float in[64], float out[16] );
|
||||
void Mat3x3Copy( float dst[3][3], const float src[3][3] );
|
||||
void VectorLerp( float a[3], float b[3], float lerp, float out[3]);
|
||||
void VectorNorm( float v[3] );
|
||||
float VectorLen( const float v[3] );
|
||||
|
||||
void TransformModelToClip( const float src[3], const float *modelMatrix, const float *projectionMatrix, float eye[4], float dst[4] );
|
||||
void TransformModelToClip_SSE( const float src[3], const float pMatModel[16], const float pMatProj[16], float dst[4] );
|
||||
void Mat4Identity( float out[4] );
|
||||
void MatrixMultiply4x4_SSE(const float A[16], const float B[16], float out[16]);
|
||||
void Mat4x1Transform_SSE( const float A[16], const float x[4], float out[4] );
|
||||
void Mat4Transform( const float in1[16], const float in2[4], float out[4] );
|
||||
void Mat4Translation( float vec[3], float out[4] );
|
||||
void Mat3x3Identity( float pMat[3][3] );
|
||||
void VectorPerp( const vec3_t src, vec3_t dst );
|
||||
float MakeTwoPerpVectors(const float forward[3], float right[3], float up[3]);
|
||||
|
||||
void Vec3Transform(const float Mat[16], const float v[3], float out[3]);
|
||||
|
||||
#endif
|
158
code/renderervk/ref_import.c
Normal file
158
code/renderervk/ref_import.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
#include "../qcommon/q_shared.h"
|
||||
#include "../renderercommon/tr_public.h"
|
||||
|
||||
extern refexport_t* R_Export(void);
|
||||
|
||||
refimport_t ri;
|
||||
|
||||
|
||||
/*
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
GetRefAPI
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
*/
|
||||
|
||||
#ifdef USE_RENDERER_DLOPEN
|
||||
Q_EXPORT refexport_t* QDECL GetRefAPI( int apiVersion, refimport_t *rimp )
|
||||
{
|
||||
#else
|
||||
refexport_t* GetRefAPI(int apiVersion, refimport_t *rimp)
|
||||
{
|
||||
#endif
|
||||
|
||||
ri = *rimp;
|
||||
|
||||
if( apiVersion != REF_API_VERSION )
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "Mismatched REF_API_VERSION: expected %i, got %i\n", REF_API_VERSION, apiVersion );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return R_Export();
|
||||
}
|
||||
|
||||
//
|
||||
// common function replacements for modular renderer
|
||||
//
|
||||
#ifdef USE_RENDERER_DLOPEN
|
||||
|
||||
void QDECL Com_Printf( const char *msg, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, msg);
|
||||
Q_vsnprintf(text, sizeof(text), msg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
ri.Printf(PRINT_ALL, "%s", text);
|
||||
}
|
||||
|
||||
void QDECL Com_Error( int level, const char *error, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, error);
|
||||
Q_vsnprintf(text, sizeof(text), error, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
ri.Error(level, "%s", text);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// =======================================
|
||||
// =======================================
|
||||
// =======================================
|
||||
|
||||
char* R_SkipPath (char *pathname)
|
||||
{
|
||||
char* last = pathname;
|
||||
while (*pathname)
|
||||
{
|
||||
if (*pathname=='/')
|
||||
last = pathname+1;
|
||||
pathname++;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
/*
|
||||
char* SkipPath(char *pathname)
|
||||
{
|
||||
char* last = pathname;
|
||||
char c;
|
||||
do{
|
||||
c = *pathname;
|
||||
if (c == '/')
|
||||
last = pathname+1;
|
||||
pathname++;
|
||||
}while(c);
|
||||
|
||||
return last;
|
||||
}
|
||||
*/
|
||||
|
||||
void R_StripExtension( const char *in, char *out, int destsize )
|
||||
{
|
||||
const char *dot = strrchr(in, '.'), *slash;
|
||||
|
||||
if (dot && (!(slash = strrchr(in, '/')) || slash < dot))
|
||||
destsize = (destsize < dot-in+1 ? destsize : dot-in+1);
|
||||
|
||||
if ( in == out && destsize > 1 )
|
||||
out[destsize-1] = '\0';
|
||||
else
|
||||
Q_strncpyz(out, in, destsize);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void stripExtension(const char *in, char *out, int destsize)
|
||||
{
|
||||
const char *dot = strrchr(in, '.');
|
||||
const char *slash = strrchr(in, '/');
|
||||
|
||||
|
||||
if ((dot != NULL) && ( (slash == NULL) || (slash < dot) ) )
|
||||
{
|
||||
int len = dot-in+1;
|
||||
if(len <= destsize)
|
||||
destsize = len;
|
||||
else
|
||||
ri.Printf( PRINT_WARNING, "stripExtension: dest size not enough!\n");
|
||||
}
|
||||
|
||||
if(in != out)
|
||||
strncpy(out, in, destsize-1);
|
||||
|
||||
out[destsize-1] = '\0';
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *R_GetExtension( const char *name )
|
||||
{
|
||||
const char *dot = strrchr(name, '.'), *slash;
|
||||
if (dot && (!(slash = strrchr(name, '/')) || slash < dot))
|
||||
return dot + 1;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
char* GetExtension( const char *name )
|
||||
{
|
||||
char* dot = strrchr(name, '.');
|
||||
char* slash = strrchr(name, '/');
|
||||
|
||||
if ((dot != NULL) && ((slash == NULL) || (slash < dot) ))
|
||||
return dot + 1;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
*/
|
13
code/renderervk/ref_import.h
Normal file
13
code/renderervk/ref_import.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef REF_IMPORT_H_
|
||||
#define REF_IMPORT_H_
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../renderercommon/tr_public.h"
|
||||
|
||||
extern refimport_t ri;
|
||||
|
||||
char* R_SkipPath (char *pathname);
|
||||
void R_StripExtension( const char *in, char *out, int destsize );
|
||||
// const char* R_GetExtension( const char *name );
|
||||
|
||||
#endif
|
65
code/renderervk/render_export.c
Normal file
65
code/renderervk/render_export.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
#include "render_export.h"
|
||||
|
||||
refexport_t* R_Export(void)
|
||||
{
|
||||
static refexport_t re;
|
||||
// memset(&re, 0, sizeof(re));
|
||||
|
||||
// the RE_ functions are Renderer Entry points
|
||||
re.Shutdown = RE_Shutdown;
|
||||
re.BeginRegistration = RE_BeginRegistration;
|
||||
re.RegisterModel = RE_RegisterModel;
|
||||
re.RegisterSkin = RE_RegisterSkin;
|
||||
re.RegisterShader = RE_RegisterShader;
|
||||
re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
|
||||
re.LoadWorld = RE_LoadWorldMap;
|
||||
re.SetWorldVisData = RE_SetWorldVisData;
|
||||
re.EndRegistration = RE_EndRegistration;
|
||||
re.ClearScene = RE_ClearScene;
|
||||
re.AddRefEntityToScene = RE_AddRefEntityToScene;
|
||||
re.AddPolyToScene = RE_AddPolyToScene;
|
||||
re.LightForPoint = RE_LightForPoint;
|
||||
re.AddLightToScene = RE_AddLightToScene;
|
||||
re.AddAdditiveLightToScene = RE_AddAdditiveLightToScene;
|
||||
|
||||
re.RenderScene = RE_RenderScene;
|
||||
re.SetColor = RE_SetColor;
|
||||
re.DrawStretchPic = RE_StretchPic;
|
||||
re.DrawStretchRaw = RE_StretchRaw;
|
||||
re.UploadCinematic = RE_UploadCinematic;
|
||||
|
||||
re.BeginFrame = RE_BeginFrame;
|
||||
re.EndFrame = RE_EndFrame;
|
||||
re.MarkFragments = RE_MarkFragments;
|
||||
re.LerpTag = RE_LerpTag;
|
||||
re.ModelBounds = RE_ModelBounds;
|
||||
re.RegisterFont = RE_RegisterFont;
|
||||
re.RemapShader = RE_RemapShader;
|
||||
re.GetEntityToken = RE_GetEntityToken;
|
||||
re.inPVS = RE_inPVS;
|
||||
|
||||
re.TakeVideoFrame = RE_TakeVideoFrame;
|
||||
|
||||
return &re;
|
||||
}
|
57
code/renderervk/render_export.h
Normal file
57
code/renderervk/render_export.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef RENDER_EXPORT_H_
|
||||
#define RENDER_EXPORT_H_
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../renderercommon/tr_types.h"
|
||||
#include "../renderercommon/tr_public.h"
|
||||
|
||||
|
||||
// Total 30 exported function
|
||||
|
||||
void RE_Shutdown( qboolean destroyWindow );
|
||||
void RE_BeginRegistration( glconfig_t *glconfig );
|
||||
|
||||
qhandle_t RE_RegisterModel( const char *name );
|
||||
qhandle_t RE_RegisterSkin( const char *name );
|
||||
qhandle_t RE_RegisterShader( const char *name );
|
||||
qhandle_t RE_RegisterShaderNoMip( const char *name );
|
||||
|
||||
void RE_LoadWorldMap( const char *mapname );
|
||||
void RE_SetWorldVisData( const byte *vis );
|
||||
void RE_EndRegistration( void );
|
||||
void RE_ClearScene( void );
|
||||
void RE_AddRefEntityToScene( const refEntity_t *ent );
|
||||
void RE_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num );
|
||||
|
||||
int RE_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir );
|
||||
void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b );
|
||||
void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b );
|
||||
void RE_RenderScene( const refdef_t *fd );
|
||||
void RE_SetColor( const float *rgba );
|
||||
|
||||
void RE_StretchPic ( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader );
|
||||
void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const unsigned char *data, int client, qboolean dirty);
|
||||
void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty);
|
||||
|
||||
void RE_BeginFrame( stereoFrame_t stereoFrame );
|
||||
void RE_EndFrame( int *frontEndMsec, int *backEndMsec );
|
||||
|
||||
|
||||
// MARKERS, POLYGON PROJECTION ON WORLD POLYGONS
|
||||
int RE_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection,
|
||||
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer );
|
||||
|
||||
int RE_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame,
|
||||
float frac, const char *tagName );
|
||||
|
||||
void RE_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs );
|
||||
void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font);
|
||||
|
||||
void RE_RemapShader(const char *oldShader, const char *newShader, const char *timeOffset);
|
||||
|
||||
qboolean RE_GetEntityToken( char *buffer, int size );
|
||||
|
||||
qboolean RE_inPVS( const vec3_t p1, const vec3_t p2 );
|
||||
void RE_TakeVideoFrame( int width, int height, unsigned char *captureBuffer, unsigned char *encodeBuffer, qboolean motionJpeg );
|
||||
|
||||
#endif
|
1
code/renderervk/shaders/.gitignore
vendored
Normal file
1
code/renderervk/shaders/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
bintoc
|
BIN
code/renderervk/shaders/Compiled/multi_texture.fspv
Normal file
BIN
code/renderervk/shaders/Compiled/multi_texture.fspv
Normal file
Binary file not shown.
BIN
code/renderervk/shaders/Compiled/multi_texture.vspv
Normal file
BIN
code/renderervk/shaders/Compiled/multi_texture.vspv
Normal file
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,208 @@
|
|||
unsigned char multi_texture_clipping_plane_vert_spv[] = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00,
|
||||
0x08, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00,
|
||||
0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73,
|
||||
0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
|
||||
0x43, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x70, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0C, 0x00,
|
||||
0x00, 0x00, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x73, 0x69, 0x74,
|
||||
0x69, 0x6F, 0x6E, 0x00, 0x05, 0x00, 0x06, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65,
|
||||
0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
|
||||
0x06, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F,
|
||||
0x6E, 0x00, 0x06, 0x00, 0x07, 0x00, 0x16, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x43, 0x6C, 0x69,
|
||||
0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x00,
|
||||
0x05, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x63, 0x6C, 0x69, 0x70, 0x5F, 0x73,
|
||||
0x70, 0x61, 0x63, 0x65, 0x5F, 0x78, 0x66, 0x6F, 0x72, 0x6D,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x79, 0x65, 0x5F,
|
||||
0x73, 0x70, 0x61, 0x63, 0x65, 0x5F, 0x78, 0x66, 0x6F, 0x72,
|
||||
0x6D, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x63, 0x6C, 0x69, 0x70, 0x70, 0x69,
|
||||
0x6E, 0x67, 0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65, 0x00, 0x00,
|
||||
0x05, 0x00, 0x03, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||
0x66, 0x72, 0x61, 0x67, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72,
|
||||
0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x3A, 0x00, 0x00, 0x00,
|
||||
0x69, 0x6E, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x66, 0x72, 0x61, 0x67, 0x5F, 0x74, 0x65, 0x78, 0x5F, 0x63,
|
||||
0x6F, 0x6F, 0x72, 0x64, 0x30, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x74, 0x65, 0x78,
|
||||
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x30, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x42, 0x00, 0x00, 0x00, 0x66, 0x72,
|
||||
0x61, 0x67, 0x5F, 0x74, 0x65, 0x78, 0x5F, 0x63, 0x6F, 0x6F,
|
||||
0x72, 0x64, 0x31, 0x00, 0x05, 0x00, 0x06, 0x00, 0x43, 0x00,
|
||||
0x00, 0x00, 0x69, 0x6E, 0x5F, 0x74, 0x65, 0x78, 0x5F, 0x63,
|
||||
0x6F, 0x6F, 0x72, 0x64, 0x31, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00,
|
||||
0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x05, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x05, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x05, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x03, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x42, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00,
|
||||
0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x3F, 0x15, 0x00, 0x04, 0x00, 0x13, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
|
||||
0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x16, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x15, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00,
|
||||
0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x05, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1F, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2B, 0x00,
|
||||
0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x09, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x2D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x36, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x39, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x04, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3A, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3F, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x3D, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00,
|
||||
0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x51, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00,
|
||||
0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||
0x1F, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x91, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00,
|
||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00,
|
||||
0x2A, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2D, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x27, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
|
||||
0x90, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x31, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x00,
|
||||
0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
|
||||
0x33, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x94, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x37, 0x00, 0x00, 0x00,
|
||||
0x35, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x41, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x03, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x04, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x44, 0x00,
|
||||
0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
|
||||
0x42, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xFD, 0x00,
|
||||
0x01, 0x00, 0x38, 0x00, 0x01, 0x00, };
|
||||
int multi_texture_clipping_plane_vert_spv_size = 2056;
|
263
code/renderervk/shaders/Compiled/multi_texture_frag.c
Normal file
263
code/renderervk/shaders/Compiled/multi_texture_frag.c
Normal file
|
@ -0,0 +1,263 @@
|
|||
unsigned char multi_texture_frag_spv[] = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00,
|
||||
0x08, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00,
|
||||
0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0A, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
|
||||
0x33, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x05, 0x00,
|
||||
0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x08, 0x00,
|
||||
0x00, 0x00, 0x63, 0x6C, 0x69, 0x70, 0x5F, 0x70, 0x6C, 0x61,
|
||||
0x6E, 0x65, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x0F, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x63, 0x6C, 0x69,
|
||||
0x70, 0x5F, 0x64, 0x69, 0x73, 0x74, 0x00, 0x00, 0x05, 0x00,
|
||||
0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x63, 0x6F, 0x6C, 0x6F,
|
||||
0x72, 0x5F, 0x61, 0x00, 0x05, 0x00, 0x05, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x63, 0x6F, 0x6C,
|
||||
0x6F, 0x72, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x74, 0x65, 0x78,
|
||||
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x30, 0x00, 0x05, 0x00,
|
||||
0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x63, 0x6F, 0x6C, 0x6F,
|
||||
0x72, 0x5F, 0x62, 0x00, 0x05, 0x00, 0x05, 0x00, 0x29, 0x00,
|
||||
0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x31,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x2B, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x74, 0x65, 0x78,
|
||||
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x31, 0x00, 0x05, 0x00,
|
||||
0x05, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x63, 0x6F, 0x6C, 0x6F,
|
||||
0x72, 0x5F, 0x6F, 0x70, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
|
||||
0x05, 0x00, 0x33, 0x00, 0x00, 0x00, 0x6F, 0x75, 0x74, 0x5F,
|
||||
0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00,
|
||||
0x06, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x61, 0x6C, 0x70, 0x68,
|
||||
0x61, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x5F, 0x66, 0x75, 0x6E,
|
||||
0x63, 0x00, 0x47, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x22, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x29, 0x00,
|
||||
0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x2E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x33, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00,
|
||||
0x00, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x0E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00,
|
||||
0x04, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00,
|
||||
0x09, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00,
|
||||
0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x23, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x1F, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x06, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x00, 0x00,
|
||||
0x2E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x3A, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x32, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4B, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0x00, 0x06, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0xAA, 0x00,
|
||||
0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x34, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x58, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x4A, 0x00,
|
||||
0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3F, 0x2B, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x63, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x34, 0x00,
|
||||
0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
|
||||
0xAA, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x63, 0x00,
|
||||
0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x0A, 0x00,
|
||||
0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x0C, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0xF5, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00,
|
||||
0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x12, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0xF7, 0x00,
|
||||
0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFA, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00,
|
||||
0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x01, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||
0x25, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x26, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x29, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x2C, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x57, 0x00,
|
||||
0x05, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
|
||||
0x2A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
|
||||
0xF7, 0x00, 0x03, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x4F, 0x00, 0x08, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0x36, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x35, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||
0x4F, 0x00, 0x08, 0x00, 0x34, 0x00, 0x00, 0x00, 0x38, 0x00,
|
||||
0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0x39, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00,
|
||||
0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x05, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x28, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
|
||||
0x43, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00,
|
||||
0x45, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x31, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||
0x49, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00,
|
||||
0x49, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x31, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x31, 0x00, 0x00, 0x00,
|
||||
0xF7, 0x00, 0x03, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x4C, 0x00, 0x00, 0x00,
|
||||
0x4D, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
|
||||
0x4F, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x33, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x50, 0x00,
|
||||
0x00, 0x00, 0xB4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x52, 0x00,
|
||||
0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x53, 0x00, 0x00, 0x00, 0xFC, 0x00,
|
||||
0x01, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x54, 0x00, 0x00, 0x00,
|
||||
0xF9, 0x00, 0x02, 0x00, 0x4E, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x56, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
|
||||
0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00,
|
||||
0x04, 0x00, 0x58, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
|
||||
0x62, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x59, 0x00,
|
||||
0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x4F, 0x00, 0x00, 0x00,
|
||||
0x5B, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x5C, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0xBE, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
||||
0x5C, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0xF7, 0x00,
|
||||
0x03, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFA, 0x00, 0x04, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x5F, 0x00,
|
||||
0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x5F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x01, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x60, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||
0x5A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x62, 0x00,
|
||||
0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x66, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x64, 0x00,
|
||||
0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x05, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
|
||||
0x33, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
|
||||
0x67, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
|
||||
0x5D, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x6B, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
|
||||
0x69, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x6B, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x6A, 0x00, 0x00, 0x00,
|
||||
0xFC, 0x00, 0x01, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x6B, 0x00,
|
||||
0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x66, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x66, 0x00, 0x00, 0x00, 0xF9, 0x00,
|
||||
0x02, 0x00, 0x5A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x5A, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x4E, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x4E, 0x00, 0x00, 0x00,
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, };
|
||||
int multi_texture_frag_spv_size = 2608;
|
215
code/renderervk/shaders/Compiled/multi_texture_vert.c
Normal file
215
code/renderervk/shaders/Compiled/multi_texture_vert.c
Normal file
|
@ -0,0 +1,215 @@
|
|||
unsigned char multi_texture_vert_spv[] = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00,
|
||||
0x08, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00,
|
||||
0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x15, 0x00,
|
||||
0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00,
|
||||
0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x01,
|
||||
0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
|
||||
0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x69, 0x6E,
|
||||
0x5F, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x13, 0x00, 0x00, 0x00, 0x67, 0x6C,
|
||||
0x5F, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x13, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
|
||||
0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x05, 0x00,
|
||||
0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x54, 0x72,
|
||||
0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x08, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x63, 0x6C, 0x69, 0x70, 0x5F, 0x73, 0x70, 0x61,
|
||||
0x63, 0x65, 0x5F, 0x78, 0x66, 0x6F, 0x72, 0x6D, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x65, 0x79, 0x65, 0x5F, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x5F, 0x78, 0x66, 0x6F, 0x72, 0x6D, 0x00,
|
||||
0x06, 0x00, 0x07, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x63, 0x6C, 0x69, 0x70, 0x70, 0x69, 0x6E, 0x67,
|
||||
0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65, 0x00, 0x00, 0x05, 0x00,
|
||||
0x03, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x05, 0x00, 0x24, 0x00, 0x00, 0x00, 0x63, 0x6C,
|
||||
0x69, 0x70, 0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65, 0x00, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x66, 0x72,
|
||||
0x61, 0x67, 0x5F, 0x63, 0x6C, 0x69, 0x70, 0x5F, 0x64, 0x69,
|
||||
0x73, 0x74, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x3A, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x63, 0x6F, 0x6C,
|
||||
0x6F, 0x72, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x69, 0x6E, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x74, 0x65, 0x78,
|
||||
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x30, 0x00, 0x05, 0x00,
|
||||
0x06, 0x00, 0x42, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x74,
|
||||
0x65, 0x78, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x30, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x44, 0x00, 0x00, 0x00,
|
||||
0x66, 0x72, 0x61, 0x67, 0x5F, 0x74, 0x65, 0x78, 0x5F, 0x63,
|
||||
0x6F, 0x6F, 0x72, 0x64, 0x31, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x45, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x74, 0x65, 0x78,
|
||||
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x31, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
|
||||
0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
|
||||
0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x03, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x3A, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x42, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x45, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00,
|
||||
0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0A, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x1E, 0x00,
|
||||
0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00,
|
||||
0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x18, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x05, 0x00,
|
||||
0x1A, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x1B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00,
|
||||
0x1C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x22, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x32, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
|
||||
0x25, 0x00, 0x00, 0x00, 0x34, 0x00, 0x06, 0x00, 0x25, 0x00,
|
||||
0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x29, 0x00,
|
||||
0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x2B, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x2C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x22, 0x00,
|
||||
0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x3B, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x3F, 0x00,
|
||||
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x41, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0E, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x12, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x18, 0x00,
|
||||
0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x91, 0x00, 0x05, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1F, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
|
||||
0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x15, 0x00,
|
||||
0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xF7, 0x00,
|
||||
0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFA, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00,
|
||||
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x27, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2C, 0x00,
|
||||
0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2F, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
|
||||
0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x90, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x33, 0x00,
|
||||
0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x36, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x37, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00,
|
||||
0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0x94, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x39, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x39, 0x00,
|
||||
0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x3A, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x3E, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x42, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x43, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3E, 0x00,
|
||||
0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x44, 0x00, 0x00, 0x00, 0x46, 0x00,
|
||||
0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
int multi_texture_vert_spv_size = 2120;
|
BIN
code/renderervk/shaders/Compiled/single_texture.fspv
Normal file
BIN
code/renderervk/shaders/Compiled/single_texture.fspv
Normal file
Binary file not shown.
BIN
code/renderervk/shaders/Compiled/single_texture.vspv
Normal file
BIN
code/renderervk/shaders/Compiled/single_texture.vspv
Normal file
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,193 @@
|
|||
unsigned char single_texture_clipping_plane_vert_spv[] = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00,
|
||||
0x08, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00,
|
||||
0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73,
|
||||
0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x05, 0x00,
|
||||
0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x09, 0x00,
|
||||
0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x73,
|
||||
0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x16, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72,
|
||||
0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x06, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74,
|
||||
0x69, 0x6F, 0x6E, 0x00, 0x06, 0x00, 0x07, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x43,
|
||||
0x6C, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63,
|
||||
0x65, 0x00, 0x05, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72,
|
||||
0x6D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6C, 0x69, 0x70,
|
||||
0x5F, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5F, 0x78, 0x66, 0x6F,
|
||||
0x72, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00,
|
||||
0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x79,
|
||||
0x65, 0x5F, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5F, 0x78, 0x66,
|
||||
0x6F, 0x72, 0x6D, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x6C, 0x69, 0x70,
|
||||
0x70, 0x69, 0x6E, 0x67, 0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65,
|
||||
0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x38, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x63, 0x6F, 0x6C,
|
||||
0x6F, 0x72, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x3A, 0x00,
|
||||
0x00, 0x00, 0x69, 0x6E, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x3E, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x74, 0x65, 0x78,
|
||||
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x00, 0x00, 0x05, 0x00,
|
||||
0x06, 0x00, 0x40, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x74,
|
||||
0x65, 0x78, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x00, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x05, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x05, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x03, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
|
||||
0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
|
||||
0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00,
|
||||
0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x70, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x38, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x3E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00,
|
||||
0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00,
|
||||
0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0B, 0x00,
|
||||
0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x15, 0x00, 0x04, 0x00,
|
||||
0x13, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00,
|
||||
0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x05, 0x00,
|
||||
0x1D, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x1F, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x1B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x25, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x27, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x1C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x36, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x38, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x39, 0x00, 0x00, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00,
|
||||
0x04, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3D, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x3F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00,
|
||||
0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x51, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00,
|
||||
0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||
0x1F, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x91, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00,
|
||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00,
|
||||
0x2A, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2D, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x27, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
|
||||
0x90, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x31, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x00,
|
||||
0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
|
||||
0x33, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x94, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x37, 0x00, 0x00, 0x00,
|
||||
0x35, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x41, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x03, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, };
|
||||
int single_texture_clipping_plane_vert_spv_size = 1908;
|
181
code/renderervk/shaders/Compiled/single_texture_frag.c
Normal file
181
code/renderervk/shaders/Compiled/single_texture_frag.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
unsigned char single_texture_frag_spv[] = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00,
|
||||
0x08, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00,
|
||||
0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x09, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x63, 0x6C,
|
||||
0x69, 0x70, 0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65, 0x00, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x66, 0x72,
|
||||
0x61, 0x67, 0x5F, 0x63, 0x6C, 0x69, 0x70, 0x5F, 0x64, 0x69,
|
||||
0x73, 0x74, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x6F, 0x75, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F,
|
||||
0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x63, 0x6F, 0x6C,
|
||||
0x6F, 0x72, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x24, 0x00,
|
||||
0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x74, 0x65, 0x78,
|
||||
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x00, 0x00, 0x05, 0x00,
|
||||
0x06, 0x00, 0x28, 0x00, 0x00, 0x00, 0x61, 0x6C, 0x70, 0x68,
|
||||
0x61, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x5F, 0x66, 0x75, 0x6E,
|
||||
0x63, 0x00, 0x47, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00,
|
||||
0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x06, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xAB, 0x00,
|
||||
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x16, 0x00, 0x03, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x09, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1F, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2A, 0x00,
|
||||
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||
0x29, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x2D, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x2E, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x2F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x37, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00,
|
||||
0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||
0xAA, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x37, 0x00,
|
||||
0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x2B, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x34, 0x00, 0x06, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00,
|
||||
0x28, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x36, 0x00,
|
||||
0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00,
|
||||
0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x0B, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xB8, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xF9, 0x00,
|
||||
0x02, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0B, 0x00,
|
||||
0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x13, 0x00,
|
||||
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x00,
|
||||
0x01, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x57, 0x00,
|
||||
0x05, 0x00, 0x17, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x85, 0x00,
|
||||
0x05, 0x00, 0x17, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||
0x1C, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x03, 0x00, 0x19, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||
0xF7, 0x00, 0x03, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x2A, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
|
||||
0x2F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x0D, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0xB4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x32, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFC, 0x00,
|
||||
0x01, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0xF9, 0x00, 0x02, 0x00, 0x2C, 0x00, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x36, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00,
|
||||
0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
|
||||
0x42, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x39, 0x00,
|
||||
0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x2E, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0xBE, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xF7, 0x00,
|
||||
0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFA, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, 0x00,
|
||||
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x3F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x01, 0x00, 0xF8, 0x00,
|
||||
0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x42, 0x00,
|
||||
0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x46, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x44, 0x00,
|
||||
0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x00, 0x41, 0x00,
|
||||
0x05, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x4B, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
|
||||
0x49, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x4B, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x4A, 0x00, 0x00, 0x00,
|
||||
0xFC, 0x00, 0x01, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x4B, 0x00,
|
||||
0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00, 0xF9, 0x00,
|
||||
0x02, 0x00, 0x3A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x2C, 0x00,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x2C, 0x00, 0x00, 0x00,
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, };
|
||||
int single_texture_frag_spv_size = 1788;
|
200
code/renderervk/shaders/Compiled/single_texture_vert.c
Normal file
200
code/renderervk/shaders/Compiled/single_texture_vert.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
unsigned char single_texture_vert_spv[] = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00,
|
||||
0x08, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00,
|
||||
0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x15, 0x00,
|
||||
0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x70, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F,
|
||||
0x6E, 0x00, 0x05, 0x00, 0x06, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74,
|
||||
0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
|
||||
0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6C,
|
||||
0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00,
|
||||
0x05, 0x00, 0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x54, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x63, 0x6C, 0x69, 0x70, 0x5F, 0x73,
|
||||
0x70, 0x61, 0x63, 0x65, 0x5F, 0x78, 0x66, 0x6F, 0x72, 0x6D,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x79, 0x65, 0x5F,
|
||||
0x73, 0x70, 0x61, 0x63, 0x65, 0x5F, 0x78, 0x66, 0x6F, 0x72,
|
||||
0x6D, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x63, 0x6C, 0x69, 0x70, 0x70, 0x69,
|
||||
0x6E, 0x67, 0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65, 0x00, 0x00,
|
||||
0x05, 0x00, 0x03, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x63, 0x6C, 0x69, 0x70, 0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65,
|
||||
0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x2A, 0x00, 0x00, 0x00,
|
||||
0x66, 0x72, 0x61, 0x67, 0x5F, 0x63, 0x6C, 0x69, 0x70, 0x5F,
|
||||
0x64, 0x69, 0x73, 0x74, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x63,
|
||||
0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x63, 0x6F, 0x6C,
|
||||
0x6F, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x5F, 0x74,
|
||||
0x65, 0x78, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x00, 0x00,
|
||||
0x05, 0x00, 0x06, 0x00, 0x42, 0x00, 0x00, 0x00, 0x69, 0x6E,
|
||||
0x5F, 0x74, 0x65, 0x78, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64,
|
||||
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x70, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1A, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2A, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00,
|
||||
0x04, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x42, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F,
|
||||
0x1E, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1E, 0x00,
|
||||
0x05, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x1A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1B, 0x00,
|
||||
0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x09, 0x00,
|
||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
|
||||
0x22, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x32, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
|
||||
0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x34, 0x00, 0x06, 0x00,
|
||||
0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xAB, 0x00,
|
||||
0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x29, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x04, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00,
|
||||
0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x22, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3B, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x3E, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
|
||||
0x3F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x41, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3B, 0x00,
|
||||
0x04, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00,
|
||||
0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0E, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x12, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1D, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x17, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x18, 0x00,
|
||||
0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x91, 0x00, 0x05, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1F, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
|
||||
0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x15, 0x00,
|
||||
0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xF7, 0x00,
|
||||
0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFA, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00,
|
||||
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
|
||||
0x27, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2C, 0x00,
|
||||
0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x2B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2F, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
|
||||
0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x90, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x33, 0x00,
|
||||
0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x36, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x37, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00,
|
||||
0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0x94, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x39, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x39, 0x00,
|
||||
0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3D, 0x00,
|
||||
0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x3A, 0x00,
|
||||
0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
|
||||
0x3E, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x42, 0x00,
|
||||
0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x43, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00,
|
||||
0x01, 0x00, };
|
||||
int single_texture_vert_spv_size = 1972;
|
26
code/renderervk/shaders/bintoc.c
Normal file
26
code/renderervk/shaders/bintoc.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if(argc != 3)
|
||||
return 0;
|
||||
|
||||
char* fn = argv[1];
|
||||
FILE* f = fopen(fn, "rb");
|
||||
printf("unsigned char %s[] = {\n", argv[2]);
|
||||
unsigned long n = 0;
|
||||
|
||||
while(!feof(f)) {
|
||||
unsigned char c;
|
||||
if(fread(&c, 1, 1, f) == 0) break;
|
||||
printf("0x%.2X, ", (int)c);
|
||||
++n;
|
||||
if(n % 10 == 0) printf("\n");
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
printf("};\n");
|
||||
|
||||
printf("int %s_size = %ld;\n", argv[2], n);
|
||||
return 0;
|
||||
}
|
25
code/renderervk/shaders/compile.bat
Normal file
25
code/renderervk/shaders/compile.bat
Normal file
|
@ -0,0 +1,25 @@
|
|||
@echo off
|
||||
set "VSCMD_START_DIR=%CD%"
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
|
||||
|
||||
set tools_dir=..\..\..\..\tools
|
||||
set bin2hex=%tools_dir%\bin2hex.exe
|
||||
set bin2hex_cpp=%tools_dir%\bin2hex.cpp
|
||||
|
||||
if not exist %bin2hex% (
|
||||
cl.exe /EHsc /nologo /Fe%tools_dir%\ /Fo%tools_dir%\ %bin2hex_cpp%
|
||||
)
|
||||
|
||||
set PATH=%tools_dir%;%PATH%
|
||||
|
||||
for %%f in (*.vert) do (
|
||||
%VULKAN_SDK%\Bin\glslangValidator.exe -V %%f
|
||||
%bin2hex% vert.spv %%~nf_vert_spv > spirv/%%~nf_vert.cpp
|
||||
del vert.spv
|
||||
)
|
||||
|
||||
for %%f in (*.frag) do (
|
||||
%VULKAN_SDK%\Bin\glslangValidator.exe -V %%f
|
||||
%bin2hex% frag.spv %%~nf_frag_spv > spirv/%%~nf_frag.cpp
|
||||
del frag.spv
|
||||
)
|
20
code/renderervk/shaders/compile.sh
Executable file
20
code/renderervk/shaders/compile.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ ! -x "./bintoc" ]]
|
||||
then
|
||||
gcc bintoc.c -o bintoc
|
||||
fi
|
||||
|
||||
find -type f -name "*.vert" | \
|
||||
while read f; do glslangValidator -V ${f} -o "Compiled/${f%.*}.vspv"; done
|
||||
|
||||
find -type f -name "*.frag" | \
|
||||
while read f; do glslangValidator -V ${f} -o "Compiled/${f%.*}.fspv"; done
|
||||
|
||||
|
||||
|
||||
find -type f -name "*.vspv" | \
|
||||
while read f; do ./bintoc ${f} `basename ${f%.*}`_vert_spv > ${f%.*}_vert.c; done
|
||||
|
||||
find -type f -name "*.fspv" | \
|
||||
while read f; do ./bintoc ${f} `basename ${f%.*}`_frag_spv > ${f%.*}_frag.c; done
|
82
code/renderervk/shaders/compile_hlsl.bat
Normal file
82
code/renderervk/shaders/compile_hlsl.bat
Normal file
|
@ -0,0 +1,82 @@
|
|||
@echo off
|
||||
set "VSCMD_START_DIR=%CD%"
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
|
||||
|
||||
set tools_dir=..\..\..\..\tools
|
||||
set bin2hex=%tools_dir%\bin2hex.exe
|
||||
set bin2hex_cpp=%tools_dir%\bin2hex.cpp
|
||||
|
||||
if not exist %bin2hex% (
|
||||
cl.exe /EHsc /nologo /Fe%tools_dir%\ /Fo%tools_dir%\ %bin2hex_cpp%
|
||||
)
|
||||
|
||||
set PATH=%tools_dir%;%PATH%
|
||||
|
||||
@rem single texture VS
|
||||
fxc.exe /nologo /T vs_4_0 /E single_texture_vs /Fo shader.bin shaders.hlsl
|
||||
%bin2hex% shader.bin single_texture_vs > hlsl_compiled/single_texture_vs.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T vs_4_0 /E single_texture_clipping_plane_vs /Fo shader.bin shaders.hlsl
|
||||
%bin2hex% shader.bin single_texture_clipping_plane_vs > hlsl_compiled/single_texture_clipping_plane_vs.cpp
|
||||
del shader.bin
|
||||
|
||||
@rem multi texture VS
|
||||
fxc.exe /nologo /T vs_4_0 /E multi_texture_vs /Fo shader.bin shaders.hlsl
|
||||
%bin2hex% shader.bin multi_texture_vs > hlsl_compiled/multi_texture_vs.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T vs_4_0 /E multi_texture_clipping_plane_vs /Fo shader.bin shaders.hlsl
|
||||
%bin2hex% shader.bin multi_texture_clipping_plane_vs > hlsl_compiled/multi_texture_clipping_plane_vs.cpp
|
||||
del shader.bin
|
||||
|
||||
@rem signle texture PS
|
||||
fxc.exe /nologo /T ps_4_0 /E single_texture_ps /Fo shader.bin shaders.hlsl
|
||||
%bin2hex% shader.bin single_texture_ps > hlsl_compiled/single_texture_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E single_texture_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_GT0
|
||||
%bin2hex% shader.bin single_texture_gt0_ps > hlsl_compiled/single_texture_gt0_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E single_texture_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_LT80
|
||||
%bin2hex% shader.bin single_texture_lt80_ps > hlsl_compiled/single_texture_lt80_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E single_texture_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_GE80
|
||||
%bin2hex% shader.bin single_texture_ge80_ps > hlsl_compiled/single_texture_ge80_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
@rem multi texture mul PS
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_mul_ps /Fo shader.bin shaders.hlsl
|
||||
%bin2hex% shader.bin multi_texture_mul_ps > hlsl_compiled/multi_texture_mul_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_mul_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_GT0
|
||||
%bin2hex% shader.bin multi_texture_mul_gt0_ps > hlsl_compiled/multi_texture_mul_gt0_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_mul_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_LT80
|
||||
%bin2hex% shader.bin multi_texture_mul_lt80_ps > hlsl_compiled/multi_texture_mul_lt80_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_mul_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_GE80
|
||||
%bin2hex% shader.bin multi_texture_mul_ge80_ps > hlsl_compiled/multi_texture_mul_ge80_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
@rem multi texture add PS
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_add_ps /Fo shader.bin shaders.hlsl
|
||||
%bin2hex% shader.bin multi_texture_add_ps > hlsl_compiled/multi_texture_add_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_add_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_GT0
|
||||
%bin2hex% shader.bin multi_texture_add_gt0_ps > hlsl_compiled/multi_texture_add_gt0_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_add_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_LT80
|
||||
%bin2hex% shader.bin multi_texture_add_lt80_ps > hlsl_compiled/multi_texture_add_lt80_ps.cpp
|
||||
del shader.bin
|
||||
|
||||
fxc.exe /nologo /T ps_4_0 /E multi_texture_add_ps /Fo shader.bin shaders.hlsl /DALPHA_TEST_GE80
|
||||
%bin2hex% shader.bin multi_texture_add_ge80_ps > hlsl_compiled/multi_texture_add_ge80_ps.cpp
|
||||
del shader.bin
|
36
code/renderervk/shaders/multi_texture.frag
Normal file
36
code/renderervk/shaders/multi_texture.frag
Normal file
|
@ -0,0 +1,36 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D texture0;
|
||||
layout(set = 1, binding = 0) uniform sampler2D texture1;
|
||||
|
||||
layout(location = 0) in vec4 frag_color;
|
||||
layout(location = 1) in vec2 frag_tex_coord0;
|
||||
layout(location = 2) in vec2 frag_tex_coord1;
|
||||
layout(location = 3) in float frag_clip_dist;
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
layout (constant_id = 0) const int alpha_test_func = 0;
|
||||
layout (constant_id = 1) const int color_op = 0;
|
||||
layout (constant_id = 2) const int clip_plane = 0;
|
||||
|
||||
void main() {
|
||||
if (clip_plane != 0 && frag_clip_dist < 0.0) discard;
|
||||
|
||||
vec4 color_a = frag_color * texture(texture0, frag_tex_coord0);
|
||||
vec4 color_b = texture(texture1, frag_tex_coord1);
|
||||
|
||||
if (color_op != 0)
|
||||
out_color = vec4(color_a.rgb + color_b.rgb, color_a.a * color_b.a);
|
||||
else {
|
||||
out_color = color_a * color_b;
|
||||
}
|
||||
|
||||
if (alpha_test_func == 1) {
|
||||
if (out_color.a == 0.0f) discard;
|
||||
} else if (alpha_test_func == 2) {
|
||||
if (out_color.a >= 0.5f) discard;
|
||||
} else if (alpha_test_func == 3) {
|
||||
if (out_color.a < 0.5f) discard;
|
||||
}
|
||||
}
|
37
code/renderervk/shaders/multi_texture.vert
Normal file
37
code/renderervk/shaders/multi_texture.vert
Normal file
|
@ -0,0 +1,37 @@
|
|||
#version 450
|
||||
|
||||
// 128 bytes
|
||||
layout(push_constant) uniform Transform {
|
||||
mat4x4 clip_space_xform;
|
||||
// a single-precision floating-point matrix with 3 columns and 4 rows
|
||||
mat3x4 eye_space_xform;
|
||||
vec4 clipping_plane; // in eye space
|
||||
};
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
layout(location = 1) in vec4 in_color;
|
||||
layout(location = 2) in vec2 in_tex_coord0;
|
||||
layout(location = 3) in vec2 in_tex_coord1;
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
layout(location = 1) out vec2 frag_tex_coord0;
|
||||
layout(location = 2) out vec2 frag_tex_coord1;
|
||||
layout(location = 3) out float frag_clip_dist;
|
||||
|
||||
layout (constant_id = 2) const int clip_plane = 0;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec4 p = vec4(in_position, 1.0);
|
||||
gl_Position = clip_space_xform * p;
|
||||
|
||||
if (clip_plane != 0)
|
||||
frag_clip_dist = dot(clipping_plane, vec4( p * eye_space_xform, 1.0));
|
||||
|
||||
frag_color = in_color;
|
||||
frag_tex_coord0 = in_tex_coord0;
|
||||
frag_tex_coord1 = in_tex_coord1;
|
||||
}
|
34
code/renderervk/shaders/multi_texture_clipping_plane.vert
Normal file
34
code/renderervk/shaders/multi_texture_clipping_plane.vert
Normal file
|
@ -0,0 +1,34 @@
|
|||
#version 450
|
||||
|
||||
// 128 bytes
|
||||
layout(push_constant) uniform Transform {
|
||||
mat4x4 clip_space_xform;
|
||||
// a single-precision floating-point matrix with 3 columns and 4 rows
|
||||
mat3x4 eye_space_xform;
|
||||
vec4 clipping_plane; // in eye space
|
||||
};
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
layout(location = 1) in vec4 in_color;
|
||||
layout(location = 2) in vec2 in_tex_coord0;
|
||||
layout(location = 3) in vec2 in_tex_coord1;
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
layout(location = 1) out vec2 frag_tex_coord0;
|
||||
layout(location = 2) out vec2 frag_tex_coord1;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
float gl_ClipDistance[1];
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec4 p = vec4(in_position, 1.0);
|
||||
|
||||
gl_Position = clip_space_xform * p;
|
||||
gl_ClipDistance[0] = dot(clipping_plane, vec4( p * eye_space_xform, 1.0));
|
||||
|
||||
frag_color = in_color;
|
||||
frag_tex_coord0 = in_tex_coord0;
|
||||
frag_tex_coord1 = in_tex_coord1;
|
||||
}
|
131
code/renderervk/shaders/shaders.hlsl
Normal file
131
code/renderervk/shaders/shaders.hlsl
Normal file
|
@ -0,0 +1,131 @@
|
|||
struct Single_Texture_PS_Data {
|
||||
float4 position : SV_POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 uv0 : TEXCOORD;
|
||||
};
|
||||
|
||||
struct Multi_Texture_PS_Data {
|
||||
float4 position : SV_POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 uv0 : TEXCOORD0;
|
||||
float2 uv1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
cbuffer Constants : register(b0) {
|
||||
float4x4 clip_space_xform;
|
||||
float4x3 eye_space_xform;
|
||||
float4 clipping_plane; // in eye space
|
||||
};
|
||||
|
||||
Texture2D texture0 : register(t0);
|
||||
SamplerState sampler0 : register(s0);
|
||||
|
||||
Texture2D texture1 : register(t1);
|
||||
SamplerState sampler1 : register(s1);
|
||||
|
||||
Single_Texture_PS_Data single_texture_vs(
|
||||
float4 position : POSITION,
|
||||
float4 color : COLOR,
|
||||
float2 uv0 : TEXCOORD)
|
||||
{
|
||||
Single_Texture_PS_Data ps_data;
|
||||
ps_data.position = mul(clip_space_xform, position);
|
||||
ps_data.color = color;
|
||||
ps_data.uv0 = uv0;
|
||||
return ps_data;
|
||||
}
|
||||
|
||||
Single_Texture_PS_Data single_texture_clipping_plane_vs(
|
||||
float4 position : POSITION,
|
||||
float4 color : COLOR,
|
||||
float2 uv0 : TEXCOORD,
|
||||
out float clip : SV_ClipDistance)
|
||||
{
|
||||
clip = dot(clipping_plane.xyz, mul(position, eye_space_xform)) + clipping_plane.w;
|
||||
|
||||
Single_Texture_PS_Data ps_data;
|
||||
ps_data.position = mul(clip_space_xform, position);
|
||||
ps_data.color = color;
|
||||
ps_data.uv0 = uv0;
|
||||
return ps_data;
|
||||
}
|
||||
|
||||
Multi_Texture_PS_Data multi_texture_vs(
|
||||
float4 position : POSITION,
|
||||
float4 color : COLOR,
|
||||
float2 uv0 : TEXCOORD0,
|
||||
float2 uv1 : TEXCOORD1)
|
||||
{
|
||||
Multi_Texture_PS_Data ps_data;
|
||||
ps_data.position = mul(clip_space_xform, position);
|
||||
ps_data.color = color;
|
||||
ps_data.uv0 = uv0;
|
||||
ps_data.uv1 = uv1;
|
||||
return ps_data;
|
||||
}
|
||||
|
||||
Multi_Texture_PS_Data multi_texture_clipping_plane_vs(
|
||||
float4 position : POSITION,
|
||||
float4 color : COLOR,
|
||||
float2 uv0 : TEXCOORD0,
|
||||
float2 uv1 : TEXCOORD1,
|
||||
out float clip : SV_ClipDistance)
|
||||
{
|
||||
clip = dot(clipping_plane.xyz, mul(position, eye_space_xform)) + clipping_plane.w;
|
||||
|
||||
Multi_Texture_PS_Data ps_data;
|
||||
ps_data.position = mul(clip_space_xform, position);
|
||||
ps_data.color = color;
|
||||
ps_data.uv0 = uv0;
|
||||
ps_data.uv1 = uv1;
|
||||
return ps_data;
|
||||
}
|
||||
|
||||
float4 single_texture_ps(Single_Texture_PS_Data data) : SV_TARGET {
|
||||
float4 out_color = data.color * texture0.Sample(sampler0, data.uv0);
|
||||
|
||||
#if defined(ALPHA_TEST_GT0)
|
||||
if (out_color.a == 0.0f) discard;
|
||||
#elif defined(ALPHA_TEST_LT80)
|
||||
if (out_color.a >= 0.5f) discard;
|
||||
#elif defined(ALPHA_TEST_GE80)
|
||||
if (out_color.a < 0.5f) discard;
|
||||
#endif
|
||||
|
||||
return out_color;
|
||||
}
|
||||
|
||||
float4 multi_texture_mul_ps(Multi_Texture_PS_Data data) : SV_TARGET {
|
||||
float4 out_color = data.color * texture0.Sample(sampler0, data.uv0) * texture1.Sample(sampler1, data.uv1);
|
||||
|
||||
#if defined(ALPHA_TEST_GT0)
|
||||
if (out_color.a == 0.0f) discard;
|
||||
#elif defined(ALPHA_TEST_LT80)
|
||||
if (out_color.a >= 0.5f) discard;
|
||||
#elif defined(ALPHA_TEST_GE80)
|
||||
if (out_color.a < 0.5f) discard;
|
||||
#endif
|
||||
|
||||
return out_color;
|
||||
}
|
||||
|
||||
float4 multi_texture_add_ps(Multi_Texture_PS_Data data) : SV_TARGET {
|
||||
float4 color_a = data.color * texture0.Sample(sampler0, data.uv0);
|
||||
float4 color_b = texture1.Sample(sampler1, data.uv1);
|
||||
|
||||
float4 out_color = float4(
|
||||
color_a.r + color_b.r,
|
||||
color_a.g + color_b.g,
|
||||
color_a.b + color_b.b,
|
||||
color_a.a * color_b.a);
|
||||
|
||||
#if defined(ALPHA_TEST_GT0)
|
||||
if (out_color.a == 0.0f) discard;
|
||||
#elif defined(ALPHA_TEST_LT80)
|
||||
if (out_color.a >= 0.5f) discard;
|
||||
#elif defined(ALPHA_TEST_GE80)
|
||||
if (out_color.a < 0.5f) discard;
|
||||
#endif
|
||||
|
||||
return out_color;
|
||||
}
|
26
code/renderervk/shaders/single_texture.frag
Normal file
26
code/renderervk/shaders/single_texture.frag
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D texture0;
|
||||
|
||||
layout(location = 0) in vec4 frag_color;
|
||||
layout(location = 1) in vec2 frag_tex_coord;
|
||||
layout(location = 3) in float frag_clip_dist;
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
layout (constant_id = 0) const int alpha_test_func = 0;
|
||||
layout (constant_id = 2) const int clip_plane = 0;
|
||||
|
||||
void main() {
|
||||
if (clip_plane != 0 && frag_clip_dist < 0.0) discard;
|
||||
|
||||
out_color = frag_color * texture(texture0, frag_tex_coord);
|
||||
|
||||
if (alpha_test_func == 1) {
|
||||
if (out_color.a == 0.0f) discard;
|
||||
} else if (alpha_test_func == 2) {
|
||||
if (out_color.a >= 0.5f) discard;
|
||||
} else if (alpha_test_func == 3) {
|
||||
if (out_color.a < 0.5f) discard;
|
||||
}
|
||||
}
|
34
code/renderervk/shaders/single_texture.vert
Normal file
34
code/renderervk/shaders/single_texture.vert
Normal file
|
@ -0,0 +1,34 @@
|
|||
#version 450
|
||||
|
||||
// 128 bytes
|
||||
layout(push_constant) uniform Transform {
|
||||
mat4x4 clip_space_xform;
|
||||
// a single-precision floating-point matrix with 3 columns and 4 rows
|
||||
mat3x4 eye_space_xform;
|
||||
vec4 clipping_plane; // in eye space
|
||||
};
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
layout(location = 1) in vec4 in_color;
|
||||
layout(location = 2) in vec2 in_tex_coord;
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
layout(location = 1) out vec2 frag_tex_coord;
|
||||
layout(location = 3) out float frag_clip_dist;
|
||||
|
||||
layout (constant_id = 2) const int clip_plane = 0;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec4 p = vec4(in_position, 1.0);
|
||||
gl_Position = clip_space_xform * p;
|
||||
|
||||
if (clip_plane != 0)
|
||||
frag_clip_dist = dot(clipping_plane, vec4( p * eye_space_xform, 1.0));
|
||||
|
||||
frag_color = in_color;
|
||||
frag_tex_coord = in_tex_coord;
|
||||
}
|
31
code/renderervk/shaders/single_texture_clipping_plane.vert
Normal file
31
code/renderervk/shaders/single_texture_clipping_plane.vert
Normal file
|
@ -0,0 +1,31 @@
|
|||
#version 450
|
||||
|
||||
// 128 bytes
|
||||
layout(push_constant) uniform Transform {
|
||||
mat4x4 clip_space_xform;
|
||||
// a single-precision floating-point matrix with 3 columns and 4 rows
|
||||
mat3x4 eye_space_xform;
|
||||
vec4 clipping_plane; // in eye space
|
||||
};
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
layout(location = 1) in vec4 in_color;
|
||||
layout(location = 2) in vec2 in_tex_coord;
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
layout(location = 1) out vec2 frag_tex_coord;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
float gl_ClipDistance[1];
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec4 p = vec4(in_position, 1.0);
|
||||
|
||||
gl_Position = clip_space_xform * p;
|
||||
gl_ClipDistance[0] = dot(clipping_plane, vec4( p * eye_space_xform, 1.0));
|
||||
|
||||
frag_color = in_color;
|
||||
frag_tex_coord = in_tex_coord;
|
||||
}
|
7049
code/renderervk/stb_image.h
Normal file
7049
code/renderervk/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
121
code/renderervk/tr_Cull.c
Normal file
121
code/renderervk/tr_Cull.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include "tr_local.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "tr_globals.h"
|
||||
/*
|
||||
=================
|
||||
|
||||
Returns CULL_IN, CULL_CLIP, or CULL_OUT
|
||||
=================
|
||||
*/
|
||||
int R_CullLocalBox (vec3_t bounds[2])
|
||||
{
|
||||
int i, j;
|
||||
vec3_t transformed[8];
|
||||
float dists[8];
|
||||
vec3_t v;
|
||||
cplane_t *frust;
|
||||
int anyBack;
|
||||
int front, back;
|
||||
|
||||
if ( r_nocull->integer ) {
|
||||
return CULL_CLIP;
|
||||
}
|
||||
|
||||
// transform into world space
|
||||
for (i = 0 ; i < 8 ; i++) {
|
||||
v[0] = bounds[i&1][0];
|
||||
v[1] = bounds[(i>>1)&1][1];
|
||||
v[2] = bounds[(i>>2)&1][2];
|
||||
|
||||
VectorCopy( tr.or.origin, transformed[i] );
|
||||
VectorMA( transformed[i], v[0], tr.or.axis[0], transformed[i] );
|
||||
VectorMA( transformed[i], v[1], tr.or.axis[1], transformed[i] );
|
||||
VectorMA( transformed[i], v[2], tr.or.axis[2], transformed[i] );
|
||||
}
|
||||
|
||||
// check against frustum planes
|
||||
anyBack = 0;
|
||||
for (i = 0 ; i < 4 ; i++) {
|
||||
frust = &tr.viewParms.frustum[i];
|
||||
|
||||
front = back = 0;
|
||||
for (j = 0 ; j < 8 ; j++) {
|
||||
dists[j] = DotProduct(transformed[j], frust->normal);
|
||||
if ( dists[j] > frust->dist ) {
|
||||
front = 1;
|
||||
if ( back ) {
|
||||
break; // a point is in front
|
||||
}
|
||||
} else {
|
||||
back = 1;
|
||||
}
|
||||
}
|
||||
if ( !front ) {
|
||||
// all points were behind one of the planes
|
||||
return CULL_OUT;
|
||||
}
|
||||
anyBack |= back;
|
||||
}
|
||||
|
||||
if ( !anyBack ) {
|
||||
return CULL_IN; // completely inside frustum
|
||||
}
|
||||
|
||||
return CULL_CLIP; // partially clipped
|
||||
}
|
||||
|
||||
|
||||
static void R_LocalPointToWorld (vec3_t local, const orientationr_t * const pRT, vec3_t world)
|
||||
{
|
||||
world[0] = local[0] * pRT->axis[0][0] + local[1] * pRT->axis[1][0] + local[2] * pRT->axis[2][0] + pRT->origin[0];
|
||||
world[1] = local[0] * pRT->axis[0][1] + local[1] * pRT->axis[1][1] + local[2] * pRT->axis[2][1] + pRT->origin[1];
|
||||
world[2] = local[0] * pRT->axis[0][2] + local[1] * pRT->axis[1][2] + local[2] * pRT->axis[2][2] + pRT->origin[2];
|
||||
}
|
||||
|
||||
|
||||
int R_CullLocalPointAndRadius( vec3_t pt, float radius )
|
||||
{
|
||||
vec3_t transformed;
|
||||
|
||||
R_LocalPointToWorld( pt, &tr.or, transformed );
|
||||
|
||||
return R_CullPointAndRadius( transformed, radius );
|
||||
}
|
||||
|
||||
/*
|
||||
** R_CullPointAndRadius
|
||||
*/
|
||||
int R_CullPointAndRadius( vec3_t pt, float radius )
|
||||
{
|
||||
int i;
|
||||
float dist;
|
||||
cplane_t *frust;
|
||||
qboolean mightBeClipped = qfalse;
|
||||
|
||||
if ( r_nocull->integer ) {
|
||||
return CULL_CLIP;
|
||||
}
|
||||
|
||||
// check against frustum planes
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
{
|
||||
frust = &tr.viewParms.frustum[i];
|
||||
|
||||
dist = DotProduct( pt, frust->normal) - frust->dist;
|
||||
if ( dist < -radius )
|
||||
{
|
||||
return CULL_OUT;
|
||||
}
|
||||
else if ( dist <= radius )
|
||||
{
|
||||
mightBeClipped = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mightBeClipped )
|
||||
{
|
||||
return CULL_CLIP;
|
||||
}
|
||||
|
||||
return CULL_IN; // completely inside frustum
|
||||
}
|
286
code/renderervk/tr_animation.c
Normal file
286
code/renderervk/tr_animation.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
#include "ref_import.h"
|
||||
#include "tr_light.h"
|
||||
#include "tr_shader.h"
|
||||
/*
|
||||
|
||||
All bones should be an identity orientation to display the mesh exactly
|
||||
as it is specified.
|
||||
|
||||
For all other frames, the bones represent the transformation from the
|
||||
orientation of the bone in the base frame to the orientation in this
|
||||
frame.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
extern int R_ComputeLOD( trRefEntity_t *ent );
|
||||
|
||||
static int R_MDRCullModel( mdrHeader_t *header, trRefEntity_t *ent )
|
||||
{
|
||||
vec3_t bounds[2];
|
||||
int i;
|
||||
|
||||
int frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
// compute frame pointers
|
||||
mdrFrame_t* newFrame = ( mdrFrame_t * ) ( ( byte * ) header + header->ofsFrames + frameSize * ent->e.frame);
|
||||
mdrFrame_t* oldFrame = ( mdrFrame_t * ) ( ( byte * ) header + header->ofsFrames + frameSize * ent->e.oldframe);
|
||||
|
||||
// cull bounding sphere ONLY if this is not an upscaled entity
|
||||
if ( !ent->e.nonNormalizedAxes )
|
||||
{
|
||||
if ( ent->e.frame == ent->e.oldframe )
|
||||
{
|
||||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
// Ummm... yeah yeah I know we don't really have an md3 here.. but we pretend
|
||||
// we do. After all, the purpose of mdrs are not that different, are they?
|
||||
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
|
||||
case CULL_IN:
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sphereCullB;
|
||||
|
||||
int sphereCull = R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius );
|
||||
if ( newFrame == oldFrame )
|
||||
{
|
||||
sphereCullB = sphereCull;
|
||||
}
|
||||
else
|
||||
{
|
||||
sphereCullB = R_CullLocalPointAndRadius( oldFrame->localOrigin, oldFrame->radius );
|
||||
}
|
||||
|
||||
if ( sphereCull == sphereCullB )
|
||||
{
|
||||
if ( sphereCull == CULL_OUT )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
else if ( sphereCull == CULL_IN )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate a bounding box in the current coordinate system
|
||||
for (i = 0 ; i < 3 ; i++)
|
||||
{
|
||||
bounds[0][i] = oldFrame->bounds[0][i] < newFrame->bounds[0][i] ? oldFrame->bounds[0][i] : newFrame->bounds[0][i];
|
||||
bounds[1][i] = oldFrame->bounds[1][i] > newFrame->bounds[1][i] ? oldFrame->bounds[1][i] : newFrame->bounds[1][i];
|
||||
}
|
||||
|
||||
switch ( R_CullLocalBox( bounds ) )
|
||||
{
|
||||
case CULL_IN:
|
||||
tr.pc.c_box_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_box_cull_md3_clip++;
|
||||
return CULL_CLIP;
|
||||
case CULL_OUT:
|
||||
default:
|
||||
tr.pc.c_box_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
static int R_MDRComputeFogNum( mdrHeader_t *header, trRefEntity_t *ent )
|
||||
{
|
||||
vec3_t localOrigin;
|
||||
|
||||
if ( tr.refdef.rd.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
// FIXME: non-normalized axis issues
|
||||
mdrFrame_t* mdrFrame = ( mdrFrame_t * ) ( ( byte * ) header + header->ofsFrames + frameSize * ent->e.frame);
|
||||
VectorAdd( ent->e.origin, mdrFrame->localOrigin, localOrigin );
|
||||
|
||||
int i, j;
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ )
|
||||
{
|
||||
fog_t* fog = &tr.world->fogs[i];
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
{
|
||||
if ( localOrigin[j] - mdrFrame->radius >= fog->bounds[1][j] )
|
||||
break;
|
||||
|
||||
if ( localOrigin[j] + mdrFrame->radius <= fog->bounds[0][j] )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( j == 3 )
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// much stuff in there is just copied from R_AddMd3Surfaces in tr_mesh.c
|
||||
|
||||
void R_MDRAddAnimSurfaces( trRefEntity_t *ent )
|
||||
{
|
||||
shader_t* shader;
|
||||
int i, j;
|
||||
|
||||
mdrHeader_t* header = (mdrHeader_t *) tr.currentModel->modelData;
|
||||
qboolean personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal;
|
||||
|
||||
if( ent->e.renderfx & RF_WRAP_FRAMES )
|
||||
{
|
||||
ent->e.frame %= header->numFrames;
|
||||
ent->e.oldframe %= header->numFrames;
|
||||
}
|
||||
|
||||
|
||||
// Validate the frames so there is no chance of a crash.
|
||||
// This will write directly into the entity structure,
|
||||
// so when the surfaces are rendered,
|
||||
// they don't need to be range checked again.
|
||||
|
||||
if ((ent->e.frame >= header->numFrames) || (ent->e.frame < 0) ||
|
||||
(ent->e.oldframe >= header->numFrames) || (ent->e.oldframe < 0) )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "R_MDRAddAnimSurfaces: no such frame %d to %d for '%s'\n", ent->e.oldframe, ent->e.frame, tr.currentModel->name );
|
||||
ent->e.frame = 0;
|
||||
ent->e.oldframe = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// cull the entire model if merged bounding box of both frames
|
||||
// is outside the view frustum.
|
||||
//
|
||||
int cull = R_MDRCullModel(header, ent);
|
||||
if ( cull == CULL_OUT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// figure out the current LOD of the model we're rendering, and set the lod pointer respectively.
|
||||
int lodnum = 0;
|
||||
|
||||
if ( tr.currentModel->numLods > 1 )
|
||||
lodnum = R_ComputeLOD( ent );
|
||||
|
||||
// check whether this model has as that many LODs at all. If not, try the closest thing we got.
|
||||
if(header->numLODs <= 0)
|
||||
return;
|
||||
if(header->numLODs <= lodnum)
|
||||
lodnum = header->numLODs - 1;
|
||||
|
||||
mdrLOD_t* lod = (mdrLOD_t *)( (unsigned char *)header + header->ofsLODs);
|
||||
for(i = 0; i < lodnum; i++)
|
||||
{
|
||||
lod = (mdrLOD_t *) ((unsigned char *)lod + lod->ofsEnd);
|
||||
}
|
||||
|
||||
// set up lighting
|
||||
if ( !personalModel || r_shadows->integer > 1 )
|
||||
{
|
||||
R_SetupEntityLighting( &tr.refdef, ent );
|
||||
}
|
||||
|
||||
// fogNum?
|
||||
int fogNum = R_MDRComputeFogNum( header, ent );
|
||||
|
||||
mdrSurface_t* surface = (mdrSurface_t *)( (unsigned char *)lod + lod->ofsSurfaces );
|
||||
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++ )
|
||||
{
|
||||
if(ent->e.customShader)
|
||||
shader = R_GetShaderByHandle(ent->e.customShader);
|
||||
else if((ent->e.customSkin > 0) && (ent->e.customSkin < tr.numSkins))
|
||||
{
|
||||
skin_t* skin = tr.skins[ent->e.customSkin];
|
||||
shader = tr.defaultShader;
|
||||
|
||||
for(j = 0; j < skin->numSurfaces; j++)
|
||||
{
|
||||
if (0 == strcmp(skin->pSurfaces[j].name, surface->name))
|
||||
{
|
||||
shader = skin->pSurfaces[j].shader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(surface->shaderIndex > 0)
|
||||
shader = R_GetShaderByHandle( surface->shaderIndex );
|
||||
else
|
||||
shader = tr.defaultShader;
|
||||
|
||||
// we will add shadows even if the main object isn't visible in the view
|
||||
|
||||
// stencil shadows can't do personal models unless I polyhedron clip
|
||||
if ( (personalModel == 0) && (r_shadows->integer == 2) && (fogNum == 0)
|
||||
&& !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) )
|
||||
&& (shader->sort == SS_OPAQUE) )
|
||||
{
|
||||
R_AddDrawSurf( (void *)surface, tr.shadowShader, 0, qfalse );
|
||||
}
|
||||
|
||||
// projection shadows work fine with personal models
|
||||
if ( (r_shadows->integer == 3) && (fogNum == 0)
|
||||
&& (ent->e.renderfx & RF_SHADOW_PLANE ) && (shader->sort == SS_OPAQUE) )
|
||||
{
|
||||
R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse );
|
||||
}
|
||||
|
||||
if (!personalModel)
|
||||
R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse );
|
||||
|
||||
surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
30
code/renderervk/tr_backend.c
Normal file
30
code/renderervk/tr_backend.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include "ref_import.h"
|
||||
#include "tr_backend.h"
|
||||
#include "R_PrintMat.h"
|
||||
#include "glConfig.h"
|
||||
backEndState_t backEnd;
|
||||
|
||||
|
||||
void R_ClearBackendState(void)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, " backend state cleared. \n");
|
||||
// clear all our internal state
|
||||
memset( &backEnd, 0, sizeof( backEnd ) );
|
||||
|
||||
int width, height;
|
||||
R_GetWinResolution(&width, &height);
|
||||
backEnd.viewParms.viewportWidth = width;
|
||||
backEnd.viewParms.viewportHeight = height;
|
||||
}
|
||||
|
||||
|
||||
void R_PrintBackEnd_OR_f(void)
|
||||
{
|
||||
// in world coordinates
|
||||
printMat1x3f("backEnd.or.origin", backEnd.or.origin);
|
||||
// orientation in world
|
||||
printMat3x3f("backEnd.or.axis", backEnd.or.axis);
|
||||
// viewParms->or.origin in local coordinates
|
||||
printMat1x3f("backEnd.or.viewOrigin", backEnd.or.viewOrigin);
|
||||
printMat4x4f("backEnd.or.modelMatrix", backEnd.or.modelMatrix);
|
||||
}
|
39
code/renderervk/tr_backend.h
Normal file
39
code/renderervk/tr_backend.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef TR_BACKEND_H_
|
||||
#define TR_BACKEND_H_
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
typedef struct {
|
||||
int c_surfaces;
|
||||
int c_shaders;
|
||||
int c_vertexes;
|
||||
int c_indexes;
|
||||
int c_totalIndexes;
|
||||
int c_dlightVertexes;
|
||||
int c_dlightIndexes;
|
||||
int msec; // total msec for backend run
|
||||
} backEndCounters_t;
|
||||
|
||||
|
||||
// all state modified by the back end is seperated
|
||||
// from the front end state
|
||||
typedef struct {
|
||||
trRefdef_t refdef;
|
||||
viewParms_t viewParms;
|
||||
orientationr_t or;
|
||||
backEndCounters_t pc;
|
||||
trRefEntity_t entity2D; // currentEntity will point at this when doing 2D rendering
|
||||
trRefEntity_t* currentEntity;
|
||||
|
||||
unsigned char Color2D[4];
|
||||
qboolean projection2D; // if qtrue, drawstretchpic doesn't need to change modes
|
||||
qboolean isHyperspace;
|
||||
|
||||
} backEndState_t;
|
||||
|
||||
extern backEndState_t backEnd;
|
||||
|
||||
void R_ClearBackendState(void);
|
||||
void R_PrintBackEnd_OR_f(void);
|
||||
|
||||
#endif
|
1890
code/renderervk/tr_bsp.c
Normal file
1890
code/renderervk/tr_bsp.c
Normal file
File diff suppressed because it is too large
Load diff
670
code/renderervk/tr_cmds.c
Normal file
670
code/renderervk/tr_cmds.c
Normal file
|
@ -0,0 +1,670 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
#include "tr_backend.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
#include "vk_instance.h"
|
||||
#include "vk_frame.h"
|
||||
#include "vk_screenshot.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
#include "RB_ShowImages.h"
|
||||
#include "R_PrintMat.h"
|
||||
#include "tr_light.h"
|
||||
|
||||
static renderCommandList_t BE_Commands;
|
||||
|
||||
/*
|
||||
============
|
||||
R_GetCommandBuffer
|
||||
|
||||
make sure there is enough command space, waiting on the
|
||||
render thread if needed.
|
||||
============
|
||||
*/
|
||||
void* R_GetCommandBuffer( int bytes )
|
||||
{
|
||||
renderCommandList_t *cmdList = &BE_Commands;
|
||||
|
||||
// always leave room for the end of list command
|
||||
if ( cmdList->used + bytes + 4 > MAX_RENDER_COMMANDS )
|
||||
{
|
||||
if ( bytes > MAX_RENDER_COMMANDS - 4 ) {
|
||||
ri.Error( ERR_FATAL, "R_GetCommandBuffer: bad size %i", bytes );
|
||||
}
|
||||
// if we run out of room, just start dropping commands
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cmdList->used += bytes;
|
||||
|
||||
return cmdList->cmds + cmdList->used - bytes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
submits a single 'draw' command into the command queue
|
||||
=============
|
||||
*/
|
||||
void R_AddDrawSurfCmd( drawSurf_t *drawSurfs, int numDrawSurfs )
|
||||
{
|
||||
drawSurfsCommand_t* cmd = (drawSurfsCommand_t*) R_GetCommandBuffer( sizeof(drawSurfsCommand_t) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_DRAW_SURFS;
|
||||
|
||||
cmd->drawSurfs = drawSurfs;
|
||||
cmd->numDrawSurfs = numDrawSurfs;
|
||||
|
||||
cmd->refdef = tr.refdef;
|
||||
cmd->viewParms = tr.viewParms;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_SetColor
|
||||
|
||||
Passing NULL will set the color to white
|
||||
=============
|
||||
*/
|
||||
void RE_SetColor( const float *rgba )
|
||||
{
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
setColorCommand_t* cmd = (setColorCommand_t*) R_GetCommandBuffer( sizeof(setColorCommand_t) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_SET_COLOR;
|
||||
|
||||
if(rgba)
|
||||
{
|
||||
cmd->color[0] = rgba[0];
|
||||
cmd->color[1] = rgba[1];
|
||||
cmd->color[2] = rgba[2];
|
||||
cmd->color[3] = rgba[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
// color white
|
||||
cmd->color[0] = 1.0f;
|
||||
cmd->color[1] = 1.0f;
|
||||
cmd->color[2] = 1.0f;
|
||||
cmd->color[3] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RE_StretchPic ( float x, float y, float w, float h,
|
||||
float s1, float t1, float s2, float t2, qhandle_t hShader )
|
||||
{
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
stretchPicCommand_t* cmd = (stretchPicCommand_t*) R_GetCommandBuffer(sizeof(stretchPicCommand_t));
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_STRETCH_PIC;
|
||||
cmd->shader = R_GetShaderByHandle( hShader );
|
||||
cmd->x = x;
|
||||
cmd->y = y;
|
||||
cmd->w = w;
|
||||
cmd->h = h;
|
||||
cmd->s1 = s1;
|
||||
cmd->t1 = t1;
|
||||
cmd->s2 = s2;
|
||||
cmd->t2 = t2;
|
||||
}
|
||||
|
||||
|
||||
void RE_BeginFrame( stereoFrame_t stereoFrame )
|
||||
{
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// use the other buffers next frame, because another CPU
|
||||
// may still be rendering into the current ones
|
||||
// draw buffer stuff
|
||||
drawBufferCommand_t* cmd = (drawBufferCommand_t*) R_GetCommandBuffer(sizeof(drawBufferCommand_t));
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_DRAW_BUFFER;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_EndFrame
|
||||
|
||||
Returns the number of msec spent in the back end
|
||||
=============
|
||||
*/
|
||||
void RE_EndFrame( int *frontEndMsec, int *backEndMsec )
|
||||
{
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
swapBuffersCommand_t* cmd = (swapBuffersCommand_t*) R_GetCommandBuffer(sizeof(swapBuffersCommand_t));
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_SWAP_BUFFERS;
|
||||
|
||||
R_IssueRenderCommands( qtrue );
|
||||
|
||||
R_InitNextFrame();
|
||||
|
||||
if ( frontEndMsec ) {
|
||||
*frontEndMsec = tr.frontEndMsec;
|
||||
}
|
||||
tr.frontEndMsec = 0;
|
||||
if ( backEndMsec ) {
|
||||
*backEndMsec = backEnd.pc.msec;
|
||||
}
|
||||
backEnd.pc.msec = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
RB_RenderDrawSurfList
|
||||
==================
|
||||
*/
|
||||
static void RB_RenderDrawSurfList( drawSurf_t* drawSurfs, int numDrawSurfs )
|
||||
{
|
||||
shader_t *shader, *oldShader;
|
||||
int fogNum, oldFogNum;
|
||||
int dlighted, oldDlighted;
|
||||
// save original time for entity shader offsets
|
||||
float originalTime = backEnd.refdef.floatTime;
|
||||
|
||||
// Any mirrored or portaled views have already been drawn,
|
||||
// so prepare to actually render the visible surfaces for this view
|
||||
// clear the z buffer, set the modelview, etc
|
||||
// RB_BeginDrawingView ();
|
||||
|
||||
// we will need to change the projection matrix before drawing
|
||||
// 2D images again
|
||||
backEnd.projection2D = qfalse;
|
||||
|
||||
|
||||
// ensures that depth writes are enabled for the depth clear
|
||||
|
||||
|
||||
// VULKAN
|
||||
vk_clearDepthStencilAttachments();
|
||||
|
||||
if ( backEnd.refdef.rd.rdflags & RDF_HYPERSPACE )
|
||||
{
|
||||
//RB_Hyperspace();
|
||||
// A player has predicted a teleport, but hasn't arrived yet
|
||||
const float c = ( backEnd.refdef.rd.time & 255 ) / 255.0f;
|
||||
const float color[4] = { c, c, c, 1 };
|
||||
|
||||
// so short, do we really need this?
|
||||
vk_clearColorAttachments(color);
|
||||
|
||||
backEnd.isHyperspace = qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
backEnd.isHyperspace = qfalse;
|
||||
}
|
||||
|
||||
|
||||
// draw everything
|
||||
int entityNum;
|
||||
int oldEntityNum = -1;
|
||||
backEnd.currentEntity = &tr.worldEntity;
|
||||
oldShader = NULL;
|
||||
oldFogNum = -1;
|
||||
oldDlighted = qfalse;
|
||||
int oldSort = -1;
|
||||
|
||||
backEnd.pc.c_surfaces += numDrawSurfs;
|
||||
|
||||
drawSurf_t* drawSurf;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++)
|
||||
{
|
||||
if ( (int)drawSurf->sort == oldSort ) {
|
||||
// fast path, same as previous sort
|
||||
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
|
||||
continue;
|
||||
}
|
||||
oldSort = drawSurf->sort;
|
||||
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted );
|
||||
|
||||
//
|
||||
// change the tess parameters if needed
|
||||
// a "entityMergable" shader is a shader that can have surfaces from seperate
|
||||
// entities merged into a single batch, like smoke and blood puff sprites
|
||||
if (shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted
|
||||
|| ( entityNum != oldEntityNum && !shader->entityMergable ) ) {
|
||||
if (oldShader != NULL) {
|
||||
RB_EndSurface();
|
||||
}
|
||||
RB_BeginSurface( shader, fogNum );
|
||||
oldShader = shader;
|
||||
oldFogNum = fogNum;
|
||||
oldDlighted = dlighted;
|
||||
}
|
||||
|
||||
//
|
||||
// change the modelview matrix if needed
|
||||
//
|
||||
if ( entityNum != oldEntityNum )
|
||||
{
|
||||
if ( entityNum != REFENTITYNUM_WORLD )
|
||||
{
|
||||
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
|
||||
backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime;
|
||||
// we have to reset the shaderTime as well otherwise image animations start
|
||||
// from the wrong frame
|
||||
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
|
||||
|
||||
// set up the transformation matrix
|
||||
R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.or );
|
||||
|
||||
|
||||
// set up the dynamic lighting if needed
|
||||
if ( backEnd.currentEntity->needDlights ) {
|
||||
R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
|
||||
}
|
||||
|
||||
if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) {
|
||||
// hack the depth range to prevent view model from poking into walls
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
backEnd.currentEntity = &tr.worldEntity;
|
||||
backEnd.refdef.floatTime = originalTime;
|
||||
backEnd.or = backEnd.viewParms.world;
|
||||
// we have to reset the shaderTime as well otherwise image animations on
|
||||
// the world (like water) continue with the wrong frame
|
||||
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
|
||||
R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
|
||||
}
|
||||
|
||||
|
||||
// VULKAN
|
||||
set_modelview_matrix(backEnd.or.modelMatrix);
|
||||
oldEntityNum = entityNum;
|
||||
}
|
||||
|
||||
// add the triangles for this surface
|
||||
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
|
||||
}
|
||||
|
||||
backEnd.refdef.floatTime = originalTime;
|
||||
|
||||
// draw the contents of the last shader batch
|
||||
if (oldShader != NULL) {
|
||||
RB_EndSurface();
|
||||
}
|
||||
|
||||
// go back to the world modelview matrix
|
||||
set_modelview_matrix(backEnd.viewParms.world.modelMatrix);
|
||||
|
||||
|
||||
// darken down any stencil shadows
|
||||
RB_ShadowFinish();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RB_StretchPic( const stretchPicCommand_t * const cmd )
|
||||
{
|
||||
|
||||
if ( qfalse == backEnd.projection2D )
|
||||
{
|
||||
|
||||
backEnd.projection2D = qtrue;
|
||||
|
||||
// set 2D virtual screen size
|
||||
// set time for 2D shaders
|
||||
int t = ri.Milliseconds();
|
||||
|
||||
backEnd.refdef.rd.time = t;
|
||||
backEnd.refdef.floatTime = t * 0.001f;
|
||||
}
|
||||
|
||||
|
||||
if ( cmd->shader != tess.shader )
|
||||
{
|
||||
if ( tess.numIndexes ) {
|
||||
RB_EndSurface();
|
||||
}
|
||||
backEnd.currentEntity = &backEnd.entity2D;
|
||||
RB_BeginSurface(cmd->shader, 0 );
|
||||
}
|
||||
|
||||
RB_CHECKOVERFLOW( 4, 6 );
|
||||
|
||||
|
||||
const unsigned int n0 = tess.numVertexes;
|
||||
const unsigned int n1 = n0 + 1;
|
||||
const unsigned int n2 = n0 + 2;
|
||||
const unsigned int n3 = n0 + 3;
|
||||
|
||||
|
||||
uint32_t numIndexes = tess.numIndexes;
|
||||
|
||||
tess.indexes[ numIndexes ] = n3;
|
||||
tess.indexes[ numIndexes + 1 ] = n0;
|
||||
tess.indexes[ numIndexes + 2 ] = n2;
|
||||
tess.indexes[ numIndexes + 3 ] = n2;
|
||||
tess.indexes[ numIndexes + 4 ] = n0;
|
||||
tess.indexes[ numIndexes + 5 ] = n1;
|
||||
|
||||
|
||||
// TODO: verify does coding this way run faster in release mode ?
|
||||
// coding this way do harm to debug version because of
|
||||
// introduce additional 4 function call.
|
||||
memcpy(tess.vertexColors[ n0 ], backEnd.Color2D, 4);
|
||||
memcpy(tess.vertexColors[ n1 ], backEnd.Color2D, 4);
|
||||
memcpy(tess.vertexColors[ n2 ], backEnd.Color2D, 4);
|
||||
memcpy(tess.vertexColors[ n3 ], backEnd.Color2D, 4);
|
||||
|
||||
|
||||
tess.xyz[ n0 ][0] = cmd->x;
|
||||
tess.xyz[ n0 ][1] = cmd->y;
|
||||
tess.xyz[ n0 ][2] = 0;
|
||||
tess.xyz[ n1 ][0] = cmd->x + cmd->w;
|
||||
tess.xyz[ n1 ][1] = cmd->y;
|
||||
tess.xyz[ n1 ][2] = 0;
|
||||
tess.xyz[ n2 ][0] = cmd->x + cmd->w;
|
||||
tess.xyz[ n2 ][1] = cmd->y + cmd->h;
|
||||
tess.xyz[ n2 ][2] = 0;
|
||||
tess.xyz[ n3 ][0] = cmd->x;
|
||||
tess.xyz[ n3 ][1] = cmd->y + cmd->h;
|
||||
tess.xyz[ n3 ][2] = 0;
|
||||
|
||||
|
||||
tess.texCoords[ n0 ][0][0] = cmd->s1;
|
||||
tess.texCoords[ n0 ][0][1] = cmd->t1;
|
||||
|
||||
tess.texCoords[ n1 ][0][0] = cmd->s2;
|
||||
tess.texCoords[ n1 ][0][1] = cmd->t1;
|
||||
|
||||
tess.texCoords[ n2 ][0][0] = cmd->s2;
|
||||
tess.texCoords[ n2 ][0][1] = cmd->t2;
|
||||
|
||||
tess.texCoords[ n3 ][0][0] = cmd->s1;
|
||||
tess.texCoords[ n3 ][0][1] = cmd->t2;
|
||||
|
||||
tess.numVertexes += 4;
|
||||
tess.numIndexes += 6;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void R_PerformanceCounters( void )
|
||||
{
|
||||
|
||||
if (r_speeds->integer == 1) {
|
||||
ri.Printf (PRINT_ALL, "%i/%i shaders/surfs %i leafs %i verts %i/%i tris\n",
|
||||
backEnd.pc.c_shaders, backEnd.pc.c_surfaces, tr.pc.c_leafs, backEnd.pc.c_vertexes,
|
||||
backEnd.pc.c_indexes/3, backEnd.pc.c_totalIndexes/3);
|
||||
} else if (r_speeds->integer == 2) {
|
||||
ri.Printf (PRINT_ALL, "(patch) %i sin %i sclip %i sout %i bin %i bclip %i bout\n",
|
||||
tr.pc.c_sphere_cull_patch_in, tr.pc.c_sphere_cull_patch_clip, tr.pc.c_sphere_cull_patch_out,
|
||||
tr.pc.c_box_cull_patch_in, tr.pc.c_box_cull_patch_clip, tr.pc.c_box_cull_patch_out );
|
||||
ri.Printf (PRINT_ALL, "(md3) %i sin %i sclip %i sout %i bin %i bclip %i bout\n",
|
||||
tr.pc.c_sphere_cull_md3_in, tr.pc.c_sphere_cull_md3_clip, tr.pc.c_sphere_cull_md3_out,
|
||||
tr.pc.c_box_cull_md3_in, tr.pc.c_box_cull_md3_clip, tr.pc.c_box_cull_md3_out );
|
||||
} else if (r_speeds->integer == 3) {
|
||||
ri.Printf (PRINT_ALL, "viewcluster: %i\n", tr.viewCluster );
|
||||
} else if (r_speeds->integer == 4) {
|
||||
if ( backEnd.pc.c_dlightVertexes ) {
|
||||
ri.Printf (PRINT_ALL, "dlight srf:%i culled:%i verts:%i tris:%i\n",
|
||||
tr.pc.c_dlightSurfaces, tr.pc.c_dlightSurfacesCulled,
|
||||
backEnd.pc.c_dlightVertexes, backEnd.pc.c_dlightIndexes / 3 );
|
||||
}
|
||||
}
|
||||
|
||||
memset( &tr.pc, 0, sizeof( tr.pc ) );
|
||||
memset( &backEnd.pc, 0, sizeof( backEnd.pc ) );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
This function will be called synchronously if running without
|
||||
smp extensions, or asynchronously by another thread.
|
||||
====================
|
||||
*/
|
||||
void R_IssueRenderCommands( qboolean runPerformanceCounters )
|
||||
{
|
||||
|
||||
if(runPerformanceCounters)
|
||||
{
|
||||
R_PerformanceCounters();
|
||||
}
|
||||
|
||||
// actually start the commands going
|
||||
// let it start on the new batch
|
||||
// RB_ExecuteRenderCommands( cmdList->cmds );
|
||||
int t1 = ri.Milliseconds ();
|
||||
|
||||
// add an end-of-list command
|
||||
*(int *)(BE_Commands.cmds + BE_Commands.used) = RC_END_OF_LIST;
|
||||
|
||||
|
||||
const void * data = BE_Commands.cmds;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
const int T = *(const int *)data;
|
||||
switch ( T )
|
||||
{
|
||||
case RC_SET_COLOR:
|
||||
{
|
||||
const setColorCommand_t * const cmd = data;
|
||||
|
||||
backEnd.Color2D[0] = cmd->color[0] * 255;
|
||||
backEnd.Color2D[1] = cmd->color[1] * 255;
|
||||
backEnd.Color2D[2] = cmd->color[2] * 255;
|
||||
backEnd.Color2D[3] = cmd->color[3] * 255;
|
||||
|
||||
data += sizeof(setColorCommand_t);
|
||||
} break;
|
||||
|
||||
case RC_STRETCH_PIC:
|
||||
{
|
||||
const stretchPicCommand_t * const cmd = data;
|
||||
|
||||
RB_StretchPic( cmd );
|
||||
|
||||
data += sizeof(stretchPicCommand_t);
|
||||
} break;
|
||||
|
||||
case RC_DRAW_SURFS:
|
||||
{
|
||||
const drawSurfsCommand_t * const cmd = (const drawSurfsCommand_t *)data;
|
||||
|
||||
// RB_DrawSurfs( cmd );
|
||||
// finish any 2D drawing if needed
|
||||
if ( tess.numIndexes ) {
|
||||
RB_EndSurface();
|
||||
}
|
||||
|
||||
backEnd.refdef = cmd->refdef;
|
||||
backEnd.viewParms = cmd->viewParms;
|
||||
|
||||
RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs );
|
||||
|
||||
data += sizeof(drawSurfsCommand_t);
|
||||
} break;
|
||||
|
||||
case RC_DRAW_BUFFER:
|
||||
{
|
||||
// data = RB_DrawBuffer( data );
|
||||
// const drawBufferCommand_t * const cmd = (const drawBufferCommand_t *)data;
|
||||
vk_resetGeometryBuffer();
|
||||
|
||||
// VULKAN
|
||||
vk_begin_frame();
|
||||
|
||||
data += sizeof(drawBufferCommand_t);
|
||||
|
||||
// begin_frame_called = qtrue;
|
||||
} break;
|
||||
|
||||
case RC_SWAP_BUFFERS:
|
||||
{
|
||||
// data = RB_SwapBuffers( data );
|
||||
// finish any 2D drawing if needed
|
||||
RB_EndSurface();
|
||||
|
||||
// texture swapping test
|
||||
if ( r_showImages->integer ) {
|
||||
RB_ShowImages(tr.images, tr.numImages);
|
||||
}
|
||||
|
||||
// VULKAN
|
||||
vk_end_frame();
|
||||
|
||||
data += sizeof(swapBuffersCommand_t);
|
||||
} break;
|
||||
|
||||
case RC_SCREENSHOT:
|
||||
{
|
||||
const screenshotCommand_t * const cmd = data;
|
||||
|
||||
RB_TakeScreenshot( cmd->width, cmd->height, cmd->fileName, cmd->jpeg);
|
||||
|
||||
data += sizeof(screenshotCommand_t);
|
||||
} break;
|
||||
|
||||
|
||||
case RC_VIDEOFRAME:
|
||||
{
|
||||
const videoFrameCommand_t * const cmd = data;
|
||||
|
||||
RB_TakeVideoFrameCmd( cmd );
|
||||
|
||||
data += sizeof(videoFrameCommand_t);
|
||||
} break;
|
||||
|
||||
case RC_END_OF_LIST:
|
||||
// stop rendering on this thread
|
||||
backEnd.pc.msec = ri.Milliseconds () - t1;
|
||||
|
||||
BE_Commands.used = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
|
||||
FixRenderCommandList
|
||||
https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=493
|
||||
Arnout: this is a nasty issue. Shaders can be registered after drawsurfaces are generated
|
||||
but before the frame is rendered. This will, for the duration of one frame, cause drawsurfaces
|
||||
to be rendered with bad shaders. To fix this, need to go through all render commands and fix
|
||||
sortedIndex.
|
||||
==============
|
||||
*/
|
||||
void FixRenderCommandList( int newShader )
|
||||
{
|
||||
renderCommandList_t *cmdList = &BE_Commands;
|
||||
|
||||
if( cmdList ) {
|
||||
const void *curCmd = cmdList->cmds;
|
||||
|
||||
while ( 1 ) {
|
||||
switch ( *(const int *)curCmd ) {
|
||||
case RC_SET_COLOR:
|
||||
{
|
||||
const setColorCommand_t *sc_cmd = (const setColorCommand_t *)curCmd;
|
||||
curCmd = (const void *)(sc_cmd + 1);
|
||||
break;
|
||||
}
|
||||
case RC_STRETCH_PIC:
|
||||
{
|
||||
const stretchPicCommand_t *sp_cmd = (const stretchPicCommand_t *)curCmd;
|
||||
curCmd = (const void *)(sp_cmd + 1);
|
||||
break;
|
||||
}
|
||||
case RC_DRAW_SURFS:
|
||||
{
|
||||
int i;
|
||||
drawSurf_t *drawSurf;
|
||||
shader_t *shader;
|
||||
int fogNum;
|
||||
int entityNum;
|
||||
int dlightMap;
|
||||
int sortedIndex;
|
||||
const drawSurfsCommand_t *ds_cmd = (const drawSurfsCommand_t *)curCmd;
|
||||
|
||||
for( i = 0, drawSurf = ds_cmd->drawSurfs; i < ds_cmd->numDrawSurfs; i++, drawSurf++ ) {
|
||||
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlightMap );
|
||||
sortedIndex = (( drawSurf->sort >> QSORT_SHADERNUM_SHIFT ) & (MAX_SHADERS-1));
|
||||
if( sortedIndex >= newShader ) {
|
||||
sortedIndex++;
|
||||
drawSurf->sort = (sortedIndex << QSORT_SHADERNUM_SHIFT) | entityNum | ( fogNum << QSORT_FOGNUM_SHIFT ) | (int)dlightMap;
|
||||
}
|
||||
}
|
||||
curCmd = (const void *)(ds_cmd + 1);
|
||||
break;
|
||||
}
|
||||
case RC_DRAW_BUFFER:
|
||||
{
|
||||
const drawBufferCommand_t *db_cmd = (const drawBufferCommand_t *)curCmd;
|
||||
curCmd = (const void *)(db_cmd + 1);
|
||||
break;
|
||||
}
|
||||
case RC_SWAP_BUFFERS:
|
||||
{
|
||||
const swapBuffersCommand_t *sb_cmd = (const swapBuffersCommand_t *)curCmd;
|
||||
curCmd = (const void *)(sb_cmd + 1);
|
||||
break;
|
||||
}
|
||||
case RC_END_OF_LIST:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
627
code/renderervk/tr_curve.c
Normal file
627
code/renderervk/tr_curve.c
Normal file
|
@ -0,0 +1,627 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This file does all of the processing necessary to turn a raw grid of points
|
||||
read from the map file into a srfGridMesh_t ready for rendering.
|
||||
|
||||
The level of detail solution is direction independent, based only on subdivided
|
||||
distance from the true curve.
|
||||
|
||||
Only a single entry point:
|
||||
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
LerpDrawVert
|
||||
============
|
||||
*/
|
||||
static void LerpDrawVert( drawVert_t *a, drawVert_t *b, drawVert_t *out ) {
|
||||
out->xyz[0] = 0.5f * (a->xyz[0] + b->xyz[0]);
|
||||
out->xyz[1] = 0.5f * (a->xyz[1] + b->xyz[1]);
|
||||
out->xyz[2] = 0.5f * (a->xyz[2] + b->xyz[2]);
|
||||
|
||||
out->st[0] = 0.5f * (a->st[0] + b->st[0]);
|
||||
out->st[1] = 0.5f * (a->st[1] + b->st[1]);
|
||||
|
||||
out->lightmap[0] = 0.5f * (a->lightmap[0] + b->lightmap[0]);
|
||||
out->lightmap[1] = 0.5f * (a->lightmap[1] + b->lightmap[1]);
|
||||
|
||||
out->color[0] = (a->color[0] + b->color[0]) >> 1;
|
||||
out->color[1] = (a->color[1] + b->color[1]) >> 1;
|
||||
out->color[2] = (a->color[2] + b->color[2]) >> 1;
|
||||
out->color[3] = (a->color[3] + b->color[3]) >> 1;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Transpose
|
||||
============
|
||||
*/
|
||||
static void Transpose( int width, int height, drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE] ) {
|
||||
int i, j;
|
||||
drawVert_t temp;
|
||||
|
||||
if ( width > height ) {
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
for ( j = i + 1 ; j < width ; j++ ) {
|
||||
if ( j < height ) {
|
||||
// swap the value
|
||||
temp = ctrl[j][i];
|
||||
ctrl[j][i] = ctrl[i][j];
|
||||
ctrl[i][j] = temp;
|
||||
} else {
|
||||
// just copy
|
||||
ctrl[j][i] = ctrl[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = i + 1 ; j < height ; j++ ) {
|
||||
if ( j < width ) {
|
||||
// swap the value
|
||||
temp = ctrl[i][j];
|
||||
ctrl[i][j] = ctrl[j][i];
|
||||
ctrl[j][i] = temp;
|
||||
} else {
|
||||
// just copy
|
||||
ctrl[i][j] = ctrl[j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
MakeMeshNormals
|
||||
|
||||
Handles all the complicated wrapping and degenerate cases
|
||||
=================
|
||||
*/
|
||||
static void MakeMeshNormals( int width, int height, drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE] ) {
|
||||
int i, j, k, dist;
|
||||
vec3_t normal;
|
||||
vec3_t sum;
|
||||
int count;
|
||||
vec3_t base;
|
||||
vec3_t delta;
|
||||
int x, y;
|
||||
drawVert_t *dv;
|
||||
vec3_t around[8], temp;
|
||||
qboolean good[8];
|
||||
qboolean wrapWidth, wrapHeight;
|
||||
float len;
|
||||
static int neighbors[8][2] = {
|
||||
{0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}
|
||||
};
|
||||
|
||||
wrapWidth = qfalse;
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
VectorSubtract( ctrl[i][0].xyz, ctrl[i][width-1].xyz, delta );
|
||||
len = VectorLengthSquared( delta );
|
||||
if ( len > 1.0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == height ) {
|
||||
wrapWidth = qtrue;
|
||||
}
|
||||
|
||||
wrapHeight = qfalse;
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
VectorSubtract( ctrl[0][i].xyz, ctrl[height-1][i].xyz, delta );
|
||||
len = VectorLengthSquared( delta );
|
||||
if ( len > 1.0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == width) {
|
||||
wrapHeight = qtrue;
|
||||
}
|
||||
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
count = 0;
|
||||
dv = &ctrl[j][i];
|
||||
VectorCopy( dv->xyz, base );
|
||||
for ( k = 0 ; k < 8 ; k++ ) {
|
||||
VectorClear( around[k] );
|
||||
good[k] = qfalse;
|
||||
|
||||
for ( dist = 1 ; dist <= 3 ; dist++ ) {
|
||||
x = i + neighbors[k][0] * dist;
|
||||
y = j + neighbors[k][1] * dist;
|
||||
if ( wrapWidth ) {
|
||||
if ( x < 0 ) {
|
||||
x = width - 1 + x;
|
||||
} else if ( x >= width ) {
|
||||
x = 1 + x - width;
|
||||
}
|
||||
}
|
||||
if ( wrapHeight ) {
|
||||
if ( y < 0 ) {
|
||||
y = height - 1 + y;
|
||||
} else if ( y >= height ) {
|
||||
y = 1 + y - height;
|
||||
}
|
||||
}
|
||||
|
||||
if ( x < 0 || x >= width || y < 0 || y >= height ) {
|
||||
break; // edge of patch
|
||||
}
|
||||
VectorSubtract( ctrl[y][x].xyz, base, temp );
|
||||
if ( VectorNormalize2( temp, temp ) == 0 ) {
|
||||
continue; // degenerate edge, get more dist
|
||||
} else {
|
||||
good[k] = qtrue;
|
||||
VectorCopy( temp, around[k] );
|
||||
break; // good edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( sum );
|
||||
for ( k = 0 ; k < 8 ; k++ ) {
|
||||
if ( !good[k] || !good[(k+1)&7] ) {
|
||||
continue; // didn't get two points
|
||||
}
|
||||
CrossProduct( around[(k+1)&7], around[k], normal );
|
||||
if ( VectorNormalize2( normal, normal ) == 0 ) {
|
||||
continue;
|
||||
}
|
||||
VectorAdd( normal, sum, sum );
|
||||
count++;
|
||||
}
|
||||
if ( count == 0 ) {
|
||||
//printf("bad normal\n");
|
||||
count = 1;
|
||||
}
|
||||
VectorNormalize2( sum, dv->normal );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
InvertCtrl
|
||||
============
|
||||
*/
|
||||
static void InvertCtrl( int width, int height, drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE] ) {
|
||||
int i, j;
|
||||
drawVert_t temp;
|
||||
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
for ( j = 0 ; j < width/2 ; j++ ) {
|
||||
temp = ctrl[i][j];
|
||||
ctrl[i][j] = ctrl[i][width-1-j];
|
||||
ctrl[i][width-1-j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
InvertErrorTable
|
||||
=================
|
||||
*/
|
||||
static void InvertErrorTable( float errorTable[2][MAX_GRID_SIZE], int width, int height ) {
|
||||
int i;
|
||||
float copy[2][MAX_GRID_SIZE];
|
||||
|
||||
memcpy( copy, errorTable, sizeof( copy ) );
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
errorTable[1][i] = copy[0][i]; //[width-1-i];
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
errorTable[0][i] = copy[1][height-1-i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
PutPointsOnCurve
|
||||
==================
|
||||
*/
|
||||
static void PutPointsOnCurve( drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
|
||||
int width, int height ) {
|
||||
int i, j;
|
||||
drawVert_t prev, next;
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 1 ; j < height ; j += 2 ) {
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j+1][i], &prev );
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j-1][i], &next );
|
||||
LerpDrawVert( &prev, &next, &ctrl[j][i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
for ( i = 1 ; i < width ; i += 2 ) {
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j][i+1], &prev );
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j][i-1], &next );
|
||||
LerpDrawVert( &prev, &next, &ctrl[j][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CreateSurfaceGridMesh
|
||||
=================
|
||||
*/
|
||||
srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
||||
drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], float errorTable[2][MAX_GRID_SIZE] ) {
|
||||
int i, j, size;
|
||||
drawVert_t *vert;
|
||||
vec3_t tmpVec;
|
||||
srfGridMesh_t *grid;
|
||||
|
||||
// copy the results out to a grid
|
||||
size = (width * height - 1) * sizeof( drawVert_t ) + sizeof( *grid );
|
||||
|
||||
#ifdef PATCH_STITCHING
|
||||
grid = /*ri.Hunk_Alloc*/ (srfGridMesh_t*) ri.Malloc( size );
|
||||
memset(grid, 0, size);
|
||||
|
||||
grid->widthLodError = /*ri.Hunk_Alloc*/ (float*) ri.Malloc( width * 4 );
|
||||
memcpy( grid->widthLodError, errorTable[0], width * 4 );
|
||||
|
||||
grid->heightLodError = /*ri.Hunk_Alloc*/ (float*) ri.Malloc( height * 4 );
|
||||
memcpy( grid->heightLodError, errorTable[1], height * 4 );
|
||||
#else
|
||||
grid = ri.Hunk_Alloc( size );
|
||||
memset(grid, 0, size);
|
||||
|
||||
grid->widthLodError = ri.Hunk_Alloc( width * 4 );
|
||||
memcpy( grid->widthLodError, errorTable[0], width * 4 );
|
||||
|
||||
grid->heightLodError = ri.Hunk_Alloc( height * 4 );
|
||||
memcpy( grid->heightLodError, errorTable[1], height * 4 );
|
||||
#endif
|
||||
|
||||
grid->width = width;
|
||||
grid->height = height;
|
||||
grid->surfaceType = SF_GRID;
|
||||
ClearBounds( grid->meshBounds[0], grid->meshBounds[1] );
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
vert = &grid->verts[j*width+i];
|
||||
*vert = ctrl[j][i];
|
||||
AddPointToBounds( vert->xyz, grid->meshBounds[0], grid->meshBounds[1] );
|
||||
}
|
||||
}
|
||||
|
||||
// compute local origin and bounds
|
||||
VectorAdd( grid->meshBounds[0], grid->meshBounds[1], grid->localOrigin );
|
||||
VectorScale( grid->localOrigin, 0.5f, grid->localOrigin );
|
||||
VectorSubtract( grid->meshBounds[0], grid->localOrigin, tmpVec );
|
||||
grid->meshRadius = VectorLength( tmpVec );
|
||||
|
||||
VectorCopy( grid->localOrigin, grid->lodOrigin );
|
||||
grid->lodRadius = grid->meshRadius;
|
||||
//
|
||||
return grid;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_FreeSurfaceGridMesh
|
||||
=================
|
||||
*/
|
||||
void R_FreeSurfaceGridMesh( srfGridMesh_t *grid ) {
|
||||
ri.Free(grid->widthLodError);
|
||||
ri.Free(grid->heightLodError);
|
||||
ri.Free(grid);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SubdividePatchToGrid
|
||||
=================
|
||||
*/
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
int i, j, k, l;
|
||||
drawVert_t prev, next, mid;
|
||||
float len, maxLen;
|
||||
int dir;
|
||||
int t;
|
||||
drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
float errorTable[2][MAX_GRID_SIZE];
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
ctrl[j][i] = points[j*width+i];
|
||||
}
|
||||
}
|
||||
|
||||
for ( dir = 0 ; dir < 2 ; dir++ ) {
|
||||
|
||||
for ( j = 0 ; j < MAX_GRID_SIZE ; j++ ) {
|
||||
errorTable[dir][j] = 0;
|
||||
}
|
||||
|
||||
// horizontal subdivisions
|
||||
for ( j = 0 ; j + 2 < width ; j += 2 ) {
|
||||
// check subdivided midpoints against control points
|
||||
|
||||
// FIXME: also check midpoints of adjacent patches against the control points
|
||||
// this would basically stitch all patches in the same LOD group together.
|
||||
|
||||
maxLen = 0;
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
vec3_t midxyz;
|
||||
vec3_t midxyz2;
|
||||
vec3_t dir;
|
||||
vec3_t projected;
|
||||
float d;
|
||||
|
||||
// calculate the point on the curve
|
||||
for ( l = 0 ; l < 3 ; l++ ) {
|
||||
midxyz[l] = (ctrl[i][j].xyz[l] + ctrl[i][j+1].xyz[l] * 2
|
||||
+ ctrl[i][j+2].xyz[l] ) * 0.25f;
|
||||
}
|
||||
|
||||
// see how far off the line it is
|
||||
// using dist-from-line will not account for internal
|
||||
// texture warping, but it gives a lot less polygons than
|
||||
// dist-from-midpoint
|
||||
VectorSubtract( midxyz, ctrl[i][j].xyz, midxyz );
|
||||
VectorSubtract( ctrl[i][j+2].xyz, ctrl[i][j].xyz, dir );
|
||||
VectorNormalize( dir );
|
||||
|
||||
d = DotProduct( midxyz, dir );
|
||||
VectorScale( dir, d, projected );
|
||||
VectorSubtract( midxyz, projected, midxyz2);
|
||||
len = VectorLengthSquared( midxyz2 ); // we will do the sqrt later
|
||||
if ( len > maxLen ) {
|
||||
maxLen = len;
|
||||
}
|
||||
}
|
||||
|
||||
maxLen = sqrt(maxLen);
|
||||
|
||||
// if all the points are on the lines, remove the entire columns
|
||||
if ( maxLen < 0.1f ) {
|
||||
errorTable[dir][j+1] = 999;
|
||||
continue;
|
||||
}
|
||||
|
||||
// see if we want to insert subdivided columns
|
||||
if ( width + 2 > MAX_GRID_SIZE ) {
|
||||
errorTable[dir][j+1] = 1.0f/maxLen;
|
||||
continue; // can't subdivide any more
|
||||
}
|
||||
|
||||
if ( maxLen <= r_subdivisions->value ) {
|
||||
errorTable[dir][j+1] = 1.0f/maxLen;
|
||||
continue; // didn't need subdivision
|
||||
}
|
||||
|
||||
errorTable[dir][j+2] = 1.0f/maxLen;
|
||||
|
||||
// insert two columns and replace the peak
|
||||
width += 2;
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
LerpDrawVert( &ctrl[i][j], &ctrl[i][j+1], &prev );
|
||||
LerpDrawVert( &ctrl[i][j+1], &ctrl[i][j+2], &next );
|
||||
LerpDrawVert( &prev, &next, &mid );
|
||||
|
||||
for ( k = width - 1 ; k > j + 3 ; k-- ) {
|
||||
ctrl[i][k] = ctrl[i][k-2];
|
||||
}
|
||||
ctrl[i][j + 1] = prev;
|
||||
ctrl[i][j + 2] = mid;
|
||||
ctrl[i][j + 3] = next;
|
||||
}
|
||||
|
||||
// back up and recheck this set again, it may need more subdivision
|
||||
j -= 2;
|
||||
|
||||
}
|
||||
|
||||
Transpose( width, height, ctrl );
|
||||
t = width;
|
||||
width = height;
|
||||
height = t;
|
||||
}
|
||||
|
||||
|
||||
// put all the aproximating points on the curve
|
||||
PutPointsOnCurve( ctrl, width, height );
|
||||
|
||||
// cull out any rows or columns that are colinear
|
||||
for ( i = 1 ; i < width-1 ; i++ ) {
|
||||
if ( errorTable[0][i] != 999 ) {
|
||||
continue;
|
||||
}
|
||||
for ( j = i+1 ; j < width ; j++ ) {
|
||||
for ( k = 0 ; k < height ; k++ ) {
|
||||
ctrl[k][j-1] = ctrl[k][j];
|
||||
}
|
||||
errorTable[0][j-1] = errorTable[0][j];
|
||||
}
|
||||
width--;
|
||||
}
|
||||
|
||||
for ( i = 1 ; i < height-1 ; i++ ) {
|
||||
if ( errorTable[1][i] != 999 ) {
|
||||
continue;
|
||||
}
|
||||
for ( j = i+1 ; j < height ; j++ ) {
|
||||
for ( k = 0 ; k < width ; k++ ) {
|
||||
ctrl[j-1][k] = ctrl[j][k];
|
||||
}
|
||||
errorTable[1][j-1] = errorTable[1][j];
|
||||
}
|
||||
height--;
|
||||
}
|
||||
|
||||
#if 1
|
||||
// flip for longest tristrips as an optimization
|
||||
// the results should be visually identical with or
|
||||
// without this step
|
||||
if ( height > width ) {
|
||||
Transpose( width, height, ctrl );
|
||||
InvertErrorTable( errorTable, width, height );
|
||||
t = width;
|
||||
width = height;
|
||||
height = t;
|
||||
InvertCtrl( width, height, ctrl );
|
||||
}
|
||||
#endif
|
||||
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
|
||||
return R_CreateSurfaceGridMesh( width, height, ctrl, errorTable );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_GridInsertColumn
|
||||
===============
|
||||
*/
|
||||
srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec3_t point, float loderror ) {
|
||||
int i, j;
|
||||
int width, height, oldwidth;
|
||||
drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
float errorTable[2][MAX_GRID_SIZE];
|
||||
float lodRadius;
|
||||
vec3_t lodOrigin;
|
||||
|
||||
oldwidth = 0;
|
||||
width = grid->width + 1;
|
||||
if (width > MAX_GRID_SIZE)
|
||||
return NULL;
|
||||
height = grid->height;
|
||||
for (i = 0; i < width; i++) {
|
||||
if (i == column) {
|
||||
//insert new column
|
||||
for (j = 0; j < grid->height; j++) {
|
||||
LerpDrawVert( &grid->verts[j * grid->width + i-1], &grid->verts[j * grid->width + i], &ctrl[j][i] );
|
||||
if (j == row)
|
||||
VectorCopy(point, ctrl[j][i].xyz);
|
||||
}
|
||||
errorTable[0][i] = loderror;
|
||||
continue;
|
||||
}
|
||||
errorTable[0][i] = grid->widthLodError[oldwidth];
|
||||
for (j = 0; j < grid->height; j++) {
|
||||
ctrl[j][i] = grid->verts[j * grid->width + oldwidth];
|
||||
}
|
||||
oldwidth++;
|
||||
}
|
||||
for (j = 0; j < grid->height; j++) {
|
||||
errorTable[1][j] = grid->heightLodError[j];
|
||||
}
|
||||
// put all the aproximating points on the curve
|
||||
//PutPointsOnCurve( ctrl, width, height );
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
|
||||
VectorCopy(grid->lodOrigin, lodOrigin);
|
||||
lodRadius = grid->lodRadius;
|
||||
// free the old grid
|
||||
R_FreeSurfaceGridMesh(grid);
|
||||
// create a new grid
|
||||
grid = R_CreateSurfaceGridMesh( width, height, ctrl, errorTable );
|
||||
grid->lodRadius = lodRadius;
|
||||
VectorCopy(lodOrigin, grid->lodOrigin);
|
||||
return grid;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_GridInsertRow
|
||||
===============
|
||||
*/
|
||||
srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t point, float loderror ) {
|
||||
int i, j;
|
||||
int width, height, oldheight;
|
||||
drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
float errorTable[2][MAX_GRID_SIZE];
|
||||
float lodRadius;
|
||||
vec3_t lodOrigin;
|
||||
|
||||
oldheight = 0;
|
||||
width = grid->width;
|
||||
height = grid->height + 1;
|
||||
if (height > MAX_GRID_SIZE)
|
||||
return NULL;
|
||||
for (i = 0; i < height; i++) {
|
||||
if (i == row) {
|
||||
//insert new row
|
||||
for (j = 0; j < grid->width; j++) {
|
||||
LerpDrawVert( &grid->verts[(i-1) * grid->width + j], &grid->verts[i * grid->width + j], &ctrl[i][j] );
|
||||
if (j == column)
|
||||
VectorCopy(point, ctrl[i][j].xyz);
|
||||
}
|
||||
errorTable[1][i] = loderror;
|
||||
continue;
|
||||
}
|
||||
errorTable[1][i] = grid->heightLodError[oldheight];
|
||||
for (j = 0; j < grid->width; j++) {
|
||||
ctrl[i][j] = grid->verts[oldheight * grid->width + j];
|
||||
}
|
||||
oldheight++;
|
||||
}
|
||||
for (j = 0; j < grid->width; j++) {
|
||||
errorTable[0][j] = grid->widthLodError[j];
|
||||
}
|
||||
// put all the aproximating points on the curve
|
||||
//PutPointsOnCurve( ctrl, width, height );
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
|
||||
VectorCopy(grid->lodOrigin, lodOrigin);
|
||||
lodRadius = grid->lodRadius;
|
||||
// free the old grid
|
||||
R_FreeSurfaceGridMesh(grid);
|
||||
// create a new grid
|
||||
grid = R_CreateSurfaceGridMesh( width, height, ctrl, errorTable );
|
||||
grid->lodRadius = lodRadius;
|
||||
VectorCopy(lodOrigin, grid->lodOrigin);
|
||||
return grid;
|
||||
}
|
169
code/renderervk/tr_cvar.c
Normal file
169
code/renderervk/tr_cvar.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
|
||||
#include "tr_cvar.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
cvar_t *r_railWidth;
|
||||
cvar_t *r_railCoreWidth;
|
||||
cvar_t *r_railSegmentLength;
|
||||
|
||||
cvar_t *r_verbose;
|
||||
|
||||
cvar_t *r_znear;
|
||||
|
||||
|
||||
cvar_t *r_inGameVideo;
|
||||
cvar_t *r_dynamiclight;
|
||||
|
||||
cvar_t *r_norefresh;
|
||||
cvar_t *r_drawentities;
|
||||
cvar_t *r_drawworld;
|
||||
cvar_t *r_speeds;
|
||||
cvar_t *r_fullbright;
|
||||
cvar_t *r_novis;
|
||||
cvar_t *r_nocull;
|
||||
cvar_t *r_facePlaneCull;
|
||||
cvar_t *r_showcluster;
|
||||
cvar_t *r_nocurves;
|
||||
|
||||
|
||||
|
||||
cvar_t* r_fullscreen;
|
||||
// display refresh rate
|
||||
cvar_t* r_displayRefresh;
|
||||
|
||||
cvar_t *r_lightmap;
|
||||
cvar_t *r_vertexLight;
|
||||
cvar_t *r_uiFullScreen;
|
||||
cvar_t *r_shadows;
|
||||
cvar_t *r_flares;
|
||||
cvar_t *r_singleShader;
|
||||
cvar_t *r_colorMipLevels;
|
||||
cvar_t *r_picmip;
|
||||
cvar_t *r_showtris;
|
||||
cvar_t *r_showsky;
|
||||
cvar_t *r_shownormals;
|
||||
cvar_t *r_offsetFactor;
|
||||
cvar_t *r_offsetUnits;
|
||||
cvar_t *r_gamma;
|
||||
cvar_t *r_intensity;
|
||||
cvar_t *r_lockpvs;
|
||||
cvar_t *r_noportals;
|
||||
cvar_t *r_portalOnly;
|
||||
|
||||
cvar_t *r_subdivisions;
|
||||
cvar_t *r_lodCurveError;
|
||||
|
||||
// r_overbrightBits->integer, but set to 0 if no hw gamma
|
||||
// cvar_t *r_overBrightBits;
|
||||
cvar_t *r_mapOverBrightBits;
|
||||
|
||||
cvar_t *r_debugSurface;
|
||||
cvar_t *r_simpleMipMaps;
|
||||
|
||||
cvar_t *r_showImages;
|
||||
|
||||
cvar_t *r_ambientScale;
|
||||
cvar_t *r_directedScale;
|
||||
cvar_t *r_debugLight;
|
||||
cvar_t *r_debugSort;
|
||||
cvar_t *r_printShaders;
|
||||
cvar_t *r_saveFontData;
|
||||
|
||||
cvar_t *r_maxpolys;
|
||||
cvar_t *r_maxpolyverts;
|
||||
|
||||
cvar_t* r_allowResize; // make window resizable
|
||||
cvar_t* r_mode;
|
||||
|
||||
cvar_t* r_loadImgAPI;
|
||||
|
||||
void R_Register( void )
|
||||
{
|
||||
//
|
||||
// latched and archived variables
|
||||
//
|
||||
r_picmip = ri.Cvar_Get ("r_picmip", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
ri.Cvar_CheckRange( r_picmip, 0, 8, qtrue );
|
||||
|
||||
r_simpleMipMaps = ri.Cvar_Get( "r_simpleMipMaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_colorMipLevels = ri.Cvar_Get ("r_colorMipLevels", "0", CVAR_LATCH );
|
||||
|
||||
// r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_vertexLight = ri.Cvar_Get( "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_uiFullScreen = ri.Cvar_Get( "r_uifullscreen", "0", 0);
|
||||
r_subdivisions = ri.Cvar_Get ("r_subdivisions", "4", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
||||
//
|
||||
// temporary latched variables that can only change over a restart
|
||||
//
|
||||
r_fullbright = ri.Cvar_Get ("r_fullbright", "0", CVAR_LATCH|CVAR_CHEAT );
|
||||
r_mapOverBrightBits = ri.Cvar_Get ("r_mapOverBrightBits", "1", CVAR_LATCH );
|
||||
r_intensity = ri.Cvar_Get ("r_intensity", "1.5", CVAR_LATCH | CVAR_ARCHIVE );
|
||||
r_singleShader = ri.Cvar_Get ("r_singleShader", "0", CVAR_CHEAT | CVAR_LATCH );
|
||||
|
||||
//
|
||||
// archived variables that can change at any time
|
||||
//
|
||||
r_lodCurveError = ri.Cvar_Get( "r_lodCurveError", "250", CVAR_ARCHIVE|CVAR_CHEAT );
|
||||
r_flares = ri.Cvar_Get ("r_flares", "0", CVAR_ARCHIVE );
|
||||
r_znear = ri.Cvar_Get( "r_znear", "4", CVAR_CHEAT );
|
||||
ri.Cvar_CheckRange( r_znear, 0.001f, 200, qtrue );
|
||||
|
||||
r_inGameVideo = ri.Cvar_Get( "r_inGameVideo", "1", CVAR_ARCHIVE );
|
||||
r_dynamiclight = ri.Cvar_Get( "r_dynamiclight", "1", CVAR_ARCHIVE );
|
||||
r_gamma = ri.Cvar_Get( "r_gamma", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_facePlaneCull = ri.Cvar_Get ("r_facePlaneCull", "1", CVAR_ARCHIVE );
|
||||
|
||||
r_railWidth = ri.Cvar_Get( "r_railWidth", "16", CVAR_ARCHIVE );
|
||||
r_railCoreWidth = ri.Cvar_Get( "r_railCoreWidth", "6", CVAR_ARCHIVE );
|
||||
r_railSegmentLength = ri.Cvar_Get( "r_railSegmentLength", "32", CVAR_ARCHIVE );
|
||||
|
||||
r_ambientScale = ri.Cvar_Get( "r_ambientScale", "0.6", CVAR_CHEAT );
|
||||
r_directedScale = ri.Cvar_Get( "r_directedScale", "1", CVAR_CHEAT );
|
||||
|
||||
//
|
||||
// temporary variables that can change at any time
|
||||
//
|
||||
r_showImages = ri.Cvar_Get( "r_showImages", "0", CVAR_TEMP );
|
||||
|
||||
r_debugLight = ri.Cvar_Get( "r_debuglight", "0", CVAR_TEMP );
|
||||
r_debugSort = ri.Cvar_Get( "r_debugSort", "0", CVAR_CHEAT );
|
||||
r_printShaders = ri.Cvar_Get( "r_printShaders", "0", 0 );
|
||||
r_saveFontData = ri.Cvar_Get( "r_saveFontData", "0", 0 );
|
||||
|
||||
r_nocurves = ri.Cvar_Get ("r_nocurves", "0", CVAR_CHEAT );
|
||||
r_drawworld = ri.Cvar_Get ("r_drawworld", "1", CVAR_CHEAT );
|
||||
r_lightmap = ri.Cvar_Get ("r_lightmap", "0", 0 );
|
||||
r_portalOnly = ri.Cvar_Get ("r_portalOnly", "0", CVAR_TEMP );
|
||||
|
||||
|
||||
r_norefresh = ri.Cvar_Get ("r_norefresh", "0", CVAR_CHEAT);
|
||||
r_drawentities = ri.Cvar_Get ("r_drawentities", "1", CVAR_CHEAT );
|
||||
r_nocull = ri.Cvar_Get ("r_nocull", "0", CVAR_CHEAT);
|
||||
r_novis = ri.Cvar_Get ("r_novis", "0", CVAR_CHEAT);
|
||||
r_showcluster = ri.Cvar_Get ("r_showcluster", "0", CVAR_CHEAT);
|
||||
r_speeds = ri.Cvar_Get ("r_speeds", "0", CVAR_CHEAT);
|
||||
r_verbose = ri.Cvar_Get( "r_verbose", "0", CVAR_CHEAT );
|
||||
r_debugSurface = ri.Cvar_Get ("r_debugSurface", "0", CVAR_TEMP);
|
||||
r_showtris = ri.Cvar_Get ("r_showtris", "0", CVAR_TEMP);
|
||||
r_showsky = ri.Cvar_Get ("r_showsky", "0", CVAR_TEMP);
|
||||
r_shownormals = ri.Cvar_Get ("r_shownormals", "0", CVAR_TEMP);
|
||||
r_offsetFactor = ri.Cvar_Get( "r_offsetfactor", "-1", CVAR_CHEAT );
|
||||
r_offsetUnits = ri.Cvar_Get( "r_offsetunits", "-2", CVAR_CHEAT );
|
||||
r_lockpvs = ri.Cvar_Get ("r_lockpvs", "0", CVAR_CHEAT);
|
||||
r_noportals = ri.Cvar_Get ("r_noportals", "0", CVAR_CHEAT);
|
||||
r_shadows = ri.Cvar_Get( "cg_shadows", "1", 0 );
|
||||
|
||||
r_maxpolys = ri.Cvar_Get( "r_maxpolys", va("%d", 600), 0);
|
||||
r_maxpolyverts = ri.Cvar_Get( "r_maxpolyverts", va("%d", 3000), 0);
|
||||
|
||||
r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_displayRefresh = ri.Cvar_Get( "r_displayRefresh", "60", CVAR_LATCH );
|
||||
ri.Cvar_CheckRange( r_displayRefresh, 0, 200, qtrue );
|
||||
|
||||
r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
r_mode = ri.Cvar_Get( "r_mode", "-2", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
r_loadImgAPI = ri.Cvar_Get( "r_loadImgAPI", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
}
|
98
code/renderervk/tr_cvar.h
Normal file
98
code/renderervk/tr_cvar.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
#ifndef TR_CVAR_H_
|
||||
#define TR_CVAR_H_
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
|
||||
|
||||
extern cvar_t *r_railWidth;
|
||||
extern cvar_t *r_railCoreWidth;
|
||||
extern cvar_t *r_railSegmentLength;
|
||||
|
||||
extern cvar_t *r_verbose; // used for verbose debug spew
|
||||
|
||||
extern cvar_t *r_znear; // near Z clip plane
|
||||
|
||||
|
||||
extern cvar_t *r_depthbits; // number of desired depth bits
|
||||
|
||||
|
||||
|
||||
|
||||
extern cvar_t *r_inGameVideo; // controls whether in game video should be draw
|
||||
extern cvar_t *r_dynamiclight; // dynamic lights enabled/disabled
|
||||
|
||||
extern cvar_t *r_norefresh; // bypasses the ref rendering
|
||||
extern cvar_t *r_drawentities; // disable/enable entity rendering
|
||||
extern cvar_t *r_drawworld; // disable/enable world rendering
|
||||
extern cvar_t *r_speeds; // various levels of information display
|
||||
|
||||
extern cvar_t *r_novis; // disable/enable usage of PVS
|
||||
extern cvar_t *r_nocull;
|
||||
extern cvar_t *r_facePlaneCull; // enables culling of planar surfaces with back side test
|
||||
extern cvar_t *r_nocurves;
|
||||
extern cvar_t *r_showcluster;
|
||||
|
||||
extern cvar_t *r_mode; // video mode
|
||||
extern cvar_t *r_fullscreen;
|
||||
extern cvar_t *r_gamma;
|
||||
|
||||
|
||||
extern cvar_t *r_singleShader; // make most world faces use default shader
|
||||
extern cvar_t *r_colorMipLevels; // development aid to see texture mip usage
|
||||
extern cvar_t *r_picmip; // controls picmip values
|
||||
extern cvar_t *r_offsetFactor;
|
||||
extern cvar_t *r_offsetUnits;
|
||||
|
||||
extern cvar_t *r_fullbright; // avoid lightmap pass
|
||||
extern cvar_t *r_lightmap; // render lightmaps only
|
||||
extern cvar_t *r_vertexLight; // vertex lighting mode for better performance
|
||||
extern cvar_t *r_uiFullScreen; // ui is running fullscreen
|
||||
|
||||
extern cvar_t *r_showtris; // enables wireframe rendering of the world
|
||||
extern cvar_t *r_showsky; // forces sky in front of all surfaces
|
||||
extern cvar_t *r_shownormals; // draws wireframe normals
|
||||
extern cvar_t *r_clear; // force screen clear every frame
|
||||
|
||||
extern cvar_t *r_shadows; // controls shadows: 0 = none, 1 = blur, 2 = stencil, 3 = black planar projection
|
||||
|
||||
extern cvar_t *r_intensity;
|
||||
|
||||
extern cvar_t *r_lockpvs;
|
||||
extern cvar_t *r_noportals;
|
||||
extern cvar_t *r_portalOnly;
|
||||
|
||||
extern cvar_t *r_subdivisions;
|
||||
extern cvar_t *r_lodCurveError;
|
||||
|
||||
//extern cvar_t *r_overBrightBits;
|
||||
extern cvar_t *r_mapOverBrightBits;
|
||||
|
||||
extern cvar_t *r_debugSurface;
|
||||
extern cvar_t *r_simpleMipMaps;
|
||||
|
||||
extern cvar_t *r_showImages;
|
||||
extern cvar_t *r_debugSort;
|
||||
|
||||
extern cvar_t *r_printShaders;
|
||||
extern cvar_t *r_saveFontData;
|
||||
|
||||
|
||||
extern cvar_t *r_maxpolys;
|
||||
extern cvar_t *r_maxpolyverts;
|
||||
|
||||
|
||||
extern cvar_t *r_ambientScale;
|
||||
extern cvar_t *r_directedScale;
|
||||
extern cvar_t *r_debugLight;
|
||||
|
||||
extern cvar_t* r_allowResize; // make window resizable
|
||||
extern cvar_t* r_mode;
|
||||
extern cvar_t* r_fullscreen;
|
||||
extern cvar_t* r_displayRefresh;
|
||||
extern cvar_t* r_loadImgAPI;
|
||||
|
||||
void R_Register( void );
|
||||
|
||||
|
||||
|
||||
#endif
|
546
code/renderervk/tr_flares.c
Normal file
546
code/renderervk/tr_flares.c
Normal file
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_flares.c
|
||||
#include "ref_import.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
extern cvar_t* r_flares;
|
||||
|
||||
void RB_SurfaceFlare(srfFlare_t *surf)
|
||||
{
|
||||
if (r_flares->integer)
|
||||
{
|
||||
ri.Printf(PRINT_DEVELOPER, "I'm so weak, don't know how to implement this.\n");
|
||||
// RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LIGHT FLARES
|
||||
|
||||
A light flare is an effect that takes place inside the eye when bright light
|
||||
sources are visible. The size of the flare relative to the screen is nearly
|
||||
constant, irrespective of distance, but the intensity should be proportional to the
|
||||
projected area of the light source.
|
||||
|
||||
A surface that has been flagged as having a light flare will calculate the depth
|
||||
buffer value that its midpoint should have when the surface is added.
|
||||
|
||||
After all opaque surfaces have been rendered, the depth buffer is read back for
|
||||
each flare in view. If the point has not been obscured by a closer surface, the
|
||||
flare should be drawn.
|
||||
|
||||
Surfaces that have a repeated texture should never be flagged as flaring, because
|
||||
there will only be a single flare added at the midpoint of the polygon.
|
||||
|
||||
To prevent abrupt popping, the intensity of the flare is interpolated up and
|
||||
down as it changes visibility. This involves scene to scene state, unlike almost
|
||||
all other aspects of the renderer, and is complicated by the fact that a single
|
||||
frame may have multiple scenes.
|
||||
|
||||
RB_RenderFlares() will be called once per view (twice in a mirrored scene, potentially
|
||||
up to five or more times in a frame with 3D status bar icons).
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
|
||||
// flare states maintain visibility over multiple frames for fading
|
||||
// layers: view, mirror, menu
|
||||
/*
|
||||
|
||||
typedef struct flare_s {
|
||||
struct flare_s *next; // for active chain
|
||||
|
||||
int addedFrame;
|
||||
|
||||
qboolean inPortal; // true if in a portal view of the scene
|
||||
int frameSceneNum;
|
||||
void *surface;
|
||||
int fogNum;
|
||||
|
||||
int fadeTime;
|
||||
|
||||
qboolean visible; // state of last test
|
||||
float drawIntensity; // may be non 0 even if !visible due to fading
|
||||
|
||||
int windowX, windowY;
|
||||
float eyeZ;
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t color;
|
||||
} flare_t;
|
||||
|
||||
#define MAX_FLARES 256
|
||||
|
||||
flare_t r_flareStructs[MAX_FLARES];
|
||||
flare_t *r_activeFlares, *r_inactiveFlares;
|
||||
|
||||
int flareCoeff;
|
||||
|
||||
|
||||
==================
|
||||
R_SetFlareCoeff
|
||||
==================
|
||||
|
||||
static void R_SetFlareCoeff( void ) {
|
||||
|
||||
if(r_flareCoeff->value == 0.0f)
|
||||
flareCoeff = atof(FLARE_STDCOEFF);
|
||||
else
|
||||
flareCoeff = r_flareCoeff->value;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
==================
|
||||
R_ClearFlares
|
||||
==================
|
||||
|
||||
void R_ClearFlares( void ) {
|
||||
int i;
|
||||
|
||||
memset( r_flareStructs, 0, sizeof( r_flareStructs ) );
|
||||
r_activeFlares = NULL;
|
||||
r_inactiveFlares = NULL;
|
||||
|
||||
for ( i = 0 ; i < MAX_FLARES ; i++ ) {
|
||||
r_flareStructs[i].next = r_inactiveFlares;
|
||||
r_inactiveFlares = &r_flareStructs[i];
|
||||
}
|
||||
|
||||
R_SetFlareCoeff();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
RB_AddFlare
|
||||
|
||||
This is called at surface tesselation time
|
||||
==================
|
||||
|
||||
void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t normal ) {
|
||||
int i;
|
||||
flare_t *f;
|
||||
vec3_t local;
|
||||
float d = 1;
|
||||
vec4_t eye, clip, normalized, window;
|
||||
|
||||
backEnd.pc.c_flareAdds++;
|
||||
|
||||
if(normal && (normal[0] || normal[1] || normal[2]))
|
||||
{
|
||||
VectorSubtract( backEnd.viewParms.or.origin, point, local );
|
||||
FastNormalize1f(local);
|
||||
d = DotProduct(local, normal);
|
||||
|
||||
// If the viewer is behind the flare don't add it.
|
||||
if(d < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// if the point is off the screen, don't bother adding it
|
||||
// calculate screen coordinates and depth
|
||||
R_TransformModelToClip( point, backEnd.or.modelMatrix,
|
||||
backEnd.viewParms.projectionMatrix, eye, clip );
|
||||
|
||||
// check to see if the point is completely off screen
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
if ( clip[i] >= clip[3] || clip[i] <= -clip[3] ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
R_TransformClipToWindow( clip, &backEnd.viewParms, normalized, window );
|
||||
|
||||
if ( window[0] < 0 || window[0] >= backEnd.viewParms.viewportWidth
|
||||
|| window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight ) {
|
||||
return; // shouldn't happen, since we check the clip[] above, except for FP rounding
|
||||
}
|
||||
|
||||
// see if a flare with a matching surface, scene, and view exists
|
||||
for ( f = r_activeFlares ; f ; f = f->next ) {
|
||||
if ( f->surface == surface && f->frameSceneNum == backEnd.viewParms.frameSceneNum
|
||||
&& f->inPortal == backEnd.viewParms.isPortal ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate a new one
|
||||
if (!f ) {
|
||||
if ( !r_inactiveFlares ) {
|
||||
// the list is completely full
|
||||
return;
|
||||
}
|
||||
f = r_inactiveFlares;
|
||||
r_inactiveFlares = r_inactiveFlares->next;
|
||||
f->next = r_activeFlares;
|
||||
r_activeFlares = f;
|
||||
|
||||
f->surface = surface;
|
||||
f->frameSceneNum = backEnd.viewParms.frameSceneNum;
|
||||
f->inPortal = backEnd.viewParms.isPortal;
|
||||
f->addedFrame = -1;
|
||||
}
|
||||
|
||||
if ( f->addedFrame != backEnd.viewParms.frameCount - 1 ) {
|
||||
f->visible = qfalse;
|
||||
f->fadeTime = backEnd.refdef.time - 2000;
|
||||
}
|
||||
|
||||
f->addedFrame = backEnd.viewParms.frameCount;
|
||||
f->fogNum = fogNum;
|
||||
|
||||
VectorCopy(point, f->origin);
|
||||
VectorCopy( color, f->color );
|
||||
|
||||
// fade the intensity of the flare down as the
|
||||
// light surface turns away from the viewer
|
||||
VectorScale( f->color, d, f->color );
|
||||
|
||||
// save info needed to test
|
||||
f->windowX = backEnd.viewParms.viewportX + window[0];
|
||||
f->windowY = backEnd.viewParms.viewportY + window[1];
|
||||
|
||||
f->eyeZ = eye[2];
|
||||
}
|
||||
*/
|
||||
/*
|
||||
==================
|
||||
RB_AddDlightFlares
|
||||
==================
|
||||
|
||||
void RB_AddDlightFlares( void ) {
|
||||
dlight_t *l;
|
||||
int i, j, k;
|
||||
fog_t *fog = NULL;
|
||||
|
||||
if ( !r_flares->integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
l = backEnd.refdef.dlights;
|
||||
|
||||
if(tr.world)
|
||||
fog = tr.world->fogs;
|
||||
|
||||
for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) {
|
||||
|
||||
if(fog)
|
||||
{
|
||||
// find which fog volume the light is in
|
||||
for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
|
||||
fog = &tr.world->fogs[j];
|
||||
for ( k = 0 ; k < 3 ; k++ ) {
|
||||
if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( k == 3 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == tr.world->numfogs ) {
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
j = 0;
|
||||
|
||||
RB_AddFlare( (void *)l, j, l->origin, l->color, NULL );
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
FLARE BACK END
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
RB_TestFlare
|
||||
==================
|
||||
|
||||
void RB_TestFlare( flare_t *f ) {
|
||||
float depth;
|
||||
qboolean visible;
|
||||
float fade;
|
||||
float screenZ;
|
||||
|
||||
backEnd.pc.c_flareTests++;
|
||||
|
||||
// doing a readpixels is as good as doing a glFinish(), so
|
||||
// don't bother with another sync
|
||||
glState.finishCalled = qfalse;
|
||||
|
||||
// read back the z buffer contents
|
||||
qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
|
||||
|
||||
screenZ = backEnd.viewParms.projectionMatrix[14] /
|
||||
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
|
||||
|
||||
visible = ( -f->eyeZ - -screenZ ) < 24;
|
||||
|
||||
if ( visible ) {
|
||||
if ( !f->visible ) {
|
||||
f->visible = qtrue;
|
||||
f->fadeTime = backEnd.refdef.time - 1;
|
||||
}
|
||||
fade = ( ( backEnd.refdef.time - f->fadeTime ) /1000.0f ) * r_flareFade->value;
|
||||
} else {
|
||||
if ( f->visible ) {
|
||||
f->visible = qfalse;
|
||||
f->fadeTime = backEnd.refdef.time - 1;
|
||||
}
|
||||
fade = 1.0f - ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
|
||||
}
|
||||
|
||||
if ( fade < 0 ) {
|
||||
fade = 0;
|
||||
}
|
||||
if ( fade > 1 ) {
|
||||
fade = 1;
|
||||
}
|
||||
|
||||
f->drawIntensity = fade;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an alternative to intensity scaling. It changes the size of the flare on screen instead
|
||||
* with growing distance. See in the description at the top why this is not the way to go.
|
||||
// size will change ~ 1/r.
|
||||
size = backEnd.viewParms.viewportWidth * (r_flareSize->value / (distance * -2.0f));
|
||||
*/
|
||||
|
||||
/*
|
||||
* As flare sizes stay nearly constant with increasing distance we must decrease the intensity
|
||||
* to achieve a reasonable visual result. The intensity is ~ (size^2 / distance^2) which can be
|
||||
* got by considering the ratio of
|
||||
* (flaresurface on screen) : (Surface of sphere defined by flare origin and distance from flare)
|
||||
* An important requirement is:
|
||||
* intensity <= 1 for all distances.
|
||||
*
|
||||
* The formula used here to compute the intensity is as follows:
|
||||
* intensity = flareCoeff * size^2 / (distance + size*sqrt(flareCoeff))^2
|
||||
* As you can see, the intensity will have a max. of 1 when the distance is 0.
|
||||
* The coefficient flareCoeff will determine the falloff speed with increasing distance.
|
||||
|
||||
void RB_RenderFlare( flare_t *f ) {
|
||||
float size;
|
||||
vec3_t color;
|
||||
int iColor[3];
|
||||
float distance, intensity, factor;
|
||||
byte fogFactors[3] = {255, 255, 255};
|
||||
|
||||
backEnd.pc.c_flareRenders++;
|
||||
|
||||
// We don't want too big values anyways when dividing by distance.
|
||||
if(f->eyeZ > -1.0f)
|
||||
distance = 1.0f;
|
||||
else
|
||||
distance = -f->eyeZ;
|
||||
|
||||
// calculate the flare size..
|
||||
size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / distance );
|
||||
|
||||
|
||||
|
||||
factor = distance + size * sqrt(flareCoeff);
|
||||
|
||||
intensity = flareCoeff * size * size / (factor * factor);
|
||||
|
||||
VectorScale(f->color, f->drawIntensity * intensity, color);
|
||||
|
||||
// Calculations for fogging
|
||||
if(tr.world && f->fogNum > 0 && f->fogNum < tr.world->numfogs)
|
||||
{
|
||||
tess.numVertexes = 1;
|
||||
VectorCopy(f->origin, tess.xyz[0]);
|
||||
tess.fogNum = f->fogNum;
|
||||
|
||||
RB_CalcModulateColorsByFog(fogFactors);
|
||||
|
||||
// We don't need to render the flare if colors are 0 anyways.
|
||||
if(!(fogFactors[0] || fogFactors[1] || fogFactors[2]))
|
||||
return;
|
||||
}
|
||||
|
||||
iColor[0] = color[0] * fogFactors[0];
|
||||
iColor[1] = color[1] * fogFactors[1];
|
||||
iColor[2] = color[2] * fogFactors[2];
|
||||
|
||||
RB_BeginSurface( tr.flareShader, f->fogNum );
|
||||
|
||||
// FIXME: use quadstamp?
|
||||
tess.xyz[tess.numVertexes][0] = f->windowX - size;
|
||||
tess.xyz[tess.numVertexes][1] = f->windowY - size;
|
||||
tess.texCoords[tess.numVertexes][0][0] = 0;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 0;
|
||||
tess.vertexColors[tess.numVertexes][0] = iColor[0];
|
||||
tess.vertexColors[tess.numVertexes][1] = iColor[1];
|
||||
tess.vertexColors[tess.numVertexes][2] = iColor[2];
|
||||
tess.vertexColors[tess.numVertexes][3] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
tess.xyz[tess.numVertexes][0] = f->windowX - size;
|
||||
tess.xyz[tess.numVertexes][1] = f->windowY + size;
|
||||
tess.texCoords[tess.numVertexes][0][0] = 0;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 1;
|
||||
tess.vertexColors[tess.numVertexes][0] = iColor[0];
|
||||
tess.vertexColors[tess.numVertexes][1] = iColor[1];
|
||||
tess.vertexColors[tess.numVertexes][2] = iColor[2];
|
||||
tess.vertexColors[tess.numVertexes][3] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
tess.xyz[tess.numVertexes][0] = f->windowX + size;
|
||||
tess.xyz[tess.numVertexes][1] = f->windowY + size;
|
||||
tess.texCoords[tess.numVertexes][0][0] = 1;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 1;
|
||||
tess.vertexColors[tess.numVertexes][0] = iColor[0];
|
||||
tess.vertexColors[tess.numVertexes][1] = iColor[1];
|
||||
tess.vertexColors[tess.numVertexes][2] = iColor[2];
|
||||
tess.vertexColors[tess.numVertexes][3] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
tess.xyz[tess.numVertexes][0] = f->windowX + size;
|
||||
tess.xyz[tess.numVertexes][1] = f->windowY - size;
|
||||
tess.texCoords[tess.numVertexes][0][0] = 1;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 0;
|
||||
tess.vertexColors[tess.numVertexes][0] = iColor[0];
|
||||
tess.vertexColors[tess.numVertexes][1] = iColor[1];
|
||||
tess.vertexColors[tess.numVertexes][2] = iColor[2];
|
||||
tess.vertexColors[tess.numVertexes][3] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
tess.indexes[tess.numIndexes++] = 0;
|
||||
tess.indexes[tess.numIndexes++] = 1;
|
||||
tess.indexes[tess.numIndexes++] = 2;
|
||||
tess.indexes[tess.numIndexes++] = 0;
|
||||
tess.indexes[tess.numIndexes++] = 2;
|
||||
tess.indexes[tess.numIndexes++] = 3;
|
||||
|
||||
RB_EndSurface();
|
||||
}
|
||||
*/
|
||||
/*
|
||||
==================
|
||||
RB_RenderFlares
|
||||
|
||||
Because flares are simulating an occular effect, they should be drawn after
|
||||
everything (all views) in the entire frame has been drawn.
|
||||
|
||||
Because of the way portals use the depth buffer to mark off areas, the
|
||||
needed information would be lost after each view, so we are forced to draw
|
||||
flares after each view.
|
||||
|
||||
The resulting artifact is that flares in mirrors or portals don't dim properly
|
||||
when occluded by something in the main view, and portal flares that should
|
||||
extend past the portal edge will be overwritten.
|
||||
==================
|
||||
|
||||
void RB_RenderFlares (void)
|
||||
{
|
||||
flare_t *f;
|
||||
flare_t **prev;
|
||||
qboolean draw;
|
||||
|
||||
if(r_flareCoeff->modified)
|
||||
{
|
||||
R_SetFlareCoeff();
|
||||
r_flareCoeff->modified = qfalse;
|
||||
}
|
||||
|
||||
// Reset currentEntity to world so that any previously referenced entities
|
||||
// don't have influence on the rendering of these flares (i.e. RF_ renderer flags).
|
||||
backEnd.currentEntity = &tr.worldEntity;
|
||||
backEnd.or = backEnd.viewParms.world;
|
||||
|
||||
// RB_AddDlightFlares();
|
||||
|
||||
// perform z buffer readback on each flare in this view
|
||||
draw = qfalse;
|
||||
prev = &r_activeFlares;
|
||||
while ( ( f = *prev ) != NULL ) {
|
||||
// throw out any flares that weren't added last frame
|
||||
if ( f->addedFrame < backEnd.viewParms.frameCount - 1 ) {
|
||||
*prev = f->next;
|
||||
f->next = r_inactiveFlares;
|
||||
r_inactiveFlares = f;
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't draw any here that aren't from this scene / portal
|
||||
f->drawIntensity = 0;
|
||||
if ( f->frameSceneNum == backEnd.viewParms.frameSceneNum
|
||||
&& f->inPortal == backEnd.viewParms.isPortal ) {
|
||||
RB_TestFlare( f );
|
||||
if ( f->drawIntensity ) {
|
||||
draw = qtrue;
|
||||
} else {
|
||||
// this flare has completely faded out, so remove it from the chain
|
||||
*prev = f->next;
|
||||
f->next = r_inactiveFlares;
|
||||
r_inactiveFlares = f;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
prev = &f->next;
|
||||
}
|
||||
|
||||
if ( !draw ) {
|
||||
return; // none visible
|
||||
}
|
||||
|
||||
if ( backEnd.viewParms.isPortal ) {
|
||||
qglDisable (GL_CLIP_PLANE0);
|
||||
}
|
||||
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity();
|
||||
qglMatrixMode( GL_PROJECTION );
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity();
|
||||
qglOrtho( backEnd.viewParms.viewportX, backEnd.viewParms.viewportX + backEnd.viewParms.viewportWidth,
|
||||
backEnd.viewParms.viewportY, backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight,
|
||||
-99999, 99999 );
|
||||
|
||||
for ( f = r_activeFlares ; f ; f = f->next ) {
|
||||
if ( f->frameSceneNum == backEnd.viewParms.frameSceneNum
|
||||
&& f->inPortal == backEnd.viewParms.isPortal
|
||||
&& f->drawIntensity ) {
|
||||
RB_RenderFlare( f );
|
||||
}
|
||||
}
|
||||
|
||||
qglPopMatrix();
|
||||
qglMatrixMode( GL_MODELVIEW );
|
||||
qglPopMatrix();
|
||||
}
|
||||
*/
|
8
code/renderervk/tr_flares.h
Normal file
8
code/renderervk/tr_flares.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef TR_FLARE_H_
|
||||
#define TR_FLARE_H_
|
||||
|
||||
|
||||
void RB_SurfaceFlare(srfFlare_t *surf);
|
||||
|
||||
|
||||
#endif
|
53
code/renderervk/tr_fog.c
Normal file
53
code/renderervk/tr_fog.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include "tr_fog.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define FOG_TABLE_SIZE 256
|
||||
|
||||
static float FogTable[FOG_TABLE_SIZE];
|
||||
|
||||
|
||||
void R_InitFogTable( void )
|
||||
{
|
||||
float exp = 0.5;
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0 ; i < FOG_TABLE_SIZE ; i++ )
|
||||
{
|
||||
FogTable[i] = pow ( (float)i/(FOG_TABLE_SIZE-1), exp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Returns a 0.0 to 1.0 fog density value
|
||||
This is called for each texel of the fog texture on startup
|
||||
and for each vertex of transparent shaders in fog dynamically
|
||||
================
|
||||
*/
|
||||
float R_FogFactor( float s, float t )
|
||||
{
|
||||
s -= 1.0/512;
|
||||
if ( s < 0 ) {
|
||||
return 0;
|
||||
}
|
||||
if ( t < 1.0/32 ) {
|
||||
return 0;
|
||||
}
|
||||
if ( t < 31.0/32 ) {
|
||||
s *= (t - 1.0f/32.0f) / (30.0f/32.0f);
|
||||
}
|
||||
|
||||
// we need to leave a lot of clamp range
|
||||
s *= 8;
|
||||
|
||||
if ( s > 1.0 ) {
|
||||
s = 1.0;
|
||||
}
|
||||
|
||||
float d = FogTable[ (int)(s * (FOG_TABLE_SIZE-1)) ];
|
||||
|
||||
return d;
|
||||
}
|
9
code/renderervk/tr_fog.h
Normal file
9
code/renderervk/tr_fog.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef TR_FOG_H_
|
||||
#define TR_FOG_H_
|
||||
|
||||
|
||||
void R_InitFogTable( void );
|
||||
float R_FogFactor( float s, float t );
|
||||
|
||||
|
||||
#endif
|
577
code/renderervk/tr_fonts.c
Normal file
577
code/renderervk/tr_fonts.c
Normal file
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_font.c
|
||||
//
|
||||
//
|
||||
// The font system uses FreeType 2.x to render TrueType fonts for use within the game.
|
||||
// As of this writing ( Nov, 2000 ) Team Arena uses these fonts for all of the ui and
|
||||
// about 90% of the cgame presentation. A few areas of the CGAME were left uses the old
|
||||
// fonts since the code is shared with standard Q3A.
|
||||
//
|
||||
// If you include this font rendering code in a commercial product you MUST include the
|
||||
// following somewhere with your product, see www.freetype.org for specifics or changes.
|
||||
// The Freetype code also uses some hinting techniques that MIGHT infringe on patents
|
||||
// held by apple so be aware of that also.
|
||||
//
|
||||
// As of Q3A 1.25+ and Team Arena, we are shipping the game with the font rendering code
|
||||
// disabled. This removes any potential patent issues and it keeps us from having to
|
||||
// distribute an actual TrueTrype font which is 1. expensive to do and 2. seems to require
|
||||
// an act of god to accomplish.
|
||||
//
|
||||
// What we did was pre-render the fonts using FreeType ( which is why we leave the FreeType
|
||||
// credit in the credits ) and then saved off the glyph data and then hand touched up the
|
||||
// font bitmaps so they scale a bit better in GL.
|
||||
//
|
||||
// There are limitations in the way fonts are saved and reloaded in that it is based on
|
||||
// point size and not name. So if you pre-render Helvetica in 18 point and Impact in 18 point
|
||||
// you will end up with a single 18 point data file and image set. Typically you will want to
|
||||
// choose 3 sizes to best approximate the scaling you will be doing in the ui scripting system
|
||||
//
|
||||
// In the UI Scripting code, a scale of 1.0 is equal to a 48 point font. In Team Arena, we
|
||||
// use three or four scales, most of them exactly equaling the specific rendered size. We
|
||||
// rendered three sizes in Team Arena, 12, 16, and 20.
|
||||
//
|
||||
// To generate new font data you need to go through the following steps.
|
||||
// 1. delete the fontImage_x_xx.tga files and fontImage_xx.dat files from the fonts path.
|
||||
// 2. in a ui script, specificy a font, smallFont, and bigFont keyword with font name and
|
||||
// point size. the original TrueType fonts must exist in fonts at this point.
|
||||
// 3. run the game, you should see things normally.
|
||||
// 4. Exit the game and there will be three dat files and at least three tga files. The
|
||||
// tga's are in 256x256 pages so if it takes three images to render a 24 point font you
|
||||
// will end up with fontImage_0_24.tga through fontImage_2_24.tga
|
||||
// 5. In future runs of the game, the system looks for these images and data files when a s
|
||||
// specific point sized font is rendered and loads them for use.
|
||||
// 6. Because of the original beta nature of the FreeType code you will probably want to hand
|
||||
// touch the font bitmaps.
|
||||
//
|
||||
// Currently a define in the project turns on or off the FreeType code which is currently
|
||||
// defined out. To pre-render new fonts you need enable the define ( BUILD_FREETYPE ) and
|
||||
// uncheck the exclude from build check box in the FreeType2 area of the Renderer project.
|
||||
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "ref_import.h"
|
||||
#include "tr_cvar.h"
|
||||
|
||||
|
||||
|
||||
#ifdef BUILD_FREETYPE
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_ERRORS_H
|
||||
#include FT_SYSTEM_H
|
||||
#include FT_IMAGE_H
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
#define _FLOOR(x) ((x) & -64)
|
||||
#define _CEIL(x) (((x)+63) & -64)
|
||||
#define _TRUNC(x) ((x) >> 6)
|
||||
|
||||
FT_Library ftLibrary = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
qhandle_t R_RegisterShaderFromImage(const char *name, int lightmapIndex, image_t *image, qboolean mipRawImage);
|
||||
qhandle_t RE_RegisterShaderNoMip( const char *name );
|
||||
|
||||
#define MAX_FONTS 6
|
||||
static int registeredFontCount = 0;
|
||||
static fontInfo_t registeredFont[MAX_FONTS];
|
||||
|
||||
|
||||
#ifdef BUILD_FREETYPE
|
||||
void R_GetGlyphInfo(FT_GlyphSlot glyph, int *left, int *right, int *width, int *top, int *bottom, int *height, int *pitch) {
|
||||
*left = _FLOOR( glyph->metrics.horiBearingX );
|
||||
*right = _CEIL( glyph->metrics.horiBearingX + glyph->metrics.width );
|
||||
*width = _TRUNC(*right - *left);
|
||||
|
||||
*top = _CEIL( glyph->metrics.horiBearingY );
|
||||
*bottom = _FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height );
|
||||
*height = _TRUNC( *top - *bottom );
|
||||
*pitch = ( qtrue ? (*width+3) & -4 : (*width+7) >> 3 );
|
||||
}
|
||||
|
||||
|
||||
FT_Bitmap *R_RenderGlyph(FT_GlyphSlot glyph, glyphInfo_t* glyphOut) {
|
||||
FT_Bitmap *bit2;
|
||||
int left, right, width, top, bottom, height, pitch, size;
|
||||
|
||||
R_GetGlyphInfo(glyph, &left, &right, &width, &top, &bottom, &height, &pitch);
|
||||
|
||||
if ( glyph->format == ft_glyph_format_outline ) {
|
||||
size = pitch*height;
|
||||
|
||||
bit2 = ri.Malloc(sizeof(FT_Bitmap));
|
||||
|
||||
bit2->width = width;
|
||||
bit2->rows = height;
|
||||
bit2->pitch = pitch;
|
||||
bit2->pixel_mode = ft_pixel_mode_grays;
|
||||
//bit2->pixel_mode = ft_pixel_mode_mono;
|
||||
bit2->buffer = ri.Malloc(pitch*height);
|
||||
bit2->num_grays = 256;
|
||||
|
||||
memset( bit2->buffer, 0, size );
|
||||
|
||||
FT_Outline_Translate( &glyph->outline, -left, -bottom );
|
||||
|
||||
FT_Outline_Get_Bitmap( ftLibrary, &glyph->outline, bit2 );
|
||||
|
||||
glyphOut->height = height;
|
||||
glyphOut->pitch = pitch;
|
||||
glyphOut->top = (glyph->metrics.horiBearingY >> 6) + 1;
|
||||
glyphOut->bottom = bottom;
|
||||
|
||||
return bit2;
|
||||
} else {
|
||||
ri.Printf(PRINT_ALL, "Non-outline fonts are not supported\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void WriteTGA (char *filename, byte *data, int width, int height) {
|
||||
byte *buffer;
|
||||
int i, c;
|
||||
int row;
|
||||
unsigned char *flip;
|
||||
unsigned char *src, *dst;
|
||||
|
||||
buffer = ri.Malloc(width*height*4 + 18);
|
||||
memset (buffer, 0, 18);
|
||||
buffer[2] = 2; // uncompressed type
|
||||
buffer[12] = width&255;
|
||||
buffer[13] = width>>8;
|
||||
buffer[14] = height&255;
|
||||
buffer[15] = height>>8;
|
||||
buffer[16] = 32; // pixel size
|
||||
|
||||
// swap rgb to bgr
|
||||
c = 18 + width * height * 4;
|
||||
for (i=18 ; i<c ; i+=4)
|
||||
{
|
||||
buffer[i] = data[i-18+2]; // blue
|
||||
buffer[i+1] = data[i-18+1]; // green
|
||||
buffer[i+2] = data[i-18+0]; // red
|
||||
buffer[i+3] = data[i-18+3]; // alpha
|
||||
}
|
||||
|
||||
// flip upside down
|
||||
flip = (unsigned char *)ri.Malloc(width*4);
|
||||
for(row = 0; row < height/2; row++)
|
||||
{
|
||||
src = buffer + 18 + row * 4 * width;
|
||||
dst = buffer + 18 + (height - row - 1) * 4 * width;
|
||||
|
||||
memcpy(flip, src, width*4);
|
||||
memcpy(src, dst, width*4);
|
||||
memcpy(dst, flip, width*4);
|
||||
}
|
||||
ri.Free(flip);
|
||||
|
||||
ri.FS_WriteFile(filename, buffer, c);
|
||||
|
||||
//f = fopen (filename, "wb");
|
||||
//fwrite (buffer, 1, c, f);
|
||||
//fclose (f);
|
||||
|
||||
ri.Free (buffer);
|
||||
}
|
||||
|
||||
static glyphInfo_t *RE_ConstructGlyphInfo(unsigned char *imageOut, int *xOut, int *yOut, int *maxHeight, FT_Face face, const unsigned char c, qboolean calcHeight) {
|
||||
int i;
|
||||
static glyphInfo_t glyph;
|
||||
unsigned char *src, *dst;
|
||||
float scaled_width, scaled_height;
|
||||
FT_Bitmap *bitmap = NULL;
|
||||
|
||||
memset(&glyph, 0, sizeof(glyphInfo_t));
|
||||
// make sure everything is here
|
||||
if (face != NULL) {
|
||||
FT_Load_Glyph(face, FT_Get_Char_Index( face, c), FT_LOAD_DEFAULT );
|
||||
bitmap = R_RenderGlyph(face->glyph, &glyph);
|
||||
if (bitmap) {
|
||||
glyph.xSkip = (face->glyph->metrics.horiAdvance >> 6) + 1;
|
||||
} else {
|
||||
return &glyph;
|
||||
}
|
||||
|
||||
if (glyph.height > *maxHeight) {
|
||||
*maxHeight = glyph.height;
|
||||
}
|
||||
|
||||
if (calcHeight) {
|
||||
ri.Free(bitmap->buffer);
|
||||
ri.Free(bitmap);
|
||||
return &glyph;
|
||||
}
|
||||
|
||||
/*
|
||||
// need to convert to power of 2 sizes so we do not get
|
||||
// any scaling from the gl upload
|
||||
for (scaled_width = 1 ; scaled_width < glyph.pitch ; scaled_width<<=1)
|
||||
;
|
||||
for (scaled_height = 1 ; scaled_height < glyph.height ; scaled_height<<=1)
|
||||
;
|
||||
*/
|
||||
|
||||
scaled_width = glyph.pitch;
|
||||
scaled_height = glyph.height;
|
||||
|
||||
// we need to make sure we fit
|
||||
if (*xOut + scaled_width + 1 >= 255) {
|
||||
*xOut = 0;
|
||||
*yOut += *maxHeight + 1;
|
||||
}
|
||||
|
||||
if (*yOut + *maxHeight + 1 >= 255) {
|
||||
*yOut = -1;
|
||||
*xOut = -1;
|
||||
ri.Free(bitmap->buffer);
|
||||
ri.Free(bitmap);
|
||||
return &glyph;
|
||||
}
|
||||
|
||||
|
||||
src = bitmap->buffer;
|
||||
dst = imageOut + (*yOut * 256) + *xOut;
|
||||
|
||||
if (bitmap->pixel_mode == ft_pixel_mode_mono) {
|
||||
for (i = 0; i < glyph.height; i++) {
|
||||
int j;
|
||||
unsigned char *_src = src;
|
||||
unsigned char *_dst = dst;
|
||||
unsigned char mask = 0x80;
|
||||
unsigned char val = *_src;
|
||||
for (j = 0; j < glyph.pitch; j++) {
|
||||
if (mask == 0x80) {
|
||||
val = *_src++;
|
||||
}
|
||||
if (val & mask) {
|
||||
*_dst = 0xff;
|
||||
}
|
||||
mask >>= 1;
|
||||
|
||||
if ( mask == 0 ) {
|
||||
mask = 0x80;
|
||||
}
|
||||
_dst++;
|
||||
}
|
||||
|
||||
src += glyph.pitch;
|
||||
dst += 256;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < glyph.height; i++) {
|
||||
memcpy(dst, src, glyph.pitch);
|
||||
src += glyph.pitch;
|
||||
dst += 256;
|
||||
}
|
||||
}
|
||||
|
||||
// we now have an 8 bit per pixel grey scale bitmap
|
||||
// that is width wide and pf->ftSize->metrics.y_ppem tall
|
||||
|
||||
glyph.imageHeight = scaled_height;
|
||||
glyph.imageWidth = scaled_width;
|
||||
glyph.s = (float)*xOut / 256;
|
||||
glyph.t = (float)*yOut / 256;
|
||||
glyph.s2 = glyph.s + (float)scaled_width / 256;
|
||||
glyph.t2 = glyph.t + (float)scaled_height / 256;
|
||||
|
||||
*xOut += scaled_width + 1;
|
||||
|
||||
ri.Free(bitmap->buffer);
|
||||
ri.Free(bitmap);
|
||||
}
|
||||
|
||||
return &glyph;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int fdOffset;
|
||||
static byte *fdFile;
|
||||
|
||||
int readInt( void ) {
|
||||
int i = fdFile[fdOffset]+(fdFile[fdOffset+1]<<8)+(fdFile[fdOffset+2]<<16)+(fdFile[fdOffset+3]<<24);
|
||||
fdOffset += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
typedef union {
|
||||
byte fred[4];
|
||||
float ffred;
|
||||
} poor;
|
||||
|
||||
float readFloat( void ) {
|
||||
poor me;
|
||||
#if defined Q3_BIG_ENDIAN
|
||||
me.fred[0] = fdFile[fdOffset+3];
|
||||
me.fred[1] = fdFile[fdOffset+2];
|
||||
me.fred[2] = fdFile[fdOffset+1];
|
||||
me.fred[3] = fdFile[fdOffset+0];
|
||||
#elif defined Q3_LITTLE_ENDIAN
|
||||
me.fred[0] = fdFile[fdOffset+0];
|
||||
me.fred[1] = fdFile[fdOffset+1];
|
||||
me.fred[2] = fdFile[fdOffset+2];
|
||||
me.fred[3] = fdFile[fdOffset+3];
|
||||
#endif
|
||||
fdOffset += 4;
|
||||
return me.ffred;
|
||||
}
|
||||
|
||||
|
||||
void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font)
|
||||
{
|
||||
#ifdef BUILD_FREETYPE
|
||||
FT_Face face;
|
||||
int j, k, xOut, yOut, lastStart, imageNumber;
|
||||
int scaledSize, newSize, maxHeight, left;
|
||||
unsigned char *out, *imageBuff;
|
||||
glyphInfo_t *glyph;
|
||||
image_t *image;
|
||||
qhandle_t h;
|
||||
float max;
|
||||
float dpi = 72;
|
||||
float glyphScale;
|
||||
#endif
|
||||
char *faceData;
|
||||
int i;
|
||||
char name[1024];
|
||||
|
||||
if (!fontName) {
|
||||
ri.Printf(PRINT_ALL, "RE_RegisterFont: called with empty name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pointSize <= 0) {
|
||||
pointSize = 12;
|
||||
}
|
||||
|
||||
|
||||
if (registeredFontCount >= MAX_FONTS) {
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: Too many fonts registered already.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "fonts/fontImage_%i.dat",pointSize);
|
||||
for (i = 0; i < registeredFontCount; i++) {
|
||||
if (Q_stricmp(name, registeredFont[i].name) == 0) {
|
||||
memcpy(font, ®isteredFont[i], sizeof(fontInfo_t));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int len = ri.FS_ReadFile(name, NULL);
|
||||
if (len == sizeof(fontInfo_t)) {
|
||||
ri.FS_ReadFile(name, (void**)&faceData);
|
||||
fdOffset = 0;
|
||||
fdFile = (unsigned char*)faceData;
|
||||
for(i=0; i<GLYPHS_PER_FONT; i++) {
|
||||
font->glyphs[i].height = readInt();
|
||||
font->glyphs[i].top = readInt();
|
||||
font->glyphs[i].bottom = readInt();
|
||||
font->glyphs[i].pitch = readInt();
|
||||
font->glyphs[i].xSkip = readInt();
|
||||
font->glyphs[i].imageWidth = readInt();
|
||||
font->glyphs[i].imageHeight = readInt();
|
||||
font->glyphs[i].s = readFloat();
|
||||
font->glyphs[i].t = readFloat();
|
||||
font->glyphs[i].s2 = readFloat();
|
||||
font->glyphs[i].t2 = readFloat();
|
||||
font->glyphs[i].glyph = readInt();
|
||||
Q_strncpyz(font->glyphs[i].shaderName, (const char *)&fdFile[fdOffset], sizeof(font->glyphs[i].shaderName));
|
||||
fdOffset += sizeof(font->glyphs[i].shaderName);
|
||||
}
|
||||
font->glyphScale = readFloat();
|
||||
memcpy(font->name, &fdFile[fdOffset], MAX_QPATH);
|
||||
|
||||
// memcpy(font, faceData, sizeof(fontInfo_t));
|
||||
Q_strncpyz(font->name, name, sizeof(font->name));
|
||||
for (i = GLYPH_START; i <= GLYPH_END; i++) {
|
||||
font->glyphs[i].glyph = RE_RegisterShaderNoMip(font->glyphs[i].shaderName);
|
||||
}
|
||||
memcpy(®isteredFont[registeredFontCount++], font, sizeof(fontInfo_t));
|
||||
ri.FS_FreeFile(faceData);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef BUILD_FREETYPE
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: FreeType code not available\n");
|
||||
#else
|
||||
if (ftLibrary == NULL) {
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: FreeType not initialized.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
len = ri.FS_ReadFile(fontName, &faceData);
|
||||
if (len <= 0) {
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: Unable to read font file '%s'\n", fontName);
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate on the stack first in case we fail
|
||||
if (FT_New_Memory_Face( ftLibrary, faceData, len, 0, &face )) {
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: FreeType, unable to allocate new face.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (FT_Set_Char_Size( face, pointSize << 6, pointSize << 6, dpi, dpi)) {
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: FreeType, unable to set face char size.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//*font = ®isteredFonts[registeredFontCount++];
|
||||
|
||||
// make a 256x256 image buffer, once it is full, register it, clean it and keep going
|
||||
// until all glyphs are rendered
|
||||
|
||||
out = ri.Malloc(256*256);
|
||||
if (out == NULL) {
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: ri.Malloc failure during output image creation.\n");
|
||||
return;
|
||||
}
|
||||
memset(out, 0, 256*256);
|
||||
|
||||
maxHeight = 0;
|
||||
|
||||
for (i = GLYPH_START; i <= GLYPH_END; i++) {
|
||||
RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qtrue);
|
||||
}
|
||||
|
||||
xOut = 0;
|
||||
yOut = 0;
|
||||
i = GLYPH_START;
|
||||
lastStart = i;
|
||||
imageNumber = 0;
|
||||
|
||||
while ( i <= GLYPH_END + 1 ) {
|
||||
|
||||
if ( i == GLYPH_END + 1 ) {
|
||||
// upload/save current image buffer
|
||||
xOut = yOut = -1;
|
||||
} else {
|
||||
glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qfalse);
|
||||
}
|
||||
|
||||
if (xOut == -1 || yOut == -1) {
|
||||
// ran out of room
|
||||
// we need to create an image from the bitmap, set all the handles in the glyphs to this point
|
||||
//
|
||||
|
||||
scaledSize = 256*256;
|
||||
newSize = scaledSize * 4;
|
||||
imageBuff = ri.Malloc(newSize);
|
||||
left = 0;
|
||||
max = 0;
|
||||
for ( k = 0; k < (scaledSize) ; k++ ) {
|
||||
if (max < out[k]) {
|
||||
max = out[k];
|
||||
}
|
||||
}
|
||||
|
||||
if (max > 0) {
|
||||
max = 255/max;
|
||||
}
|
||||
|
||||
for ( k = 0; k < (scaledSize) ; k++ ) {
|
||||
imageBuff[left++] = 255;
|
||||
imageBuff[left++] = 255;
|
||||
imageBuff[left++] = 255;
|
||||
|
||||
imageBuff[left++] = ((float)out[k] * max);
|
||||
}
|
||||
|
||||
snprintf (name, sizeof(name), "fonts/fontImage_%i_%i.tga", imageNumber++, pointSize);
|
||||
if (r_saveFontData->integer) {
|
||||
WriteTGA(name, imageBuff, 256, 256);
|
||||
}
|
||||
|
||||
image = R_CreateImage(name, imageBuff, 256, 256, qfalse, qfalse, GL_CLAMP);
|
||||
|
||||
ri.Printf(PRINT_WARNING, "RE_RegisterFont: ri.Malloc failure during output image creation.\n");
|
||||
|
||||
h = R_RegisterShaderFromImage(name, LIGHTMAP_2D, image, qfalse);
|
||||
for (j = lastStart; j < i; j++) {
|
||||
font->glyphs[j].glyph = h;
|
||||
Q_strncpyz(font->glyphs[j].shaderName, name, sizeof(font->glyphs[j].shaderName));
|
||||
}
|
||||
lastStart = i;
|
||||
memset(out, 0, 256*256);
|
||||
xOut = 0;
|
||||
yOut = 0;
|
||||
ri.Free(imageBuff);
|
||||
if ( i == GLYPH_END + 1 )
|
||||
i++;
|
||||
} else {
|
||||
memcpy(&font->glyphs[i], glyph, sizeof(glyphInfo_t));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// change the scale to be relative to 1 based on 72 dpi ( so dpi of 144 means a scale of .5 )
|
||||
glyphScale = 72.0f / dpi;
|
||||
|
||||
// we also need to adjust the scale based on point size relative to 48 points as the ui scaling is based on a 48 point font
|
||||
glyphScale *= 48.0f / pointSize;
|
||||
|
||||
registeredFont[registeredFontCount].glyphScale = glyphScale;
|
||||
font->glyphScale = glyphScale;
|
||||
memcpy(®isteredFont[registeredFontCount++], font, sizeof(fontInfo_t));
|
||||
|
||||
if (r_saveFontData->integer) {
|
||||
ri.FS_WriteFile(va("fonts/fontImage_%i.dat", pointSize), font, sizeof(fontInfo_t));
|
||||
}
|
||||
|
||||
ri.Free(out);
|
||||
|
||||
ri.FS_FreeFile(faceData);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void R_InitFreeType(void)
|
||||
{
|
||||
#ifdef BUILD_FREETYPE
|
||||
if (FT_Init_FreeType( &ftLibrary )) {
|
||||
ri.Printf(PRINT_WARNING, "R_InitFreeType: Unable to initialize FreeType.\n");
|
||||
}
|
||||
#endif
|
||||
registeredFontCount = 0;
|
||||
r_saveFontData = ri.Cvar_Get( "r_saveFontData", "0", 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void R_DoneFreeType(void) {
|
||||
#ifdef BUILD_FREETYPE
|
||||
if (ftLibrary) {
|
||||
FT_Done_FreeType( ftLibrary );
|
||||
ftLibrary = NULL;
|
||||
}
|
||||
#endif
|
||||
registeredFontCount = 0;
|
||||
|
||||
}
|
||||
|
4
code/renderervk/tr_globals.c
Normal file
4
code/renderervk/tr_globals.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
#include "tr_globals.h"
|
||||
|
||||
trGlobals_t tr;
|
||||
|
101
code/renderervk/tr_globals.h
Normal file
101
code/renderervk/tr_globals.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
#ifndef TR_GLOBALS_H_
|
||||
#define TR_GLOBALS_H_
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_model.h"
|
||||
|
||||
// 12 bits, see QSORT_SHADERNUM_SHIFT
|
||||
#define MAX_SHADERS 16384
|
||||
|
||||
/*
|
||||
** trGlobals_t
|
||||
**
|
||||
** Most renderer globals are defined here.
|
||||
** backend functions should never modify any of these fields,
|
||||
** but may read fields that aren't dynamically modified
|
||||
** by the frontend.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
qboolean registered; // cleared at shutdown, set at beginRegistration
|
||||
|
||||
int visCount; // incremented every time a new vis cluster is entered
|
||||
int viewCount; // incremented every view (twice a scene if portaled)
|
||||
// and every R_MarkFragments call
|
||||
|
||||
qboolean worldMapLoaded;
|
||||
world_t *world;
|
||||
|
||||
const unsigned char *externalVisData; // from RE_SetWorldVisData, shared with CM_Load
|
||||
|
||||
image_t *defaultImage;
|
||||
image_t *scratchImage[32];
|
||||
image_t *fogImage;
|
||||
image_t *dlightImage; // inverse-quare highlight for projective adding
|
||||
image_t *whiteImage; // full of 0xff
|
||||
image_t *identityLightImage; // full of tr.identityLightByte
|
||||
|
||||
shader_t *defaultShader;
|
||||
shader_t *cinematicShader;
|
||||
shader_t *shadowShader;
|
||||
shader_t *projectionShadowShader;
|
||||
|
||||
int numLightmaps;
|
||||
image_t *lightmaps[MAX_LIGHTMAPS];
|
||||
|
||||
trRefEntity_t *currentEntity;
|
||||
trRefEntity_t worldEntity; // point currentEntity at this when rendering world
|
||||
int currentEntityNum;
|
||||
int shiftedEntityNum; // currentEntityNum << QSORT_ENTITYNUM_SHIFT
|
||||
model_t *currentModel;
|
||||
|
||||
viewParms_t viewParms;
|
||||
|
||||
float identityLight; // 1.0 / ( 1 << overbrightBits )
|
||||
int identityLightByte; // identityLight * 255
|
||||
|
||||
orientationr_t or; // for current entity
|
||||
|
||||
trRefdef_t refdef;
|
||||
|
||||
int viewCluster;
|
||||
|
||||
vec3_t sunLight; // from the sky shader for this level
|
||||
vec3_t sunDirection;
|
||||
|
||||
frontEndCounters_t pc;
|
||||
int frontEndMsec; // not in pc due to clearing issue
|
||||
|
||||
//
|
||||
// put large tables at the end, so most elements will be
|
||||
// within the +/32K indexed range on risc processors
|
||||
//
|
||||
model_t *models[MAX_MOD_KNOWN];
|
||||
int numModels;
|
||||
|
||||
int numImages;
|
||||
image_t * images[MAX_DRAWIMAGES];
|
||||
|
||||
// shader indexes from other modules will be looked up in tr.shaders[]
|
||||
// shader indexes from drawsurfs will be looked up in sortedShaders[]
|
||||
// lower indexed sortedShaders must be rendered first (opaque surfaces before translucent)
|
||||
int numShaders;
|
||||
shader_t *shaders[MAX_SHADERS];
|
||||
shader_t *sortedShaders[MAX_SHADERS];
|
||||
|
||||
int numSkins;
|
||||
skin_t *skins[MAX_SKINS];
|
||||
|
||||
float sinTable[FUNCTABLE_SIZE];
|
||||
float squareTable[FUNCTABLE_SIZE];
|
||||
float triangleTable[FUNCTABLE_SIZE];
|
||||
float sawToothTable[FUNCTABLE_SIZE];
|
||||
float inverseSawToothTable[FUNCTABLE_SIZE];
|
||||
} trGlobals_t;
|
||||
|
||||
|
||||
|
||||
extern trGlobals_t tr;
|
||||
|
||||
#endif
|
310
code/renderervk/tr_image.c
Normal file
310
code/renderervk/tr_image.c
Normal file
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
SKINS
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
#include "ref_import.h"
|
||||
#include "tr_shader.h"
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CommaParse
|
||||
|
||||
This is unfortunate, but the skin files aren't
|
||||
compatable with our normal parsing rules.
|
||||
==================
|
||||
*/
|
||||
static char *CommaParse( char **data_p )
|
||||
{
|
||||
int c = 0, len;
|
||||
char *data;
|
||||
static char com_token[MAX_TOKEN_CHARS];
|
||||
|
||||
data = *data_p;
|
||||
len = 0;
|
||||
com_token[0] = 0;
|
||||
|
||||
// make sure incoming data is valid
|
||||
if ( !data ) {
|
||||
*data_p = NULL;
|
||||
return com_token;
|
||||
}
|
||||
|
||||
while ( 1 ) {
|
||||
// skip whitespace
|
||||
while( (c = *data) <= ' ') {
|
||||
if( !c ) {
|
||||
break;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
|
||||
|
||||
c = *data;
|
||||
|
||||
// skip double slash comments
|
||||
if ( c == '/' && data[1] == '/' )
|
||||
{
|
||||
while (*data && *data != '\n')
|
||||
data++;
|
||||
}
|
||||
// skip /* */ comments
|
||||
else if ( c=='/' && data[1] == '*' )
|
||||
{
|
||||
while ( *data && ( *data != '*' || data[1] != '/' ) )
|
||||
{
|
||||
data++;
|
||||
}
|
||||
if ( *data )
|
||||
{
|
||||
data += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( c == 0 ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// handle quoted strings
|
||||
if (c == '\"')
|
||||
{
|
||||
data++;
|
||||
while (1)
|
||||
{
|
||||
c = *data++;
|
||||
if (c=='\"' || !c)
|
||||
{
|
||||
com_token[len] = 0;
|
||||
*data_p = ( char * ) data;
|
||||
return com_token;
|
||||
}
|
||||
if (len < MAX_TOKEN_CHARS)
|
||||
{
|
||||
com_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse a regular word
|
||||
do
|
||||
{
|
||||
if (len < MAX_TOKEN_CHARS)
|
||||
{
|
||||
com_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
data++;
|
||||
c = *data;
|
||||
} while (c>32 && c != ',' );
|
||||
|
||||
if (len == MAX_TOKEN_CHARS)
|
||||
{
|
||||
ri.Printf (PRINT_ALL, "Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS);
|
||||
len = 0;
|
||||
}
|
||||
com_token[len] = 0;
|
||||
|
||||
*data_p = ( char * ) data;
|
||||
return com_token;
|
||||
}
|
||||
|
||||
|
||||
|
||||
qhandle_t RE_RegisterSkin( const char *name )
|
||||
{
|
||||
skinSurface_t parseSurfaces[MAX_SKIN_SURFACES];
|
||||
qhandle_t hSkin;
|
||||
skin_t *skin;
|
||||
skinSurface_t *surf;
|
||||
char *text, *text_p;
|
||||
char *token;
|
||||
char surfName[MAX_QPATH];
|
||||
|
||||
if ( !name || !name[0] ) {
|
||||
ri.Printf(PRINT_ALL, "Empty name passed to RE_RegisterSkin\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (int)strlen( name ) >= MAX_QPATH ) {
|
||||
ri.Printf(PRINT_ALL, "Skin name exceeds MAX_QPATH\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// see if the skin is already loaded
|
||||
for ( hSkin = 1; hSkin < tr.numSkins ; hSkin++ ) {
|
||||
skin = tr.skins[hSkin];
|
||||
if ( !Q_stricmp( skin->name, name ) ) {
|
||||
if( skin->numSurfaces == 0 ) {
|
||||
return 0; // default skin
|
||||
}
|
||||
return hSkin;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate a new skin
|
||||
if ( tr.numSkins == MAX_SKINS ) {
|
||||
ri.Printf( PRINT_WARNING, "WARNING: RE_RegisterSkin( '%s' ) MAX_SKINS hit\n", name );
|
||||
return 0;
|
||||
}
|
||||
tr.numSkins++;
|
||||
skin = (skin_t*) ri.Hunk_Alloc( sizeof( skin_t ), h_low );
|
||||
tr.skins[hSkin] = skin;
|
||||
Q_strncpyz( skin->name, name, sizeof( skin->name ) );
|
||||
skin->numSurfaces = 0;
|
||||
|
||||
|
||||
// If not a .skin file, load as a single shader
|
||||
if ( strcmp( name + (int)strlen( name ) - 5, ".skin" ) ) {
|
||||
skin->numSurfaces = 1;
|
||||
skin->pSurfaces = (skinSurface_t *) ri.Hunk_Alloc( sizeof(skinSurface_t), h_low );
|
||||
skin->pSurfaces[0].shader = R_FindShader( name, LIGHTMAP_NONE, qtrue );
|
||||
return hSkin;
|
||||
}
|
||||
|
||||
// load and parse the skin file
|
||||
ri.FS_ReadFile( name, (void**)&text );
|
||||
if ( !text ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
text_p = text;
|
||||
while ( text_p && *text_p ) {
|
||||
// get surface name
|
||||
token = CommaParse( &text_p );
|
||||
Q_strncpyz( surfName, token, sizeof( surfName ) );
|
||||
|
||||
if ( !token[0] ) {
|
||||
break;
|
||||
}
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surfName );
|
||||
|
||||
if ( *text_p == ',' ) {
|
||||
text_p++;
|
||||
}
|
||||
|
||||
if ( strstr( token, "tag_" ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse the shader name
|
||||
token = CommaParse( &text_p );
|
||||
|
||||
// surf = skin->surfaces[ skin->numSurfaces ] = (skinSurface_t*) ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low );
|
||||
surf = &parseSurfaces[skin->numSurfaces];
|
||||
Q_strncpyz( surf->name, surfName, sizeof( surf->name ) );
|
||||
surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue );
|
||||
skin->numSurfaces++;
|
||||
}
|
||||
|
||||
ri.FS_FreeFile( text );
|
||||
|
||||
|
||||
// never let a skin have 0 shaders
|
||||
if ( skin->numSurfaces == 0 ) {
|
||||
return 0; // use default skin
|
||||
}
|
||||
|
||||
// copy surfaces to skin
|
||||
skin->pSurfaces = ri.Hunk_Alloc( skin->numSurfaces * sizeof( skinSurface_t ), h_low );
|
||||
memcpy( skin->pSurfaces, parseSurfaces, skin->numSurfaces * sizeof( skinSurface_t ) );
|
||||
|
||||
|
||||
|
||||
return hSkin;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_InitSkins
|
||||
===============
|
||||
*/
|
||||
void R_InitSkins( void )
|
||||
{
|
||||
skin_t *skin;
|
||||
|
||||
tr.numSkins = 1;
|
||||
|
||||
// make the default skin have all default shaders
|
||||
skin = tr.skins[0] = (skin_t*) ri.Hunk_Alloc( sizeof( skin_t ), h_low );
|
||||
Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) );
|
||||
skin->numSurfaces = 1;
|
||||
// skin->surfaces[0] = (skinSurface_t*) ri.Hunk_Alloc( sizeof( *skin->surfaces ), h_low );
|
||||
// skin->surfaces[0]->shader = tr.defaultShader;
|
||||
skin->pSurfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low );
|
||||
skin->pSurfaces[0].shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_GetSkinByHandle
|
||||
===============
|
||||
*/
|
||||
skin_t* R_GetSkinByHandle( qhandle_t hSkin )
|
||||
{
|
||||
if ( hSkin < 1 || hSkin >= tr.numSkins ) {
|
||||
return tr.skins[0];
|
||||
}
|
||||
return tr.skins[ hSkin ];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_SkinList_f
|
||||
===============
|
||||
*/
|
||||
void R_SkinList_f( void )
|
||||
{
|
||||
int i, j;
|
||||
skin_t *skin;
|
||||
|
||||
ri.Printf (PRINT_ALL, "------------------\n");
|
||||
|
||||
for ( i = 0 ; i < tr.numSkins ; i++ ) {
|
||||
skin = tr.skins[i];
|
||||
|
||||
// ri.Printf( PRINT_ALL, "%3i:%s\n", i, skin->name );
|
||||
ri.Printf( PRINT_ALL, "%3i:%s (%d surfaces)\n", i, skin->name, skin->numSurfaces );
|
||||
for ( j = 0 ; j < skin->numSurfaces ; j++ ) {
|
||||
ri.Printf( PRINT_ALL, " %s = %s\n",
|
||||
skin->pSurfaces[j].name, skin->pSurfaces[j].shader->name );
|
||||
}
|
||||
}
|
||||
ri.Printf (PRINT_ALL, "------------------\n");
|
||||
}
|
||||
|
37
code/renderervk/tr_image.h
Normal file
37
code/renderervk/tr_image.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef TR_IMAGE_H_
|
||||
#define TR_IMAGE_H_
|
||||
|
||||
#include "VKimpl.h"
|
||||
|
||||
|
||||
typedef struct image_s {
|
||||
char imgName[MAX_QPATH]; // game path, including extension
|
||||
uint32_t width, height; // source image
|
||||
uint32_t uploadWidth, uploadHeight; // after power of two and picmip but not including clamp to MAX_TEXTURE_SIZE
|
||||
|
||||
uint32_t index;
|
||||
|
||||
VkImage handle;
|
||||
// To use any VkImage, including those in the swap chain, int the render pipeline
|
||||
// we have to create a VkImageView object. An image view is quite literally a
|
||||
// view into image. It describe how to access the image and witch part of the
|
||||
// image to access, if it should be treated as a 2D texture depth texture without
|
||||
// any mipmapping levels.
|
||||
|
||||
VkImageView view;
|
||||
|
||||
// Descriptor set that contains single descriptor used to access the given image.
|
||||
// It is updated only once during image initialization.
|
||||
VkDescriptorSet descriptor_set;
|
||||
|
||||
int wrapClampMode; // GL_CLAMP or GL_REPEAT, for vulkan
|
||||
VkBool32 mipmap; // for vulkan
|
||||
uint32_t mipLevels; // gl texture binding
|
||||
VkBool32 allowPicmip; // for vulkan
|
||||
VkBool32 isLightmap;
|
||||
|
||||
struct image_s* next;
|
||||
} image_t;
|
||||
|
||||
|
||||
#endif
|
226
code/renderervk/tr_init.c
Normal file
226
code/renderervk/tr_init.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_init.c -- functions that are not called every frame
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
#include "tr_model.h"
|
||||
#include "tr_cvar.h"
|
||||
|
||||
#include "vk_init.h"
|
||||
|
||||
#include "vk_screenshot.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
#include "vk_pipelines.h"
|
||||
#include "vk_image.h"
|
||||
|
||||
#include "tr_fog.h"
|
||||
#include "tr_backend.h"
|
||||
#include "glConfig.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
extern void RE_ClearScene( void );
|
||||
|
||||
|
||||
|
||||
void R_Init( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
ri.Printf( PRINT_ALL, "----- R_Init -----\n" );
|
||||
|
||||
|
||||
// clear all our internal state
|
||||
memset( &tr, 0, sizeof( tr ) );
|
||||
memset( &tess, 0, sizeof( tess ) );
|
||||
|
||||
R_ClearBackendState();
|
||||
|
||||
if ( (intptr_t)tess.xyz & 15 ) {
|
||||
ri.Printf( PRINT_ALL, "WARNING: tess.xyz not 16 byte aligned\n" );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// init function tables
|
||||
//
|
||||
for ( i = 0; i < FUNCTABLE_SIZE; i++ )
|
||||
{
|
||||
tr.sinTable[i] = sin( DEG2RAD( i * 360.0f / ( ( float ) ( FUNCTABLE_SIZE - 1 ) ) ) );
|
||||
tr.squareTable[i] = ( i < FUNCTABLE_SIZE/2 ) ? 1.0f : -1.0f;
|
||||
tr.sawToothTable[i] = (float)i / FUNCTABLE_SIZE;
|
||||
tr.inverseSawToothTable[i] = 1.0f - tr.sawToothTable[i];
|
||||
|
||||
if ( i < FUNCTABLE_SIZE / 2 )
|
||||
{
|
||||
if ( i < FUNCTABLE_SIZE / 4 )
|
||||
{
|
||||
tr.triangleTable[i] = ( float ) i / ( FUNCTABLE_SIZE / 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.triangleTable[i] = 1.0f - tr.triangleTable[i-FUNCTABLE_SIZE / 4];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.triangleTable[i] = -tr.triangleTable[i-FUNCTABLE_SIZE/2];
|
||||
}
|
||||
}
|
||||
|
||||
R_InitDisplayResolution();
|
||||
|
||||
R_InitFogTable();
|
||||
|
||||
R_NoiseInit();
|
||||
|
||||
R_Register();
|
||||
|
||||
// make sure all the commands added here are also
|
||||
// removed in R_Shutdown
|
||||
ri.Cmd_AddCommand( "displayResoList", R_DisplayResolutionList_f );
|
||||
|
||||
ri.Cmd_AddCommand( "modellist", R_Modellist_f );
|
||||
ri.Cmd_AddCommand( "screenshotJPEG", R_ScreenShotJPEG_f );
|
||||
ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
|
||||
ri.Cmd_AddCommand( "shaderlist", R_ShaderList_f );
|
||||
ri.Cmd_AddCommand( "skinlist", R_SkinList_f );
|
||||
|
||||
ri.Cmd_AddCommand( "vkinfo", vulkanInfo_f );
|
||||
ri.Cmd_AddCommand( "minimize", vk_minimizeWindow );
|
||||
|
||||
ri.Cmd_AddCommand( "pipelineList", R_PipelineList_f );
|
||||
|
||||
ri.Cmd_AddCommand( "gpuMem", gpuMemUsageInfo_f );
|
||||
|
||||
ri.Cmd_AddCommand( "printOR", R_PrintBackEnd_OR_f );
|
||||
|
||||
R_InitScene();
|
||||
|
||||
R_glConfigInit();
|
||||
|
||||
// VULKAN
|
||||
if ( !isVKinitialied() )
|
||||
{
|
||||
vk_initialize();
|
||||
|
||||
// print info
|
||||
vulkanInfo_f();
|
||||
}
|
||||
|
||||
|
||||
R_InitImages();
|
||||
|
||||
R_InitShaders();
|
||||
|
||||
R_InitSkins();
|
||||
|
||||
R_ModelInit();
|
||||
|
||||
R_InitFreeType();
|
||||
|
||||
ri.Printf( PRINT_ALL, "----- R_Init finished -----\n" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RE_Shutdown( qboolean destroyWindow )
|
||||
{
|
||||
|
||||
ri.Printf( PRINT_ALL, "\nRE_Shutdown( %i )\n", destroyWindow );
|
||||
|
||||
ri.Cmd_RemoveCommand("displayResoList");
|
||||
|
||||
ri.Cmd_RemoveCommand("modellist");
|
||||
ri.Cmd_RemoveCommand("screenshotJPEG");
|
||||
ri.Cmd_RemoveCommand("screenshot");
|
||||
ri.Cmd_RemoveCommand("shaderlist");
|
||||
ri.Cmd_RemoveCommand("skinlist");
|
||||
|
||||
ri.Cmd_RemoveCommand("minimize");
|
||||
|
||||
ri.Cmd_RemoveCommand("vkinfo");
|
||||
ri.Cmd_RemoveCommand("pipelineList");
|
||||
ri.Cmd_RemoveCommand("gpuMem");
|
||||
ri.Cmd_RemoveCommand("printOR");
|
||||
|
||||
R_DoneFreeType();
|
||||
|
||||
// VULKAN
|
||||
// Releases vulkan resources allocated during program execution.
|
||||
// This effectively puts vulkan subsystem into initial state
|
||||
// (the state we have after vk_initialize call).
|
||||
|
||||
// contains vulkan resources/state, reinitialized on a map change.
|
||||
|
||||
vk_destroyShaderStagePipeline();
|
||||
|
||||
|
||||
vk_resetGeometryBuffer();
|
||||
|
||||
if ( tr.registered )
|
||||
{
|
||||
vk_destroyImageRes();
|
||||
tr.registered = qfalse;
|
||||
}
|
||||
|
||||
if (destroyWindow)
|
||||
{
|
||||
vk_shutdown();
|
||||
vk_destroyWindow();
|
||||
|
||||
// It is cleared not for renderer_vulkan,
|
||||
// but fot rendergl1, renderergl2 to create the window
|
||||
R_glConfigClear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RE_BeginRegistration(glconfig_t * pGlCfg)
|
||||
{
|
||||
R_Init();
|
||||
|
||||
R_GetGlConfig(pGlCfg);
|
||||
|
||||
tr.viewCluster = -1; // force markleafs to regenerate
|
||||
|
||||
RE_ClearScene();
|
||||
|
||||
tr.registered = qtrue;
|
||||
|
||||
ri.Printf(PRINT_ALL, "RE_BeginRegistration finished.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_EndRegistration
|
||||
|
||||
Touch all images to make sure they are resident
|
||||
=============
|
||||
*/
|
||||
void RE_EndRegistration( void )
|
||||
{
|
||||
if ( tr.registered ) {
|
||||
R_IssueRenderCommands( qfalse );
|
||||
}
|
||||
}
|
396
code/renderervk/tr_light.c
Normal file
396
code/renderervk/tr_light.c
Normal file
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_light.c
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
#include "ref_import.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "tr_light.h"
|
||||
|
||||
|
||||
|
||||
#define DLIGHT_AT_RADIUS 16
|
||||
// at the edge of a dlight's influence, this amount of light will be added
|
||||
|
||||
#define DLIGHT_MINIMUM_RADIUS 16
|
||||
// never calculate a range less than this to prevent huge light numbers
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_TransformDlights
|
||||
|
||||
Transforms the origins of an array of dlights.
|
||||
Used by both the front end (for DlightBmodel) and
|
||||
the back end (before doing the lighting calculation)
|
||||
===============
|
||||
*/
|
||||
void R_TransformDlights( int count, dlight_t *dl, const orientationr_t * const or)
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < count ; i++, dl++ )
|
||||
{
|
||||
vec3_t temp;
|
||||
VectorSubtract( dl->origin, or->origin, temp );
|
||||
dl->transformed[0] = DotProduct( temp, or->axis[0] );
|
||||
dl->transformed[1] = DotProduct( temp, or->axis[1] );
|
||||
dl->transformed[2] = DotProduct( temp, or->axis[2] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_DlightBmodel
|
||||
|
||||
Determine which dynamic lights may effect this bmodel
|
||||
=============
|
||||
*/
|
||||
void R_DlightBmodel( bmodel_t *bmodel ) {
|
||||
int i, j;
|
||||
dlight_t *dl;
|
||||
int mask;
|
||||
msurface_t *surf;
|
||||
|
||||
// transform all the lights
|
||||
R_TransformDlights( tr.refdef.num_dlights, tr.refdef.dlights, &tr.or );
|
||||
|
||||
mask = 0;
|
||||
for ( i=0 ; i<tr.refdef.num_dlights ; i++ ) {
|
||||
dl = &tr.refdef.dlights[i];
|
||||
|
||||
// see if the point is close enough to the bounds to matter
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( dl->transformed[j] - bmodel->bounds[1][j] > dl->radius ) {
|
||||
break;
|
||||
}
|
||||
if ( bmodel->bounds[0][j] - dl->transformed[j] > dl->radius ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j < 3 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// we need to check this light
|
||||
mask |= 1 << i;
|
||||
}
|
||||
|
||||
tr.currentEntity->needDlights = (qboolean) (mask != 0);
|
||||
|
||||
// set the dlight bits in all the surfaces
|
||||
for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) {
|
||||
surf = bmodel->firstSurface + i;
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->dlightBits = mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LIGHT SAMPLING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SetupEntityLightingGrid
|
||||
|
||||
=================
|
||||
*/
|
||||
static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
|
||||
vec3_t lightOrigin;
|
||||
int pos[3];
|
||||
int i, j;
|
||||
byte *gridData;
|
||||
float frac[3];
|
||||
int gridStep[3];
|
||||
vec3_t direction;
|
||||
float totalFactor;
|
||||
|
||||
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
|
||||
// seperate lightOrigins are needed so an object that is
|
||||
// sinking into the ground can still be lit, and so
|
||||
// multi-part models can be lit identically
|
||||
VectorCopy( ent->e.lightingOrigin, lightOrigin );
|
||||
} else {
|
||||
VectorCopy( ent->e.origin, lightOrigin );
|
||||
}
|
||||
|
||||
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
float v;
|
||||
|
||||
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
|
||||
pos[i] = floor( v );
|
||||
frac[i] = v - pos[i];
|
||||
if ( pos[i] < 0 ) {
|
||||
pos[i] = 0;
|
||||
} else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
|
||||
pos[i] = tr.world->lightGridBounds[i] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( ent->ambientLight );
|
||||
VectorClear( ent->directedLight );
|
||||
VectorClear( direction );
|
||||
|
||||
assert( tr.world->lightGridData ); // bk010103 - NULL with -nolight maps
|
||||
|
||||
// trilerp the light value
|
||||
gridStep[0] = 8;
|
||||
gridStep[1] = 8 * tr.world->lightGridBounds[0];
|
||||
gridStep[2] = 8 * tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
|
||||
gridData = tr.world->lightGridData + pos[0] * gridStep[0]
|
||||
+ pos[1] * gridStep[1] + pos[2] * gridStep[2];
|
||||
|
||||
totalFactor = 0;
|
||||
for ( i = 0 ; i < 8 ; i++ ) {
|
||||
float factor;
|
||||
byte *data;
|
||||
int lat, lng;
|
||||
vec3_t normal;
|
||||
#if idppc
|
||||
float d0, d1, d2, d3, d4, d5;
|
||||
#endif
|
||||
factor = 1.0;
|
||||
data = gridData;
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( i & (1<<j) ) {
|
||||
factor *= frac[j];
|
||||
data += gridStep[j];
|
||||
} else {
|
||||
factor *= (1.0f - frac[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !(data[0]+data[1]+data[2]) ) {
|
||||
continue; // ignore samples in walls
|
||||
}
|
||||
totalFactor += factor;
|
||||
#if idppc
|
||||
d0 = data[0]; d1 = data[1]; d2 = data[2];
|
||||
d3 = data[3]; d4 = data[4]; d5 = data[5];
|
||||
|
||||
ent->ambientLight[0] += factor * d0;
|
||||
ent->ambientLight[1] += factor * d1;
|
||||
ent->ambientLight[2] += factor * d2;
|
||||
|
||||
ent->directedLight[0] += factor * d3;
|
||||
ent->directedLight[1] += factor * d4;
|
||||
ent->directedLight[2] += factor * d5;
|
||||
#else
|
||||
ent->ambientLight[0] += factor * data[0];
|
||||
ent->ambientLight[1] += factor * data[1];
|
||||
ent->ambientLight[2] += factor * data[2];
|
||||
|
||||
ent->directedLight[0] += factor * data[3];
|
||||
ent->directedLight[1] += factor * data[4];
|
||||
ent->directedLight[2] += factor * data[5];
|
||||
#endif
|
||||
lat = data[7];
|
||||
lng = data[6];
|
||||
lat *= (FUNCTABLE_SIZE/256);
|
||||
lng *= (FUNCTABLE_SIZE/256);
|
||||
|
||||
// decode X as cos( lat ) * sin( long )
|
||||
// decode Y as sin( lat ) * sin( long )
|
||||
// decode Z as cos( long )
|
||||
|
||||
normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
|
||||
normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
|
||||
normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
|
||||
|
||||
VectorMA( direction, factor, normal, direction );
|
||||
}
|
||||
|
||||
if ( totalFactor > 0 && totalFactor < 0.99 ) {
|
||||
totalFactor = 1.0f / totalFactor;
|
||||
VectorScale( ent->ambientLight, totalFactor, ent->ambientLight );
|
||||
VectorScale( ent->directedLight, totalFactor, ent->directedLight );
|
||||
}
|
||||
|
||||
VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
|
||||
VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
|
||||
|
||||
VectorNormalize2( direction, ent->lightDir );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
LogLight
|
||||
===============
|
||||
*/
|
||||
static void LogLight( trRefEntity_t *ent ) {
|
||||
int max1, max2;
|
||||
|
||||
if ( !(ent->e.renderfx & RF_FIRST_PERSON ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
max1 = ent->ambientLight[0];
|
||||
if ( ent->ambientLight[1] > max1 ) {
|
||||
max1 = ent->ambientLight[1];
|
||||
} else if ( ent->ambientLight[2] > max1 ) {
|
||||
max1 = ent->ambientLight[2];
|
||||
}
|
||||
|
||||
max2 = ent->directedLight[0];
|
||||
if ( ent->directedLight[1] > max2 ) {
|
||||
max2 = ent->directedLight[1];
|
||||
} else if ( ent->directedLight[2] > max2 ) {
|
||||
max2 = ent->directedLight[2];
|
||||
}
|
||||
|
||||
ri.Printf( PRINT_ALL, "amb:%i dir:%i\n", max1, max2 );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SetupEntityLighting
|
||||
|
||||
Calculates all the lighting values that will be used
|
||||
by the Calc_* functions
|
||||
=================
|
||||
*/
|
||||
void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
||||
int i;
|
||||
dlight_t *dl;
|
||||
float power;
|
||||
vec3_t dir;
|
||||
float d;
|
||||
vec3_t lightDir;
|
||||
vec3_t lightOrigin;
|
||||
|
||||
// lighting calculations
|
||||
if ( ent->lightingCalculated ) {
|
||||
return;
|
||||
}
|
||||
ent->lightingCalculated = qtrue;
|
||||
|
||||
//
|
||||
// trace a sample point down to find ambient light
|
||||
//
|
||||
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
|
||||
// seperate lightOrigins are needed so an object that is
|
||||
// sinking into the ground can still be lit, and so
|
||||
// multi-part models can be lit identically
|
||||
VectorCopy( ent->e.lightingOrigin, lightOrigin );
|
||||
} else {
|
||||
VectorCopy( ent->e.origin, lightOrigin );
|
||||
}
|
||||
|
||||
// if NOWORLDMODEL, only use dynamic lights (menu system, etc)
|
||||
if ( !(refdef->rd.rdflags & RDF_NOWORLDMODEL )
|
||||
&& tr.world->lightGridData ) {
|
||||
R_SetupEntityLightingGrid( ent );
|
||||
} else {
|
||||
ent->ambientLight[0] = ent->ambientLight[1] =
|
||||
ent->ambientLight[2] = tr.identityLight * 150;
|
||||
ent->directedLight[0] = ent->directedLight[1] =
|
||||
ent->directedLight[2] = tr.identityLight * 150;
|
||||
VectorCopy( tr.sunDirection, ent->lightDir );
|
||||
}
|
||||
|
||||
// bonus items and view weapons have a fixed minimum add
|
||||
if ( 1 /* ent->e.renderfx & RF_MINLIGHT */ ) {
|
||||
// give everything a minimum light add
|
||||
ent->ambientLight[0] += tr.identityLight * 32;
|
||||
ent->ambientLight[1] += tr.identityLight * 32;
|
||||
ent->ambientLight[2] += tr.identityLight * 32;
|
||||
}
|
||||
|
||||
//
|
||||
// modify the light by dynamic lights
|
||||
//
|
||||
d = VectorLength( ent->directedLight );
|
||||
VectorScale( ent->lightDir, d, lightDir );
|
||||
|
||||
for ( i = 0 ; i < refdef->num_dlights ; i++ ) {
|
||||
dl = &refdef->dlights[i];
|
||||
VectorSubtract( dl->origin, lightOrigin, dir );
|
||||
d = VectorNormalize( dir );
|
||||
|
||||
power = DLIGHT_AT_RADIUS * ( dl->radius * dl->radius );
|
||||
if ( d < DLIGHT_MINIMUM_RADIUS ) {
|
||||
d = DLIGHT_MINIMUM_RADIUS;
|
||||
}
|
||||
d = power / ( d * d );
|
||||
|
||||
VectorMA( ent->directedLight, d, dl->color, ent->directedLight );
|
||||
VectorMA( lightDir, d, dir, lightDir );
|
||||
}
|
||||
|
||||
// clamp ambient
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
if ( ent->ambientLight[i] > tr.identityLightByte ) {
|
||||
ent->ambientLight[i] = tr.identityLightByte;
|
||||
}
|
||||
}
|
||||
|
||||
if ( r_debugLight->integer ) {
|
||||
LogLight( ent );
|
||||
}
|
||||
|
||||
// save out the byte packet version
|
||||
ent->ambientLightRGBA[0] = (unsigned char)( ent->ambientLight[0] );
|
||||
ent->ambientLightRGBA[1] = (unsigned char)( ent->ambientLight[1] );
|
||||
ent->ambientLightRGBA[2] = (unsigned char)( ent->ambientLight[2] );
|
||||
ent->ambientLightRGBA[3] = 0xff;
|
||||
|
||||
// transform the direction to local space
|
||||
VectorNormalize( lightDir );
|
||||
ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
|
||||
ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] );
|
||||
ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] );
|
||||
}
|
||||
|
||||
int RE_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir )
|
||||
{
|
||||
trRefEntity_t ent;
|
||||
|
||||
// bk010103 - this segfaults with -nolight maps
|
||||
if ( tr.world->lightGridData == NULL )
|
||||
return qfalse;
|
||||
|
||||
memset(&ent, 0, sizeof(ent));
|
||||
VectorCopy( point, ent.e.origin );
|
||||
R_SetupEntityLightingGrid( &ent );
|
||||
VectorCopy(ent.ambientLight, ambientLight);
|
||||
VectorCopy(ent.directedLight, directedLight);
|
||||
VectorCopy(ent.lightDir, lightDir);
|
||||
|
||||
return qtrue;
|
||||
}
|
23
code/renderervk/tr_light.h
Normal file
23
code/renderervk/tr_light.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef TR_LIGHT_H_
|
||||
#define TR_LIGHT_H_
|
||||
|
||||
|
||||
// can't be increased without changing bit packing for drawsurfs
|
||||
|
||||
typedef struct dlight_s {
|
||||
float origin[3];
|
||||
float color[3]; // range from 0.0 to 1.0, should be color normalized
|
||||
float transformed[3]; // origin in local coordinate system
|
||||
float radius;
|
||||
int additive; // texture detail is lost tho when the lightmap is dark
|
||||
} dlight_t;
|
||||
|
||||
|
||||
|
||||
void R_DlightBmodel( bmodel_t *bmodel );
|
||||
void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent );
|
||||
void R_TransformDlights( int count, dlight_t *dl, const orientationr_t * const or );
|
||||
|
||||
|
||||
|
||||
#endif
|
1021
code/renderervk/tr_local.h
Normal file
1021
code/renderervk/tr_local.h
Normal file
File diff suppressed because it is too large
Load diff
1311
code/renderervk/tr_main.c
Normal file
1311
code/renderervk/tr_main.c
Normal file
File diff suppressed because it is too large
Load diff
441
code/renderervk/tr_marks.c
Normal file
441
code/renderervk/tr_marks.c
Normal file
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_marks.c -- polygon projection on the world polygons
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
#include "matrix_multiplication.h"
|
||||
|
||||
|
||||
#define MAX_VERTS_ON_POLY 64
|
||||
|
||||
#define MARKER_OFFSET 0 // 1
|
||||
|
||||
/*
|
||||
=============
|
||||
R_ChopPolyBehindPlane
|
||||
|
||||
Out must have space for two more vertexes than in
|
||||
=============
|
||||
*/
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_BACK 1
|
||||
#define SIDE_ON 2
|
||||
static void R_ChopPolyBehindPlane( int numInPoints, vec3_t inPoints[MAX_VERTS_ON_POLY],
|
||||
int *numOutPoints, vec3_t outPoints[MAX_VERTS_ON_POLY],
|
||||
vec3_t normal, vec_t dist, vec_t epsilon) {
|
||||
float dists[MAX_VERTS_ON_POLY+4];
|
||||
int sides[MAX_VERTS_ON_POLY+4];
|
||||
int counts[3];
|
||||
float dot;
|
||||
int i, j;
|
||||
float *p1, *p2, *clip;
|
||||
float d;
|
||||
|
||||
// don't clip if it might overflow
|
||||
if ( numInPoints >= MAX_VERTS_ON_POLY - 2 ) {
|
||||
*numOutPoints = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
|
||||
// determine sides for each point
|
||||
for ( i = 0 ; i < numInPoints ; i++ ) {
|
||||
dot = DotProduct( inPoints[i], normal );
|
||||
dot -= dist;
|
||||
dists[i] = dot;
|
||||
if ( dot > epsilon ) {
|
||||
sides[i] = SIDE_FRONT;
|
||||
} else if ( dot < -epsilon ) {
|
||||
sides[i] = SIDE_BACK;
|
||||
} else {
|
||||
sides[i] = SIDE_ON;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
|
||||
*numOutPoints = 0;
|
||||
|
||||
if ( !counts[0] ) {
|
||||
return;
|
||||
}
|
||||
if ( !counts[1] ) {
|
||||
*numOutPoints = numInPoints;
|
||||
memcpy( outPoints, inPoints, numInPoints * sizeof(vec3_t) );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < numInPoints ; i++ ) {
|
||||
p1 = inPoints[i];
|
||||
clip = outPoints[ *numOutPoints ];
|
||||
|
||||
if ( sides[i] == SIDE_ON ) {
|
||||
VectorCopy( p1, clip );
|
||||
(*numOutPoints)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[i] == SIDE_FRONT ) {
|
||||
VectorCopy( p1, clip );
|
||||
(*numOutPoints)++;
|
||||
clip = outPoints[ *numOutPoints ];
|
||||
}
|
||||
|
||||
if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// generate a split point
|
||||
p2 = inPoints[ (i+1) % numInPoints ];
|
||||
|
||||
d = dists[i] - dists[i+1];
|
||||
if ( d == 0 ) {
|
||||
dot = 0;
|
||||
} else {
|
||||
dot = dists[i] / d;
|
||||
}
|
||||
|
||||
// clip xyz
|
||||
|
||||
for (j=0 ; j<3 ; j++) {
|
||||
clip[j] = p1[j] + dot * ( p2[j] - p1[j] );
|
||||
}
|
||||
|
||||
(*numOutPoints)++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_BoxSurfaces_r
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_BoxSurfaces_r(mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int listsize, int *listlength, vec3_t dir) {
|
||||
|
||||
int s, c;
|
||||
msurface_t *surf, **mark;
|
||||
|
||||
// do the tail recursion in a loop
|
||||
while ( node->contents == -1 ) {
|
||||
s = BoxOnPlaneSide( mins, maxs, node->plane );
|
||||
if (s == 1) {
|
||||
node = node->children[0];
|
||||
} else if (s == 2) {
|
||||
node = node->children[1];
|
||||
} else {
|
||||
R_BoxSurfaces_r(node->children[0], mins, maxs, list, listsize, listlength, dir);
|
||||
node = node->children[1];
|
||||
}
|
||||
}
|
||||
|
||||
// add the individual surfaces
|
||||
mark = node->firstmarksurface;
|
||||
c = node->nummarksurfaces;
|
||||
while (c--) {
|
||||
//
|
||||
if (*listlength >= listsize) break;
|
||||
//
|
||||
surf = *mark;
|
||||
// check if the surface has NOIMPACT or NOMARKS set
|
||||
if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) )
|
||||
|| ( surf->shader->contentFlags & CONTENTS_FOG ) ) {
|
||||
surf->viewCount = tr.viewCount;
|
||||
}
|
||||
// extra check for surfaces to avoid list overflows
|
||||
else if (*(surf->data) == SF_FACE) {
|
||||
// the face plane should go through the box
|
||||
s = BoxOnPlaneSide( mins, maxs, &(( srfSurfaceFace_t * ) surf->data)->plane );
|
||||
if (s == 1 || s == 2) {
|
||||
surf->viewCount = tr.viewCount;
|
||||
} else if (DotProduct((( srfSurfaceFace_t * ) surf->data)->plane.normal, dir) > -0.5) {
|
||||
// don't add faces that make sharp angles with the projection direction
|
||||
surf->viewCount = tr.viewCount;
|
||||
}
|
||||
}
|
||||
else if (*(surfaceType_t *) (surf->data) != SF_GRID) surf->viewCount = tr.viewCount;
|
||||
// check the viewCount because the surface may have
|
||||
// already been added if it spans multiple leafs
|
||||
if (surf->viewCount != tr.viewCount) {
|
||||
surf->viewCount = tr.viewCount;
|
||||
list[*listlength] = (surfaceType_t *) surf->data;
|
||||
(*listlength)++;
|
||||
}
|
||||
mark++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AddMarkFragments
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_AddMarkFragments(int numClipPoints, vec3_t clipPoints[2][MAX_VERTS_ON_POLY],
|
||||
int numPlanes, vec3_t *normals, float *dists,
|
||||
int maxPoints, vec3_t pointBuffer,
|
||||
int maxFragments, markFragment_t *fragmentBuffer,
|
||||
int *returnedPoints, int *returnedFragments,
|
||||
vec3_t mins, vec3_t maxs) {
|
||||
int pingPong, i;
|
||||
markFragment_t *mf;
|
||||
|
||||
// chop the surface by all the bounding planes of the to be projected polygon
|
||||
pingPong = 0;
|
||||
|
||||
for ( i = 0 ; i < numPlanes ; i++ ) {
|
||||
|
||||
R_ChopPolyBehindPlane( numClipPoints, clipPoints[pingPong],
|
||||
&numClipPoints, clipPoints[!pingPong],
|
||||
normals[i], dists[i], 0.5 );
|
||||
pingPong ^= 1;
|
||||
if ( numClipPoints == 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// completely clipped away?
|
||||
if ( numClipPoints == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add this fragment to the returned list
|
||||
if ( numClipPoints + (*returnedPoints) > maxPoints ) {
|
||||
return; // not enough space for this polygon
|
||||
}
|
||||
/*
|
||||
// all the clip points should be within the bounding box
|
||||
for ( i = 0 ; i < numClipPoints ; i++ ) {
|
||||
int j;
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if (clipPoints[pingPong][i][j] < mins[j] - 0.5) break;
|
||||
if (clipPoints[pingPong][i][j] > maxs[j] + 0.5) break;
|
||||
}
|
||||
if (j < 3) break;
|
||||
}
|
||||
if (i < numClipPoints) return;
|
||||
*/
|
||||
|
||||
mf = fragmentBuffer + (*returnedFragments);
|
||||
mf->firstPoint = (*returnedPoints);
|
||||
mf->numPoints = numClipPoints;
|
||||
memcpy( pointBuffer + (*returnedPoints) * 3, clipPoints[pingPong], numClipPoints * sizeof(vec3_t) );
|
||||
|
||||
(*returnedPoints) += numClipPoints;
|
||||
(*returnedFragments)++;
|
||||
}
|
||||
|
||||
|
||||
int RE_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection,
|
||||
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer )
|
||||
{
|
||||
int numsurfaces, numPlanes;
|
||||
int i, j, k, m, n;
|
||||
surfaceType_t *surfaces[64];
|
||||
vec3_t mins, maxs;
|
||||
int returnedFragments;
|
||||
int returnedPoints;
|
||||
vec3_t normals[MAX_VERTS_ON_POLY+2];
|
||||
float dists[MAX_VERTS_ON_POLY+2];
|
||||
vec3_t clipPoints[2][MAX_VERTS_ON_POLY];
|
||||
int numClipPoints;
|
||||
float *v;
|
||||
srfSurfaceFace_t *surf;
|
||||
srfGridMesh_t *cv;
|
||||
drawVert_t *dv;
|
||||
vec3_t normal;
|
||||
vec3_t projectionDir;
|
||||
vec3_t v1, v2;
|
||||
int *indexes;
|
||||
|
||||
//increment view count for double check prevention
|
||||
tr.viewCount++;
|
||||
|
||||
//
|
||||
VectorNormalize2( projection, projectionDir );
|
||||
// find all the brushes that are to be considered
|
||||
ClearBounds( mins, maxs );
|
||||
for ( i = 0 ; i < numPoints ; i++ ) {
|
||||
vec3_t temp;
|
||||
|
||||
AddPointToBounds( points[i], mins, maxs );
|
||||
VectorAdd( points[i], projection, temp );
|
||||
AddPointToBounds( temp, mins, maxs );
|
||||
// make sure we get all the leafs (also the one(s) in front of the hit surface)
|
||||
VectorMA( points[i], -20, projectionDir, temp );
|
||||
AddPointToBounds( temp, mins, maxs );
|
||||
}
|
||||
|
||||
if (numPoints > MAX_VERTS_ON_POLY) numPoints = MAX_VERTS_ON_POLY;
|
||||
// create the bounding planes for the to be projected polygon
|
||||
for ( i = 0 ; i < numPoints ; i++ ) {
|
||||
VectorSubtract(points[(i+1)%numPoints], points[i], v1);
|
||||
VectorAdd(points[i], projection, v2);
|
||||
VectorSubtract(points[i], v2, v2);
|
||||
CrossProduct(v1, v2, normals[i]);
|
||||
VectorNorm(normals[i]);
|
||||
dists[i] = DotProduct(normals[i], points[i]);
|
||||
}
|
||||
// add near and far clipping planes for projection
|
||||
VectorCopy(projectionDir, normals[numPoints]);
|
||||
dists[numPoints] = DotProduct(normals[numPoints], points[0]) - 32;
|
||||
VectorCopy(projectionDir, normals[numPoints+1]);
|
||||
VectorInverse(normals[numPoints+1]);
|
||||
dists[numPoints+1] = DotProduct(normals[numPoints+1], points[0]) - 20;
|
||||
numPlanes = numPoints + 2;
|
||||
|
||||
numsurfaces = 0;
|
||||
R_BoxSurfaces_r(tr.world->nodes, mins, maxs, surfaces, 64, &numsurfaces, projectionDir);
|
||||
//assert(numsurfaces <= 64);
|
||||
//assert(numsurfaces != 64);
|
||||
|
||||
returnedPoints = 0;
|
||||
returnedFragments = 0;
|
||||
|
||||
for ( i = 0 ; i < numsurfaces ; i++ ) {
|
||||
|
||||
if (*surfaces[i] == SF_GRID) {
|
||||
|
||||
cv = (srfGridMesh_t *) surfaces[i];
|
||||
for ( m = 0 ; m < cv->height - 1 ; m++ ) {
|
||||
for ( n = 0 ; n < cv->width - 1 ; n++ ) {
|
||||
// We triangulate the grid and chop all triangles within
|
||||
// the bounding planes of the to be projected polygon.
|
||||
// LOD is not taken into account, not such a big deal though.
|
||||
//
|
||||
// It's probably much nicer to chop the grid itself and deal
|
||||
// with this grid as a normal SF_GRID surface so LOD will
|
||||
// be applied. However the LOD of that chopped grid must
|
||||
// be synced with the LOD of the original curve.
|
||||
// One way to do this; the chopped grid shares vertices with
|
||||
// the original curve. When LOD is applied to the original
|
||||
// curve the unused vertices are flagged. Now the chopped curve
|
||||
// should skip the flagged vertices. This still leaves the
|
||||
// problems with the vertices at the chopped grid edges.
|
||||
//
|
||||
// To avoid issues when LOD applied to "hollow curves" (like
|
||||
// the ones around many jump pads) we now just add a 2 unit
|
||||
// offset to the triangle vertices.
|
||||
// The offset is added in the vertex normal vector direction
|
||||
// so all triangles will still fit together.
|
||||
// The 2 unit offset should avoid pretty much all LOD problems.
|
||||
|
||||
numClipPoints = 3;
|
||||
|
||||
dv = cv->verts + m * cv->width + n;
|
||||
|
||||
VectorCopy(dv[0].xyz, clipPoints[0][0]);
|
||||
VectorMA(clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0]);
|
||||
VectorCopy(dv[cv->width].xyz, clipPoints[0][1]);
|
||||
VectorMA(clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1]);
|
||||
VectorCopy(dv[1].xyz, clipPoints[0][2]);
|
||||
VectorMA(clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2]);
|
||||
// check the normal of this triangle
|
||||
VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
|
||||
VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
|
||||
CrossProduct(v1, v2, normal);
|
||||
VectorNorm(normal);
|
||||
if (DotProduct(normal, projectionDir) < -0.1) {
|
||||
// add the fragments of this triangle
|
||||
R_AddMarkFragments(numClipPoints, clipPoints,
|
||||
numPlanes, normals, dists,
|
||||
maxPoints, pointBuffer,
|
||||
maxFragments, fragmentBuffer,
|
||||
&returnedPoints, &returnedFragments, mins, maxs);
|
||||
|
||||
if ( returnedFragments == maxFragments ) {
|
||||
return returnedFragments; // not enough space for more fragments
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy(dv[1].xyz, clipPoints[0][0]);
|
||||
VectorMA(clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0]);
|
||||
VectorCopy(dv[cv->width].xyz, clipPoints[0][1]);
|
||||
VectorMA(clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1]);
|
||||
VectorCopy(dv[cv->width+1].xyz, clipPoints[0][2]);
|
||||
VectorMA(clipPoints[0][2], MARKER_OFFSET, dv[cv->width+1].normal, clipPoints[0][2]);
|
||||
// check the normal of this triangle
|
||||
VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
|
||||
VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
|
||||
CrossProduct(v1, v2, normal);
|
||||
VectorNorm(normal);
|
||||
if (DotProduct(normal, projectionDir) < -0.05) {
|
||||
// add the fragments of this triangle
|
||||
R_AddMarkFragments(numClipPoints, clipPoints,
|
||||
numPlanes, normals, dists,
|
||||
maxPoints, pointBuffer,
|
||||
maxFragments, fragmentBuffer,
|
||||
&returnedPoints, &returnedFragments, mins, maxs);
|
||||
|
||||
if ( returnedFragments == maxFragments ) {
|
||||
return returnedFragments; // not enough space for more fragments
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*surfaces[i] == SF_FACE) {
|
||||
|
||||
surf = ( srfSurfaceFace_t * ) surfaces[i];
|
||||
// check the normal of this face
|
||||
if (DotProduct(surf->plane.normal, projectionDir) > -0.5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
|
||||
VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
|
||||
CrossProduct(v1, v2, normal);
|
||||
VectorNormalize(normal);
|
||||
if (DotProduct(normal, projectionDir) > -0.5) continue;
|
||||
*/
|
||||
indexes = (int *)( (byte *)surf + surf->ofsIndices );
|
||||
for ( k = 0 ; k < surf->numIndices ; k += 3 ) {
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
v = surf->points[0] + VERTEXSIZE * indexes[k+j];;
|
||||
VectorMA( v, MARKER_OFFSET, surf->plane.normal, clipPoints[0][j] );
|
||||
}
|
||||
// add the fragments of this face
|
||||
R_AddMarkFragments( 3 , clipPoints,
|
||||
numPlanes, normals, dists,
|
||||
maxPoints, pointBuffer,
|
||||
maxFragments, fragmentBuffer,
|
||||
&returnedPoints, &returnedFragments, mins, maxs);
|
||||
if ( returnedFragments == maxFragments ) {
|
||||
return returnedFragments; // not enough space for more fragments
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// ignore all other world surfaces
|
||||
// might be cool to also project polygons on a triangle soup
|
||||
// however this will probably create huge amounts of extra polys
|
||||
// even more than the projection onto curves
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return returnedFragments;
|
||||
}
|
||||
|
347
code/renderervk/tr_mesh.c
Normal file
347
code/renderervk/tr_mesh.c
Normal file
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_mesh.c: triangle model functions
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
#include "tr_cvar.h"
|
||||
#include "vk_shade_geometry.h"
|
||||
|
||||
#include "ref_import.h"
|
||||
#include "tr_light.h"
|
||||
|
||||
|
||||
static int R_CullModel( md3Header_t *header, trRefEntity_t *ent )
|
||||
{
|
||||
vec3_t bounds[2];
|
||||
int i;
|
||||
|
||||
// compute frame pointers
|
||||
md3Frame_t* newFrame = ( md3Frame_t * ) ( ( byte * ) header + header->ofsFrames ) + ent->e.frame;
|
||||
md3Frame_t* oldFrame = ( md3Frame_t * ) ( ( byte * ) header + header->ofsFrames ) + ent->e.oldframe;
|
||||
|
||||
// cull bounding sphere ONLY if this is not an upscaled entity
|
||||
if ( !ent->e.nonNormalizedAxes )
|
||||
{
|
||||
if ( ent->e.frame == ent->e.oldframe )
|
||||
{
|
||||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
|
||||
case CULL_IN:
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sphereCull, sphereCullB;
|
||||
|
||||
sphereCull = R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius );
|
||||
if ( newFrame == oldFrame ) {
|
||||
sphereCullB = sphereCull;
|
||||
} else {
|
||||
sphereCullB = R_CullLocalPointAndRadius( oldFrame->localOrigin, oldFrame->radius );
|
||||
}
|
||||
|
||||
if ( sphereCull == sphereCullB )
|
||||
{
|
||||
if ( sphereCull == CULL_OUT )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
else if ( sphereCull == CULL_IN )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate a bounding box in the current coordinate system
|
||||
for (i = 0 ; i < 3 ; i++) {
|
||||
bounds[0][i] = oldFrame->bounds[0][i] < newFrame->bounds[0][i] ? oldFrame->bounds[0][i] : newFrame->bounds[0][i];
|
||||
bounds[1][i] = oldFrame->bounds[1][i] > newFrame->bounds[1][i] ? oldFrame->bounds[1][i] : newFrame->bounds[1][i];
|
||||
}
|
||||
|
||||
switch ( R_CullLocalBox( bounds ) )
|
||||
{
|
||||
case CULL_IN:
|
||||
tr.pc.c_box_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_box_cull_md3_clip++;
|
||||
return CULL_CLIP;
|
||||
case CULL_OUT:
|
||||
default:
|
||||
tr.pc.c_box_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int R_ComputeLOD( trRefEntity_t *ent )
|
||||
{
|
||||
|
||||
int lod = 0;
|
||||
|
||||
float radius;
|
||||
// radius are guarentee large than 0;
|
||||
|
||||
// multiple LODs exist, so compute projected bounding sphere
|
||||
// and use that as a criteria for selecting LOD
|
||||
if(tr.currentModel->type == MOD_MDR)
|
||||
{
|
||||
mdrHeader_t * mdr = (mdrHeader_t *) tr.currentModel->modelData;
|
||||
int frameSize = (size_t) (&((mdrFrame_t *)0)->bones[mdr->numBones]);
|
||||
|
||||
mdrFrame_t * mdrframe = (mdrFrame_t *) ((byte *) mdr + mdr->ofsFrames + frameSize * ent->e.frame);
|
||||
|
||||
radius = RadiusFromBounds(mdrframe->bounds[0], mdrframe->bounds[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
md3Frame_t * frame = ( md3Frame_t * ) ( ( ( unsigned char * ) tr.currentModel->md3[0] ) + tr.currentModel->md3[0]->ofsFrames );
|
||||
|
||||
frame += ent->e.frame;
|
||||
|
||||
radius = RadiusFromBounds( frame->bounds[0], frame->bounds[1] );
|
||||
}
|
||||
|
||||
float tmpVec[3];
|
||||
VectorSubtract(ent->e.origin, tr.viewParms.or.origin, tmpVec);
|
||||
float dist = DotProduct( tr.viewParms.or.axis[0], tmpVec);
|
||||
if ( dist > 0 )
|
||||
{
|
||||
|
||||
// vec3_t p;
|
||||
// p[0] = 0;
|
||||
// p[1] = r ;
|
||||
// p[2] = -dist;
|
||||
// p[3] = 1;
|
||||
|
||||
// pMatProj = tr.viewParms.projectionMatrix
|
||||
// float projected[4];
|
||||
// projected[0] = p[0] * pMatProj[0] + p[1] * pMatProj[4] + p[2] * pMatProj[8] + pMatProj[12];
|
||||
// projected[1] = p[0] * pMatProj[1] - p[1] * pMatProj[5] + p[2] * pMatProj[9] + pMatProj[13];
|
||||
// projected[2] = p[0] * pMatProj[2] + p[1] * pMatProj[6] + p[2] * pMatProj[10] + pMatProj[14];
|
||||
// projected[3] = p[0] * pMatProj[3] + p[1] * pMatProj[7] + p[2] * pMatProj[11] + pMatProj[15];
|
||||
// perspective devide
|
||||
// pr = projected[1] / projected[3];
|
||||
|
||||
float p1 = - radius * tr.viewParms.projectionMatrix[5] - dist * tr.viewParms.projectionMatrix[9] + tr.viewParms.projectionMatrix[13];
|
||||
float p3 = radius * tr.viewParms.projectionMatrix[7] - dist * tr.viewParms.projectionMatrix[11] + tr.viewParms.projectionMatrix[15];
|
||||
|
||||
float projectedRadius = p1 / p3;
|
||||
|
||||
//ri.Printf( PRINT_ALL, "%f: \n", projectedRadius);
|
||||
|
||||
lod = (1.0f - projectedRadius * 6 ) * tr.currentModel->numLods;
|
||||
|
||||
|
||||
if ( lod < 0 )
|
||||
{
|
||||
lod = 0;
|
||||
}
|
||||
else if ( lod >= tr.currentModel->numLods )
|
||||
{
|
||||
lod = tr.currentModel->numLods - 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return lod;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_ComputeFogNum
|
||||
|
||||
=================
|
||||
*/
|
||||
int R_ComputeFogNum( md3Header_t *header, trRefEntity_t *ent ) {
|
||||
int i, j;
|
||||
fog_t *fog;
|
||||
md3Frame_t *md3Frame;
|
||||
vec3_t localOrigin;
|
||||
|
||||
if ( tr.refdef.rd.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: non-normalized axis issues
|
||||
md3Frame = ( md3Frame_t * ) ( ( byte * ) header + header->ofsFrames ) + ent->e.frame;
|
||||
VectorAdd( ent->e.origin, md3Frame->localOrigin, localOrigin );
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
|
||||
fog = &tr.world->fogs[i];
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( localOrigin[j] - md3Frame->radius >= fog->bounds[1][j] ) {
|
||||
break;
|
||||
}
|
||||
if ( localOrigin[j] + md3Frame->radius <= fog->bounds[0][j] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == 3 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void R_AddMD3Surfaces( trRefEntity_t *ent )
|
||||
{
|
||||
int i;
|
||||
md3Header_t *header = NULL;
|
||||
md3Surface_t *surface = NULL;
|
||||
md3Shader_t *md3Shader = NULL;
|
||||
shader_t *shader = NULL;
|
||||
int cull;
|
||||
int lod = 0;
|
||||
int fogNum;
|
||||
|
||||
// don't add third_person objects if not in a portal
|
||||
qboolean personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal;
|
||||
|
||||
if ( ent->e.renderfx & RF_WRAP_FRAMES ) {
|
||||
ent->e.frame %= tr.currentModel->md3[0]->numFrames;
|
||||
ent->e.oldframe %= tr.currentModel->md3[0]->numFrames;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate the frames so there is no chance of a crash.
|
||||
// This will write directly into the entity structure, so
|
||||
// when the surfaces are rendered, they don't need to be
|
||||
// range checked again.
|
||||
|
||||
|
||||
if ( (ent->e.frame >= tr.currentModel->md3[0]->numFrames)
|
||||
|| (ent->e.frame < 0)
|
||||
|| (ent->e.oldframe >= tr.currentModel->md3[0]->numFrames)
|
||||
|| (ent->e.oldframe < 0) )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "R_AddMD3Surfaces: no such frame %d to %d for '%s'\n",
|
||||
ent->e.oldframe, ent->e.frame,
|
||||
tr.currentModel->name );
|
||||
ent->e.frame = 0;
|
||||
ent->e.oldframe = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// compute LOD
|
||||
// model has only 1 LOD level, skip computations and bias
|
||||
if ( tr.currentModel->numLods > 1 )
|
||||
lod = R_ComputeLOD( ent );
|
||||
|
||||
header = tr.currentModel->md3[lod];
|
||||
|
||||
//
|
||||
// cull the entire model if merged bounding box of both frames
|
||||
// is outside the view frustum.
|
||||
//
|
||||
cull = R_CullModel ( header, ent );
|
||||
if ( cull == CULL_OUT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// set up lighting now that we know we aren't culled
|
||||
//
|
||||
if ( !personalModel) {
|
||||
R_SetupEntityLighting( &tr.refdef, ent );
|
||||
}
|
||||
|
||||
//
|
||||
// draw all surfaces
|
||||
//
|
||||
surface = (md3Surface_t *)( (byte *)header + header->ofsSurfaces );
|
||||
for ( i = 0 ; i < header->numSurfaces ; i++ )
|
||||
{
|
||||
if ( ent->e.customShader )
|
||||
{
|
||||
shader = R_GetShaderByHandle( ent->e.customShader );
|
||||
}
|
||||
else if ( ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins )
|
||||
{
|
||||
skin_t *skin = R_GetSkinByHandle( ent->e.customSkin );
|
||||
|
||||
// match the surface name to something in the skin file
|
||||
shader = tr.defaultShader;
|
||||
|
||||
int j;
|
||||
|
||||
for ( j = 0 ; j < skin->numSurfaces ; j++ )
|
||||
{
|
||||
// the names have both been lowercased
|
||||
if ( !strcmp( skin->pSurfaces[j].name, surface->name ) ) {
|
||||
shader = skin->pSurfaces[j].shader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shader == tr.defaultShader) {
|
||||
ri.Printf( PRINT_DEVELOPER, "no shader for surface %s in skin %s\n", surface->name, skin->name);
|
||||
}
|
||||
else if (shader->defaultShader) {
|
||||
ri.Printf( PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name);
|
||||
}
|
||||
} else if ( surface->numShaders <= 0 ) {
|
||||
shader = tr.defaultShader;
|
||||
} else {
|
||||
md3Shader = (md3Shader_t *) ( (byte *)surface + surface->ofsShaders );
|
||||
md3Shader += ent->e.skinNum % surface->numShaders;
|
||||
shader = tr.shaders[ md3Shader->shaderIndex ];
|
||||
}
|
||||
|
||||
|
||||
// we will add shadows even if the main object isn't visible in the view
|
||||
|
||||
// don't add third_person objects if not viewing through a portal
|
||||
if ( !personalModel )
|
||||
{
|
||||
// see if we are in a fog volume
|
||||
fogNum = R_ComputeFogNum( header, ent );
|
||||
R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse );
|
||||
}
|
||||
|
||||
surface = (md3Surface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
}
|
||||
|
81
code/renderervk/tr_model.c
Normal file
81
code/renderervk/tr_model.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_models.c -- model loading and caching
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tr_globals.h"
|
||||
|
||||
#include "tr_model.h"
|
||||
#include "ref_import.h"
|
||||
|
||||
|
||||
model_t* R_GetModelByHandle( qhandle_t index )
|
||||
{
|
||||
if ( (index < 0) || (index >= tr.numModels) )
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "index = %d, out of range gets the defualt model.\n", index);
|
||||
return tr.models[0];
|
||||
}
|
||||
|
||||
return tr.models[index];
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void R_ModelInit( void )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "R_ModelInit: \n");
|
||||
|
||||
// leave a space for NULL model
|
||||
model_t* mod = ri.Hunk_Alloc( sizeof( model_t ), h_low );
|
||||
mod->index = tr.numModels = 0;
|
||||
mod->type = MOD_BAD;
|
||||
|
||||
tr.models[tr.numModels] = mod;
|
||||
tr.numModels++;
|
||||
}
|
||||
|
||||
|
||||
void R_Modellist_f( void )
|
||||
{
|
||||
int i;
|
||||
int total = 0;
|
||||
|
||||
for ( i = 1 ; i < tr.numModels; i++ )
|
||||
{
|
||||
model_t* mod = tr.models[i];
|
||||
int lods = 1;
|
||||
int j;
|
||||
for ( j = 1 ; j < MD3_MAX_LODS ; j++ )
|
||||
{
|
||||
if ( mod->md3[j] && mod->md3[j] != mod->md3[j-1] )
|
||||
{
|
||||
lods++;
|
||||
}
|
||||
}
|
||||
ri.Printf( PRINT_ALL, "%8i : (%i) %s\n",mod->dataSize, lods, mod->name );
|
||||
total += mod->dataSize;
|
||||
}
|
||||
ri.Printf( PRINT_ALL, "%8i : Total models\n", total );
|
||||
}
|
102
code/renderervk/tr_model.h
Normal file
102
code/renderervk/tr_model.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
#ifndef TR_MODEL_H_
|
||||
#define TR_MODEL_H_
|
||||
|
||||
#include "../renderercommon/iqm.h"
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
MOD_BAD,
|
||||
MOD_BRUSH,
|
||||
MOD_MESH,
|
||||
MOD_MDR,
|
||||
MOD_IQM
|
||||
} modtype_t;
|
||||
|
||||
typedef struct model_s {
|
||||
char name[MAX_QPATH];
|
||||
modtype_t type;
|
||||
int index; // model = tr.models[model->index]
|
||||
|
||||
int dataSize; // just for listing purposes
|
||||
bmodel_t *bmodel; // only if type == MOD_BRUSH
|
||||
md3Header_t *md3[MD3_MAX_LODS]; // only if type == MOD_MESH
|
||||
void *modelData; // only if type == (MOD_MDR | MOD_IQM)
|
||||
|
||||
int numLods;
|
||||
} model_t;
|
||||
|
||||
|
||||
#define MAX_MOD_KNOWN 1024
|
||||
|
||||
void R_ModelInit( void );
|
||||
model_t* R_GetModelByHandle( qhandle_t hModel );
|
||||
void R_Modellist_f( void );
|
||||
|
||||
//====================================================
|
||||
|
||||
qhandle_t R_RegisterMD3(const char *name, model_t *mod);
|
||||
|
||||
qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char *mod_name );
|
||||
qhandle_t R_RegisterMDR(const char *name, model_t *mod);
|
||||
|
||||
qboolean R_LoadIQM (model_t *mod, void *buffer, int filesize, const char *name );
|
||||
qhandle_t R_RegisterIQM(const char *name, model_t *mod);
|
||||
|
||||
|
||||
//====================================================
|
||||
// IQM
|
||||
|
||||
// inter-quake-model
|
||||
typedef struct {
|
||||
int num_vertexes;
|
||||
int num_triangles;
|
||||
int num_frames;
|
||||
int num_surfaces;
|
||||
int num_joints;
|
||||
int num_poses;
|
||||
struct srfIQModel_s *surfaces;
|
||||
|
||||
float *positions;
|
||||
float *texcoords;
|
||||
float *normals;
|
||||
float *tangents;
|
||||
byte *blendIndexes;
|
||||
union {
|
||||
float *f;
|
||||
byte *b;
|
||||
} blendWeights;
|
||||
byte *colors;
|
||||
int *triangles;
|
||||
|
||||
// depending upon the exporter, blend indices and weights might be int/float
|
||||
// as opposed to the recommended byte/byte, for example Noesis exports
|
||||
// int/float whereas the official IQM tool exports byte/byte
|
||||
byte blendWeightsType; // IQM_UBYTE or IQM_FLOAT
|
||||
|
||||
int *jointParents;
|
||||
float *jointMats;
|
||||
float *poseMats;
|
||||
float *bounds;
|
||||
char *names;
|
||||
} iqmData_t;
|
||||
|
||||
// inter-quake-model surface
|
||||
typedef struct srfIQModel_s {
|
||||
surfaceType_t surfaceType;
|
||||
char name[MAX_QPATH];
|
||||
shader_t *shader;
|
||||
iqmData_t *data;
|
||||
int first_vertex, num_vertexes;
|
||||
int first_triangle, num_triangles;
|
||||
} srfIQModel_t;
|
||||
|
||||
|
||||
void R_AddIQMSurfaces( trRefEntity_t *ent );
|
||||
void RB_IQMSurfaceAnim( surfaceType_t *surface );
|
||||
void ComputePoseMats( iqmData_t *data, int frame, int oldframe, float backlerp, float *mat );
|
||||
|
||||
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue