Codebase list iortcw / upstream/1.50a+dfsg1
New upstream version 1.50a+dfsg1 Simon McVittie 7 years ago
244 changed file(s) with 13488 addition(s) and 13931 deletion(s). Raw diff Collapse all Expand all
11 Makefile.local
22 *.swp
33 *tags
4 *~
45
56 # OS X
67 ####################
3435
3536 # Microsoft Visual Studio
3637 ####################
37 *.sdf
38 *.sdf
11 Makefile.local
22 *.swp
33 *tags
4 *~
45
56 # OS X
67 ####################
3435
3536 # Microsoft Visual Studio
3637 ####################
37 *.sdf
38 *.sdf
33 # GNU Make required
44 #
55
6 COMPILE_PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]'|sed -e 's/\//_/g')
7
8 COMPILE_ARCH=$(shell uname -m | sed -e s/i.86/i386/ | sed -e 's/^arm.*/arm/')
9
6 COMPILE_PLATFORM=$(shell uname | sed -e 's/_.*//' | tr '[:upper:]' '[:lower:]' | sed -e 's/\//_/g')
7 COMPILE_ARCH=$(shell uname -m | sed -e 's/i.86/x86/' | sed -e 's/^arm.*/arm/')
108 ARM_VER_CHECK=$(shell uname -m)
119
1210 ifeq ($(COMPILE_PLATFORM),sunos)
1311 # Solaris uname and GNU uname differ
14 COMPILE_ARCH=$(shell uname -p | sed -e s/i.86/i386/)
15 endif
16 ifeq ($(COMPILE_PLATFORM),darwin)
17 # Apple does some things a little differently...
18 COMPILE_ARCH=$(shell uname -p | sed -e s/i.86/i386/)
12 COMPILE_ARCH=$(shell uname -p | sed -e 's/i.86/x86/')
1913 endif
2014
2115 ifndef BUILD_STANDALONE
131125 export CROSS_COMPILING
132126
133127 ifndef VERSION
134 VERSION=1.42d
128 VERSION=1.5a
135129 endif
136130
137131 ifndef CLIENTBIN
258252 USE_RENDERER_DLOPEN=1
259253 endif
260254
255 ifndef USE_XDG
256 USE_XDG=0
257 endif
258
259 ifndef USE_YACC
260 USE_YACC=0
261 endif
262
261263 ifndef DEBUG_CFLAGS
262264 DEBUG_CFLAGS=-g -O0
263265 endif
280282
281283 ifndef USE_PBMD5
282284 USE_PBMD5=1
285 endif
286
287 ifndef USE_AUTHORIZE_SERVER
288 USE_AUTHORIZE_SERVER=0
283289 endif
284290
285291
302308 UIDIR=$(MOUNT_DIR)/ui
303309 JPDIR=$(MOUNT_DIR)/jpeg-8c
304310 OGGDIR=$(MOUNT_DIR)/libogg-1.3.2
305 VORBISDIR=$(MOUNT_DIR)/libvorbis-1.3.4
306 OPUSDIR=$(MOUNT_DIR)/opus-1.1
307 OPUSFILEDIR=$(MOUNT_DIR)/opusfile-0.6
311 VORBISDIR=$(MOUNT_DIR)/libvorbis-1.3.5
312 OPUSDIR=$(MOUNT_DIR)/opus-1.1.2
313 OPUSFILEDIR=$(MOUNT_DIR)/opusfile-0.7
308314 ZDIR=$(MOUNT_DIR)/zlib-1.2.8
309 FTDIR=$(MOUNT_DIR)/freetype-2.5.5
315 FTDIR=$(MOUNT_DIR)/freetype-2.6.4
310316 SPLDIR=$(MOUNT_DIR)/splines
311317 Q3ASMDIR=$(MOUNT_DIR)/tools/asm
312318 LBURGDIR=$(MOUNT_DIR)/tools/lcc/lburg
343349 endif
344350 endif
345351
346 # Add git version info
347 #USE_GIT=
348 #ifeq ($(wildcard ../.git),../.git)
349 # GIT_REV=$(shell git show -s --pretty=format:%h-%ad --date=short)
350 # ifneq ($(GIT_REV),)
351 # VERSION:=$(VERSION)_GIT_$(GIT_REV)
352 # USE_GIT=1
353 # endif
354 #endif
355
356352
357353 #############################################################################
358354 # SETUP AND BUILD -- LINUX
420416 ifeq ($(CROSS_COMPILING),1)
421417 ifeq ($(ARCH),x86)
422418 SDL_LIBS = $(LIBSDIR)/linux32/libSDL2main.a \
423 $(LIBSDIR)/linux32/libSDL2.so
419 $(LIBSDIR)/linux32/libSDL2-2.0.so.0.4.0
424420 endif
425421 ifeq ($(ARCH),x86_64)
426422 SDL_LIBS = $(LIBSDIR)/linux64/libSDL2main.a \
427 $(LIBSDIR)/linux64/libSDL2.so
423 $(LIBSDIR)/linux64/libSDL2-2.0.so.0.4.0
428424 endif
429425 endif
430426 endif
519515 $(error Architecture $(ARCH) is not supported when cross compiling)
520516 endif
521517 endif
522 else
523 TOOLS_CFLAGS += -DMACOS_X
524 endif
525
526 BASE_CFLAGS += -fno-strict-aliasing -DMACOS_X -fno-common -pipe
518 endif
519
520 BASE_CFLAGS += -fno-strict-aliasing -fno-common -pipe
527521
528522 ifeq ($(USE_OPENAL),1)
529523 ifneq ($(USE_OPENAL_DLOPEN),1)
596590
597591 # We need to figure out the correct gcc and windres
598592 ifeq ($(ARCH),x86_64)
599 MINGW_PREFIXES=amd64-mingw32msvc x86_64-w64-mingw32
593 MINGW_PREFIXES=x86_64-w64-mingw32 amd64-mingw32msvc
600594 endif
601595 ifeq ($(ARCH),x86)
602 MINGW_PREFIXES=i586-mingw32msvc i686-w64-mingw32 i686-pc-mingw32
596 MINGW_PREFIXES=i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32
603597 endif
604598
605599 ifndef CC
606 CC=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
607 $(call bin_path, $(MINGW_PREFIX)-gcc)))
600 CC=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
601 $(call bin_path, $(MINGW_PREFIX)-gcc))))
608602 endif
609603
610604 ifndef CXX
611 CXX=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
612 $(call bin_path, $(MINGW_PREFIX)-g++)))
605 CXX=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
606 $(call bin_path, $(MINGW_PREFIX)-g++))))
613607 endif
614608
615609 ifndef WINDRES
616 WINDRES=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
617 $(call bin_path, $(MINGW_PREFIX)-windres)))
610 WINDRES=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
611 $(call bin_path, $(MINGW_PREFIX)-windres))))
618612 endif
619613 else
620614 # Some MinGW installations define CC to cc, but don't actually provide cc,
624618 endif
625619
626620 ifndef CXX
627 CC=g++
621 CXX=g++
628622 endif
629623
630624 ifndef WINDRES
741735 else # ifdef MINGW
742736
743737 #############################################################################
744 # SETUP AND BUILD -- FREEBSD
745 #############################################################################
746
747 ifeq ($(PLATFORM),freebsd)
748
749 # flags
750 BASE_CFLAGS = $(shell env MACHINE_ARCH=$(ARCH) make -f /dev/null -VCFLAGS) \
751 -Wall -fno-strict-aliasing \
752 -DUSE_ICON -DMAP_ANONYMOUS=MAP_ANON
753 CLIENT_CFLAGS += $(SDL_CFLAGS)
754
755 OPTIMIZEVM = -O3
756 OPTIMIZE = $(OPTIMIZEVM) -ffast-math
757
758 SHLIBEXT=so
759 SHLIBCFLAGS=-fPIC
760 SHLIBLDFLAGS=-shared $(LDFLAGS)
761
762 THREAD_LIBS=-lpthread
763 # don't need -ldl (FreeBSD)
764 LIBS=-lm
765
766 CLIENT_LIBS =
767
768 CLIENT_LIBS += $(SDL_LIBS)
769 RENDERER_LIBS = $(SDL_LIBS) -lGL
770
771 # optional features/libraries
772 ifeq ($(USE_OPENAL),1)
773 ifeq ($(USE_OPENAL_DLOPEN),1)
774 CLIENT_LIBS += $(THREAD_LIBS) $(OPENAL_LIBS)
775 endif
776 endif
777
778 ifeq ($(USE_CURL),1)
779 CLIENT_CFLAGS += $(CURL_CFLAGS)
780 ifeq ($(USE_CURL_DLOPEN),1)
781 CLIENT_LIBS += $(CURL_LIBS)
782 endif
783 endif
784
785 else # ifeq freebsd
786
787 #############################################################################
788 # SETUP AND BUILD -- OPENBSD
789 #############################################################################
790
791 ifeq ($(PLATFORM),openbsd)
738 # SETUP AND BUILD -- *BSD (is dying)
739 #############################################################################
740
741 ifneq (,$(findstring "$(PLATFORM)", "freebsd" "openbsd" "netbsd"))
792742
793743 BASE_CFLAGS = -Wall -fno-strict-aliasing \
794744 -pipe -DUSE_ICON -DMAP_ANONYMOUS=MAP_ANON
800750 ifeq ($(ARCH),x86_64)
801751 OPTIMIZEVM = -O3
802752 OPTIMIZE = $(OPTIMIZEVM) -ffast-math
753 FILE_ARCH = amd64
803754 endif
804755 ifeq ($(ARCH),x86)
805756 OPTIMIZEVM = -O3 -march=i586
830781 USE_CURL_DLOPEN=0
831782 endif
832783
833 # no shm_open on OpenBSD
834 USE_MUMBLE=0
835
836784 SHLIBEXT=so
837785 SHLIBCFLAGS=-fPIC
838786 SHLIBLDFLAGS=-shared $(LDFLAGS)
856804 CLIENT_LIBS += $(CURL_LIBS)
857805 endif
858806 endif
859 else # ifeq openbsd
860
861 #############################################################################
862 # SETUP AND BUILD -- NETBSD
863 #############################################################################
864
865 ifeq ($(PLATFORM),netbsd)
866
867 LIBS=-lm
868 SHLIBEXT=so
869 SHLIBCFLAGS=-fPIC
870 SHLIBLDFLAGS=-shared $(LDFLAGS)
871 THREAD_LIBS=-lpthread
872
873 BASE_CFLAGS = -Wall -fno-strict-aliasing
874
875 BUILD_CLIENT = 0
876 else # ifeq netbsd
807 else # ifeq *BSD
877808
878809 #############################################################################
879810 # SETUP AND BUILD -- IRIX
965896 endif #Linux
966897 endif #darwin
967898 endif #MINGW
968 endif #FreeBSD
969 endif #OpenBSD
970 endif #NetBSD
899 endif #*BSD
971900 endif #IRIX
972901 endif #SunOS
973902
976905 endif
977906
978907 ifndef CXX
979 CC=g++
908 CXX=g++
980909 endif
981910
982911 ifndef RANLIB
11031032
11041033 ifeq ($(NEED_OPUS),1)
11051034 ifeq ($(USE_INTERNAL_OPUS),1)
1106 OPUS_CFLAGS = -DOPUS_BUILD -DHAVE_LRINTF -DFLOATING_POINT -DUSE_ALLOCA \
1035 OPUS_CFLAGS = -DOPUS_BUILD -DHAVE_LRINTF -DFLOAT_APPROX -DUSE_ALLOCA \
11071036 -I$(OPUSDIR)/include -I$(OPUSDIR)/celt -I$(OPUSDIR)/silk \
11081037 -I$(OPUSDIR)/silk/float -I$(OPUSFILEDIR)/include
11091038 else
11411070
11421071 ifeq ($(USE_RENDERER_DLOPEN),1)
11431072 CLIENT_CFLAGS += -DUSE_RENDERER_DLOPEN
1073 endif
1074
1075 ifeq ($(USE_XDG),1)
1076 CLIENT_CFLAGS += -DUSE_XDG
1077 SERVER_CFLAGS += -DUSE_XDG
11441078 endif
11451079
11461080 ifeq ($(USE_MUMBLE),1)
11991133 BASE_CFLAGS += -DSTANDALONE
12001134 endif
12011135
1136 ifeq ($(USE_AUTHORIZE_SERVER),1)
1137 BASE_CFLAGS += -DUSE_AUTHORIZE_SERVER
1138 endif
1139
12021140 ifeq ($(GENERATE_DEPENDENCIES),1)
12031141 DEPEND_CFLAGS = -MMD
12041142 else
12211159
12221160 ifeq ($(USE_PBMD5),1)
12231161 CLIENT_CFLAGS += -DUSE_PBMD5
1162 endif
1163
1164 # https://reproducible-builds.org/specs/source-date-epoch/
1165 ifdef SOURCE_DATE_EPOCH
1166 BASE_CFLAGS += -DPRODUCT_DATE=\\\"$(shell date --date="@$$SOURCE_DATE_EPOCH" "+%b %_d %Y" | sed -e 's/ /\\\ /'g)\\\"
12241167 endif
12251168
12261169 BASE_CFLAGS += -DPRODUCT_VERSION=\\\"$(VERSION)\\\"
14581401 TOOLS_CC = gcc
14591402 endif
14601403
1404 ifndef YACC
1405 YACC = yacc
1406 endif
1407
14611408 TOOLS_OPTIMIZE = -g -Wall -fno-strict-aliasing
14621409 TOOLS_CFLAGS += $(TOOLS_OPTIMIZE) \
14631410 -DTEMPDIR=\"$(TEMPDIR)\" -DSYSTEM=\"\" \
14701417 TOOLS_CFLAGS += -MMD
14711418 endif
14721419
1420 define DO_YACC
1421 $(echo_cmd) "YACC $<"
1422 $(Q)$(YACC) $<
1423 $(Q)mv -f y.tab.c $@
1424 endef
1425
14731426 define DO_TOOLS_CC
14741427 $(echo_cmd) "TOOLS_CC $<"
14751428 $(Q)$(TOOLS_CC) $(TOOLS_CFLAGS) -o $@ -c $<
14901443 LBURGOBJ= \
14911444 $(B)/tools/lburg/lburg.o \
14921445 $(B)/tools/lburg/gram.o
1446
1447 # override GNU Make built-in rule for converting gram.y to gram.c
1448 %.c: %.y
1449 ifeq ($(USE_YACC),1)
1450 $(DO_YACC)
1451 endif
14931452
14941453 $(B)/tools/lburg/%.o: $(LBURGDIR)/%.c
14951454 $(DO_TOOLS_CC)
17341693 $(B)/rend2/tr_bsp.o \
17351694 $(B)/rend2/tr_cmds.o \
17361695 $(B)/rend2/tr_curve.o \
1696 $(B)/rend2/tr_dsa.o \
17371697 $(B)/rend2/tr_extramath.o \
17381698 $(B)/rend2/tr_extensions.o \
17391699 $(B)/rend2/tr_fbo.o \
17461706 $(B)/rend2/tr_image_pcx.o \
17471707 $(B)/rend2/tr_image_png.o \
17481708 $(B)/rend2/tr_image_tga.o \
1709 $(B)/rend2/tr_image_dds.o \
17491710 $(B)/rend2/tr_init.o \
17501711 $(B)/rend2/tr_light.o \
17511712 $(B)/rend2/tr_main.o \
19121873 $(B)/renderer/ftbdf.o \
19131874 $(B)/renderer/ftbitmap.o \
19141875 $(B)/renderer/ftcid.o \
1876 $(B)/renderer/ftfntfmt.o \
19151877 $(B)/renderer/ftfstype.o \
19161878 $(B)/renderer/ftgasp.o \
19171879 $(B)/renderer/ftglyph.o \
19251887 $(B)/renderer/ftsynth.o \
19261888 $(B)/renderer/fttype1.o \
19271889 $(B)/renderer/ftwinfnt.o \
1928 $(B)/renderer/ftxf86.o \
19291890 $(B)/renderer/truetype.o \
19301891 $(B)/renderer/type1.o \
19311892 $(B)/renderer/cff.o \
22032164 ifneq ($(USE_RENDERER_DLOPEN),0)
22042165 $(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(LIBSDLMAIN)
22052166 $(echo_cmd) "LD $@"
2206 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
2167 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
22072168 -o $@ $(Q3OBJ) \
22082169 $(LIBSDLMAIN) $(CLIENT_LIBS) $(LIBS)
22092170
22192180 else
22202181 $(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(Q3ROBJ) $(JPGOBJ) $(FTOBJ) $(LIBSDLMAIN)
22212182 $(echo_cmd) "LD $@"
2222 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
2183 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
22232184 -o $@ $(Q3OBJ) $(Q3ROBJ) $(JPGOBJ) $(FTOBJ) \
22242185 $(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
22252186
22262187 $(B)/$(CLIENTBIN)_rend2$(FULLBINEXT): $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) $(FTOBJ) $(LIBSDLMAIN)
22272188 $(echo_cmd) "LD $@"
2228 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
2189 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
22292190 -o $@ $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) $(FTOBJ) \
22302191 $(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
22312192 endif
23742335
23752336 $(B)/$(SERVERBIN)$(FULLBINEXT): $(Q3DOBJ)
23762337 $(echo_cmd) "LD $@"
2377 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(Q3DOBJ) $(LIBS)
2338 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) -o $@ $(Q3DOBJ) $(LIBS)
23782339
23792340
23802341
27302691 $(DO_DED_CC)
27312692
27322693 # Extra dependencies to ensure the git version is incorporated
2733 #ifeq ($(USE_GIT),1)
2734 # $(B)/client/cl_console.o : ../.git/index
2735 # $(B)/client/common.o : ../.git/index
2736 # $(B)/ded/common.o : ../.git/index
2737 #endif
2694 $(B)/client/cl_console.o : ../.git/index
2695 $(B)/client/common.o : ../.git/index
2696 $(B)/ded/common.o : ../.git/index
27382697
27392698
27402699 #############################################################################
151151 } //end else if
152152 else
153153 {
154 Log_Write( "portal using area %d is seperating more than two clusters\r\n", areanum );
154 Log_Write( "portal using area %d is separating more than two clusters\r\n", areanum );
155155 //remove the cluster portal flag contents
156156 ( *aasworld ).areasettings[areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL;
157157 return qfalse;
12941294 script = LoadScriptMemory( string, strlen( string ), "*extern" );
12951295 //create a new source
12961296 memset( &src, 0, sizeof( source_t ) );
1297 strncpy( src.filename, "*extern", _MAX_PATH );
1297 strncpy( src.filename, "*extern", sizeof( src.filename ) - 1 );
12981298 src.scriptstack = script;
12991299 #if DEFINEHASHING
13001300 src.definehash = GetClearedMemory( DEFINEHASHSIZE * sizeof( define_t * ) );
15201520 if ( cg_reticles.integer ) {
15211521
15221522 // sides
1523 if ( cg_fixedAspect.integer ) {
1523 if ( cg_fixedAspect.integer && !cg.limboMenu ) {
15241524 if ( cgs.glconfig.vidWidth * 480.0 > cgs.glconfig.vidHeight * 640.0 ) {
15251525 mask = 0.5 * ( ( cgs.glconfig.vidWidth - ( cgs.screenXScale * 480.0 ) ) / cgs.screenXScale );
15261526
15721572 if ( cg_reticles.integer ) {
15731573
15741574 // sides
1575 if ( cg_fixedAspect.integer ) {
1575 if ( cg_fixedAspect.integer && !cg.limboMenu ) {
15761576 if ( cgs.glconfig.vidWidth * 480.0 > cgs.glconfig.vidHeight * 640.0 ) {
15771577 mask = 0.5 * ( ( cgs.glconfig.vidWidth - ( cgs.screenXScale * 480.0 ) ) / cgs.screenXScale );
15781578
17221722 float f;
17231723 float x, y;
17241724 int weapnum; // DHM - Nerve
1725 vec4_t hcolor = {1, 1, 1, 1};
17251726
17261727 if ( cg.renderingThirdPerson ) {
17271728 return;
17921793
17931794 // set color based on health
17941795 if ( cg_crosshairHealth.integer ) {
1795 vec4_t hcolor;
1796
17971796 CG_ColorForHealth( hcolor );
17981797 trap_R_SetColor( hcolor );
17991798 } else {
18741873 qhandle_t hShader;
18751874 float f;
18761875 int weapnum; // DHM - Nerve
1877
18781876 trace_t trace;
18791877 vec3_t endpos;
18801878 float stereoSep, zProj, maxdist, xmax;
19791977 ent.radius = w / 640 * xmax * trace.fraction * maxdist / zProj;
19801978 ent.customShader = hShader;
19811979
1980 ent.shaderRGBA[0]=255;
1981 ent.shaderRGBA[1]=255;
1982 ent.shaderRGBA[2]=255;
1983 ent.shaderRGBA[3]=255;
1984
19821985 trap_R_AddRefEntityToScene(&ent);
1986
1987 if ( cg.crosshairShaderAlt[ cg_drawCrosshair.integer % NUM_CROSSHAIRS ] ) {
1988 ent.customShader = cg.crosshairShaderAlt[ cg_drawCrosshair.integer % NUM_CROSSHAIRS ];
1989
1990 ent.shaderRGBA[0]=255;
1991 ent.shaderRGBA[1]=255;
1992 ent.shaderRGBA[2]=255;
1993 ent.shaderRGBA[3]=255;
1994
1995 trap_R_AddRefEntityToScene(&ent);
1996 }
19831997 }
19841998
19851999
28462860 if ( cg_fixedAspect.integer ) {
28472861 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
28482862 CG_FillRect( -10, -10, 650, 490, col );
2863 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
28492864 } else {
28502865 CG_FillRect( -10, -10, 650, 490, col );
28512866 }
29052920 if ( cg_fixedAspect.integer ) {
29062921 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
29072922 CG_FillRect( -10, -10, 650, 490, color );
2923 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
29082924 } else {
29092925 CG_FillRect( -10, -10, 650, 490, color );
29102926 }
29262942 return;
29272943 }
29282944
2945 if (!cg_blood.integer) {
2946 return;
2947 }
2948
29292949 if ( cg.v_dmg_time > cg.time ) {
29302950 redFlash = fabs( cg.v_dmg_pitch * ( ( cg.v_dmg_time - cg.time ) / DAMAGE_TIME ) );
29312951
29402960 if ( cg_fixedAspect.integer ) {
29412961 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
29422962 CG_FillRect( -10, -10, 650, 490, col );
2963 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
29432964 } else {
29442965 CG_FillRect( -10, -10, 650, 490, col );
29452966 }
29933014 if ( cg_fixedAspect.integer ) {
29943015 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
29953016 CG_DrawPic( -10, -10, 650, 490, cgs.media.viewFlashFire[( cg.time / 50 ) % 16] );
3017 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
29963018 } else {
29973019 CG_DrawPic( -10, -10, 650, 490, cgs.media.viewFlashFire[( cg.time / 50 ) % 16] );
29983020 }
30373059 if ( cg_fixedAspect.integer ) {
30383060 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
30393061 CG_DrawPic( -10, -10, 650, 490, shader );
3062 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
30403063 } else {
30413064 CG_DrawPic( -10, -10, 650, 490, shader );
30423065 }
31363159 return;
31373160 }
31383161
3162 if ( cg_fixedAspect.integer ) {
3163 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
3164 }
3165
31393166 trap_R_SetColor( color );
31403167
31413168 start = cg.oidPrint;
34743501 if ( cg_fixedAspect.integer ) {
34753502 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
34763503 CG_FillRect( 0, 0, 640, 480, cg.fadeColor1 );
3504 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
34773505 } else {
34783506 CG_FillRect( 0, 0, 640, 480, cg.fadeColor1 );
34793507 }
34903518 if ( cg_fixedAspect.integer ) {
34913519 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
34923520 CG_FillRect( 0, 0, 640, 480, color );
3521 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
34933522 } else {
34943523 CG_FillRect( 0, 0, 640, 480, color );
34953524 }
175175 int otime;
176176 int lastch, nextch;
177177
178 if ( !cent->dl_stylestring ) {
178 if ( cent->dl_stylestring[0] == '\0' ) {
179179 return;
180180 }
181181
13261326 float f;
13271327 static qboolean foginited = qfalse; // only set the portal fog values once
13281328
1329 if ( !cg_skybox.integer ) {
1330 return;
1331 }
1332
13331329 if ( !( cstr = (char *)CG_ConfigString( CS_SKYBOXORG ) ) || !strlen( cstr ) ) {
13341330 // no skybox in this map
13351331 return;
13441340
13451341 backuprefdef = cg.refdef;
13461342
1347 token = COM_ParseExt( &cstr, qfalse );
1348 if ( !token || !token[0] ) {
1349 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1350 }
1351 cg.refdef.vieworg[0] = atof( token );
1352
1353 token = COM_ParseExt( &cstr, qfalse );
1354 if ( !token || !token[0] ) {
1355 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1356 }
1357 cg.refdef.vieworg[1] = atof( token );
1358
1359 token = COM_ParseExt( &cstr, qfalse );
1360 if ( !token || !token[0] ) {
1361 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1362 }
1363 cg.refdef.vieworg[2] = atof( token );
1364
1365 token = COM_ParseExt( &cstr, qfalse );
1366 if ( !token || !token[0] ) {
1367 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1368 }
1369
1370 // setup fog the first time, ignore this part of the configstring after that
1371 token = COM_ParseExt( &cstr, qfalse );
1372 if ( !token || !token[0] ) {
1373 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog state\n" );
1374 } else {
1375 vec4_t fogColor;
1376 int fogStart, fogEnd;
1377
1378 if ( atoi( token ) ) { // this camera has fog
1379 if ( !foginited ) {
1380 token = COM_ParseExt( &cstr, qfalse );
1381 if ( !token || !token[0] ) {
1382 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[0]\n" );
1343 if ( cg_skybox.integer ) {
1344 token = COM_ParseExt( &cstr, qfalse );
1345 if ( !token || !token[0] ) {
1346 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1347 }
1348 cg.refdef.vieworg[0] = atof( token );
1349
1350 token = COM_ParseExt( &cstr, qfalse );
1351 if ( !token || !token[0] ) {
1352 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1353 }
1354 cg.refdef.vieworg[1] = atof( token );
1355
1356 token = COM_ParseExt( &cstr, qfalse );
1357 if ( !token || !token[0] ) {
1358 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1359 }
1360 cg.refdef.vieworg[2] = atof( token );
1361
1362 token = COM_ParseExt( &cstr, qfalse );
1363 if ( !token || !token[0] ) {
1364 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
1365 }
1366
1367 // setup fog the first time, ignore this part of the configstring after that
1368 token = COM_ParseExt( &cstr, qfalse );
1369 if ( !token || !token[0] ) {
1370 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog state\n" );
1371 } else {
1372 vec4_t fogColor;
1373 int fogStart, fogEnd;
1374
1375 if ( atoi( token ) ) { // this camera has fog
1376 if ( 1 ) {
1377 token = COM_ParseExt( &cstr, qfalse );
1378 if ( !token || !token[0] ) {
1379 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[0]\n" );
1380 }
1381 fogColor[0] = atof( token );
1382
1383 token = COM_ParseExt( &cstr, qfalse );
1384 if ( !token || !token[0] ) {
1385 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[1]\n" );
1386 }
1387 fogColor[1] = atof( token );
1388
1389 token = COM_ParseExt( &cstr, qfalse );
1390 if ( !token || !token[0] ) {
1391 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[2]\n" );
1392 }
1393 fogColor[2] = atof( token );
1394
1395 token = COM_ParseExt( &cstr, qfalse );
1396 if ( !token || !token[0] ) {
1397 fogStart = 0;
1398 } else {
1399 fogStart = atoi( token );
1400 }
1401
1402 token = COM_ParseExt( &cstr, qfalse );
1403 if ( !token || !token[0] ) {
1404 fogEnd = 0;
1405 } else {
1406 fogEnd = atoi( token );
1407 }
1408
1409 trap_R_SetFog( FOG_PORTALVIEW, fogStart, fogEnd, fogColor[0], fogColor[1], fogColor[2], 1.1 );
1410 foginited = qtrue;
13831411 }
1384 fogColor[0] = atof( token );
1385
1386 token = COM_ParseExt( &cstr, qfalse );
1387 if ( !token || !token[0] ) {
1388 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[1]\n" );
1412 } else {
1413 if ( !foginited ) {
1414 trap_R_SetFog( FOG_PORTALVIEW, 0,0,0,0,0,0 ); // init to null
1415 foginited = qtrue;
13891416 }
1390 fogColor[1] = atof( token );
1391
1392 token = COM_ParseExt( &cstr, qfalse );
1393 if ( !token || !token[0] ) {
1394 CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[2]\n" );
1395 }
1396 fogColor[2] = atof( token );
1397
1398 token = COM_ParseExt( &cstr, qfalse );
1399 if ( !token || !token[0] ) {
1400 fogStart = 0;
1401 } else {
1402 fogStart = atoi( token );
1403 }
1404
1405 token = COM_ParseExt( &cstr, qfalse );
1406 if ( !token || !token[0] ) {
1407 fogEnd = 0;
1408 } else {
1409 fogEnd = atoi( token );
1410 }
1411
1412 trap_R_SetFog( FOG_PORTALVIEW, fogStart, fogEnd, fogColor[0], fogColor[1], fogColor[2], 1.1 );
1413 foginited = qtrue;
14141417 }
1415 } else {
1416 if ( !foginited ) {
1417 trap_R_SetFog( FOG_PORTALVIEW, 0,0,0,0,0,0 ); // init to null
1418 foginited = qtrue;
1419 }
1420 }
1421 }
1422
1423 //----(SA) end
1424
1425
1426 if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
1427 // if in intermission, use a fixed value
1428 fov_x = 90;
1429 } else {
1430 // user selectable
1431 if ( ( cgs.dmflags & DF_FIXED_FOV ) || cg_fixedAspect.integer ) {
1432 // dmflag to prevent wide fov for all clients
1418 }
1419
1420 //----(SA) end
1421
1422
1423 if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
1424 // if in intermission, use a fixed value
14331425 fov_x = 90;
14341426 } else {
1435 fov_x = cg_fov.value;
1436 if ( fov_x < 1 ) {
1437 fov_x = 1;
1438 } else if ( fov_x > 160 ) {
1439 fov_x = 160;
1427 // user selectable
1428 if ( ( cgs.dmflags & DF_FIXED_FOV ) || cg_fixedAspect.integer ) {
1429 // dmflag to prevent wide fov for all clients
1430 fov_x = 90;
1431 } else {
1432 fov_x = cg_fov.value;
1433 if ( fov_x < 1 ) {
1434 fov_x = 1;
1435 } else if ( fov_x > 160 ) {
1436 fov_x = 160;
1437 }
14401438 }
1441 }
1442
1443 // account for zooms
1444 if ( cg.zoomval ) {
1445 zoomFov = cg.zoomval; // (SA) use user scrolled amount
1446
1447 if ( zoomFov < 1 ) {
1448 zoomFov = 1;
1449 } else if ( zoomFov > 160 ) {
1450 zoomFov = 160;
1439
1440 // account for zooms
1441 if ( cg.zoomval ) {
1442 zoomFov = cg.zoomval; // (SA) use user scrolled amount
1443
1444 if ( zoomFov < 1 ) {
1445 zoomFov = 1;
1446 } else if ( zoomFov > 160 ) {
1447 zoomFov = 160;
1448 }
1449 } else {
1450 zoomFov = lastfov;
14511451 }
1452
1453 // do smooth transitions for the binocs
1454 if ( cg.zoomedBinoc ) { // binoc zooming in
1455 f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
1456 if ( f > 1.0 ) {
1457 fov_x = zoomFov;
1458 } else {
1459 fov_x = fov_x + f * ( zoomFov - fov_x );
1460 }
1461 lastfov = fov_x;
1462 } else if ( cg.zoomval ) { // zoomed by sniper/snooper
1463 fov_x = cg.zoomval;
1464 lastfov = fov_x;
1465 } else { // binoc zooming out
1466 f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
1467 if ( f <= 1.0 ) {
1468 fov_x = zoomFov + f * ( fov_x - zoomFov );
1469 }
1470 }
1471 }
1472
1473 if ( cg.weaponSelect == WP_SNOOPERSCOPE ) {
1474 cg.refdef.rdflags |= RDF_SNOOPERVIEW;
14521475 } else {
1453 zoomFov = lastfov;
1454 }
1455
1456 // do smooth transitions for the binocs
1457 if ( cg.zoomedBinoc ) { // binoc zooming in
1458 f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
1459 if ( f > 1.0 ) {
1460 fov_x = zoomFov;
1461 } else {
1462 fov_x = fov_x + f * ( zoomFov - fov_x );
1463 }
1464 lastfov = fov_x;
1465 } else if ( cg.zoomval ) { // zoomed by sniper/snooper
1466 fov_x = cg.zoomval;
1467 lastfov = fov_x;
1468 } else { // binoc zooming out
1469 f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
1470 if ( f <= 1.0 ) {
1471 fov_x = zoomFov + f * ( fov_x - zoomFov );
1472 }
1473 }
1474 }
1475
1476 if ( cg.weaponSelect == WP_SNOOPERSCOPE ) {
1477 cg.refdef.rdflags |= RDF_SNOOPERVIEW;
1478 } else {
1479 cg.refdef.rdflags &= ~RDF_SNOOPERVIEW;
1480 }
1481
1482 if ( cg.snap->ps.persistant[PERS_HWEAPON_USE] ) {
1483 fov_x = 55;
1484 }
1485
1486 if ( cg_fixedAspect.integer ) {
1487 // Based on LordHavoc's code for Darkplaces
1488 // http://www.quakeworld.nu/forum/topic/53/what-does-your-qw-look-like/page/30
1489 const float baseAspect = 0.75f; // 3/4
1490 const float aspect = (float)cg.refdef.width/(float)cg.refdef.height;
1491 const float desiredFov = fov_x;
1492
1493 fov_x = atan2( tan( desiredFov*M_PI / 360.0f ) * baseAspect*aspect, 1 )*360.0f / M_PI;
1494 }
1476 cg.refdef.rdflags &= ~RDF_SNOOPERVIEW;
1477 }
1478
1479 if ( cg.snap->ps.persistant[PERS_HWEAPON_USE] ) {
1480 fov_x = 55;
1481 }
1482
1483 if ( cg_fixedAspect.integer ) {
1484 // Based on LordHavoc's code for Darkplaces
1485 // http://www.quakeworld.nu/forum/topic/53/what-does-your-qw-look-like/page/30
1486 const float baseAspect = 0.75f; // 3/4
1487 const float aspect = (float)cg.refdef.width/(float)cg.refdef.height;
1488 const float desiredFov = fov_x;
1489
1490 fov_x = atan2( tan( desiredFov*M_PI / 360.0f ) * baseAspect*aspect, 1 )*360.0f / M_PI;
1491 }
1492
1493 x = cg.refdef.width / tan( fov_x / 360 * M_PI );
1494 fov_y = atan2( cg.refdef.height, x );
1495 fov_y = fov_y * 360 / M_PI;
1496
1497 cg.refdef.fov_x = fov_x;
1498 cg.refdef.fov_y = fov_y;
1499 }
1500
1501 cg.refdef.rdflags |= RDF_SKYBOXPORTAL;
14951502
14961503 cg.refdef.time = cg.time;
1497
1498 x = cg.refdef.width / tan( fov_x / 360 * M_PI );
1499 fov_y = atan2( cg.refdef.height, x );
1500 fov_y = fov_y * 360 / M_PI;
1501
1502 cg.refdef.fov_x = fov_x;
1503 cg.refdef.fov_y = fov_y;
1504
1505 cg.refdef.rdflags |= RDF_SKYBOXPORTAL;
15061504
15071505 // draw the skybox
15081506 trap_R_RenderScene( &cg.refdef );
28302830 fovOffset[2] = -0.2 * ( cg_fov.integer - 90 );
28312831 }
28322832
2833 memset( &hand, 0, sizeof( hand ) );
2834
28332835 if ( ps->weapon > WP_NONE ) {
28342836 CG_RegisterWeapon( ps->weapon );
28352837 weapon = &cg_weapons[ ps->weapon ];
2836
2837 memset( &hand, 0, sizeof( hand ) );
28382838
28392839 // set up gun position
28402840 CG_CalculateWeaponPosition( hand.origin, angles );
28582858 CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp ); //----(SA) changed
28592859 }
28602860
2861 VectorCopy( hand.origin, hand.lightingOrigin );
28612862
28622863 hand.hModel = weapon->handsModel;
28632864 hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT; //----(SA)
14361436 RoQReset();
14371437 } else {
14381438 RoQShutdown();
1439 return FMV_EOF;
14391440 }
14401441 }
14411442
2727 #include "../qcommon/qcommon.h"
2828
2929 #ifdef USE_LOCAL_HEADERS
30 #include "../libcurl-7.35.0/curl/curl.h"
30 #include "../curl-7.46.0/include/curl/curl.h"
3131 #else
3232 #include <curl/curl.h>
3333 #endif
3636 #ifdef WIN32
3737 #define DEFAULT_CURL_LIB "libcurl-4.dll"
3838 #define ALTERNATE_CURL_LIB "libcurl-3.dll"
39 #elif defined(MACOS_X)
39 #elif defined(__APPLE__)
4040 #define DEFAULT_CURL_LIB "libcurl.dylib"
4141 #else
4242 #define DEFAULT_CURL_LIB "libcurl.so.4"
462462 void CL_JoystickMove( usercmd_t *cmd ) {
463463 float anglespeed;
464464
465 float yaw = j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
466 float right = j_side->value * cl.joystickAxis[j_side_axis->integer];
467 float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
468 float pitch = j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
469 float up = j_up->value * cl.joystickAxis[j_up_axis->integer];
470
465471 if ( !( kb[KB_SPEED].active ^ cl_run->integer ) ) {
466472 cmd->buttons |= BUTTON_WALKING;
467473 }
473479 }
474480
475481 if ( !kb[KB_STRAFE].active ) {
476 cl.viewangles[YAW] += anglespeed * j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
477 cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_side->value * cl.joystickAxis[j_side_axis->integer]) );
478 } else {
479 cl.viewangles[YAW] += anglespeed * j_side->value * cl.joystickAxis[j_side_axis->integer];
480 cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_yaw->value * cl.joystickAxis[j_yaw_axis->integer]) );
482 cl.viewangles[YAW] += anglespeed * yaw;
483 cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
484 } else {
485 cl.viewangles[YAW] += anglespeed * right;
486 cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
481487 }
482488 if ( kb[KB_MLOOK].active ) {
483 cl.viewangles[PITCH] += anglespeed * j_forward->value * cl.joystickAxis[j_forward_axis->integer];
484 cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_pitch->value * cl.joystickAxis[j_pitch_axis->integer]) );
485 } else {
486 cl.viewangles[PITCH] += anglespeed * j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
487 cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_forward->value * cl.joystickAxis[j_forward_axis->integer]) );
488 }
489
490 cmd->upmove = ClampChar( cmd->upmove + (int) (j_up->value * cl.joystickAxis[j_up_axis->integer]) );
489 cl.viewangles[PITCH] += anglespeed * forward;
490 cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
491 } else {
492 cl.viewangles[PITCH] += anglespeed * pitch;
493 cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
494 }
495
496 cmd->upmove = ClampChar( cmd->upmove + (int)up );
491497 }
492498
493499 /*
728734 }
729735
730736 frame_msec = com_frameTime - old_com_frameTime;
737
738 // if running over 1000fps, act as if each frame is 1ms
739 // prevents divisions by zero
740 if ( frame_msec < 1 ) {
741 frame_msec = 1;
742 }
731743
732744 // if running less than 5fps, truncate the extra time to prevent
733745 // unexpected moves after a hitch
297297 {"EURO", K_EURO},
298298 {"UNDO", K_UNDO},
299299
300 {"PAD0_A", K_PAD0_A },
301 {"PAD0_B", K_PAD0_B },
302 {"PAD0_X", K_PAD0_X },
303 {"PAD0_Y", K_PAD0_Y },
304 {"PAD0_BACK", K_PAD0_BACK },
305 {"PAD0_GUIDE", K_PAD0_GUIDE },
306 {"PAD0_START", K_PAD0_START },
307 {"PAD0_LEFTSTICK_CLICK", K_PAD0_LEFTSTICK_CLICK },
308 {"PAD0_RIGHTSTICK_CLICK", K_PAD0_RIGHTSTICK_CLICK },
309 {"PAD0_LEFTSHOULDER", K_PAD0_LEFTSHOULDER },
310 {"PAD0_RIGHTSHOULDER", K_PAD0_RIGHTSHOULDER },
311 {"PAD0_DPAD_UP", K_PAD0_DPAD_UP },
312 {"PAD0_DPAD_DOWN", K_PAD0_DPAD_DOWN },
313 {"PAD0_DPAD_LEFT", K_PAD0_DPAD_LEFT },
314 {"PAD0_DPAD_RIGHT", K_PAD0_DPAD_RIGHT },
315
316 {"PAD0_LEFTSTICK_LEFT", K_PAD0_LEFTSTICK_LEFT },
317 {"PAD0_LEFTSTICK_RIGHT", K_PAD0_LEFTSTICK_RIGHT },
318 {"PAD0_LEFTSTICK_UP", K_PAD0_LEFTSTICK_UP },
319 {"PAD0_LEFTSTICK_DOWN", K_PAD0_LEFTSTICK_DOWN },
320 {"PAD0_RIGHTSTICK_LEFT", K_PAD0_RIGHTSTICK_LEFT },
321 {"PAD0_RIGHTSTICK_RIGHT", K_PAD0_RIGHTSTICK_RIGHT },
322 {"PAD0_RIGHTSTICK_UP", K_PAD0_RIGHTSTICK_UP },
323 {"PAD0_RIGHTSTICK_DOWN", K_PAD0_RIGHTSTICK_DOWN },
324 {"PAD0_LEFTTRIGGER", K_PAD0_LEFTTRIGGER },
325 {"PAD0_RIGHTTRIGGER", K_PAD0_RIGHTTRIGGER },
326
300327 {NULL,0}
301328 };
302329
14811481 }
14821482
14831483 // shutting down the client so enter full screen ui mode
1484 Cvar_Set("r_uiFullScreen", "1");
1484 Cvar_Set( "r_uiFullScreen", "1" );
14851485
14861486 if ( clc.demorecording ) {
14871487 CL_StopRecord_f ();
15171517 for (i = 0; i < MAX_CLIENTS; i++) {
15181518 opus_decoder_destroy(clc.opusDecoder[i]);
15191519 }
1520 clc.voipCodecInitialized = qfalse;
15201521 }
15211522 Cmd_RemoveCommand ("voip");
15221523 #endif
16851686 ===================
16861687 */
16871688 #ifndef STANDALONE
1689 #ifdef USE_AUTHORIZE_SERVER
16881690 void CL_RequestAuthorization( void ) {
16891691 char nums[64];
16901692 int i, j, l;
17281730
17291731 NET_OutOfBandPrint(NS_CLIENT, cls.authorizeServer, "getKeyAuthorize %i %s", fs->integer, nums );
17301732 }
1733 #endif
17311734 #endif
17321735
17331736 /*
25052508 case CA_CONNECTING:
25062509 // requesting a challenge .. IPv6 users always get in as authorize server supports no ipv6.
25072510 #ifndef STANDALONE
2511 #ifdef USE_AUTHORIZE_SERVER
25082512 if (!com_standalone->integer && clc.serverAddress.type == NA_IP && !Sys_IsLANAddress( clc.serverAddress ) )
25092513 CL_RequestAuthorization();
2514 #endif
25102515 #endif
25112516
25122517 // The challenge request shall be followed by a client challenge so no malicious server can hijack this connection.
40744079 j_yaw = Cvar_Get ("j_yaw", "-0.022", CVAR_ARCHIVE);
40754080 j_forward = Cvar_Get ("j_forward", "-0.25", CVAR_ARCHIVE);
40764081 j_side = Cvar_Get ("j_side", "0.25", CVAR_ARCHIVE);
4077 j_up = Cvar_Get ("j_up", "1", CVAR_ARCHIVE);
4082 j_up = Cvar_Get ("j_up", "0", CVAR_ARCHIVE);
40784083
40794084 j_pitch_axis = Cvar_Get ("j_pitch_axis", "3", CVAR_ARCHIVE);
4080 j_yaw_axis = Cvar_Get ("j_yaw_axis", "4", CVAR_ARCHIVE);
4085 j_yaw_axis = Cvar_Get ("j_yaw_axis", "2", CVAR_ARCHIVE);
40814086 j_forward_axis = Cvar_Get ("j_forward_axis", "1", CVAR_ARCHIVE);
40824087 j_side_axis = Cvar_Get ("j_side_axis", "0", CVAR_ARCHIVE);
4083 j_up_axis = Cvar_Get ("j_up_axis", "2", CVAR_ARCHIVE);
4088 j_up_axis = Cvar_Get ("j_up_axis", "4", CVAR_ARCHIVE);
40844089
40854090 Cvar_CheckRange(j_pitch_axis, 0, MAX_JOYSTICK_AXIS-1, qtrue);
40864091 Cvar_CheckRange(j_yaw_axis, 0, MAX_JOYSTICK_AXIS-1, qtrue);
672672 if ( UI_usesUniqueCDKey() && fs && fs->string[0] != 0 ) {
673673 memcpy( &cl_cdkey[16], buf, 16 );
674674 cl_cdkey[32] = 0;
675 // set the flag so the fle will be written at the next opportunity
675 // set the flag so the file will be written at the next opportunity
676676 cvar_modifiedFlags |= CVAR_ARCHIVE;
677677 } else {
678678 memcpy( cl_cdkey, buf, 16 );
679 // set the flag so the fle will be written at the next opportunity
679 // set the flag so the file will be written at the next opportunity
680680 cvar_modifiedFlags |= CVAR_ARCHIVE;
681681 }
682682 }
4242
4343 #ifdef USE_VOIP
4444 #ifdef USE_LOCAL_HEADERS
45 #include "../opus-1.1/include/opus.h"
46 #include "../opusfile-0.6/include/opusfile.h"
45 #include "../opus-1.1.2/include/opus.h"
46 #include "../opusfile-0.7/include/opusfile.h"
4747 #else
4848 #include <opus/opus.h>
4949 #include <opus/opusfile.h>
265265 K_EURO,
266266 K_UNDO,
267267
268 // Gamepad controls
269 // Ordered to match SDL2 game controller buttons and axes
270 // Do not change this order without also changing IN_GamepadMove() in SDL_input.c
271 K_PAD0_A,
272 K_PAD0_B,
273 K_PAD0_X,
274 K_PAD0_Y,
275 K_PAD0_BACK,
276 K_PAD0_GUIDE,
277 K_PAD0_START,
278 K_PAD0_LEFTSTICK_CLICK,
279 K_PAD0_RIGHTSTICK_CLICK,
280 K_PAD0_LEFTSHOULDER,
281 K_PAD0_RIGHTSHOULDER,
282 K_PAD0_DPAD_UP,
283 K_PAD0_DPAD_DOWN,
284 K_PAD0_DPAD_LEFT,
285 K_PAD0_DPAD_RIGHT,
286
287 K_PAD0_LEFTSTICK_LEFT,
288 K_PAD0_LEFTSTICK_RIGHT,
289 K_PAD0_LEFTSTICK_UP,
290 K_PAD0_LEFTSTICK_DOWN,
291 K_PAD0_RIGHTSTICK_LEFT,
292 K_PAD0_RIGHTSTICK_RIGHT,
293 K_PAD0_RIGHTSTICK_UP,
294 K_PAD0_RIGHTSTICK_DOWN,
295 K_PAD0_LEFTTRIGGER,
296 K_PAD0_RIGHTTRIGGER,
297
268298 // Pseudo-key that brings the console down
269299 K_CONSOLE,
270300
3131 // includes for the OGG codec
3232 #include <errno.h>
3333 #define OV_EXCLUDE_STATIC_CALLBACKS
34 #include <vorbis/vorbisfile.h>
34 #ifdef USE_LOCAL_HEADERS
35 #include "../libvorbis-1.3.5/include/vorbis/vorbisfile.h"
36 #else
37 #include <vorbis/vorbisfile.h>
38 #endif
3539
3640 // The OGG codec can return the samples in a number of different formats,
3741 // we use the standard signed short format.
614614 int inplay, allowed;
615615 qboolean fullVolume;
616616
617 if ( !s_soundStarted || s_soundMuted || ( clc.state != CA_ACTIVE && clc.state != CA_DISCONNECTED ) ) {
617 if ( !s_soundStarted || s_soundMuted ) {
618618 return;
619619 }
620620
719719 continue;
720720 }
721721 }
722
723722 }
724723 }
725724
2222
2323 #include "client.h"
2424 #include "snd_local.h"
25 #if idppc_altivec && !defined(MACOS_X)
25 #if idppc_altivec && !defined(__APPLE__)
2626 #include <altivec.h>
2727 #endif
2828
583583 int flags; // flags from StartSoundEx
584584 } src_t;
585585
586 #ifdef MACOS_X
586 #ifdef __APPLE__
587587 #define MAX_SRC 128
588588 #else
589589 #define MAX_SRC 256
11101110 continue;
11111111 }
11121112
1113 // re-use channel if applicable
1114 if ( curSource->sfx == sfx && !cutDuplicateSound ) {
1115 cutDuplicateSound = qtrue;
1116 S_AL_SrcKill(i);
1117 if (empty == -1)
1118 empty = i;
1119 continue;
1120 }
1121
11221113 // cutoff sounds that expect to be overwritten
11231114 if ( curSource->flags & SND_OKTOCUT ) {
11241115 S_AL_SrcKill(i);
11351126 empty = i;
11361127 continue;
11371128 }
1129 }
1130
1131 // re-use channel if applicable
1132 if ( curSource->channel != -1 && curSource->sfx == sfx && !cutDuplicateSound ) {
1133 cutDuplicateSound = qtrue;
1134 S_AL_SrcKill(i);
1135 if (empty == -1)
1136 empty = i;
1137 continue;
11381138 }
11391139 }
11401140 }
23062306
23072307 #ifdef _WIN32
23082308 #define ALDRIVER_DEFAULT "OpenAL32.dll"
2309 #elif defined(MACOS_X)
2309 #elif defined(__APPLE__)
23102310 #define ALDRIVER_DEFAULT "libopenal.dylib"
23112311 #elif defined(__OpenBSD__)
23122312 #define ALDRIVER_DEFAULT "libopenal.so"
25312531 #ifdef USE_VOIP
25322532 if(capture_ext)
25332533 {
2534 #ifdef MACOS_X
2534 #ifdef __APPLE__
25352535 Com_Printf(" Input Device: %s\n", qalcGetString(alCaptureDevice, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
25362536 #else
25372537 Com_Printf(" Input Device: %s\n", qalcGetString(alCaptureDevice, ALC_CAPTURE_DEVICE_SPECIFIER));
26272627 {
26282628 #if defined( _WIN32 )
26292629 if( !Q_stricmp( s_alDriver->string, ALDRIVER_DEFAULT ) && !QAL_Init( "OpenAL64.dll" ) ) {
2630 #elif defined ( MACOS_X )
2630 #elif defined ( __APPLE__ )
26312631 if( !Q_stricmp( s_alDriver->string, ALDRIVER_DEFAULT ) && !QAL_Init( "/System/Library/Frameworks/OpenAL.framework/OpenAL" ) ) {
26322632 #else
26332633 if( !Q_stricmp( s_alDriver->string, ALDRIVER_DEFAULT ) || !QAL_Init( ALDRIVER_DEFAULT ) ) {
27552755 #endif
27562756 else
27572757 {
2758 #ifdef MACOS_X
2758 #ifdef __APPLE__
27592759 // !!! FIXME: Apple has a 1.1-compliant OpenAL, which includes
27602760 // !!! FIXME: capture support, but they don't list it in the
27612761 // !!! FIXME: extension string. We need to check the version string,
2929 void daub4(float b[], unsigned long n, int isign)
3030 {
3131 float wksp[4097] = { 0.0f };
32 float *a=b-1; // numerical recipies so a[1] = b[0]
32 #define a(x) b[(x)-1] // numerical recipies so a[1] = b[0]
3333
3434 unsigned long nh,nh1,i,j;
3535
3838 nh1=(nh=n >> 1)+1;
3939 if (isign >= 0) {
4040 for (i=1,j=1;j<=n-3;j+=2,i++) {
41 wksp[i] = C0*a[j]+C1*a[j+1]+C2*a[j+2]+C3*a[j+3];
42 wksp[i+nh] = C3*a[j]-C2*a[j+1]+C1*a[j+2]-C0*a[j+3];
43 }
44 wksp[i ] = C0*a[n-1]+C1*a[n]+C2*a[1]+C3*a[2];
45 wksp[i+nh] = C3*a[n-1]-C2*a[n]+C1*a[1]-C0*a[2];
41 wksp[i] = C0*a(j)+C1*a(j+1)+C2*a(j+2)+C3*a(j+3);
42 wksp[i+nh] = C3*a(j)-C2*a(j+1)+C1*a(j+2)-C0*a(j+3);
43 }
44 wksp[i ] = C0*a(n-1)+C1*a(n)+C2*a(1)+C3*a(2);
45 wksp[i+nh] = C3*a(n-1)-C2*a(n)+C1*a(1)-C0*a(2);
4646 } else {
47 wksp[1] = C2*a[nh]+C1*a[n]+C0*a[1]+C3*a[nh1];
48 wksp[2] = C3*a[nh]-C0*a[n]+C1*a[1]-C2*a[nh1];
47 wksp[1] = C2*a(nh)+C1*a(n)+C0*a(1)+C3*a(nh1);
48 wksp[2] = C3*a(nh)-C0*a(n)+C1*a(1)-C2*a(nh1);
4949 for (i=1,j=3;i<nh;i++) {
50 wksp[j++] = C2*a[i]+C1*a[i+nh]+C0*a[i+1]+C3*a[i+nh1];
51 wksp[j++] = C3*a[i]-C0*a[i+nh]+C1*a[i+1]-C2*a[i+nh1];
50 wksp[j++] = C2*a(i)+C1*a(i+nh)+C0*a(i+1)+C3*a(i+nh1);
51 wksp[j++] = C3*a(i)-C0*a(i+nh)+C1*a(i+1)-C2*a(i+nh1);
5252 }
5353 }
5454 for (i=1;i<=n;i++) {
55 a[i]=wksp[i];
56 }
55 a(i)=wksp[i];
56 }
57 #undef a
5758 }
5859
5960 void wt1(float a[], unsigned long n, int isign)
12921292 }
12931293 }
12941294
1295 // if we didnt just play a scripted sound, then play one of the default sounds
1295 // if we didn't just play a scripted sound, then play one of the default sounds
12961296 if ( cs->lastScriptSound < level.time ) {
12971297 G_AddEvent( ent, EV_GENERAL_SOUND, G_SoundIndex( aiDefaults[ent->aiCharacter].painSoundScript ) );
12981298 }
871871 cs->scriptPauseTime = 0;
872872 return AIFunc_IdleStart( cs );
873873 }
874 // make sure we didnt change thinkfunc
874 // make sure we didn't change thinkfunc
875875 if ( cs->aifunc != AIFunc_InspectBulletImpact ) {
876876 //G_Error( "scripting passed control out of AIFunc_InspectBulletImpact(), this is bad" );
877877 return NULL;
11801180
11811181 }
11821182
1183 if ( !g_entities[cs->entityNum].client->ps.weapons ) {
1183 if ( !( g_entities[cs->entityNum].client->ps.weapons[0] ) && !( g_entities[cs->entityNum].client->ps.weapons[1] ) ) {
11841184 if ( cs->bs ) {
11851185 cs->bs->weaponnum = WP_NONE;
11861186 } else {
10521052 //VectorCopy( thisHitVec, startHitVec );
10531053 VectorCopy( pm.ps->origin, lastOrg );
10541054 }
1055 // if we didnt reach the marker, then check for something that blocked us
1055 // if we didn't reach the marker, then check for something that blocked us
10561056 for ( i = 0; i < pm.numtouch; i++ ) {
10571057 if ( pm.touchents[i] == pm.ps->groundEntityNum ) {
10581058 continue;
10791079 // hack, if we are above ground, chances are it's because we only did one frame, and gravity isn't applied until
10801080 // after the frame, so try and drop us down some
10811081 if ( pm.ps->groundEntityNum == ENTITYNUM_NONE ) {
1082 VectorCopy( move->endpos, end );
1082 VectorCopy( pm.ps->origin, end );
10831083 end[2] -= 32;
1084 trap_Trace( &tr, move->endpos, pm.mins, pm.maxs, end, pm.ps->clientNum, pm.tracemask );
1084 trap_Trace( &tr, pm.ps->origin, pm.mins, pm.maxs, end, pm.ps->clientNum, pm.tracemask );
10851085 if ( !tr.startsolid && !tr.allsolid && tr.fraction < 1 ) {
10861086 VectorCopy( tr.endpos, pm.ps->origin );
10871087 pm.ps->groundEntityNum = tr.entityNum;
513513 bs->teammessage_time = 0;
514514 }
515515 //
516 if ( bs->lastkilledplayer == bs->teamgoal.entitynum ) {
516 if (bs->killedenemy_time > bs->teamgoal_time - TEAM_KILL_SOMEONE && bs->lastkilledplayer == bs->teamgoal.entitynum) {
517517 EasyClientName( bs->teamgoal.entitynum, buf, sizeof( buf ) );
518518 BotAI_BotInitialChat( bs, "kill_done", buf, NULL );
519519 trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
520 bs->lastkilledplayer = -1;
521520 bs->ltgtype = 0;
522521 }
523522 //
936936
937937 // read digits
938938 value = 0;
939 if ( string[0] != '.' ) {
939 if ( string[0] == '.' ) {
940 // read decimal point if followed by a digit
941 if ( string[1] >= '0' && string[1] <= '9' ) {
942 c = *string++;
943 }
944 } else {
940945 do {
941946 c = *string++;
942947 if ( c < '0' || c > '9' ) {
25062506 }
25072507 return;
25082508 }
2509 } else
2510 {
2509 } else {
25112510 pm->ps->pm_flags &= ~PMF_USE_ITEM_HELD;
25122511 }
25132512
26062605 }
26072606 }
26082607 }
2609 // jpw
2610
2611 }
2612
2613
2608 // jpw
2609 }
26142610
26152611 // check for weapon change
26162612 // can't change if weapon is firing, but can change
27342730 }
27352731
27362732 // start the animation even if out of ammo
2737 switch ( pm->ps->weapon )
2738 {
2733 switch ( pm->ps->weapon ) {
27392734 default:
27402735 if ( !weaponstateFiring ) {
27412736 // delay so the weapon can get up into position before firing (and showing the flash)
27442739 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qtrue );
27452740 }
27462741 break;
2747 // machineguns should continue the anim, rather than start each fire
2742 // machineguns should continue the anim, rather than start each fire
27482743 case WP_MP40:
27492744 case WP_THOMPSON:
27502745 case WP_STEN:
27952790 }
27962791 break;
27972792
2798 // melee
2793 // melee
27992794 case WP_KNIFE:
28002795 case WP_KNIFE2:
28012796 if ( !delayedFire ) {
28082803 }
28092804 break;
28102805
2811 // throw
2806 // throw
28122807 case WP_DYNAMITE:
28132808 case WP_DYNAMITE2:
28142809 case WP_GRENADE_LAUNCHER:
29662961
29672962 default:
29682963 // RF, testing
2969 // PM_ContinueWeaponAnim(weapattackanim);
2964 // PM_ContinueWeaponAnim(weapattackanim);
29702965 PM_StartWeaponAnim( weapattackanim );
29712966 break;
29722967 }
31203115 break;
31213116
31223117 default:
3123 case WP_GAUNTLET:
3124 switch ( pm->ps->aiChar )
3125 {
3118 case WP_GAUNTLET:
3119 switch ( pm->ps->aiChar ) {
31263120 case AICHAR_LOPER: // delay 'til next attack
31273121 case AICHAR_SEALOPER:
31283122 addTime = 1000;
31543148
31553149 // add the recoil amount to the aimSpreadScale
31563150 // pm->ps->aimSpreadScale += 3.0*aimSpreadScaleAdd;
3157 // if (pm->ps->aimSpreadScale > 255) pm->ps->aimSpreadScale = 255;
3151 // if (pm->ps->aimSpreadScale > 255)
3152 // pm->ps->aimSpreadScale = 255;
31583153 pm->ps->aimSpreadScaleFloat += 3.0 * aimSpreadScaleAdd;
31593154 if ( pm->ps->aimSpreadScaleFloat > 255 ) {
31603155 pm->ps->aimSpreadScaleFloat = 255;
167167
168168 // noset vars
169169 { NULL, "gamename", GAMEVERSION, CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
170 { NULL, "gamedate", __DATE__, CVAR_ROM, 0, qfalse },
170 { NULL, "gamedate", PRODUCT_DATE, CVAR_ROM, 0, qfalse },
171171 { &g_restarted, "g_restarted", "0", CVAR_ROM, 0, qfalse },
172172
173173 // latched vars
10941094 if ( trap_Cvar_VariableIntegerValue( "g_gametype" ) != GT_SINGLE_PLAYER ) {
10951095 G_Printf( "------- Game Initialization -------\n" );
10961096 G_Printf( "gamename: %s\n", GAMEVERSION );
1097 G_Printf( "gamedate: %s\n", __DATE__ );
1097 G_Printf( "gamedate: %s\n", PRODUCT_DATE );
10981098 }
10991099
11001100 srand( randomSeed );
19451945 G_LogPrintf( "red:%i blue:%i\n",
19461946 level.teamScores[TEAM_RED], level.teamScores[TEAM_BLUE] );
19471947 }
1948
1949 // NERVE - SMF - send gameCompleteStatus message to master servers
1950 trap_SendConsoleCommand( EXEC_APPEND, "gameCompleteStatus\n" );
19511948
19521949 for ( i = 0 ; i < numSorted ; i++ ) {
19531950 int ping;
389389 break;
390390 }
391391 }
392 // didnt work, so set the position back
392 // didn't work, so set the position back
393393 VectorCopy( org, check->s.pos.trBase );
394394 if ( check->client ) {
395395 VectorCopy( org, check->client->ps.origin );
201201
202202 attacker->client->pers.teamState.carrierdefense++;
203203 team = attacker->client->sess.sessionTeam;
204 PrintMsg( NULL, "%s" S_COLOR_WHITE " defends %s's flag carrier against an agressive enemy\n",
204 PrintMsg( NULL, "%s" S_COLOR_WHITE " defends %s's flag carrier against an aggressive enemy\n",
205205 attacker->client->pers.netname, TeamName( team ) );
206206 return;
207207 }
292292 }
293293
294294 if ( !num_choices ) {
295 G_Printf( "GetNextTrack didnt find a track\n" );
295 G_Printf( "GetNextTrack didn't find a track\n" );
296296 return;
297297 }
298298
3434 void GLimp_EndFrame( void ) {
3535 }
3636
37 int GLimp_Init( void )
38 {
37 void GLimp_Init( void ) {
3938 }
4039
4140 void GLimp_Shutdown( void ) {
4443 void GLimp_EnableLogging( qboolean enable ) {
4544 }
4645
47 void GLimp_LogComment( char *comment ) {
46 void GLimp_LogComment( char *comment ) {
4847 }
4948
50 qboolean QGL_Init( const char *dllname ) {
49 qboolean QGL_Init( const char *dllname ) {
5150 return qtrue;
5251 }
5352
5453 void QGL_Shutdown( void ) {
5554 }
55
56 void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] ) {
57 }
58
59 void GLimp_Minimize( void ) {
60 }
10511051 }
10521052
10531053 //
1054 // find the point distances to the seperating plane
1054 // find the point distances to the separating plane
10551055 // and the offset for the size of the box
10561056 //
10571057 node = cm.nodes + num;
8080 cvar_t *com_legacyversion;
8181 cvar_t *com_blood;
8282 cvar_t *com_buildScript; // for automated data building scripts
83 #ifdef CINEMATICS_INTRO
8384 cvar_t *com_introPlayed;
85 #endif
8486 cvar_t *cl_paused;
8587 cvar_t *sv_paused;
8688 cvar_t *cl_packetdelay;
128130 qboolean com_errorEntered = qfalse;
129131 qboolean com_fullyInitialized = qfalse;
130132 qboolean com_gameRestarting = qfalse;
133 qboolean com_gameClientRestarting = qfalse;
131134
132135 char com_errorMessage[MAXPRINTMSG];
133136
275278 static int lastErrorTime;
276279 static int errorCount;
277280 int currentTime;
281 qboolean restartClient;
278282
279283 if(com_errorEntered)
280284 Sys_Error("recursive error after: %s", com_errorMessage);
307311 if (code != ERR_DISCONNECT && code != ERR_NEED_CD)
308312 Cvar_Set( "com_errorMessage", com_errorMessage );
309313
314 restartClient = com_gameClientRestarting && !( com_cl_running && com_cl_running->integer );
315
316 com_gameRestarting = qfalse;
317 com_gameClientRestarting = qfalse;
318
310319 if (code == ERR_DISCONNECT || code == ERR_SERVERDISCONNECT) {
311320 VM_Forced_Unload_Start();
312321 SV_Shutdown( "Server disconnected" );
322 if ( restartClient ) {
323 CL_Init();
324 }
313325 CL_Disconnect( qtrue );
314326 CL_FlushMemory();
315327 VM_Forced_Unload_Done();
321333 Com_Printf( "********************\nERROR: %s\n********************\n", com_errorMessage );
322334 VM_Forced_Unload_Start();
323335 SV_Shutdown (va("Server crashed: %s", com_errorMessage));
336 if ( restartClient ) {
337 CL_Init();
338 }
324339 CL_Disconnect( qtrue );
325340 CL_FlushMemory();
326341 VM_Forced_Unload_Done();
330345 } else if ( code == ERR_NEED_CD ) {
331346 VM_Forced_Unload_Start();
332347 SV_Shutdown( "Server didn't have CD" );
348 if ( restartClient ) {
349 CL_Init();
350 }
333351 if ( com_cl_running && com_cl_running->integer ) {
334352 CL_Disconnect( qtrue );
335353 CL_FlushMemory();
418436 com_numConsoleLines = 1;
419437
420438 while ( *commandLine ) {
421 // look for a + seperating character
439 // look for a + separating character
422440 // if commandLine came from a file, we might have real line seperators
423441 if ( *commandLine == '+' || *commandLine == '\n' ) {
424442 if ( com_numConsoleLines == MAX_CONSOLE_LINES ) {
23902408 // make sure no recursion can be triggered
23912409 if(!com_gameRestarting && com_fullyInitialized)
23922410 {
2393 int clWasRunning;
2394
23952411 com_gameRestarting = qtrue;
2396 clWasRunning = com_cl_running->integer;
2397
2412 com_gameClientRestarting = com_cl_running->integer;
2413
23982414 // Kill server if we have one
23992415 if(com_sv_running->integer)
24002416 SV_Shutdown("Game directory changed");
24012417
2402 if(clWasRunning)
2418 if(com_gameClientRestarting)
24032419 {
24042420 if(disconnect)
24052421 CL_Disconnect(qfalse);
24212437 NET_Restart_f();
24222438 }
24232439
2424 if(clWasRunning)
2440 if(com_gameClientRestarting)
24252441 {
24262442 CL_Init();
24272443 CL_StartHunkUsers(qfalse);
24282444 }
24292445
24302446 com_gameRestarting = qfalse;
2447 com_gameClientRestarting = qfalse;
24312448 }
24322449 }
24332450
25632580
25642581 FS_Printf( f, "\n// generated by RTCW, do not modify\r\n" );
25652582 FS_Printf( f, "// Do not give this file to ANYONE.\r\n" );
2566 #ifdef MACOS_X
2583 #ifdef __APPLE__
25672584 FS_Printf( f, "// Aspyr will NOT ask you to send this file to them.\r\n" );
25682585 #else
25692586 FS_Printf( f, "// id Software and Activision will NOT ask you to send this file to them.\r\n" );
27002717 // TTimo gcc warning: variable `safeMode' might be clobbered by `longjmp' or `vfork'
27012718 volatile qboolean safeMode = qtrue;
27022719
2703 Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, __DATE__ );
2720 Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, PRODUCT_DATE );
27042721
27052722 if ( setjmp( abortframe ) ) {
27062723 Sys_Error( "Error during initialization" );
28212838 com_busyWait = Cvar_Get("com_busyWait", "0", CVAR_ARCHIVE);
28222839 Cvar_Get("com_errorMessage", "", CVAR_ROM | CVAR_NORESTART);
28232840
2841 #ifdef CINEMATICS_INTRO
28242842 com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE );
2843 #endif
28252844 com_recommendedSet = Cvar_Get( "com_recommendedSet", "0", CVAR_ARCHIVE );
28262845
2827 s = va( "%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
2828 t = va( "%s %s %s", OLDVERSION, PLATFORM_STRING, __DATE__ );
2846 s = va( "%s %s %s", Q3_VERSION, PLATFORM_STRING, PRODUCT_DATE );
2847 t = va( "%s %s %s", OLDVERSION, PLATFORM_STRING, PRODUCT_DATE );
28292848 com_fsgame = Cvar_Get( "fs_game", "", CVAR_INIT | CVAR_SYSTEMINFO );
28302849 com_legacyversion = Cvar_Get( "com_legacyversion", "0", CVAR_ARCHIVE );
28312850
28502869
28512870 Sys_Init();
28522871
2853 if( Sys_WritePIDFile( ) ) {
2854 #ifndef DEDICATED
2855 const char *message = "The last time " CLIENT_WINDOW_TITLE " ran, "
2856 "it didn't exit properly. This may be due to inappropriate video "
2857 "settings. Would you like to start with \"safe\" video settings?";
2858
2859 if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) {
2860 Cvar_Set( "com_abnormalExit", "1" );
2861 }
2862 #endif
2863 }
2872 Sys_InitPIDFile( FS_GetCurrentGameDir() );
28642873
28652874 // Pick a random port value
28662875 Com_RandomBytes( (byte*)&qport, sizeof(int) );
28982907 Cvar_Set( "com_recommendedSet", "1" );
28992908
29002909 if ( !com_dedicated->integer ) {
2901 Cbuf_AddText( "cinematic gmlogo.RoQ\n" );
2910 #ifdef CINEMATICS_LOGO
2911 Cbuf_AddText( "cinematic " CINEMATICS_LOGO "\n" );
2912 #endif
2913 #ifdef CINEMATICS_INTRO
29022914 if ( !com_introPlayed->integer ) {
29032915 Cvar_Set( com_introPlayed->name, "1" );
2904 Cvar_Set( "nextmap", "cinematic wolfintro.RoQ" );
2905 }
2916 Cvar_Set( "nextmap", "cinematic " CINEMATICS_INTRO );
2917 }
2918 #endif
29062919 }
29072920
29082921 com_fullyInitialized = qtrue;
246246 static cvar_t *fs_debug;
247247 static cvar_t *fs_homepath;
248248
249 #ifdef MACOS_X
249 #ifdef __APPLE__
250250 // Also search the .app bundle for .pk3 files
251251 static cvar_t *fs_apppath;
252252 #endif
307307
308308 // last valid game folder used
309309 char lastValidBase[MAX_OSPATH];
310 char lastValidComBaseGame[MAX_OSPATH];
311 char lastValidFsBaseGame[MAX_OSPATH];
310312 char lastValidGame[MAX_OSPATH];
311313
312314 #ifdef FS_MISSING
13121314 pak->referenced |= FS_UI_REF;
13131315
13141316 // DHM -- Nerve :: Don't allow singleplayer maps to be loaded from pak0
1315 if(!FS_IsExt(filename, ".bsp", len) == 0 &&
1316 Q_stricmp( pak->pakBasename, "pak0" ) == 0 ) {
1317 if ( Q_stricmp( filename + len - 4, ".bsp" ) == 0 &&
1318 Q_stricmp( pak->pakBasename, "pak0" ) == 0 ) {
13171319
13181320 *file = 0;
13191321 return -1;
27142716
27152717 /*
27162718 ================
2719 FS_GetModDescription
2720 ================
2721 */
2722 void FS_GetModDescription( const char *modDir, char *description, int descriptionLen ) {
2723 fileHandle_t descHandle;
2724 char descPath[MAX_QPATH];
2725 int nDescLen;
2726 FILE *file;
2727
2728 Com_sprintf( descPath, sizeof ( descPath ), "%s/description.txt", modDir );
2729 nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
2730
2731 if ( nDescLen > 0 && descHandle ) {
2732 file = FS_FileForHandle(descHandle);
2733 Com_Memset( description, 0, descriptionLen );
2734 nDescLen = fread(description, 1, descriptionLen, file);
2735 if (nDescLen >= 0) {
2736 description[nDescLen] = '\0';
2737 }
2738 FS_FCloseFile(descHandle);
2739 } else {
2740 Q_strncpyz( description, modDir, descriptionLen );
2741 }
2742 }
2743
2744 /*
2745 ================
27172746 FS_GetModList
27182747
27192748 Returns a list of mod directory names
27262755 char **pFiles = NULL;
27272756 char **pPaks = NULL;
27282757 char *name, *path;
2729 char descPath[MAX_OSPATH];
2730 fileHandle_t descHandle;
2758 char description[MAX_OSPATH];
27312759
27322760 int dummy;
27332761 char **pFiles0 = NULL;
28122840 nLen = strlen(name) + 1;
28132841 // nLen is the length of the mod path
28142842 // we need to see if there is a description available
2815 descPath[0] = '\0';
2816 strcpy(descPath, name);
2817 strcat(descPath, "/description.txt");
2818 nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
2819 if ( nDescLen > 0 && descHandle) {
2820 FILE *file;
2821 file = FS_FileForHandle(descHandle);
2822 Com_Memset( descPath, 0, sizeof( descPath ) );
2823 nDescLen = fread(descPath, 1, 48, file);
2824 if (nDescLen >= 0) {
2825 descPath[nDescLen] = '\0';
2826 }
2827 FS_FCloseFile(descHandle);
2828 } else {
2829 strcpy(descPath, name);
2830 }
2831 nDescLen = strlen(descPath) + 1;
2843 FS_GetModDescription( name, description, sizeof( description ) );
2844 nDescLen = strlen(description) + 1;
28322845
28332846 if (nTotal + nLen + 1 + nDescLen + 1 < bufsize) {
28342847 strcpy(listbuf, name);
28352848 listbuf += nLen;
2836 strcpy(listbuf, descPath);
2849 strcpy(listbuf, description);
28372850 listbuf += nDescLen;
28382851 nTotal += nLen + nDescLen;
28392852 nMods++;
32493262 if ( !FS_FilenameCompare( pak, va( "%s/mp_pak%d",base,i ) ) ) {
32503263 break;
32513264 }
3252 if ( !FS_FilenameCompare( pak, va( "%s/sp_pak%d",base,i ) ) ) {
3265 if ( !FS_FilenameCompare( pak, va( "%s/sp_pak%d",base,i + 1) ) ) {
32533266 break;
32543267 }
32553268 // jpw
35163529 }
35173530 // fs_homepath is somewhat particular to *nix systems, only add if relevant
35183531
3519 #ifdef MACOS_X
3532 #ifdef __APPLE__
35203533 fs_apppath = Cvar_Get ("fs_apppath", Sys_DefaultAppPath(), CVAR_INIT|CVAR_PROTECTED );
35213534 // Make MacOSX also include the base path included with the .app bundle
35223535 if (fs_apppath->string[0])
42194232 #endif
42204233
42214234 Q_strncpyz( lastValidBase, fs_basepath->string, sizeof( lastValidBase ) );
4235 Q_strncpyz( lastValidComBaseGame, com_basegame->string, sizeof( lastValidComBaseGame ) );
4236 Q_strncpyz( lastValidFsBaseGame, fs_basegame->string, sizeof( lastValidFsBaseGame ) );
42224237 Q_strncpyz( lastValidGame, fs_gamedirvar->string, sizeof( lastValidGame ) );
42234238 }
42244239
42294244 ================
42304245 */
42314246 void FS_Restart( int checksumFeed ) {
4247 const char *lastGameDir;
42324248
42334249 // free anything we currently have loaded
42344250 FS_Shutdown( qfalse );
42554271 if ( lastValidBase[0] ) {
42564272 FS_PureServerSetLoadedPaks( "", "" );
42574273 Cvar_Set( "fs_basepath", lastValidBase );
4258 Cvar_Set("fs_game", lastValidGame);
4274 Cvar_Set( "com_basegame", lastValidComBaseGame );
4275 Cvar_Set( "fs_basegame", lastValidFsBaseGame );
4276 Cvar_Set( "fs_game", lastValidGame );
42594277 lastValidBase[0] = '\0';
4278 lastValidComBaseGame[0] = '\0';
4279 lastValidFsBaseGame[0] = '\0';
42604280 lastValidGame[0] = '\0';
42614281 FS_Restart( checksumFeed );
42624282 Com_Error( ERR_DROP, "Invalid game folder" );
42654285 Com_Error( ERR_FATAL, "Couldn't load default.cfg" );
42664286 }
42674287
4268 if ( Q_stricmp( fs_gamedirvar->string, lastValidGame ) ) {
4288 lastGameDir = ( lastValidGame[0] ) ? lastValidGame : lastValidComBaseGame;
4289
4290 if ( Q_stricmp( FS_GetCurrentGameDir(), lastGameDir ) ) {
4291 Sys_RemovePIDFile( lastGameDir );
4292 Sys_InitPIDFile( FS_GetCurrentGameDir() );
4293
42694294 // skip the wolfconfig.cfg if "safe" is on the command line
42704295 if ( !Com_SafeMode() ) {
42714296 Cbuf_AddText("exec " Q3CONFIG_CFG "\n");
42734298 }
42744299
42754300 Q_strncpyz( lastValidBase, fs_basepath->string, sizeof( lastValidBase ) );
4301 Q_strncpyz( lastValidComBaseGame, com_basegame->string, sizeof( lastValidComBaseGame ) );
4302 Q_strncpyz( lastValidFsBaseGame, fs_basegame->string, sizeof( lastValidFsBaseGame ) );
42764303 Q_strncpyz( lastValidGame, fs_gamedirvar->string, sizeof( lastValidGame ) );
42774304
42784305 }
0 /*
1 ===========================================================================
2 Copyright (C) 2016 James Canete
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 ===========================================================================
18 */
19
20 #ifndef JSON_H
21 #define JSON_H
22
23 enum
24 {
25 JSONTYPE_STRING, // string
26 JSONTYPE_OBJECT, // object
27 JSONTYPE_ARRAY, // array
28 JSONTYPE_VALUE, // number, true, false, or null
29 JSONTYPE_ERROR // out of data
30 };
31
32 // --------------------------------------------------------------------------
33 // Array Functions
34 // --------------------------------------------------------------------------
35
36 // Get pointer to first value in array
37 // When given pointer to an array, returns pointer to the first
38 // returns NULL if array is empty or not an array.
39 const char *JSON_ArrayGetFirstValue(const char *json, const char *jsonEnd);
40
41 // Get pointer to next value in array
42 // When given pointer to a value, returns pointer to the next value
43 // returns NULL when no next value.
44 const char *JSON_ArrayGetNextValue(const char *json, const char *jsonEnd);
45
46 // Get pointers to values in an array
47 // returns 0 if not an array, array is empty, or out of data
48 // returns number of values in the array and copies into index if successful
49 unsigned int JSON_ArrayGetIndex(const char *json, const char *jsonEnd, const char **indexes, unsigned int numIndexes);
50
51 // Get pointer to indexed value from array
52 // returns NULL if not an array, no index, or out of data
53 const char *JSON_ArrayGetValue(const char *json, const char *jsonEnd, unsigned int index);
54
55 // --------------------------------------------------------------------------
56 // Object Functions
57 // --------------------------------------------------------------------------
58
59 // Get pointer to named value from object
60 // returns NULL if not an object, name not found, or out of data
61 const char *JSON_ObjectGetNamedValue(const char *json, const char *jsonEnd, const char *name);
62
63 // --------------------------------------------------------------------------
64 // Value Functions
65 // --------------------------------------------------------------------------
66
67 // Get type of value
68 // returns JSONTYPE_ERROR if out of data
69 unsigned int JSON_ValueGetType(const char *json, const char *jsonEnd);
70
71 // Get value as string
72 // returns 0 if out of data
73 // returns length and copies into string if successful, including terminating nul.
74 // string values are stripped of enclosing quotes but not escaped
75 unsigned int JSON_ValueGetString(const char *json, const char *jsonEnd, char *outString, unsigned int stringLen);
76
77 // Get value as appropriate type
78 // returns 0 if value is false, value is null, or out of data
79 // returns 1 if value is true
80 // returns value otherwise
81 double JSON_ValueGetDouble(const char *json, const char *jsonEnd);
82 float JSON_ValueGetFloat(const char *json, const char *jsonEnd);
83 int JSON_ValueGetInt(const char *json, const char *jsonEnd);
84
85 #endif
86
87 #ifdef JSON_IMPLEMENTATION
88 #include <stdio.h>
89
90 // --------------------------------------------------------------------------
91 // Internal Functions
92 // --------------------------------------------------------------------------
93
94 static const char *JSON_SkipSeparators(const char *json, const char *jsonEnd);
95 static const char *JSON_SkipString(const char *json, const char *jsonEnd);
96 static const char *JSON_SkipStruct(const char *json, const char *jsonEnd);
97 static const char *JSON_SkipValue(const char *json, const char *jsonEnd);
98 static const char *JSON_SkipValueAndSeparators(const char *json, const char *jsonEnd);
99
100 #define IS_SEPARATOR(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r' || (x) == ',' || (x) == ':')
101 #define IS_STRUCT_OPEN(x) ((x) == '{' || (x) == '[')
102 #define IS_STRUCT_CLOSE(x) ((x) == '}' || (x) == ']')
103
104 static const char *JSON_SkipSeparators(const char *json, const char *jsonEnd)
105 {
106 while (json < jsonEnd && IS_SEPARATOR(*json))
107 json++;
108
109 return json;
110 }
111
112 static const char *JSON_SkipString(const char *json, const char *jsonEnd)
113 {
114 for (json++; json < jsonEnd && *json != '"'; json++)
115 if (*json == '\\')
116 json++;
117
118 return (json + 1 > jsonEnd) ? jsonEnd : json + 1;
119 }
120
121 static const char *JSON_SkipStruct(const char *json, const char *jsonEnd)
122 {
123 json = JSON_SkipSeparators(json + 1, jsonEnd);
124 while (json < jsonEnd && !IS_STRUCT_CLOSE(*json))
125 json = JSON_SkipValueAndSeparators(json, jsonEnd);
126
127 return (json + 1 > jsonEnd) ? jsonEnd : json + 1;
128 }
129
130 static const char *JSON_SkipValue(const char *json, const char *jsonEnd)
131 {
132 if (json >= jsonEnd)
133 return jsonEnd;
134 else if (*json == '"')
135 json = JSON_SkipString(json, jsonEnd);
136 else if (IS_STRUCT_OPEN(*json))
137 json = JSON_SkipStruct(json, jsonEnd);
138 else
139 {
140 while (json < jsonEnd && !IS_SEPARATOR(*json) && !IS_STRUCT_CLOSE(*json))
141 json++;
142 }
143
144 return json;
145 }
146
147 static const char *JSON_SkipValueAndSeparators(const char *json, const char *jsonEnd)
148 {
149 json = JSON_SkipValue(json, jsonEnd);
150 return JSON_SkipSeparators(json, jsonEnd);
151 }
152
153 // returns 0 if value requires more parsing, 1 if no more data/false/null, 2 if true
154 static unsigned int JSON_NoParse(const char *json, const char *jsonEnd)
155 {
156 if (!json || json >= jsonEnd || *json == 'f' || *json == 'n')
157 return 1;
158
159 if (*json == 't')
160 return 2;
161
162 return 0;
163 }
164
165 // --------------------------------------------------------------------------
166 // Array Functions
167 // --------------------------------------------------------------------------
168
169 const char *JSON_ArrayGetFirstValue(const char *json, const char *jsonEnd)
170 {
171 if (!json || json >= jsonEnd || !IS_STRUCT_OPEN(*json))
172 return NULL;
173
174 json = JSON_SkipSeparators(json + 1, jsonEnd);
175
176 return (json >= jsonEnd || IS_STRUCT_CLOSE(*json)) ? NULL : json;
177 }
178
179 const char *JSON_ArrayGetNextValue(const char *json, const char *jsonEnd)
180 {
181 if (!json || json >= jsonEnd || IS_STRUCT_CLOSE(*json))
182 return NULL;
183
184 json = JSON_SkipValueAndSeparators(json, jsonEnd);
185
186 return (json >= jsonEnd || IS_STRUCT_CLOSE(*json)) ? NULL : json;
187 }
188
189 unsigned int JSON_ArrayGetIndex(const char *json, const char *jsonEnd, const char **indexes, unsigned int numIndexes)
190 {
191 unsigned int length = 0;
192
193 for (json = JSON_ArrayGetFirstValue(json, jsonEnd); json; json = JSON_ArrayGetNextValue(json, jsonEnd))
194 {
195 if (indexes && numIndexes)
196 {
197 *indexes++ = json;
198 numIndexes--;
199 }
200 length++;
201 }
202
203 return length;
204 }
205
206 const char *JSON_ArrayGetValue(const char *json, const char *jsonEnd, unsigned int index)
207 {
208 for (json = JSON_ArrayGetFirstValue(json, jsonEnd); json && index; json = JSON_ArrayGetNextValue(json, jsonEnd))
209 index--;
210
211 return json;
212 }
213
214 // --------------------------------------------------------------------------
215 // Object Functions
216 // --------------------------------------------------------------------------
217
218 const char *JSON_ObjectGetNamedValue(const char *json, const char *jsonEnd, const char *name)
219 {
220 unsigned int nameLen = strlen(name);
221
222 for (json = JSON_ArrayGetFirstValue(json, jsonEnd); json; json = JSON_ArrayGetNextValue(json, jsonEnd))
223 {
224 if (*json == '"')
225 {
226 const char *thisNameStart, *thisNameEnd;
227
228 thisNameStart = json + 1;
229 json = JSON_SkipString(json, jsonEnd);
230 thisNameEnd = json - 1;
231 json = JSON_SkipSeparators(json, jsonEnd);
232
233 if ((unsigned int)(thisNameEnd - thisNameStart) == nameLen)
234 if (strncmp(thisNameStart, name, nameLen) == 0)
235 return json;
236 }
237 }
238
239 return NULL;
240 }
241
242 // --------------------------------------------------------------------------
243 // Value Functions
244 // --------------------------------------------------------------------------
245
246 unsigned int JSON_ValueGetType(const char *json, const char *jsonEnd)
247 {
248 if (!json || json >= jsonEnd)
249 return JSONTYPE_ERROR;
250 else if (*json == '"')
251 return JSONTYPE_STRING;
252 else if (*json == '{')
253 return JSONTYPE_OBJECT;
254 else if (*json == '[')
255 return JSONTYPE_ARRAY;
256
257 return JSONTYPE_VALUE;
258 }
259
260 unsigned int JSON_ValueGetString(const char *json, const char *jsonEnd, char *outString, unsigned int stringLen)
261 {
262 const char *stringEnd, *stringStart;
263
264 if (!json)
265 {
266 *outString = '\0';
267 return 0;
268 }
269
270 stringStart = json;
271 stringEnd = JSON_SkipValue(stringStart, jsonEnd);
272 if (stringEnd >= jsonEnd)
273 {
274 *outString = '\0';
275 return 0;
276 }
277
278 // skip enclosing quotes if they exist
279 if (*stringStart == '"')
280 stringStart++;
281
282 if (*(stringEnd - 1) == '"')
283 stringEnd--;
284
285 stringLen--;
286 if (stringLen > stringEnd - stringStart)
287 stringLen = stringEnd - stringStart;
288
289 json = stringStart;
290 while (stringLen--)
291 *outString++ = *json++;
292 *outString = '\0';
293
294 return stringEnd - stringStart;
295 }
296
297 double JSON_ValueGetDouble(const char *json, const char *jsonEnd)
298 {
299 char cValue[256];
300 double dValue = 0.0;
301 unsigned int np = JSON_NoParse(json, jsonEnd);
302
303 if (np)
304 return (double)(np - 1);
305
306 if (!JSON_ValueGetString(json, jsonEnd, cValue, 256))
307 return 0.0;
308
309 sscanf(cValue, "%lf", &dValue);
310
311 return dValue;
312 }
313
314 float JSON_ValueGetFloat(const char *json, const char *jsonEnd)
315 {
316 char cValue[256];
317 float fValue = 0.0f;
318 unsigned int np = JSON_NoParse(json, jsonEnd);
319
320 if (np)
321 return (float)(np - 1);
322
323 if (!JSON_ValueGetString(json, jsonEnd, cValue, 256))
324 return 0.0f;
325
326 sscanf(cValue, "%f", &fValue);
327
328 return fValue;
329 }
330
331 int JSON_ValueGetInt(const char *json, const char *jsonEnd)
332 {
333 char cValue[256];
334 int iValue = 0;
335 unsigned int np = JSON_NoParse(json, jsonEnd);
336
337 if (np)
338 return np - 1;
339
340 if (!JSON_ValueGetString(json, jsonEnd, cValue, 256))
341 return 0;
342
343 sscanf(cValue, "%d", &iValue);
344
345 return iValue;
346 }
347
348 #undef IS_SEPARATOR
349 #undef IS_STRUCT_OPEN
350 #undef IS_STRUCT_CLOSE
351
352 #endif
105105 =============================================================================
106106 */
107107
108 int overflows;
109
110108 // negative bit values include signs
111109 void MSG_WriteBits( msg_t *msg, int value, int bits ) {
112110 int i;
113 // FILE* fp;
114111
115112 oldsize += bits;
116113
126123 Com_Error( ERR_DROP, "MSG_WriteBits: bad bits %i", bits );
127124 }
128125
129 // check for overflows
130 if ( bits != 32 ) {
131 if ( bits > 0 ) {
132 if ( value > ( ( 1 << bits ) - 1 ) || value < 0 ) {
133 overflows++;
134 }
135 } else {
136 int r;
137
138 r = 1 << ( bits - 1 );
139
140 if ( value > r - 1 || value < -r ) {
141 overflows++;
142 }
143 }
144 }
145126 if ( bits < 0 ) {
146127 bits = -bits;
147128 }
164145 Com_Error( ERR_DROP, "can't read %d bits", bits );
165146 }
166147 } else {
167 // fp = fopen("c:\\netchan.bin", "a");
168148 value &= ( 0xffffffff >> ( 32 - bits ) );
169149 if ( bits & 7 ) {
170150 int nbits;
177157 }
178158 if ( bits ) {
179159 for ( i = 0; i < bits; i += 8 ) {
180 // fwrite(bp, 1, 1, fp);
181160 Huff_offsetTransmit( &msgHuff.compressor, ( value & 0xff ), msg->data, &msg->bit );
182161 value = ( value >> 8 );
183162 }
184163 }
185164 msg->cursize = ( msg->bit >> 3 ) + 1;
186 // fclose(fp);
187165 }
188166 }
189167
5151 #include "qcommon.h"
5252
5353 /* typedef a 32 bit type */
54 typedef unsigned long int UINT4;
54 typedef uint32_t UINT4;
5555
5656 /* Data structure for MD5 (Message Digest) computation */
5757 typedef struct {
322322
323323 k = key;
324324
325 // Com_DPrintf( "GUID of cdkey %s: ", k );
325 // Com_DPrintf( "cdkey: %s\n", k );
326326
327327 // Process first seed
328 k = do_md5x( k, strlen( k ), get_num( "0x00b684a3", NULL ) );
328 k = do_md5x( k, 16, get_num( "0x00b684a3", NULL ) );
329329
330330 // Process second seed
331331 k = do_md5x( k, 32, get_num( "0x00051a56", NULL ) );
332332
333333 guid = Q_strupr( k );
334 // Com_DPrintf( "%s\n", guid );
334 // Com_DPrintf( "guid: %s\n", guid );
335335
336336 return guid;
337337 }
4545 #define idppc 1
4646 #if defined(__VEC__)
4747 #define idppc_altivec 1
48 #ifdef MACOS_X // Apple's GCC does this differently than the FSF.
48 #ifdef __APPLE__ // Apple's GCC does this differently than the FSF.
4949 #define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
5050 (vector unsigned char) (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
5151 #else
138138
139139 //============================================================== MAC OS X ===
140140
141 #if defined(MACOS_X) || defined(__APPLE_CC__)
142
143 // make sure this is defined, just for sanity's sake...
144 #ifndef MACOS_X
145 #define MACOS_X
146 #endif
141 #if defined(__APPLE__) || defined(__APPLE_CC__)
147142
148143 #define OS_STRING "macosx"
149144 #define ID_INLINE inline
3030
3131 // os x game bundles have no standard library links, and the defines are not always defined!
3232
33 #ifdef MACOS_X
33 #ifdef __APPLE__
3434 int qmax( int x, int y ) {
3535 return ( ( ( x ) > ( y ) ) ? ( x ) : ( y ) );
3636 }
604604 =================
605605 SkipBracedSection
606606
607 The next token should be an open brace.
607 The next token should be an open brace or set depth to 1 if already parsed it.
608608 Skips until a matching close brace is found.
609609 Internal brace depths are properly skipped.
610610 =================
611611 */
612 void SkipBracedSection (char **program) {
612 qboolean SkipBracedSection (char **program, int depth) {
613613 char *token;
614 int depth;
615
616 depth = 0;
614
617615 do {
618616 token = COM_ParseExt( program, qtrue );
619617 if( token[1] == 0 ) {
625623 }
626624 }
627625 } while( depth && *program );
626
627 return ( depth == 0 );
628628 }
629629
630630 /*
5252 // #define STEAMPATH_APPID ""
5353 #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
5454 #define GAMENAME_FOR_MASTER "foobar" // must NOT contain whitespace
55 #define CINEMATICS_LOGO "foologo.roq"
56 #define CINEMATICS_INTRO "foointro.roq"
5557 // #define LEGACY_PROTOCOL // You probably don't need this for your standalone game
5658 #else
5759 #define PRODUCT_NAME "iortcw"
5961 #define BASEGAME "main"
6062 #define CLIENT_WINDOW_TITLE "Return To Castle Wolfenstein"
6163 #define CLIENT_WINDOW_MIN_TITLE "iowolfmp"
64 #ifdef USE_XDG
65 #define HOMEPATH_NAME_UNIX "iortcw"
66 #else
6267 #define HOMEPATH_NAME_UNIX ".wolf"
68 #endif
6369 #define HOMEPATH_NAME_WIN "RTCW"
6470 #define STEAMPATH_NAME "Return To Castle Wolfenstein"
6571 #define STEAMPATH_APPID "9010"
6672 #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
6773 #define GAMENAME_FOR_MASTER "wolfmp"
74 #define CINEMATICS_LOGO "gmlogo.RoQ" // non-existent
75 #define CINEMATICS_INTRO "wolfintro.RoQ" // SP only
6876 #define LEGACY_PROTOCOL
6977 #endif
7078
7886 #define LEGACY_HEARTBEAT_FOR_MASTER "Wolfenstein-1"
7987
8088 #ifndef PRODUCT_VERSION
81 #define PRODUCT_VERSION "1.42d"
89 #define PRODUCT_VERSION "1.5a"
8290 #endif
8391
8492 #ifndef OLD_PRODUCT_VERSION
8593 #define OLD_PRODUCT_VERSION "1.41-MP"
94 #endif
95
96 #ifndef PRODUCT_DATE
97 # define PRODUCT_DATE __DATE__
8698 #endif
8799
88100 #define Q3_VERSION PRODUCT_NAME " " PRODUCT_VERSION
835847
836848 void COM_MatchToken( char**buf_p, char *match );
837849
838 void SkipBracedSection( char **program );
839 void SkipBracedSection_Depth( char **program, int depth ); // start at given depth if already matching stuff
850 qboolean SkipBracedSection( char **program, int depth );
840851 void SkipRestOfLine( char **data );
841852
842853 void Parse1DMatrix( char **buf_p, int x, float *m );
300300 #endif
301301
302302 #ifndef MASTER_SERVER_NAME
303 //#define MASTER_SERVER_NAME "wolfmaster.idsoftware.com" // Official master server decommissioned
304 #define MASTER_SERVER_NAME "dpmaster.deathmask.net"
303 #define MASTER_SERVER_NAME "wolfmaster.idsoftware.com" // Official master server
304 //#define MASTER_SERVER_NAME "dpmaster.deathmask.net"
305305 #endif
306306
307307 #ifndef STANDALONE
308 #ifdef USE_AUTHORIZE_SERVER
308309 #ifndef AUTHORIZE_SERVER_NAME
309 #define AUTHORIZE_SERVER_NAME "wolfauthorize.idsoftware.com"
310 #define AUTHORIZE_SERVER_NAME "wolfauthorize.idsoftware.com" // Decommissioned
310311 #endif
311312 #ifndef PORT_AUTHORIZE
312313 #define PORT_AUTHORIZE 27952
313314 #endif
315 #endif
314316 #endif
315317
316318 //#define AUTOUPDATE_SERVER_NAME "foobar"
657659 #define FS_CGAME_REF 0x04
658660 // #define FS_QAGAME_REF 0x08
659661 // number of id paks that will never be autodownloaded from main
660 #define NUM_ID_PAKS 1
662 #define NUM_ID_PAKS 6
661663 #define NUM_MP_PAKS 6
662664
663665 #define MAX_FILE_HANDLES 64
699701
700702 int FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
701703 int FS_GetModList( char *listbuf, int bufsize );
704
705 void FS_GetModDescription( const char *modDir, char *description, int descriptionLen );
702706
703707 fileHandle_t FS_FOpenFileWrite( const char *qpath );
704708 fileHandle_t FS_FOpenFileAppend( const char *filename );
12311235 char *Sys_SteamPath(void);
12321236 #endif
12331237
1234 #ifdef MACOS_X
1238 #ifdef __APPLE__
12351239 char *Sys_DefaultAppPath(void);
12361240 #endif
12371241
12781282
12791283 dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title );
12801284
1281 qboolean Sys_WritePIDFile( void );
1285 void Sys_RemovePIDFile( const char *gamedir );
1286 void Sys_InitPIDFile( const char *gamedir );
12821287
12831288 /* This is based on the Adaptive Huffman algorithm described in Sayood's Data
12841289 * Compression book. The ranks are not actually stored, but implicitly defined
1313
1414 #ifdef FIRST_PASS
1515
16 #if defined(r_framebufferGamma)
17 minAvgMax = pow(minAvgMax, vec3(r_framebufferGamma));
16 #if defined(USE_PBR)
17 minAvgMax *= minAvgMax;
1818 #endif
1919
2020 float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001);
00 uniform sampler2D u_ScreenImageMap;
11 uniform sampler2D u_ScreenDepthMap;
22
3 uniform vec4 u_ViewInfo; // zfar / znear, zfar
3 uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
44 varying vec2 var_ScreenTex;
55
6 //float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06);
67 //float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033);
78 float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044);
89 //float gauss[3] = float[3](0.60, 0.19, 0.0066);
9 #define GAUSS_SIZE 4
10 #define BLUR_SIZE 4
11
12 #if !defined(USE_DEPTH)
13 //#define USE_GAUSS
14 #endif
1015
1116 float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
1217 {
13 float sampleZDivW = texture2D(depthMap, tex).r;
14 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
18 float sampleZDivW = texture2D(depthMap, tex).r;
19 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
1520 }
1621
17 vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar)
22 vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale)
1823 {
19 float scale = 1.0 / 256.0;
24
25 #if defined(USE_DEPTH)
26 float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear);
27 vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
28 scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0);
29 #endif
2030
2131 #if defined(USE_HORIZONTAL_BLUR)
22 vec2 direction = vec2(1.0, 0.0) * scale;
32 vec2 direction = vec2(scale.x * 2.0, 0.0);
33 vec2 nudge = vec2(0.0, scale.y * 0.5);
2334 #else // if defined(USE_VERTICAL_BLUR)
24 vec2 direction = vec2(0.0, 1.0) * scale;
35 vec2 direction = vec2(0.0, scale.y * 2.0);
36 vec2 nudge = vec2(-scale.x * 0.5, 0.0);
2537 #endif
26
27 float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
28 vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
29
38
39 #if defined(USE_GAUSS)
3040 vec4 result = texture2D(imageMap, tex) * gauss[0];
3141 float total = gauss[0];
42 #else
43 vec4 result = texture2D(imageMap, tex);
44 float total = 1.0;
45 #endif
3246
47 float zLimit = 5.0 / zFar;
3348 int i, j;
3449 for (i = 0; i < 2; i++)
3550 {
36 for (j = 1; j < GAUSS_SIZE; j++)
51 for (j = 1; j < BLUR_SIZE; j++)
3752 {
38 vec2 offset = direction * j;
39 float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
40 float depthExpected = depthCenter + dot(centerSlope, offset);
41 if(abs(depthSample - depthExpected) < 5.0)
42 {
43 result += texture2D(imageMap, tex + offset) * gauss[j];
44 total += gauss[j];
45 }
53 vec2 offset = direction * (float(j) - 0.25) + nudge;
54 #if defined(USE_DEPTH)
55 float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
56 float depthExpected = depthCenter + dot(slope, offset);
57 float useSample = float(abs(depthSample - depthExpected) < zLimit);
58 #else
59 float useSample = 1.0;
60 #endif
61 #if defined(USE_GAUSS)
62 result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
63 total += gauss[j] * useSample;
64 #else
65 result += texture2D(imageMap, tex + offset) * useSample;
66 total += useSample;
67 #endif
68 nudge = -nudge;
4669 }
47
70
4871 direction = -direction;
49 }
50
72 nudge = -nudge;
73 }
74
5175 return result / total;
5276 }
5377
5478 void main()
55 {
56 gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
79 {
80 gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw);
5781 }
00 attribute vec4 attr_Position;
11 attribute vec4 attr_TexCoord0;
2
3 uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
24
35 varying vec2 var_ScreenTex;
46
57 void main()
68 {
79 gl_Position = attr_Position;
8 var_ScreenTex = attr_TexCoord0.xy;
10 vec2 wh = vec2(1.0) / u_ViewInfo.zw - vec2(1.0);
11 var_ScreenTex = (floor(attr_TexCoord0.xy * wh) + vec2(0.5)) * u_ViewInfo.zw;
12
913 //vec2 screenCoords = gl_Position.xy / gl_Position.w;
1014 //var_ScreenTex = screenCoords * 0.5 + 0.5;
1115 }
2828 uniform vec4 u_EnableTextures;
2929 #endif
3030
31 #if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
32 uniform vec3 u_DirectedLight;
33 uniform vec3 u_AmbientLight;
34 #endif
35
3631 #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
3732 uniform vec3 u_PrimaryLightColor;
3833 uniform vec3 u_PrimaryLightAmbient;
5247 varying vec4 var_TexCoords;
5348
5449 varying vec4 var_Color;
55
5650 #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
57 #if defined(USE_VERT_TANGENT_SPACE)
51 varying vec4 var_ColorAmbient;
52 #endif
53
54 #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
5855 varying vec4 var_Normal;
5956 varying vec4 var_Tangent;
6057 varying vec4 var_Bitangent;
61 #else
62 varying vec3 var_Normal;
63 varying vec3 var_ViewDir;
64 #endif
6558 #endif
6659
6760 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
149142 }
150143 #endif
151144
152 vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float roughness)
145 vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
153146 {
154147 #if defined(USE_BURLEY)
155148 // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
170163 return vec3(v) + specular;
171164 }
172165
173 vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float roughness)
166 vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness)
174167 {
175168 // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
176169 float rr = roughness*roughness;
197190 return attenuation;
198191 }
199192
200 // from http://www.thetenthplanet.de/archives/1180
201 mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv )
202 {
203 // get edge vectors of the pixel triangle
204 vec3 dp1 = dFdx( p );
205 vec3 dp2 = dFdy( p );
206 vec2 duv1 = dFdx( uv );
207 vec2 duv2 = dFdy( uv );
208
209 // solve the linear system
210 vec3 dp2perp = cross( dp2, N );
211 vec3 dp1perp = cross( N, dp1 );
212 vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
213 vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
214
215 // construct a scale-invariant frame
216 float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
217 return mat3( T * invmax, B * invmax, N );
218 }
219193
220194 void main()
221195 {
222 vec3 viewDir, lightColor, ambientColor;
196 vec3 viewDir, lightColor, ambientColor, reflectance;
223197 vec3 L, N, E, H;
224198 float NL, NH, NE, EH, attenuation;
225199
226200 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
227 #if defined(USE_VERT_TANGENT_SPACE)
228201 mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);
229202 viewDir = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w);
230 #else
231 mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy);
232 viewDir = var_ViewDir;
233 #endif
234
235203 E = normalize(viewDir);
236
237 L = var_LightDir.xyz;
238 #if defined(USE_DELUXEMAP)
239 L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
240 #endif
241 float sqrLightDist = dot(L, L);
242 #endif
204 #endif
205
206 lightColor = var_Color.rgb;
243207
244208 #if defined(USE_LIGHTMAP)
245209 vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw);
246210 #if defined(RGBM_LIGHTMAP)
247211 lightmapColor.rgb *= lightmapColor.a;
248212 #endif
213 #if defined(USE_PBR) && !defined(USE_FAST_LIGHT)
214 lightmapColor.rgb *= lightmapColor.rgb;
215 #endif
216 lightColor *= lightmapColor.rgb;
249217 #endif
250218
251219 vec2 texCoords = var_TexCoords.xy;
261229 vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
262230
263231 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
264 #if defined(USE_LIGHTMAP)
265 lightColor = lightmapColor.rgb * var_Color.rgb;
266 ambientColor = vec3(0.0);
232 L = var_LightDir.xyz;
233 #if defined(USE_DELUXEMAP)
234 L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
235 #endif
236 float sqrLightDist = dot(L, L);
237 L /= sqrt(sqrLightDist);
238
239 #if defined(USE_LIGHT_VECTOR)
240 attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
241 #else
267242 attenuation = 1.0;
268 #elif defined(USE_LIGHT_VECTOR)
269 lightColor = u_DirectedLight * var_Color.rgb;
270 ambientColor = u_AmbientLight * var_Color.rgb;
271 attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
272 #elif defined(USE_LIGHT_VERTEX)
273 lightColor = var_Color.rgb;
274 ambientColor = vec3(0.0);
275 attenuation = 1.0;
276 #endif
277
278 #if defined(r_lightGamma)
279 lightColor = pow(lightColor, vec3(r_lightGamma));
280 ambientColor = pow(ambientColor, vec3(r_lightGamma));
281243 #endif
282244
283245 #if defined(USE_NORMALMAP)
294256 #endif
295257
296258 N = normalize(N);
297 L /= sqrt(sqrLightDist);
298259
299260 #if defined(USE_SHADOWMAP)
300261 vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
301262 float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
302263
303264 // surfaces not facing the light are always shadowed
304 shadowValue *= float(dot(var_Normal.xyz, var_PrimaryLightDir.xyz) > 0.0);
265 shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0);
305266
306267 #if defined(SHADOWMAP_MODULATE)
307268 lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
308269 #endif
309270 #endif
310271
311 #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
272 #if !defined(USE_LIGHT_VECTOR)
312273 ambientColor = lightColor;
313274 float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
275
276 // reserve 25% ambient to avoid black areas on normalmaps
277 lightColor *= 0.75;
314278
315279 // Scale the incoming light to compensate for the baked-in light angle
316280 // attenuation.
318282
319283 // Recover any unused light as ambient, in case attenuation is over 4x or
320284 // light is below the surface
321 ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0);
322 #endif
323
324 vec3 reflectance;
285 ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0));
286 #else
287 ambientColor = var_ColorAmbient.rgb;
288 #endif
325289
326290 NL = clamp(dot(N, L), 0.0, 1.0);
327291 NE = clamp(dot(N, E), 0.0, 1.0);
331295 #else
332296 vec4 specular = vec4(1.0);
333297 #endif
334
335298 specular *= u_SpecularScale;
336299
337 #if defined(r_materialGamma)
338 diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma));
339 #if !defined(SPECULAR_IS_METALLIC)
340 specular.rgb = pow(specular.rgb, vec3(r_materialGamma));
341 #endif
342 #endif
343
300 #if defined(USE_PBR)
301 diffuse.rgb *= diffuse.rgb;
302 #endif
303
304 #if defined(USE_PBR)
305 // diffuse rgb is base color
306 // specular red is gloss
307 // specular green is metallicness
308 float gloss = specular.r;
309 float metal = specular.g;
310 specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal);
311 diffuse.rgb *= 1.0 - metal;
312 #else
313 // diffuse rgb is diffuse
314 // specular rgb is specular reflectance at normal incidence
315 // specular alpha is gloss
344316 float gloss = specular.a;
345 #if defined(GLOSS_IS_ROUGHNESS)
346 float roughness = gloss;
347 #else
348 float roughness = exp2(-3.0 * gloss);
349 #endif
350
351 #if defined(SPECULAR_IS_METALLIC)
352 // diffuse is actually base color, and green of specular is metallicness
353 float metallic = specular.g;
354
355 specular.rgb = metallic * diffuse.rgb + vec3(0.04 - 0.04 * metallic);
356 diffuse.rgb *= 1.0 - metallic;
357 #else
317
358318 // adjust diffuse by specular reflectance, to maintain energy conservation
359319 diffuse.rgb *= vec3(1.0) - specular.rgb;
360320 #endif
361321
362 reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness);
322 #if defined(GLOSS_IS_GLOSS)
323 float roughness = exp2(-3.0 * gloss);
324 #elif defined(GLOSS_IS_SMOOTHNESS)
325 float roughness = 1.0 - gloss;
326 #elif defined(GLOSS_IS_ROUGHNESS)
327 float roughness = gloss;
328 #elif defined(GLOSS_IS_SHININESS)
329 float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25);
330 #endif
331
332 reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness);
363333
364334 gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
365 gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb);
335 gl_FragColor.rgb += ambientColor * diffuse.rgb;
366336
367337 #if defined(USE_CUBEMAP)
368338 reflectance = EnvironmentBRDF(roughness, NE, specular.rgb);
373343 // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
374344 vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
375345
376 #if defined(GLOSS_IS_ROUGHNESS)
377 vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w;
378 #else
379 vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w;
380 #endif
381
382 // normalize cubemap based on lowest mip (~diffuse)
346 vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w;
347
348 // normalize cubemap based on last roughness mip (~diffuse)
383349 // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
384 //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, 6.0).rgb, 0.5 / 255.0);
350 //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, ROUGHNESS_MIPS).rgb, 0.5 / 255.0);
385351 //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721));
386352
387 #if defined(r_framebufferGamma)
388 cubeLightColor = pow(cubeLightColor, vec3(r_framebufferGamma));
353 #if defined(USE_PBR)
354 cubeLightColor *= cubeLightColor;
389355 #endif
390356
391357 // multiply cubemap values by lighting
406372 //L2 /= sqrt(sqrLightDist);
407373
408374 NL2 = clamp(dot(N, L2), 0.0, 1.0);
409
410375 H2 = normalize(L2 + E);
411376 EH2 = clamp(dot(E, H2), 0.0, 1.0);
412377 NH2 = clamp(dot(N, H2), 0.0, 1.0);
413378
414 reflectance = CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness);
379 reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness);
415380
416381 // bit of a hack, with modulated shadowmaps, ignore diffuse
417382 #if !defined(SHADOWMAP_MODULATE)
418 reflectance += CalcDiffuse(diffuse.rgb, EH2, NH2, roughness);
383 reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness);
419384 #endif
420385
421386 lightColor = u_PrimaryLightColor;
422
423 #if defined(r_lightGamma)
424 lightColor = pow(lightColor, vec3(r_lightGamma));
425 #endif
426387
427388 #if defined(USE_SHADOWMAP)
428389 lightColor *= shadowValue;
433394
434395 gl_FragColor.rgb += lightColor * reflectance * NL2;
435396 #endif
397
398 #if defined(USE_PBR)
399 gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
400 #endif
401
436402 #else
437 lightColor = var_Color.rgb;
438
439 #if defined(USE_LIGHTMAP)
440 lightColor *= lightmapColor.rgb;
441 #endif
442
443 #if defined(r_lightGamma)
444 lightColor = pow(lightColor, vec3(r_lightGamma));
445 #endif
446
447 #if defined(r_materialGamma)
448 diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma));
449 #endif
450403
451404 gl_FragColor.rgb = diffuse.rgb * lightColor;
452405
453406 #endif
454407
455 #if defined(r_framebufferGamma)
456 gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / r_framebufferGamma));
457 #endif
458
459408 gl_FragColor.a = diffuse.a * var_Color.a;
460409 }
55
66 attribute vec3 attr_Position;
77 attribute vec3 attr_Normal;
8 #if defined(USE_VERT_TANGENT_SPACE)
98 attribute vec4 attr_Tangent;
10 #endif
119
1210 #if defined(USE_VERTEX_ANIMATION)
1311 attribute vec3 attr_Position2;
1412 attribute vec3 attr_Normal2;
15 #if defined(USE_VERT_TANGENT_SPACE)
1613 attribute vec4 attr_Tangent2;
17 #endif
1814 #endif
1915
2016 #if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
5652 #if defined(USE_LIGHT_VECTOR)
5753 uniform vec4 u_LightOrigin;
5854 uniform float u_LightRadius;
59 #if defined(USE_FAST_LIGHT)
6055 uniform vec3 u_DirectedLight;
6156 uniform vec3 u_AmbientLight;
62 #endif
6357 #endif
6458
6559 #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
7064 varying vec4 var_TexCoords;
7165
7266 varying vec4 var_Color;
73
74 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
75 #if defined(USE_VERT_TANGENT_SPACE)
67 #if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
68 varying vec4 var_ColorAmbient;
69 #endif
70
71 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
7672 varying vec4 var_Normal;
7773 varying vec4 var_Tangent;
7874 varying vec4 var_Bitangent;
79 #else
80 varying vec3 var_Normal;
81 varying vec3 var_ViewDir;
82 #endif
8375 #endif
8476
8577 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
155147 #if defined(USE_VERTEX_ANIMATION)
156148 vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
157149 vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
158 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
150 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
159151 vec3 tangent = mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp);
160152 #endif
161153 #else
162154 vec3 position = attr_Position;
163155 vec3 normal = attr_Normal;
164 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
156 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
165157 vec3 tangent = attr_Tangent.xyz;
166158 #endif
167159 #endif
183175 #if defined(USE_MODELMATRIX)
184176 position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
185177 normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;
186 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
178 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
187179 tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;
188180 #endif
189181 #endif
190182
191 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
183 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
192184 vec3 bitangent = cross(normal, tangent) * attr_Tangent.w;
193185 #endif
194186
207199
208200 var_Color = u_VertColor * attr_Color + u_BaseColor;
209201
210 #if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)
202 #if defined(USE_LIGHT_VECTOR)
203 #if defined(USE_FAST_LIGHT)
211204 float sqrLightDist = dot(L, L);
205 float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
212206 float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
213 float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
214207
215208 var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight;
209 #else
210 var_ColorAmbient.rgb = u_AmbientLight * var_Color.rgb;
211 var_Color.rgb *= u_DirectedLight;
212 #if defined(USE_PBR)
213 var_ColorAmbient.rgb *= var_ColorAmbient.rgb;
214 #endif
215 #endif
216 #endif
217
218 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) && defined(USE_PBR)
219 var_Color.rgb *= var_Color.rgb;
216220 #endif
217221
218222 #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
233237
234238 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
235239 vec3 viewDir = u_ViewOrigin - position;
236 #if defined(USE_VERT_TANGENT_SPACE)
237240 // store view direction in tangent space to save on varyings
238241 var_Normal = vec4(normal, viewDir.x);
239242 var_Tangent = vec4(tangent, viewDir.y);
240243 var_Bitangent = vec4(bitangent, viewDir.z);
241 #else
242 var_Normal = normal;
243 var_ViewDir = viewDir;
244 #endif
245 #endif
246 }
244 #endif
245 }
00 uniform sampler2D u_ScreenDepthMap;
11
2 uniform vec4 u_ViewInfo; // zfar / znear, zfar
2 uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
33
44 varying vec2 var_ScreenTex;
55
1010 vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
1111 vec2(0.7320465, 0.6317794)
1212 );
13 #define NUM_SAMPLES 3
1314
1415 // Input: It uses texture coords as the random number seed.
1516 // Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
3839
3940 float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
4041 {
41 float sampleZDivW = texture2D(depthMap, tex).r;
42 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
42 float sampleZDivW = texture2D(depthMap, tex).r;
43 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
4344 }
4445
45 float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar)
46 float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale)
4647 {
4748 float result = 0;
4849
49 float sampleZ = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
50 float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
51 float scaleZ = zFarDivZNear * sampleZ;
5052
51 vec2 expectedSlope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
52
53 if (length(expectedSlope) > 5000.0)
53 vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
54
55 if (length(slope) * zFar > 5000.0)
5456 return 1.0;
55
56 vec2 offsetScale = vec2(3.0 / sampleZ);
57
57
58 vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
59
5860 mat2 rmat = randomRotation(tex);
59
61
62 float invZFar = 1.0 / zFar;
63 float zLimit = 20.0 * invZFar;
6064 int i;
61 for (i = 0; i < 3; i++)
65 for (i = 0; i < NUM_SAMPLES; i++)
6266 {
6367 vec2 offset = rmat * poissonDisc[i] * offsetScale;
64 float sampleZ2 = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
68 float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ;
6569
66 if (abs(sampleZ - sampleZ2) > 20.0)
67 result += 1.0;
68 else
69 {
70 float expectedZ = sampleZ + dot(expectedSlope, offset);
71 result += step(expectedZ - 1.0, sampleZ2);
72 }
70 bool s1 = abs(sampleDiff) > zLimit;
71 bool s2 = sampleDiff + invZFar > dot(slope, offset);
72 result += float(s1 || s2);
7373 }
74
75 result *= 0.33333;
76
74
75 result *= 1.0 / float(NUM_SAMPLES);
76
7777 return result;
7878 }
7979
8080 void main()
8181 {
82 float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
83
82 float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz);
83
8484 gl_FragColor = vec4(vec3(result), 1.0);
8585 }
2727 {
2828 vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color;
2929
30 #if defined(r_framebufferGamma)
31 color.rgb = pow(color.rgb, vec3(r_framebufferGamma));
30 #if defined(USE_PBR)
31 color.rgb *= color.rgb;
3232 #endif
3333
3434 vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb;
4545
4646 color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0);
4747
48 #if defined(r_tonemapGamma)
49 color.rgb = pow(color.rgb, vec3(1.0 / r_tonemapGamma));
48 #if defined(USE_PBR)
49 color.rgb = sqrt(color.rgb);
5050 #endif
51
52 // add a bit of dither to reduce banding
53 color.rgb += vec3(1.0/510.0 * mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) - 1.0/1020.0);
5154
5255 gl_FragColor = color;
5356 }
00 /*
11 ===========================================================================
2 Copyright (C) 1999-2005 Id Software, Inc.
3
4 This file is part of Quake III Arena source code.
5
6 Quake III Arena source code is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 Quake III Arena source code is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
2
3 Return to Castle Wolfenstein multiplayer GPL Source Code
4 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
5
6 This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (“RTCW MP Source Code”).
7
8 RTCW MP Source Code is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 RTCW MP Source Code is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
1315 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1416 GNU General Public License for more details.
1517
1618 You should have received a copy of the GNU General Public License
17 along with Quake III Arena source code; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 along with RTCW MP Source Code. If not, see <http://www.gnu.org/licenses/>.
20
21 In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code. If not, please request a copy in writing from id Software at the address below.
22
23 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
24
1925 ===========================================================================
2026 */
27
2128 /*
2229 ** QGL.H
2330 */
3138 # include <SDL_opengl.h>
3239 #endif
3340
34 extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
35 extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
36 extern void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
37
38 extern void ( APIENTRY * qglLockArraysEXT )( GLint, GLint );
39 extern void ( APIENTRY * qglUnlockArraysEXT )( void );
41 extern void (APIENTRYP qglActiveTextureARB) (GLenum texture);
42 extern void (APIENTRYP qglClientActiveTextureARB) (GLenum texture);
43 extern void (APIENTRYP qglMultiTexCoord2fARB) (GLenum target, GLfloat s, GLfloat t);
44
45 extern void (APIENTRYP qglLockArraysEXT) (GLint first, GLsizei count);
46 extern void (APIENTRYP qglUnlockArraysEXT) (void);
4047
4148 //===========================================================================
4249
5966 // GL_ATI_pn_triangles
6067 #ifndef GL_ATI_pn_triangles
6168 #define GL_ATI_pn_triangles 1
62 #ifndef MACOS_X //DAJ BUGFIX changed the numbers
69 #ifndef __APPLE__ //DAJ BUGFIX changed the numbers
6370 #define GL_PN_TRIANGLES_ATI 0x6090
6471 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x6091
6572 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x6092
8087 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
8188 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
8289 #endif
83 typedef void ( APIENTRY * PFNGLPNTRIANGLESIATIPROC )( GLenum pname, GLint param );
84 typedef void ( APIENTRY * PFNGLPNTRIANGLESFATIPROC )( GLenum pname, GLfloat param );
90 typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC)(GLenum pname, GLint param);
91 typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param);
8592 #endif
8693
8794 //----(SA) added
88 extern void ( APIENTRY * qglPNTrianglesiATI )( GLenum pname, GLint param );
89 extern void ( APIENTRY * qglPNTrianglesfATI )( GLenum pname, GLfloat param );
95 extern void (APIENTRYP qglPNTrianglesiATI)(GLenum pname, GLint param);
96 extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
9097 //----(SA) end
9198
9299 // for NV fog distance
452459 #define qglVertexPointer glVertexPointer
453460 #define qglViewport glViewport
454461
455 // GL_EXT_draw_range_elements
456 extern void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
457
458 // GL_EXT_multi_draw_arrays
459 extern void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
460 extern void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
461
462 // rend2
463
464 // GL_ARB_shading_language_100
465 #ifndef GL_ARB_shading_language_100
466 #define GL_ARB_shading_language_100
467 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
468 #endif
469
470 // GL_ARB_vertex_program
471 extern void (APIENTRY * qglVertexAttrib4fARB) (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
472 extern void (APIENTRY * qglVertexAttrib4fvARB) (GLuint, const GLfloat *);
473 extern void (APIENTRY * qglVertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized,
474 GLsizei stride, const GLvoid * pointer);
475 extern void (APIENTRY * qglEnableVertexAttribArrayARB) (GLuint index);
476 extern void (APIENTRY * qglDisableVertexAttribArrayARB) (GLuint index);
477
478 // GL_ARB_vertex_buffer_object
479 extern void (APIENTRY * qglBindBufferARB) (GLenum target, GLuint buffer);
480 extern void (APIENTRY * qglDeleteBuffersARB) (GLsizei n, const GLuint * buffers);
481 extern void (APIENTRY * qglGenBuffersARB) (GLsizei n, GLuint * buffers);
482 extern GLboolean(APIENTRY * qglIsBufferARB) (GLuint buffer);
483 extern void (APIENTRY * qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
484 extern void (APIENTRY * qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
485 extern void (APIENTRY * qglGetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data);
486 extern void (APIENTRY * qglGetBufferParameterivARB) (GLenum target, GLenum pname, GLint * params);
487 extern void (APIENTRY * qglGetBufferPointervARB) (GLenum target, GLenum pname, GLvoid * *params);
488
489 // GL_ARB_shader_objects
490 extern void (APIENTRY * qglDeleteObjectARB) (GLhandleARB obj);
491 extern GLhandleARB(APIENTRY * qglGetHandleARB) (GLenum pname);
492 extern void (APIENTRY * qglDetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj);
493 extern GLhandleARB(APIENTRY * qglCreateShaderObjectARB) (GLenum shaderType);
494 extern void (APIENTRY * qglShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB * *string,
495 const GLint * length);
496 extern void (APIENTRY * qglCompileShaderARB) (GLhandleARB shaderObj);
497 extern GLhandleARB(APIENTRY * qglCreateProgramObjectARB) (void);
498 extern void (APIENTRY * qglAttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj);
499 extern void (APIENTRY * qglLinkProgramARB) (GLhandleARB programObj);
500 extern void (APIENTRY * qglUseProgramObjectARB) (GLhandleARB programObj);
501 extern void (APIENTRY * qglValidateProgramARB) (GLhandleARB programObj);
502 extern void (APIENTRY * qglUniform1fARB) (GLint location, GLfloat v0);
503 extern void (APIENTRY * qglUniform2fARB) (GLint location, GLfloat v0, GLfloat v1);
504 extern void (APIENTRY * qglUniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
505 extern void (APIENTRY * qglUniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
506 extern void (APIENTRY * qglUniform1iARB) (GLint location, GLint v0);
507 extern void (APIENTRY * qglUniform2iARB) (GLint location, GLint v0, GLint v1);
508 extern void (APIENTRY * qglUniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2);
509 extern void (APIENTRY * qglUniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
510 extern void (APIENTRY * qglUniform1fvARB) (GLint location, GLsizei count, const GLfloat * value);
511 extern void (APIENTRY * qglUniform2fvARB) (GLint location, GLsizei count, const GLfloat * value);
512 extern void (APIENTRY * qglUniform3fvARB) (GLint location, GLsizei count, const GLfloat * value);
513 extern void (APIENTRY * qglUniform4fvARB) (GLint location, GLsizei count, const GLfloat * value);
514 extern void (APIENTRY * qglUniform2ivARB) (GLint location, GLsizei count, const GLint * value);
515 extern void (APIENTRY * qglUniform3ivARB) (GLint location, GLsizei count, const GLint * value);
516 extern void (APIENTRY * qglUniform4ivARB) (GLint location, GLsizei count, const GLint * value);
517 extern void (APIENTRY * qglUniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
518 extern void (APIENTRY * qglUniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
519 extern void (APIENTRY * qglUniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
520 extern void (APIENTRY * qglGetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat * params);
521 extern void (APIENTRY * qglGetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint * params);
522 extern void (APIENTRY * qglGetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog);
523 extern void (APIENTRY * qglGetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count,
524 GLhandleARB * obj);
525 extern GLint(APIENTRY * qglGetUniformLocationARB) (GLhandleARB programObj, const GLcharARB * name);
526 extern void (APIENTRY * qglGetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxIndex, GLsizei * length,
527 GLint * size, GLenum * type, GLcharARB * name);
528 extern void (APIENTRY * qglGetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat * params);
529 extern void (APIENTRY * qglGetUniformivARB) (GLhandleARB programObj, GLint location, GLint * params);
530 extern void (APIENTRY * qglGetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source);
531
532 // GL_ARB_vertex_shader
533 extern void (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB * name);
534 extern void (APIENTRY * qglGetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length,
535 GLint * size, GLenum * type, GLcharARB * name);
536 extern GLint(APIENTRY * qglGetAttribLocationARB) (GLhandleARB programObj, const GLcharARB * name);
537
538 // GL_ARB_texture_compression
539 extern void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
540 GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
541 extern void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
542 GLint border, GLsizei imageSize, const GLvoid *data);
543 extern void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
544 GLsizei imageSize, const GLvoid *data);
545 extern void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
546 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
547 extern void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
548 GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
549 extern void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
550 GLsizei imageSize, const GLvoid *data);
551 extern void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
552 GLvoid *img);
462 // GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
463
464 // OpenGL 1.2, was GL_EXT_draw_range_elements
465 #define QGL_1_2_PROCS \
466 GLE(void, DrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) \
467
468 // OpenGL 1.3, was GL_ARB_texture_compression
469 #define QGL_1_3_PROCS \
470 GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
471 GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
472
473 // OpenGL 1.4, was GL_EXT_multi_draw_arrays
474 #define QGL_1_4_PROCS \
475 GLE(void, MultiDrawElements, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) \
476
477 // OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
478 #define QGL_1_5_PROCS \
479 GLE(void, GenQueries, GLsizei n, GLuint *ids) \
480 GLE(void, DeleteQueries, GLsizei n, const GLuint *ids) \
481 GLE(void, BeginQuery, GLenum target, GLuint id) \
482 GLE(void, EndQuery, GLenum target) \
483 GLE(void, GetQueryObjectiv, GLuint id, GLenum pname, GLint *params) \
484 GLE(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params) \
485 GLE(void, BindBuffer, GLenum target, GLuint buffer) \
486 GLE(void, DeleteBuffers, GLsizei n, const GLuint *buffers) \
487 GLE(void, GenBuffers, GLsizei n, GLuint *buffers) \
488 GLE(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) \
489 GLE(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) \
490
491 // OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
492 #define QGL_2_0_PROCS \
493 GLE(void, AttachShader, GLuint program, GLuint shader) \
494 GLE(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) \
495 GLE(void, CompileShader, GLuint shader) \
496 GLE(GLuint, CreateProgram, void) \
497 GLE(GLuint, CreateShader, GLenum type) \
498 GLE(void, DeleteProgram, GLuint program) \
499 GLE(void, DeleteShader, GLuint shader) \
500 GLE(void, DetachShader, GLuint program, GLuint shader) \
501 GLE(void, DisableVertexAttribArray, GLuint index) \
502 GLE(void, EnableVertexAttribArray, GLuint index) \
503 GLE(void, GetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) \
504 GLE(void, GetProgramiv, GLuint program, GLenum pname, GLint *params) \
505 GLE(void, GetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
506 GLE(void, GetShaderiv, GLuint shader, GLenum pname, GLint *params) \
507 GLE(void, GetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
508 GLE(void, GetShaderSource, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) \
509 GLE(GLint, GetUniformLocation, GLuint program, const GLchar *name) \
510 GLE(void, LinkProgram, GLuint program) \
511 GLE(void, ShaderSource, GLuint shader, GLsizei count, const GLchar* *string, const GLint *length) \
512 GLE(void, UseProgram, GLuint program) \
513 GLE(void, Uniform1f, GLint location, GLfloat v0) \
514 GLE(void, Uniform2f, GLint location, GLfloat v0, GLfloat v1) \
515 GLE(void, Uniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
516 GLE(void, Uniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
517 GLE(void, Uniform1i, GLint location, GLint v0) \
518 GLE(void, Uniform1fv, GLint location, GLsizei count, const GLfloat *value) \
519 GLE(void, UniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
520 GLE(void, ValidateProgram, GLuint program) \
521 GLE(void, VertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) \
553522
554523 // GL_NVX_gpu_memory_info
555524 #ifndef GL_NVX_gpu_memory_info
600569 #endif
601570
602571 // GL_EXT_framebuffer_object
603 extern GLboolean (APIENTRY * qglIsRenderbufferEXT)(GLuint renderbuffer);
604 extern void (APIENTRY * qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
605 extern void (APIENTRY * qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
606 extern void (APIENTRY * qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
607 extern void (APIENTRY * qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
608 extern void (APIENTRY * qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
609 extern GLboolean (APIENTRY * qglIsFramebufferEXT)(GLuint framebuffer);
610 extern void (APIENTRY * qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
611 extern void (APIENTRY * qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
612 extern void (APIENTRY * qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
613 extern GLenum (APIENTRY * qglCheckFramebufferStatusEXT)(GLenum target);
614 extern void (APIENTRY * qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
615 GLint level);
616 extern void (APIENTRY * qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
617 GLint level);
618 extern void (APIENTRY * qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
619 GLint level, GLint zoffset);
620 extern void (APIENTRY * qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget,
621 GLuint renderbuffer);
622 extern void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
623 extern void (APIENTRY * qglGenerateMipmapEXT)(GLenum target);
572 #define QGL_EXT_framebuffer_object_PROCS \
573 GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
574 GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
575 GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
576 GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
577 GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
578 GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
579 GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
580 GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
581 GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
582 GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
583 GLE(void, GenerateMipmapEXT, GLenum target) \
624584
625585 #ifndef GL_EXT_framebuffer_object
626586 #define GL_EXT_framebuffer_object
677637 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
678638 #endif
679639
680 // GL_EXT_packed_depth_stencil
681 #ifndef GL_EXT_packed_depth_stencil
682 #define GL_EXT_packed_depth_stencil
683 #define GL_DEPTH_STENCIL_EXT 0x84F9
684 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA
685 #define GL_DEPTH24_STENCIL8_EXT 0x88F0
686 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
687 #endif
688
689 // GL_ARB_occlusion_query
690 extern void (APIENTRY * qglGenQueriesARB)(GLsizei n, GLuint *ids);
691 extern void (APIENTRY * qglDeleteQueriesARB)(GLsizei n, const GLuint *ids);
692 extern GLboolean (APIENTRY * qglIsQueryARB)(GLuint id);
693 extern void (APIENTRY * qglBeginQueryARB)(GLenum target, GLuint id);
694 extern void (APIENTRY * qglEndQueryARB)(GLenum target);
695 extern void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
696 extern void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
697 extern void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
698
699 #ifndef GL_ARB_occlusion_query
700 #define GL_ARB_occlusion_query
701 #define GL_SAMPLES_PASSED_ARB 0x8914
702 #define GL_QUERY_COUNTER_BITS_ARB 0x8864
703 #define GL_CURRENT_QUERY_ARB 0x8865
704 #define GL_QUERY_RESULT_ARB 0x8866
705 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
706 #endif
707
708640 // GL_EXT_framebuffer_blit
709 extern void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
710 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
711 GLbitfield mask, GLenum filter);
641 #define QGL_EXT_framebuffer_blit_PROCS \
642 GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
712643
713644 #ifndef GL_EXT_framebuffer_blit
714645 #define GL_EXT_framebuffer_blit
719650 #endif
720651
721652 // GL_EXT_framebuffer_multisample
722 extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
723 GLenum internalformat, GLsizei width, GLsizei height);
653 #define QGL_EXT_framebuffer_multisample_PROCS \
654 GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
724655
725656 #ifndef GL_EXT_framebuffer_multisample
726657 #define GL_EXT_framebuffer_multisample
727658 #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
728659 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
729660 #define GL_MAX_SAMPLES_EXT 0x8D57
730 #endif
731
732 #ifndef GL_EXT_texture_sRGB
733 #define GL_EXT_texture_sRGB
734 #define GL_SRGB_EXT 0x8C40
735 #define GL_SRGB8_EXT 0x8C41
736 #define GL_SRGB_ALPHA_EXT 0x8C42
737 #define GL_SRGB8_ALPHA8_EXT 0x8C43
738 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44
739 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
740 #define GL_SLUMINANCE_EXT 0x8C46
741 #define GL_SLUMINANCE8_EXT 0x8C47
742 #define GL_COMPRESSED_SRGB_EXT 0x8C48
743 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
744 #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
745 #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
746 #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
747 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
748 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
749 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
750 #endif
751
752 #ifndef GL_EXT_framebuffer_sRGB
753 #define GL_EXT_framebuffer_sRGB
754 #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
755661 #endif
756662
757663 #ifndef GL_ARB_texture_compression_rgtc
770676 #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
771677 #endif
772678
773 // GL_ARB_draw_buffers
774 extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
775 #ifndef GL_ARB_draw_buffers
776 #define GL_ARB_draw_buffers
777 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824
778 #define GL_DRAW_BUFFER0_ARB 0x8825
779 #define GL_DRAW_BUFFER1_ARB 0x8826
780 #define GL_DRAW_BUFFER2_ARB 0x8827
781 #define GL_DRAW_BUFFER3_ARB 0x8828
782 #define GL_DRAW_BUFFER4_ARB 0x8829
783 #define GL_DRAW_BUFFER5_ARB 0x882A
784 #define GL_DRAW_BUFFER6_ARB 0x882B
785 #define GL_DRAW_BUFFER7_ARB 0x882C
786 #define GL_DRAW_BUFFER8_ARB 0x882D
787 #define GL_DRAW_BUFFER9_ARB 0x882E
788 #define GL_DRAW_BUFFER10_ARB 0x882F
789 #define GL_DRAW_BUFFER11_ARB 0x8830
790 #define GL_DRAW_BUFFER12_ARB 0x8831
791 #define GL_DRAW_BUFFER13_ARB 0x8832
792 #define GL_DRAW_BUFFER14_ARB 0x8833
793 #define GL_DRAW_BUFFER15_ARB 0x8834
794 #endif
795
796679 #ifndef GL_ARB_depth_clamp
797680 #define GL_ARB_depth_clamp
798681 #define GL_DEPTH_CLAMP 0x864F
804687 #endif
805688
806689 // GL_ARB_vertex_array_object
807 extern void (APIENTRY * qglBindVertexArrayARB)(GLuint array);
808 extern void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays);
809 extern void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
810 extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
690 #define QGL_ARB_vertex_array_object_PROCS \
691 GLE(void, BindVertexArray, GLuint array) \
692 GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
693 GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
694
811695 #ifndef GL_ARB_vertex_array_object
812696 #define GL_ARB_vertex_array_object
813697 #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5
814698 #endif
815699
816 #if defined(WIN32)
817 // WGL_ARB_create_context
818 #ifndef WGL_ARB_create_context
819 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
820 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
821 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
822 #define WGL_CONTEXT_FLAGS_ARB 0x2094
823 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
824 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
825 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
826 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
827 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
828 #define ERROR_INVALID_VERSION_ARB 0x2095
829 #define ERROR_INVALID_PROFILE_ARB 0x2096
830 #endif
831
832 extern HGLRC(APIENTRY * qwglCreateContextAttribsARB) (HDC hdC, HGLRC hShareContext, const int *attribList);
833 #endif
834
835 #if 0 //defined(__linux__)
836 // GLX_ARB_create_context
837 #ifndef GLX_ARB_create_context
838 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
839 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
840 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
841 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
842 #define GLX_CONTEXT_FLAGS_ARB 0x2094
843 #endif
844
845 extern GLXContext (APIENTRY * qglXCreateContextAttribsARB) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
846 #endif
700 // GL_EXT_direct_state_access
701 #define QGL_EXT_direct_state_access_PROCS \
702 GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
703 GLE(GLvoid, TextureParameterfEXT, GLuint texture, GLenum target, GLenum pname, GLfloat param) \
704 GLE(GLvoid, TextureParameteriEXT, GLuint texture, GLenum target, GLenum pname, GLint param) \
705 GLE(GLvoid, TextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
706 GLE(GLvoid, TextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
707 GLE(GLvoid, CopyTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) \
708 GLE(GLvoid, CompressedTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) \
709 GLE(GLvoid, CompressedTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) \
710 GLE(GLvoid, GenerateTextureMipmapEXT, GLuint texture, GLenum target) \
711 GLE(GLvoid, ProgramUniform1iEXT, GLuint program, GLint location, GLint v0) \
712 GLE(GLvoid, ProgramUniform1fEXT, GLuint program, GLint location, GLfloat v0) \
713 GLE(GLvoid, ProgramUniform2fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1) \
714 GLE(GLvoid, ProgramUniform3fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
715 GLE(GLvoid, ProgramUniform4fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
716 GLE(GLvoid, ProgramUniform1fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value) \
717 GLE(GLvoid, ProgramUniformMatrix4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
718 GLE(GLvoid, NamedRenderbufferStorageEXT, GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) \
719 GLE(GLvoid, NamedRenderbufferStorageMultisampleEXT, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
720 GLE(GLenum, CheckNamedFramebufferStatusEXT, GLuint framebuffer, GLenum target) \
721 GLE(GLvoid, NamedFramebufferTexture2DEXT, GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
722 GLE(GLvoid, NamedFramebufferRenderbufferEXT, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
723
724 #define GLE(ret, name, ...) typedef ret APIENTRY name##proc(__VA_ARGS__); extern name##proc * qgl##name;
725 QGL_1_2_PROCS;
726 QGL_1_3_PROCS;
727 QGL_1_4_PROCS;
728 QGL_1_5_PROCS;
729 QGL_2_0_PROCS;
730 QGL_EXT_framebuffer_object_PROCS;
731 QGL_EXT_framebuffer_blit_PROCS;
732 QGL_EXT_framebuffer_multisample_PROCS;
733 QGL_ARB_vertex_array_object_PROCS;
734 QGL_EXT_direct_state_access_PROCS;
735 #undef GLE
847736
848737 #endif // __QGL_H__
849
4343 //#define DBG_PROFILE_BONES
4444
4545 //-----------------------------------------------------------------------------
46 // Static Vars, ugly but easiest (and fastest) means of seperating RB_SurfaceAnim
46 // Static Vars, ugly but easiest (and fastest) means of separating RB_SurfaceAnim
4747 // and R_CalcBones
4848
4949 static float frontlerp, backlerp;
6767 static float *pf;
6868 static vec3_t angles, tangles, torsoParentOffset, torsoAxis[3], tmpAxis[3];
6969 static float *tempVert;
70 static uint32_t *tempNormal;
70 static int16_t *tempNormal;
7171 static vec3_t vec, v2, dir;
7272 static float diff, a1, a2;
7373 static int render_count;
11651165 numVerts = surface->numVerts;
11661166 v = ( mdsVertex_t * )( (byte *)surface + surface->ofsVerts );
11671167 tempVert = ( float * )( tess.xyz + baseVertex );
1168 tempNormal = ( uint32_t * )( tess.normal + baseVertex );
1169 for ( j = 0; j < render_count; j++, tempVert += 4, tempNormal++ ) {
1168 tempNormal = ( int16_t * )( tess.normal + baseVertex );
1169 for ( j = 0; j < render_count; j++, tempVert += 4, tempNormal += 4 ) {
11701170 mdsWeight_t *w;
11711171 vec3_t newNormal;
11721172
11801180
11811181 LocalMatrixTransformVector( v->normal, bones[v->weights[0].boneIndex].matrix, newNormal );
11821182
1183 R_VaoPackNormal((byte *)tempNormal, newNormal);
1183 R_VaoPackNormal(tempNormal, newNormal);
11841184
11851185 tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
11861186 tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
11971197 for ( i = 0; i < surface->numBoneReferences; i++, boneRefs++ ) {
11981198 bonePtr = &bones[*boneRefs];
11991199
1200 GL_Bind( tr.whiteImage );
1200 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
12011201 qglLineWidth( 1 );
12021202 qglBegin( GL_LINES );
12031203 for ( j = 0; j < 3; j++ ) {
12291229
12301230 // show mesh edges
12311231 tempVert = ( float * )( tess.xyz + baseVertex );
1232 tempNormal = ( uint32_t * )( tess.normal + baseVertex );
1233
1234 GL_Bind( tr.whiteImage );
1232 tempNormal = ( int16_t * )( tess.normal + baseVertex );
1233
1234 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
12351235 qglLineWidth( 1 );
12361236 qglBegin( GL_LINES );
12371237 qglColor3f( .0,.0,.8 );
13511351 if (r_bonesDebug->integer == 4) {
13521352 int j;
13531353 // DEBUG: show the tag position/axis
1354 GL_Bind( tr.whiteImage );
1354 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
13551355 qglLineWidth( 2 );
13561356 qglBegin( GL_LINES );
13571357 for (j=0; j<3; j++) {
17491749 tess.xyz[baseVertex + j][1] = tempVert[1];
17501750 tess.xyz[baseVertex + j][2] = tempVert[2];
17511751
1752 R_VaoPackNormal((byte *)&tess.normal[baseVertex + j], tempNormal);
1752 R_VaoPackNormal(tess.normal[baseVertex + j], tempNormal);
17531753
17541754 tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
17551755 tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
2626 */
2727
2828 #include "tr_local.h"
29 #include "tr_fbo.h"
30 #include "tr_dsa.h"
2931
3032 backEndData_t *backEndData;
3133 backEndState_t backEnd;
4244
4345
4446 /*
45 ** GL_Bind
46 */
47 void GL_Bind( image_t *image ) {
48 int texnum;
49
50 if ( !image ) {
51 ri.Printf( PRINT_WARNING, "GL_Bind: NULL image\n" );
52 texnum = tr.defaultImage->texnum;
53 } else {
54 texnum = image->texnum;
55 }
56
57 if ( r_nobind->integer && tr.dlightImage ) { // performance evaluation option
58 texnum = tr.dlightImage->texnum;
59 }
60
61 if ( glState.currenttextures[glState.currenttmu] != texnum ) {
62 if ( image ) {
63 image->frameUsed = tr.frameCount;
64 }
65 glState.currenttextures[glState.currenttmu] = texnum;
66 if (image && image->flags & IMGFLAG_CUBEMAP)
67 qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
68 else
69 qglBindTexture( GL_TEXTURE_2D, texnum );
70 }
71 }
72
73
74 /*
75 ** GL_SelectTexture
76 */
77 void GL_SelectTexture( int unit ) {
78 if ( glState.currenttmu == unit ) {
79 return;
80 }
81
82 if (!(unit >= 0 && unit <= 31))
83 ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit );
84
85 if (!qglActiveTextureARB)
86 ri.Error( ERR_DROP, "GL_SelectTexture: multitexture disabled" );
87
88 qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
89
90 glState.currenttmu = unit;
91 }
92
93
94 /*
9547 ** GL_BindToTMU
9648 */
9749 void GL_BindToTMU( image_t *image, int tmu )
9850 {
99 int texnum;
100 int oldtmu = glState.currenttmu;
101
102 if (!image)
103 texnum = 0;
51 GLuint texture = (tmu == TB_COLORMAP) ? tr.defaultImage->texnum : 0;
52 GLenum target = GL_TEXTURE_2D;
53
54 if (image)
55 {
56 if (image->flags & IMGFLAG_CUBEMAP)
57 target = GL_TEXTURE_CUBE_MAP;
58
59 image->frameUsed = tr.frameCount;
60 texture = image->texnum;
61 }
10462 else
105 texnum = image->texnum;
106
107 if ( glState.currenttextures[tmu] != texnum ) {
108 GL_SelectTexture( tmu );
109 if (image)
110 image->frameUsed = tr.frameCount;
111 glState.currenttextures[tmu] = texnum;
112
113 if (image && (image->flags & IMGFLAG_CUBEMAP))
114 qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
115 else
116 qglBindTexture( GL_TEXTURE_2D, texnum );
117 GL_SelectTexture( oldtmu );
118 }
63 {
64 ri.Printf(PRINT_WARNING, "GL_BindToTMU: NULL image\n");
65 }
66
67 GL_BindMultiTexture(GL_TEXTURE0_ARB + tmu, target, texture);
11968 }
12069
12170 /*
14493 }
14594
14695 glState.faceCulling = cullType;
147 }
148
149 /*
150 ** GL_TexEnv
151 */
152 void GL_TexEnv( int env ) {
153 if ( env == glState.texEnv[glState.currenttmu] ) {
154 return;
155 }
156
157 glState.texEnv[glState.currenttmu] = env;
158
159
160 switch ( env )
161 {
162 case GL_MODULATE:
163 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
164 break;
165 case GL_REPLACE:
166 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
167 break;
168 case GL_DECAL:
169 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
170 break;
171 case GL_ADD:
172 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
173 break;
174 default:
175 ri.Error( ERR_DROP, "GL_TexEnv: invalid env '%d' passed", env );
176 break;
177 }
17896 }
17997
18098 /*
451369
452370 if (glRefConfig.framebufferObject)
453371 {
372 FBO_t *fbo = backEnd.viewParms.targetFbo;
373
454374 // FIXME: HUGE HACK: render to the screen fbo if we've already postprocessed the frame and aren't drawing more world
455375 // drawing more world check is in case of double renders, such as skyportals
456 if (backEnd.viewParms.targetFbo == NULL)
457 {
458 if (!tr.renderFbo || (backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL)))
459 {
460 FBO_Bind(NULL);
461 }
462 else
463 {
464 FBO_Bind(tr.renderFbo);
465 }
466 }
467 else
468 {
469 FBO_Bind(backEnd.viewParms.targetFbo);
470
471 // FIXME: hack for cubemap testing
472 if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
473 {
474 cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
475 //qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, backEnd.viewParms.targetFbo->colorImage[0]->texnum, 0);
476 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, cubemap->image->texnum, 0);
477 }
478 }
376 if (fbo == NULL && !(backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL)))
377 fbo = tr.renderFbo;
378
379 if (tr.renderCubeFbo && fbo == tr.renderCubeFbo)
380 {
381 cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
382 FBO_AttachImage(fbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, backEnd.viewParms.targetFboLayer);
383 }
384 FBO_Bind(fbo);
479385 }
480386
481387 //
811717 R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
812718
813719 if (inQuery) {
814 qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
720 qglEndQuery(GL_SAMPLES_PASSED);
815721 }
816722
817723 if (glRefConfig.framebufferObject)
879785 // set time for 2D shaders
880786 backEnd.refdef.time = ri.Milliseconds();
881787 backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f;
882
883 // reset color scaling
884 backEnd.refdef.colorScale = 1.0f;
885788 }
886789
887790
927830 }
928831
929832 RE_UploadCinematic (w, h, cols, rows, data, client, dirty);
833 GL_BindToTMU(tr.scratchImage[client], TB_COLORMAP);
930834
931835 if ( r_speeds->integer ) {
932836 end = ri.Milliseconds();
936840 // FIXME: HUGE hack
937841 if (glRefConfig.framebufferObject)
938842 {
939 if (!tr.renderFbo || backEnd.framePostProcessed)
940 {
941 FBO_Bind(NULL);
942 }
943 else
944 {
945 FBO_Bind(tr.renderFbo);
946 }
843 FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo);
947844 }
948845
949846 RB_SetGL2D();
968865
969866
970867 void RE_UploadCinematic( int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty ) {
971
972 GL_Bind( tr.scratchImage[client] );
868 GLuint texture;
869
870 if (!tr.scratchImage[client])
871 {
872 ri.Printf(PRINT_WARNING, "RE_UploadCinematic: scratch images not initialized\n");
873 return;
874 }
875
876 texture = tr.scratchImage[client]->texnum;
973877
974878 // if the scratchImage isn't in the format we want, specify it as a new texture
975879 if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
976880 tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
977881 tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
978 qglTexImage2D( GL_TEXTURE_2D, 0, 3, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
979 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
980 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
981 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
982 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
882 qglTextureImage2DEXT(texture, GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
883 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
884 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
885 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
886 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
983887 } else {
984888 if ( dirty ) {
985889 // otherwise, just subimage upload it so that drivers can tell we are going to be changing
986890 // it and don't try and do a texture compression
987 qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
891 qglTextureSubImage2DEXT(texture, GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data);
988892 }
989893 }
990894 }
1023927
1024928 // FIXME: HUGE hack
1025929 if (glRefConfig.framebufferObject)
1026 {
1027 if (!tr.renderFbo || backEnd.framePostProcessed)
1028 {
1029 FBO_Bind(NULL);
1030 }
1031 else
1032 {
1033 FBO_Bind(tr.renderFbo);
1034 }
1035 }
930 FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo);
1036931
1037932 RB_SetGL2D();
1038933
1060955 tess.indexes[ numIndexes + 5 ] = numVerts + 1;
1061956
1062957 {
1063 vec4_t color;
1064
1065 VectorScale4(backEnd.color2D, 1.0f / 255.0f, color);
1066
1067 VectorCopy4(color, tess.vertexColors[ numVerts ]);
1068 VectorCopy4(color, tess.vertexColors[ numVerts + 1]);
1069 VectorCopy4(color, tess.vertexColors[ numVerts + 2]);
1070 VectorCopy4(color, tess.vertexColors[ numVerts + 3 ]);
958 uint16_t color[4];
959
960 VectorScale4(backEnd.color2D, 257, color);
961
962 VectorCopy4(color, tess.color[ numVerts ]);
963 VectorCopy4(color, tess.color[ numVerts + 1]);
964 VectorCopy4(color, tess.color[ numVerts + 2]);
965 VectorCopy4(color, tess.color[ numVerts + 3 ]);
1071966 }
1072967
1073968 tess.xyz[ numVerts ][0] = cmd->x;
11551050 tess.indexes[ numIndexes + 5 ] = numVerts + 1;
11561051
11571052 {
1158 vec4_t color;
1159
1160 VectorScale4(backEnd.color2D, 1.0f / 255.0f, color);
1161
1162 VectorCopy4(color, tess.vertexColors[ numVerts ]);
1163 VectorCopy4(color, tess.vertexColors[ numVerts + 1]);
1164 VectorCopy4(color, tess.vertexColors[ numVerts + 2]);
1165 VectorCopy4(color, tess.vertexColors[ numVerts + 3 ]);
1053 uint16_t color[4];
1054
1055 VectorScale4(backEnd.color2D, 257, color);
1056
1057 VectorCopy4(color, tess.color[ numVerts ]);
1058 VectorCopy4(color, tess.color[ numVerts + 1]);
1059 VectorCopy4(color, tess.color[ numVerts + 2]);
1060 VectorCopy4(color, tess.color[ numVerts + 3 ]);
11661061 }
11671062
11681063 angle = cmd->angle * pi2;
12511146 tess.indexes[ numIndexes + 4 ] = numVerts + 0;
12521147 tess.indexes[ numIndexes + 5 ] = numVerts + 1;
12531148
1254 // *(int *)tess.vertexColors[ numVerts ] =
1255 // *(int *)tess.vertexColors[ numVerts + 1 ] =
1256 // *(int *)tess.vertexColors[ numVerts + 2 ] =
1257 // *(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)backEnd.color2D;
1258
1259 *(int *)tess.vertexColors[ numVerts ] =
1260 *(int *)tess.vertexColors[ numVerts + 1 ] = *(int *)backEnd.color2D;
1261
1262 *(int *)tess.vertexColors[ numVerts + 2 ] =
1263 *(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)cmd->gradientColor;
1149 {
1150 uint16_t color[4];
1151
1152 VectorScale4(backEnd.color2D, 257, color);
1153
1154 VectorCopy4(color, tess.color[ numVerts ]);
1155 VectorCopy4(color, tess.color[ numVerts + 1]);
1156
1157 VectorScale4(cmd->gradientColor, 257, color);
1158
1159 VectorCopy4(color, tess.color[ numVerts + 2]);
1160 VectorCopy4(color, tess.color[ numVerts + 3 ]);
1161 }
12641162
12651163 tess.xyz[ numVerts ][0] = cmd->x;
12661164 tess.xyz[ numVerts ][1] = cmd->y;
13241222 if (glRefConfig.framebufferObject && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW)))
13251223 {
13261224 FBO_t *oldFbo = glState.currentFBO;
1225 vec4_t viewInfo;
1226
1227 VectorSet4(viewInfo, backEnd.viewParms.zFar / r_znear->value, backEnd.viewParms.zFar, 0.0, 0.0);
13271228
13281229 backEnd.depthFill = qtrue;
13291230 qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
13361237 // If we're using multisampling, resolve the depth first
13371238 FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
13381239 }
1339 else if (tr.renderFbo == NULL)
1240 else if (tr.renderFbo == NULL && tr.renderDepthImage)
13401241 {
13411242 // If we're rendering directly to the screen, copy the depth to a texture
1342 GL_BindToTMU(tr.renderDepthImage, 0);
1343 qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
1344 }
1345
1346 if (r_ssao->integer)
1243 qglCopyTextureImage2DEXT(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
1244 }
1245
1246 if (tr.hdrDepthFbo)
13471247 {
13481248 // need the depth in a texture we can do GL_LINEAR sampling on, so copy it to an HDR image
1349 FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
1249 vec4_t srcTexCoords;
1250
1251 VectorSet4(srcTexCoords, 0.0f, 0.0f, 1.0f, 1.0f);
1252
1253 FBO_BlitFromTexture(tr.renderDepthImage, srcTexCoords, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
13501254 }
13511255
13521256 if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT)
14111315
14121316 GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
14131317 {
1414 vec4_t viewInfo;
14151318 vec3_t viewVector;
14161319
14171320 float zmax = backEnd.viewParms.zFar;
14181321 float ymax = zmax * tan(backEnd.viewParms.fovY * M_PI / 360.0f);
14191322 float xmax = zmax * tan(backEnd.viewParms.fovX * M_PI / 360.0f);
1420
1421 float zmin = r_znear->value;
14221323
14231324 VectorScale(backEnd.refdef.viewaxis[0], zmax, viewVector);
14241325 GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWFORWARD, viewVector);
14271328 VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector);
14281329 GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWUP, viewVector);
14291330
1430 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1431
14321331 GLSL_SetUniformVec4(&tr.shadowmaskShader, UNIFORM_VIEWINFO, viewInfo);
14331332 }
14341333
14351334
14361335 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
1336
1337 if (r_shadowBlur->integer)
1338 {
1339 viewInfo[2] = 1.0f / (float)(tr.screenScratchFbo->width);
1340 viewInfo[3] = 1.0f / (float)(tr.screenScratchFbo->height);
1341
1342 FBO_Bind(tr.screenScratchFbo);
1343
1344 GLSL_BindProgram(&tr.depthBlurShader[0]);
1345
1346 GL_BindToTMU(tr.screenShadowImage, TB_COLORMAP);
1347 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
1348
1349 GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
1350
1351 RB_InstantQuad2(quadVerts, texCoords);
1352
1353 FBO_Bind(tr.screenShadowFbo);
1354
1355 GLSL_BindProgram(&tr.depthBlurShader[1]);
1356
1357 GL_BindToTMU(tr.screenScratchImage, TB_COLORMAP);
1358 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
1359
1360 GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
1361
1362 RB_InstantQuad2(quadVerts, texCoords);
1363 }
14371364 }
14381365
14391366 if (r_ssao->integer)
14401367 {
14411368 vec4_t quadVerts[4];
14421369 vec2_t texCoords[4];
1370
1371 viewInfo[2] = 1.0f / ((float)(tr.quarterImage[0]->width) * tan(backEnd.viewParms.fovX * M_PI / 360.0f) * 2.0f);
1372 viewInfo[3] = 1.0f / ((float)(tr.quarterImage[0]->height) * tan(backEnd.viewParms.fovY * M_PI / 360.0f) * 2.0f);
1373 viewInfo[3] *= (float)backEnd.viewParms.viewportHeight / (float)backEnd.viewParms.viewportWidth;
14431374
14441375 FBO_Bind(tr.quarterFbo[0]);
14451376
14621393
14631394 GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP);
14641395
1465 {
1466 vec4_t viewInfo;
1467
1468 float zmax = backEnd.viewParms.zFar;
1469 float zmin = r_znear->value;
1470
1471 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1472
1473 GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
1474 }
1396 GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
14751397
14761398 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
14771399
1400
1401 viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width);
1402 viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height);
14781403
14791404 FBO_Bind(tr.quarterFbo[1]);
14801405
14861411 GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
14871412 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
14881413
1489 {
1490 vec4_t viewInfo;
1491
1492 float zmax = backEnd.viewParms.zFar;
1493 float zmin = r_znear->value;
1494
1495 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1496
1497 GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
1498 }
1414 GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
14991415
15001416 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
15011417
15101426 GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
15111427 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
15121428
1513 {
1514 vec4_t viewInfo;
1515
1516 float zmax = backEnd.viewParms.zFar;
1517 float zmin = r_znear->value;
1518
1519 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1520
1521 GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
1522 }
1429 GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
15231430
15241431
15251432 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
15441451 RB_DrawSun(0.2, tr.sunShader);
15451452 }
15461453
1547 if (r_drawSunRays->integer)
1454 if (glRefConfig.framebufferObject && r_drawSunRays->integer)
15481455 {
15491456 FBO_t *oldFbo = glState.currentFBO;
15501457 FBO_Bind(tr.sunRaysFbo);
15551462 if (glRefConfig.occlusionQuery)
15561463 {
15571464 tr.sunFlareQueryActive[tr.sunFlareQueryIndex] = qtrue;
1558 qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, tr.sunFlareQuery[tr.sunFlareQueryIndex]);
1465 qglBeginQuery(GL_SAMPLES_PASSED, tr.sunFlareQuery[tr.sunFlareQueryIndex]);
15591466 }
15601467
15611468 RB_DrawSun(0.3, tr.sunFlareShader);
15621469
15631470 if (glRefConfig.occlusionQuery)
15641471 {
1565 qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
1472 qglEndQuery(GL_SAMPLES_PASSED);
15661473 }
15671474
15681475 FBO_Bind(oldFbo);
15801487 cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
15811488
15821489 FBO_Bind(NULL);
1583 GL_SelectTexture(TB_CUBEMAP);
1584 GL_BindToTMU(cubemap->image, TB_CUBEMAP);
1585 qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
1586 GL_SelectTexture(0);
1490 if (cubemap && cubemap->image)
1491 qglGenerateTextureMipmapEXT(cubemap->image->texnum, GL_TEXTURE_CUBE_MAP);
15871492 }
15881493
15891494 return (const void *)( cmd + 1 );
16621567 {
16631568 vec4_t quadVerts[4];
16641569
1665 GL_Bind(image);
1570 GL_BindToTMU(image, TB_COLORMAP);
16661571
16671572 VectorSet4(quadVerts[0], x, y, 0, 1);
16681573 VectorSet4(quadVerts[1], x + w, y, 0, 1);
18371742
18381743 if (cmd->map != -1)
18391744 {
1840 GL_SelectTexture(0);
18411745 if (cmd->cubeSide != -1)
18421746 {
18431747 if (tr.shadowCubemaps[cmd->map])
18441748 {
1845 GL_Bind(tr.shadowCubemaps[cmd->map]);
1846 qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
1749 qglCopyTextureImage2DEXT(tr.shadowCubemaps[cmd->map]->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
18471750 }
18481751 }
18491752 else
18501753 {
18511754 if (tr.pshadowMaps[cmd->map])
18521755 {
1853 GL_Bind(tr.pshadowMaps[cmd->map]);
1854 qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
1756 qglCopyTextureImage2DEXT(tr.pshadowMaps[cmd->map]->texnum, GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - (backEnd.refdef.y + PSHADOW_MAP_SIZE), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
18551757 }
18561758 }
18571759 }
19101812 srcBox[2] = backEnd.viewParms.viewportWidth * tr.screenSsaoImage->width / (float)glConfig.vidWidth;
19111813 srcBox[3] = backEnd.viewParms.viewportHeight * tr.screenSsaoImage->height / (float)glConfig.vidHeight;
19121814
1913 //FBO_BlitFromTexture(tr.screenSsaoImage, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
1914 srcBox[1] = tr.screenSsaoImage->height - srcBox[1];
1915 srcBox[3] = -srcBox[3];
1916
19171815 FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
19181816 }
19191817
19241822
19251823 if (srcFbo)
19261824 {
1927 if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer) && qglActiveTextureARB)
1825 if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer))
19281826 {
19291827 autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer;
19301828 RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure);
19531851 RB_BokehBlur(NULL, srcBox, NULL, dstBox, backEnd.refdef.blurFactor);
19541852 else
19551853 RB_GaussianBlur(backEnd.refdef.blurFactor);
1854
1855 #if 0
1856 if (0)
1857 {
1858 vec4_t quadVerts[4];
1859 vec2_t texCoords[4];
1860 ivec4_t iQtrBox;
1861 vec4_t box;
1862 vec4_t viewInfo;
1863 static float scale = 5.0f;
1864
1865 scale -= 0.005f;
1866 if (scale < 0.01f)
1867 scale = 5.0f;
1868
1869 FBO_FastBlit(NULL, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
1870
1871 iQtrBox[0] = backEnd.viewParms.viewportX * tr.quarterImage[0]->width / (float)glConfig.vidWidth;
1872 iQtrBox[1] = backEnd.viewParms.viewportY * tr.quarterImage[0]->height / (float)glConfig.vidHeight;
1873 iQtrBox[2] = backEnd.viewParms.viewportWidth * tr.quarterImage[0]->width / (float)glConfig.vidWidth;
1874 iQtrBox[3] = backEnd.viewParms.viewportHeight * tr.quarterImage[0]->height / (float)glConfig.vidHeight;
1875
1876 qglViewport(iQtrBox[0], iQtrBox[1], iQtrBox[2], iQtrBox[3]);
1877 qglScissor(iQtrBox[0], iQtrBox[1], iQtrBox[2], iQtrBox[3]);
1878
1879 VectorSet4(box, 0.0f, 0.0f, 1.0f, 1.0f);
1880
1881 texCoords[0][0] = box[0]; texCoords[0][1] = box[3];
1882 texCoords[1][0] = box[2]; texCoords[1][1] = box[3];
1883 texCoords[2][0] = box[2]; texCoords[2][1] = box[1];
1884 texCoords[3][0] = box[0]; texCoords[3][1] = box[1];
1885
1886 VectorSet4(box, -1.0f, -1.0f, 1.0f, 1.0f);
1887
1888 VectorSet4(quadVerts[0], box[0], box[3], 0, 1);
1889 VectorSet4(quadVerts[1], box[2], box[3], 0, 1);
1890 VectorSet4(quadVerts[2], box[2], box[1], 0, 1);
1891 VectorSet4(quadVerts[3], box[0], box[1], 0, 1);
1892
1893 GL_State(GLS_DEPTHTEST_DISABLE);
1894
1895
1896 VectorSet4(viewInfo, backEnd.viewParms.zFar / r_znear->value, backEnd.viewParms.zFar, 0.0, 0.0);
1897
1898 viewInfo[2] = scale / (float)(tr.quarterImage[0]->width);
1899 viewInfo[3] = scale / (float)(tr.quarterImage[0]->height);
1900
1901 FBO_Bind(tr.quarterFbo[1]);
1902 GLSL_BindProgram(&tr.depthBlurShader[2]);
1903 GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
1904 GLSL_SetUniformVec4(&tr.depthBlurShader[2], UNIFORM_VIEWINFO, viewInfo);
1905 RB_InstantQuad2(quadVerts, texCoords);
1906
1907 FBO_Bind(tr.quarterFbo[0]);
1908 GLSL_BindProgram(&tr.depthBlurShader[3]);
1909 GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
1910 GLSL_SetUniformVec4(&tr.depthBlurShader[3], UNIFORM_VIEWINFO, viewInfo);
1911 RB_InstantQuad2(quadVerts, texCoords);
1912
1913 SetViewportAndScissor();
1914
1915 FBO_FastBlit(tr.quarterFbo[1], NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
1916 FBO_Bind(NULL);
1917 }
1918 #endif
19561919
19571920 if (0 && r_sunlightMode->integer)
19581921 {
20031966 return (const void *)(cmd + 1);
20041967 }
20051968
1969 // FIXME: put this function declaration elsewhere
1970 void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth);
1971
1972 /*
1973 =============
1974 RB_ExportCubemaps
1975
1976 =============
1977 */
1978 const void *RB_ExportCubemaps(const void *data)
1979 {
1980 const exportCubemapsCommand_t *cmd = data;
1981
1982 // finish any 2D drawing if needed
1983 if (tess.numIndexes)
1984 RB_EndSurface();
1985
1986 if (!glRefConfig.framebufferObject || !tr.world || tr.numCubemaps == 0)
1987 {
1988 // do nothing
1989 ri.Printf(PRINT_ALL, "Nothing to export!\n");
1990 return (const void *)(cmd + 1);
1991 }
1992
1993 if (cmd)
1994 {
1995 FBO_t *oldFbo = glState.currentFBO;
1996 int sideSize = r_cubemapSize->integer * r_cubemapSize->integer * 4;
1997 byte *cubemapPixels = ri.Z_Malloc(sideSize * 6);
1998 int i, j;
1999
2000 FBO_Bind(tr.renderCubeFbo);
2001
2002 for (i = 0; i < tr.numCubemaps; i++)
2003 {
2004 char filename[MAX_QPATH];
2005 cubemap_t *cubemap = &tr.cubemaps[i];
2006 byte *p = cubemapPixels;
2007
2008 for (j = 0; j < 6; j++)
2009 {
2010 FBO_AttachImage(tr.renderCubeFbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, j);
2011 qglReadPixels(0, 0, r_cubemapSize->integer, r_cubemapSize->integer, GL_RGBA, GL_UNSIGNED_BYTE, p);
2012 p += sideSize;
2013 }
2014
2015 if (cubemap->name[0])
2016 {
2017 COM_StripExtension(cubemap->name, filename, MAX_QPATH);
2018 Q_strcat(filename, MAX_QPATH, ".dds");
2019 }
2020 else
2021 {
2022 Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i);
2023 }
2024
2025 R_SaveDDS(filename, cubemapPixels, r_cubemapSize->integer, r_cubemapSize->integer, 6);
2026 ri.Printf(PRINT_ALL, "Saved cubemap %d as %s\n", i, filename);
2027 }
2028
2029 FBO_Bind(oldFbo);
2030
2031 ri.Free(cubemapPixels);
2032 }
2033
2034 return (const void *)(cmd + 1);
2035 }
20062036
20072037 /*
20082038 ====================
20572087 case RC_POSTPROCESS:
20582088 data = RB_PostProcess(data);
20592089 break;
2090 case RC_EXPORT_CUBEMAPS:
2091 data = RB_ExportCubemaps(data);
2092 break;
20602093 case RC_END_OF_LIST:
20612094 default:
20622095 // finish any 2D drawing if needed
2828 // tr_map.c
2929
3030 #include "tr_local.h"
31
32 #define JSON_IMPLEMENTATION
33 #include "../qcommon/json.h"
34 #undef JSON_IMPLEMENTATION
3135
3236 /*
3337
106110 int shift, r, g, b;
107111
108112 // shift the color data based on overbright range
109 #if defined(USE_OVERBRIGHT)
110113 shift = r_mapOverBrightBits->integer - tr.overbrightBits;
111 #else
112 shift = 0;
113 #endif
114114
115115 // shift the data based on overbright range
116116 r = in[0] << shift;
140140
141141 ===============
142142 */
143 static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale )
143 static void R_ColorShiftLightingFloats(float in[4], float out[4])
144144 {
145145 float r, g, b;
146146
147 #if defined(USE_OVERBRIGHT)
148 scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits);
149 #endif
147 float scale = (1 << (r_mapOverBrightBits->integer - tr.overbrightBits)) / 255.0f;
150148
151149 r = in[0] * scale;
152150 g = in[1] * scale;
193191 }
194192
195193
196 void ColorToRGBA16F(const vec3_t color, unsigned short rgba16f[4])
194 void ColorToRGB16(const vec3_t color, uint16_t rgb16[3])
197195 {
198 rgba16f[0] = FloatToHalf(color[0]);
199 rgba16f[1] = FloatToHalf(color[1]);
200 rgba16f[2] = FloatToHalf(color[2]);
201 rgba16f[3] = FloatToHalf(1.0f);
196 rgb16[0] = color[0] * 65535.0f + 0.5f;
197 rgb16[1] = color[1] * 65535.0f + 0.5f;
198 rgb16[2] = color[2] * 65535.0f + 0.5f;
202199 }
203200
204201 /*
208205 ===============
209206 */
210207 #define DEFAULT_LIGHTMAP_SIZE 128
211 #define MAX_LIGHTMAP_PAGES 2
212208 static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
209 imgFlags_t imgFlags = IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE;
213210 byte *buf, *buf_p;
214211 dsurface_t *surf;
215212 int len;
216213 byte *image;
217214 int i, j, numLightmaps, textureInternalFormat = 0;
215 int numLightmapsPerPage = 16;
218216 float maxIntensity = 0;
219217 double sumIntensity = 0;
220218
254252 if (tr.worldDeluxeMapping)
255253 numLightmaps >>= 1;
256254
257 if(numLightmaps == 1)
258 {
259 //FIXME: HACK: maps with only one lightmap turn up fullbright for some reason.
260 //this avoids this, but isn't the correct solution.
261 numLightmaps++;
262 }
263 else if (r_mergeLightmaps->integer && numLightmaps >= 1024 )
264 {
265 // FIXME: fat light maps don't support more than 1024 light maps
266 ri.Printf(PRINT_WARNING, "WARNING: number of lightmaps > 1024\n");
267 numLightmaps = 1024;
268 }
269
270 // use fat lightmaps of an appropriate size
255 // Use fat lightmaps of an appropriate size.
271256 if (r_mergeLightmaps->integer)
272257 {
273 tr.fatLightmapSize = 512;
274 tr.fatLightmapStep = tr.fatLightmapSize / tr.lightmapSize;
275
276 // at most MAX_LIGHTMAP_PAGES
277 while (tr.fatLightmapStep * tr.fatLightmapStep * MAX_LIGHTMAP_PAGES < numLightmaps && tr.fatLightmapSize != glConfig.maxTextureSize )
278 {
279 tr.fatLightmapSize <<= 1;
280 tr.fatLightmapStep = tr.fatLightmapSize / tr.lightmapSize;
281 }
282
283 tr.numLightmaps = numLightmaps / (tr.fatLightmapStep * tr.fatLightmapStep);
284
285 if (numLightmaps % (tr.fatLightmapStep * tr.fatLightmapStep) != 0)
286 tr.numLightmaps++;
258 int maxLightmapsPerAxis = glConfig.maxTextureSize / tr.lightmapSize;
259 int lightmapCols = 4, lightmapRows = 4;
260
261 // Increase width at first, then height.
262 while (lightmapCols * lightmapRows < numLightmaps && lightmapCols != maxLightmapsPerAxis)
263 lightmapCols <<= 1;
264
265 while (lightmapCols * lightmapRows < numLightmaps && lightmapRows != maxLightmapsPerAxis)
266 lightmapRows <<= 1;
267
268 tr.fatLightmapCols = lightmapCols;
269 tr.fatLightmapRows = lightmapRows;
270 numLightmapsPerPage = lightmapCols * lightmapRows;
271
272 tr.numLightmaps = (numLightmaps + (numLightmapsPerPage - 1)) / numLightmapsPerPage;
287273 }
288274 else
289275 {
293279 tr.lightmaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
294280
295281 if (tr.worldDeluxeMapping)
296 {
297282 tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
298 }
299
300 if (glRefConfig.floatLightmap)
301 textureInternalFormat = GL_RGBA16F_ARB;
302 else
303 textureInternalFormat = GL_RGBA8;
283
284 textureInternalFormat = GL_RGBA8;
285 if (r_hdr->integer)
286 {
287 // Check for the first hdr lightmap, if it exists, use GL_RGBA16 for textures.
288 char filename[MAX_QPATH];
289
290 Com_sprintf(filename, sizeof(filename), "maps/%s/lm_0000.hdr", s_worldData.baseName);
291 if (ri.FS_FileExists(filename))
292 textureInternalFormat = GL_RGBA16;
293 }
304294
305295 if (r_mergeLightmaps->integer)
306296 {
297 int width = tr.fatLightmapCols * tr.lightmapSize;
298 int height = tr.fatLightmapRows * tr.lightmapSize;
299
307300 for (i = 0; i < tr.numLightmaps; i++)
308301 {
309 tr.lightmaps[i] = R_CreateImage(va("_fatlightmap%d", i), NULL, tr.fatLightmapSize, tr.fatLightmapSize, IMGTYPE_COLORALPHA, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, textureInternalFormat );
302 tr.lightmaps[i] = R_CreateImage(va("_fatlightmap%d", i), NULL, width, height, IMGTYPE_COLORALPHA, imgFlags, textureInternalFormat);
310303
311304 if (tr.worldDeluxeMapping)
312 {
313 tr.deluxemaps[i] = R_CreateImage(va("_fatdeluxemap%d", i), NULL, tr.fatLightmapSize, tr.fatLightmapSize, IMGTYPE_DELUXE, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, 0 );
314 }
305 tr.deluxemaps[i] = R_CreateImage(va("_fatdeluxemap%d", i), NULL, width, height, IMGTYPE_DELUXE, imgFlags, 0);
315306 }
316307 }
317308
323314
324315 if (r_mergeLightmaps->integer)
325316 {
326 int lightmaponpage = i % (tr.fatLightmapStep * tr.fatLightmapStep);
327 xoff = (lightmaponpage % tr.fatLightmapStep) * tr.lightmapSize;
328 yoff = (lightmaponpage / tr.fatLightmapStep) * tr.lightmapSize;
329
330 lightmapnum /= (tr.fatLightmapStep * tr.fatLightmapStep);
317 int lightmaponpage = i % numLightmapsPerPage;
318 xoff = (lightmaponpage % tr.fatLightmapCols) * tr.lightmapSize;
319 yoff = (lightmaponpage / tr.fatLightmapCols) * tr.lightmapSize;
320
321 lightmapnum /= numLightmapsPerPage;
331322 }
332323
333324 // if (tr.worldLightmapping)
337328 int size = 0;
338329
339330 // look for hdr lightmaps
340 if (r_hdr->integer)
331 if (textureInternalFormat == GL_RGBA16)
341332 {
342333 Com_sprintf( filename, sizeof( filename ), "maps/%s/lm_%04d.hdr", s_worldData.baseName, i * (tr.worldDeluxeMapping ? 2 : 1) );
343334 //ri.Printf(PRINT_ALL, "looking for %s\n", filename);
347338
348339 if (hdrLightmap)
349340 {
350 byte *p = hdrLightmap;
341 byte *p = hdrLightmap, *end = hdrLightmap + size;
351342 //ri.Printf(PRINT_ALL, "found!\n");
352343
353344 /* FIXME: don't just skip over this header and actually parse it */
354 while (size && !(*p == '\n' && *(p+1) == '\n'))
355 {
356 size--;
345 while (p < end && !(*p == '\n' && *(p+1) == '\n'))
357346 p++;
358 }
359
360 if (!size)
361 ri.Error(ERR_DROP, "Bad header for %s!", filename);
362
363 size -= 2;
347
364348 p += 2;
365349
366 while (size && !(*p == '\n'))
367 {
368 size--;
350 while (p < end && !(*p == '\n'))
369351 p++;
370 }
371
372 size--;
352
373353 p++;
374354
375 buf_p = (byte *)p;
355 if (p >= end)
356 ri.Error(ERR_DROP, "Bad header for %s!", filename);
357
358 buf_p = p;
376359
377360 #if 0 // HDRFILE_RGBE
378 if (size != tr.lightmapSize * tr.lightmapSize * 4)
361 if ((int)(end - hdrLightmap) != tr.lightmapSize * tr.lightmapSize * 4)
379362 ri.Error(ERR_DROP, "Bad size for %s (%i)!", filename, size);
380363 #else // HDRFILE_FLOAT
381 if (size != tr.lightmapSize * tr.lightmapSize * 12)
364 if ((int)(end - hdrLightmap) != tr.lightmapSize * tr.lightmapSize * 12)
382365 ri.Error(ERR_DROP, "Bad size for %s (%i)!", filename, size);
383366 #endif
384367 }
385368 else
386369 {
387 if (tr.worldDeluxeMapping)
388 buf_p = buf + (i * 2) * tr.lightmapSize * tr.lightmapSize * 3;
389 else
390 buf_p = buf + i * tr.lightmapSize * tr.lightmapSize * 3;
370 int imgOffset = tr.worldDeluxeMapping ? i * 2 : i;
371 buf_p = buf + imgOffset * tr.lightmapSize * tr.lightmapSize * 3;
391372 }
392373
393374 for ( j = 0 ; j < tr.lightmapSize * tr.lightmapSize; j++ )
410391 #endif
411392 color[3] = 1.0f;
412393
413 R_ColorShiftLightingFloats(color, color, 1.0f/255.0f);
414
415 if (glRefConfig.floatLightmap)
416 ColorToRGBA16F(color, (unsigned short *)(&image[j*8]));
417 else
418 ColorToRGBM(color, &image[j*4]);
394 R_ColorShiftLightingFloats(color, color);
395
396 ColorToRGB16(color, (uint16_t *)(&image[j * 8]));
397 ((uint16_t *)(&image[j * 8]))[3] = 65535;
419398 }
420 else if (glRefConfig.floatLightmap)
399 else if (textureInternalFormat == GL_RGBA16)
421400 {
422401 vec4_t color;
423402
437416 }
438417 color[3] = 1.0f;
439418
440 R_ColorShiftLightingFloats(color, color, 1.0f/255.0f);
441
442 ColorToRGBA16F(color, (unsigned short *)(&image[j*8]));
419 R_ColorShiftLightingFloats(color, color);
420
421 ColorToRGB16(color, (uint16_t *)(&image[j * 8]));
422 ((uint16_t *)(&image[j * 8]))[3] = 65535;
443423 }
444424 else
445425 {
479459 }
480460
481461 if (r_mergeLightmaps->integer)
482 R_UpdateSubImage(tr.lightmaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize);
462 R_UpdateSubImage(tr.lightmaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize, textureInternalFormat);
483463 else
484 tr.lightmaps[i] = R_CreateImage(va("*lightmap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_COLORALPHA, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, textureInternalFormat );
464 tr.lightmaps[i] = R_CreateImage(va("*lightmap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_COLORALPHA, imgFlags, textureInternalFormat );
485465
486466 if (hdrLightmap)
487467 ri.FS_FreeFile(hdrLightmap);
508488 }
509489
510490 if (r_mergeLightmaps->integer)
511 {
512 R_UpdateSubImage(tr.deluxemaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize );
513 }
491 R_UpdateSubImage(tr.deluxemaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize, GL_RGBA8 );
514492 else
515 {
516 tr.deluxemaps[i] = R_CreateImage(va("*deluxemap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_DELUXE, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, 0 );
517 }
493 tr.deluxemaps[i] = R_CreateImage(va("*deluxemap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_DELUXE, imgFlags, 0 );
518494 }
519495 }
520496
533509 if (tr.worldDeluxeMapping)
534510 lightmapnum >>= 1;
535511
536 if(tr.fatLightmapSize > 0)
537 {
538 int x;
539
540 lightmapnum %= (tr.fatLightmapStep * tr.fatLightmapStep);
541
542 x = lightmapnum % tr.fatLightmapStep;
543
544 return (input / ((float)tr.fatLightmapStep)) + ((1.0 / ((float)tr.fatLightmapStep)) * (float)x);
512 if (tr.fatLightmapCols > 0)
513 {
514 lightmapnum %= (tr.fatLightmapCols * tr.fatLightmapRows);
515 return (input + (lightmapnum % tr.fatLightmapCols)) / (float)(tr.fatLightmapCols);
545516 }
546517
547518 return input;
555526 if (tr.worldDeluxeMapping)
556527 lightmapnum >>= 1;
557528
558 if(tr.fatLightmapSize > 0)
559 {
560 int y;
561
562 lightmapnum %= (tr.fatLightmapStep * tr.fatLightmapStep);
563
564 y = lightmapnum / tr.fatLightmapStep;
565
566 return (input / ((float)tr.fatLightmapStep)) + ((1.0 / ((float)tr.fatLightmapStep)) * (float)y);
529 if (tr.fatLightmapCols > 0)
530 {
531 lightmapnum %= (tr.fatLightmapCols * tr.fatLightmapRows);
532 return (input + (lightmapnum / tr.fatLightmapCols)) / (float)(tr.fatLightmapRows);
567533 }
568534
569535 return input;
578544 if (tr.worldDeluxeMapping)
579545 lightmapnum >>= 1;
580546
581 if (tr.fatLightmapSize > 0)
582 {
583 return lightmapnum / (tr.fatLightmapStep * tr.fatLightmapStep);
584 }
547 if (tr.fatLightmapCols > 0)
548 return lightmapnum / (tr.fatLightmapCols * tr.fatLightmapRows);
585549
586550 return lightmapnum;
587551 }
708672
709673 return (void *)retval;
710674 }
675
676 void LoadDrawVertToSrfVert(srfVert_t *s, drawVert_t *d, int realLightmapNum, float hdrVertColors[3], vec3_t *bounds)
677 {
678 vec4_t v;
679
680 s->xyz[0] = LittleFloat(d->xyz[0]);
681 s->xyz[1] = LittleFloat(d->xyz[1]);
682 s->xyz[2] = LittleFloat(d->xyz[2]);
683
684 if (bounds)
685 AddPointToBounds(s->xyz, bounds[0], bounds[1]);
686
687 s->st[0] = LittleFloat(d->st[0]);
688 s->st[1] = LittleFloat(d->st[1]);
689
690 if (realLightmapNum >= 0)
691 {
692 s->lightmap[0] = FatPackU(LittleFloat(d->lightmap[0]), realLightmapNum);
693 s->lightmap[1] = FatPackV(LittleFloat(d->lightmap[1]), realLightmapNum);
694 }
695 else
696 {
697 s->lightmap[0] = LittleFloat(d->lightmap[0]);
698 s->lightmap[1] = LittleFloat(d->lightmap[1]);
699 }
700
701 v[0] = LittleFloat(d->normal[0]);
702 v[1] = LittleFloat(d->normal[1]);
703 v[2] = LittleFloat(d->normal[2]);
704
705 R_VaoPackNormal(s->normal, v);
706
707 if (hdrVertColors)
708 {
709 v[0] = hdrVertColors[0];
710 v[1] = hdrVertColors[1];
711 v[2] = hdrVertColors[2];
712 }
713 else
714 {
715 //hack: convert LDR vertex colors to HDR
716 if (r_hdr->integer)
717 {
718 v[0] = MAX(d->color[0], 0.499f);
719 v[1] = MAX(d->color[1], 0.499f);
720 v[2] = MAX(d->color[2], 0.499f);
721 }
722 else
723 {
724 v[0] = d->color[0];
725 v[1] = d->color[1];
726 v[2] = d->color[2];
727 }
728
729 }
730 v[3] = d->color[3] / 255.0f;
731
732 R_ColorShiftLightingFloats(v, v);
733 R_VaoPackColor(s->color, v);
734 }
735
711736
712737 /*
713738 ===============
756781 ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
757782 verts += LittleLong(ds->firstVert);
758783 for(i = 0; i < numVerts; i++)
759 {
760 vec4_t color;
761
762 for(j = 0; j < 3; j++)
763 {
764 cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]);
765 cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]);
766 }
767 AddPointToBounds(cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
768 for(j = 0; j < 2; j++)
769 {
770 cv->verts[i].st[j] = LittleFloat(verts[i].st[j]);
771 //cv->verts[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]);
772 }
773 cv->verts[i].lightmap[0] = FatPackU(LittleFloat(verts[i].lightmap[0]), realLightmapNum);
774 cv->verts[i].lightmap[1] = FatPackV(LittleFloat(verts[i].lightmap[1]), realLightmapNum);
775
776 if (hdrVertColors)
777 {
778 color[0] = hdrVertColors[(ds->firstVert + i) * 3 ];
779 color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1];
780 color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2];
781 }
782 else
783 {
784 //hack: convert LDR vertex colors to HDR
785 if (r_hdr->integer)
786 {
787 color[0] = MAX(verts[i].color[0], 0.499f);
788 color[1] = MAX(verts[i].color[1], 0.499f);
789 color[2] = MAX(verts[i].color[2], 0.499f);
790 }
791 else
792 {
793 color[0] = verts[i].color[0];
794 color[1] = verts[i].color[1];
795 color[2] = verts[i].color[2];
796 }
797
798 }
799 color[3] = verts[i].color[3] / 255.0f;
800
801 R_ColorShiftLightingFloats( color, cv->verts[i].vertexColors, 1.0f / 255.0f );
802 }
784 LoadDrawVertToSrfVert(&cv->verts[i], &verts[i], realLightmapNum, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, surf->cullinfo.bounds);
803785
804786 // copy triangles
805787 badTriangles = 0;
840822
841823 surf->data = (surfaceType_t *)cv;
842824
843 #ifdef USE_VERT_TANGENT_SPACE
844825 // Calculate tangent spaces
845826 {
846827 srfVert_t *dv[3];
854835 R_CalcTangentVectors(dv);
855836 }
856837 }
857 #endif
858838 }
859839
860840
864844 ===============
865845 */
866846 static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf ) {
867 srfBspSurface_t *grid;
868 int i, j;
847 srfBspSurface_t *grid = (srfBspSurface_t *)surf->data;
848 int i;
869849 int width, height, numPoints;
870850 srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE];
871851 vec3_t bounds[2];
900880 verts += LittleLong( ds->firstVert );
901881 numPoints = width * height;
902882 for(i = 0; i < numPoints; i++)
903 {
904 vec4_t color;
905
906 for(j = 0; j < 3; j++)
907 {
908 points[i].xyz[j] = LittleFloat(verts[i].xyz[j]);
909 points[i].normal[j] = LittleFloat(verts[i].normal[j]);
910 }
911
912 for(j = 0; j < 2; j++)
913 {
914 points[i].st[j] = LittleFloat(verts[i].st[j]);
915 //points[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]);
916 }
917 points[i].lightmap[0] = FatPackU(LittleFloat(verts[i].lightmap[0]), realLightmapNum);
918 points[i].lightmap[1] = FatPackV(LittleFloat(verts[i].lightmap[1]), realLightmapNum);
919
920 if (hdrVertColors)
921 {
922 color[0] = hdrVertColors[(ds->firstVert + i) * 3 ];
923 color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1];
924 color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2];
925 }
926 else
927 {
928 //hack: convert LDR vertex colors to HDR
929 if (r_hdr->integer)
930 {
931 color[0] = MAX(verts[i].color[0], 0.499f);
932 color[1] = MAX(verts[i].color[1], 0.499f);
933 color[2] = MAX(verts[i].color[2], 0.499f);
934 }
935 else
936 {
937 color[0] = verts[i].color[0];
938 color[1] = verts[i].color[1];
939 color[2] = verts[i].color[2];
940 }
941 }
942 color[3] = verts[i].color[3] / 255.0f;
943
944 R_ColorShiftLightingFloats( color, points[i].vertexColors, 1.0f / 255.0f );
945 }
883 LoadDrawVertToSrfVert(&points[i], &verts[i], realLightmapNum, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, NULL);
946884
947885 // pre-tesseleate
948 grid = R_SubdividePatchToGrid( width, height, points );
949 surf->data = (surfaceType_t *)grid;
886 R_SubdividePatchToGrid( grid, width, height, points );
950887
951888 // copy the level of detail origin, which is the center
952889 // of the group of all curves that must subdivide the same
959896 VectorScale( bounds[1], 0.5f, grid->lodOrigin );
960897 VectorSubtract( bounds[0], grid->lodOrigin, tmpVec );
961898 grid->lodRadius = VectorLength( tmpVec );
899
900 surf->cullinfo.type = CULLINFO_BOX | CULLINFO_SPHERE;
901 VectorCopy(grid->cullBounds[0], surf->cullinfo.bounds[0]);
902 VectorCopy(grid->cullBounds[1], surf->cullinfo.bounds[1]);
903 VectorCopy(grid->cullOrigin, surf->cullinfo.localOrigin);
904 surf->cullinfo.radius = grid->cullRadius;
962905 }
963906
964907 /*
1001944 ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
1002945 verts += LittleLong(ds->firstVert);
1003946 for(i = 0; i < numVerts; i++)
1004 {
1005 vec4_t color;
1006
1007 for(j = 0; j < 3; j++)
1008 {
1009 cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]);
1010 cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]);
1011 }
1012
1013 AddPointToBounds( cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1] );
1014
1015 for(j = 0; j < 2; j++)
1016 {
1017 cv->verts[i].st[j] = LittleFloat(verts[i].st[j]);
1018 cv->verts[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]);
1019 }
1020
1021 if (hdrVertColors)
1022 {
1023 color[0] = hdrVertColors[(ds->firstVert + i) * 3 ];
1024 color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1];
1025 color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2];
1026 }
1027 else
1028 {
1029 //hack: convert LDR vertex colors to HDR
1030 if (r_hdr->integer)
1031 {
1032 color[0] = MAX(verts[i].color[0], 0.499f);
1033 color[1] = MAX(verts[i].color[1], 0.499f);
1034 color[2] = MAX(verts[i].color[2], 0.499f);
1035 }
1036 else
1037 {
1038 color[0] = verts[i].color[0];
1039 color[1] = verts[i].color[1];
1040 color[2] = verts[i].color[2];
1041 }
1042 }
1043 color[3] = verts[i].color[3] / 255.0f;
1044
1045 R_ColorShiftLightingFloats( color, cv->verts[i].vertexColors, 1.0f / 255.0f );
1046 }
947 LoadDrawVertToSrfVert(&cv->verts[i], &verts[i], -1, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, surf->cullinfo.bounds);
1047948
1048949 // copy triangles
1049950 badTriangles = 0;
1073974 cv->numIndexes -= badTriangles * 3;
1074975 }
1075976
1076 #ifdef USE_VERT_TANGENT_SPACE
1077977 // Calculate tangent spaces
1078978 {
1079979 srfVert_t *dv[3];
1087987 R_CalcTangentVectors(dv);
1088988 }
1089989 }
1090 #endif
1091990 }
1092991
1093992 /*
11191018 flare->color[i] = LittleFloat( ds->lightmapVecs[0][i] );
11201019 flare->normal[i] = LittleFloat( ds->lightmapVecs[2][i] );
11211020 }
1021
1022 surf->cullinfo.type = CULLINFO_NONE;
11221023 }
11231024
11241025
14451346 if ( m ) {
14461347 row = grid2->height - 1;
14471348 } else { row = 0;}
1448 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1449 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1349 R_GridInsertColumn( grid2, l + 1, row,
1350 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
14501351 grid2->lodStitched = qfalse;
14511352 s_worldData.surfaces[grid2num].data = (void *) grid2;
14521353 return qtrue;
15011402 if ( m ) {
15021403 column = grid2->width - 1;
15031404 } else { column = 0;}
1504 grid2 = R_GridInsertRow( grid2, l + 1, column,
1505 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1405 R_GridInsertRow( grid2, l + 1, column,
1406 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
15061407 grid2->lodStitched = qfalse;
15071408 s_worldData.surfaces[grid2num].data = (void *) grid2;
15081409 return qtrue;
15681469 if ( m ) {
15691470 row = grid2->height - 1;
15701471 } else { row = 0;}
1571 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1572 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1472 R_GridInsertColumn( grid2, l + 1, row,
1473 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
15731474 grid2->lodStitched = qfalse;
15741475 s_worldData.surfaces[grid2num].data = (void *) grid2;
15751476 return qtrue;
16241525 if ( m ) {
16251526 column = grid2->width - 1;
16261527 } else { column = 0;}
1627 grid2 = R_GridInsertRow( grid2, l + 1, column,
1628 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1528 R_GridInsertRow( grid2, l + 1, column,
1529 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
16291530 grid2->lodStitched = qfalse;
16301531 s_worldData.surfaces[grid2num].data = (void *) grid2;
16311532 return qtrue;
16921593 if ( m ) {
16931594 row = grid2->height - 1;
16941595 } else { row = 0;}
1695 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1696 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1596 R_GridInsertColumn( grid2, l + 1, row,
1597 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
16971598 grid2->lodStitched = qfalse;
16981599 s_worldData.surfaces[grid2num].data = (void *) grid2;
16991600 return qtrue;
17481649 if ( m ) {
17491650 column = grid2->width - 1;
17501651 } else { column = 0;}
1751 grid2 = R_GridInsertRow( grid2, l + 1, column,
1752 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1652 R_GridInsertRow( grid2, l + 1, column,
1653 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
17531654 if ( !grid2 ) {
17541655 break;
17551656 }
18181719 if ( m ) {
18191720 row = grid2->height - 1;
18201721 } else { row = 0;}
1821 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1822 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1722 R_GridInsertColumn( grid2, l + 1, row,
1723 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
18231724 grid2->lodStitched = qfalse;
18241725 s_worldData.surfaces[grid2num].data = (void *) grid2;
18251726 return qtrue;
18741775 if ( m ) {
18751776 column = grid2->width - 1;
18761777 } else { column = 0;}
1877 grid2 = R_GridInsertRow( grid2, l + 1, column,
1878 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1778 R_GridInsertRow( grid2, l + 1, column,
1779 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
18791780 grid2->lodStitched = qfalse;
18801781 s_worldData.surfaces[grid2num].data = (void *) grid2;
18811782 return qtrue;
19761877 ===============
19771878 */
19781879 void R_MovePatchSurfacesToHunk( void ) {
1979 int i, size;
1980 srfBspSurface_t *grid, *hunkgrid;
1880 int i;
1881 srfBspSurface_t *grid;
19811882
19821883 for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
1884 void *copyFrom;
19831885 //
19841886 grid = (srfBspSurface_t *) s_worldData.surfaces[i].data;
19851887 // if this surface is not a grid
19871889 continue;
19881890 }
19891891 //
1990 size = sizeof(*grid);
1991 hunkgrid = ri.Hunk_Alloc(size, h_low);
1992 Com_Memcpy( hunkgrid, grid, size );
1993
1994 hunkgrid->widthLodError = ri.Hunk_Alloc( grid->width * 4, h_low );
1995 Com_Memcpy( hunkgrid->widthLodError, grid->widthLodError, grid->width * 4 );
1996
1997 hunkgrid->heightLodError = ri.Hunk_Alloc( grid->height * 4, h_low );
1998 Com_Memcpy( hunkgrid->heightLodError, grid->heightLodError, grid->height * 4 );
1999
2000 hunkgrid->numIndexes = grid->numIndexes;
2001 hunkgrid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low);
2002 Com_Memcpy(hunkgrid->indexes, grid->indexes, grid->numIndexes * sizeof(glIndex_t));
2003
2004 hunkgrid->numVerts = grid->numVerts;
2005 hunkgrid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low);
2006 Com_Memcpy(hunkgrid->verts, grid->verts, grid->numVerts * sizeof(srfVert_t));
2007
2008 R_FreeSurfaceGridMesh( grid );
2009
2010 s_worldData.surfaces[i].data = (void *) hunkgrid;
1892 copyFrom = grid->widthLodError;
1893 grid->widthLodError = ri.Hunk_Alloc( grid->width * 4, h_low );
1894 Com_Memcpy(grid->widthLodError, copyFrom, grid->width * 4);
1895 ri.Free(copyFrom);
1896
1897 copyFrom = grid->heightLodError;
1898 grid->heightLodError = ri.Hunk_Alloc(grid->height * 4, h_low);
1899 Com_Memcpy(grid->heightLodError, copyFrom, grid->height * 4);
1900 ri.Free(copyFrom);
1901
1902 copyFrom = grid->indexes;
1903 grid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low);
1904 Com_Memcpy(grid->indexes, copyFrom, grid->numIndexes * sizeof(glIndex_t));
1905 ri.Free(copyFrom);
1906
1907 copyFrom = grid->verts;
1908 grid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low);
1909 Com_Memcpy(grid->verts, copyFrom, grid->numVerts * sizeof(srfVert_t));
1910 ri.Free(copyFrom);
20111911 }
20121912 }
20131913
20671967 static void CopyVert(const srfVert_t * in, srfVert_t * out)
20681968 {
20691969 VectorCopy(in->xyz, out->xyz);
2070 #ifdef USE_VERT_TANGENT_SPACE
20711970 VectorCopy4(in->tangent, out->tangent);
2072 #endif
2073 VectorCopy(in->normal, out->normal);
2074 VectorCopy(in->lightdir, out->lightdir);
1971 VectorCopy4(in->normal, out->normal);
1972 VectorCopy4(in->lightdir, out->lightdir);
20751973
20761974 VectorCopy2(in->st, out->st);
20771975 VectorCopy2(in->lightmap, out->lightmap);
20781976
2079 VectorCopy4(in->vertexColors, out->vertexColors);
1977 VectorCopy4(in->color, out->color);
20801978 }
20811979
20821980
23482246 // -1 represents 0, -2 represents 1, and so on
23492247 s_worldData.viewSurfaces = ri.Hunk_Alloc(sizeof(*s_worldData.viewSurfaces) * s_worldData.nummarksurfaces, h_low);
23502248
2351 // copy view surfaces into mark surfaces
2352 for (i = 0; i < s_worldData.nummarksurfaces; i++)
2353 {
2354 s_worldData.viewSurfaces[i] = s_worldData.marksurfaces[i];
2355 }
2356
23572249 // actually merge surfaces
23582250 mergedSurf = s_worldData.mergedSurfaces;
23592251 for(firstSurf = lastSurf = surfacesSorted; firstSurf < surfacesSorted + numSortedSurfaces; firstSurf = lastSurf)
24142306 mergedSurf->cubemapIndex = (*firstSurf)->cubemapIndex;
24152307 mergedSurf->shader = (*firstSurf)->shader;
24162308
2417 // redirect view surfaces to this surf
2309 // change surfacesViewCount[] from leaf index to viewSurface index - 1 so we can redirect later
2310 // subtracting 2 (viewSurface index - 1) to avoid collision with -1 (no leaf)
24182311 for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
2419 s_worldData.surfacesViewCount[*currSurf - s_worldData.surfaces] = -2;
2420
2421 for (k = 0; k < s_worldData.nummarksurfaces; k++)
2422 {
2423 if (s_worldData.surfacesViewCount[s_worldData.marksurfaces[k]] == -2)
2424 s_worldData.viewSurfaces[k] = -((int)(mergedSurf - s_worldData.mergedSurfaces) + 1);
2425 }
2426
2427 for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
2428 s_worldData.surfacesViewCount[*currSurf - s_worldData.surfaces] = -1;
2312 s_worldData.surfacesViewCount[*currSurf - s_worldData.surfaces] = -((int)(mergedSurf - s_worldData.mergedSurfaces)) - 2;
24292313
24302314 mergedSurf++;
24312315 }
24322316
2433 ri.Printf(PRINT_ALL, "Processed %d mergeable surfaces into %d merged, %d unmerged\n",
2317 // direct viewSurfaces to merged and unmerged surfaces
2318 for (i = 0; i < s_worldData.nummarksurfaces; i++)
2319 {
2320 int viewSurfaceIndex = s_worldData.surfacesViewCount[s_worldData.marksurfaces[i]] + 1;
2321 s_worldData.viewSurfaces[i] = (viewSurfaceIndex < 0) ? viewSurfaceIndex : s_worldData.marksurfaces[i];
2322 }
2323
2324 ri.Printf(PRINT_ALL, "Processed %d mergeable surfaces into %d merged, %d unmerged\n",
24342325 numSortedSurfaces, numMergedSurfaces, numUnmergedSurfaces);
24352326 }
24362327
25182409 for ( i = 0 ; i < count ; i++, in++, out++ ) {
25192410 switch ( LittleLong( in->surfaceType ) ) {
25202411 case MST_PATCH:
2521 // FIXME: do this
2412 out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
25222413 break;
25232414 case MST_TRIANGLE_SOUP:
25242415 out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
25402431 switch ( LittleLong( in->surfaceType ) ) {
25412432 case MST_PATCH:
25422433 ParseMesh ( in, dv, hdrVertColors, out );
2543 {
2544 srfBspSurface_t *surface = (srfBspSurface_t *)out->data;
2545
2546 out->cullinfo.type = CULLINFO_BOX | CULLINFO_SPHERE;
2547 VectorCopy(surface->cullBounds[0], out->cullinfo.bounds[0]);
2548 VectorCopy(surface->cullBounds[1], out->cullinfo.bounds[1]);
2549 VectorCopy(surface->cullOrigin, out->cullinfo.localOrigin);
2550 out->cullinfo.radius = surface->cullRadius;
2551 }
25522434 numMeshes++;
25532435 break;
25542436 case MST_TRIANGLE_SOUP:
25612443 break;
25622444 case MST_FLARE:
25632445 ParseFlare( in, dv, out, indexes );
2564 {
2565 out->cullinfo.type = CULLINFO_NONE;
2566 }
25672446 numFlares++;
25682447 break;
25692448 default:
29182797
29192798 out->parms = shader->fogParms;
29202799
2921 out->colorInt = ColorBytes4( shader->fogParms.color[0] * tr.identityLight,
2922 shader->fogParms.color[1] * tr.identityLight,
2923 shader->fogParms.color[2] * tr.identityLight, 1.0 );
2800 out->colorInt = ColorBytes4 ( shader->fogParms.color[0],
2801 shader->fogParms.color[1],
2802 shader->fogParms.color[2], 1.0 );
29242803
29252804 d = shader->fogParms.depthForOpaque < 1 ? 1 : shader->fogParms.depthForOpaque;
29262805 out->tcScale = 1.0f / ( d * 8 );
31102989
31112990 if (hdrLightGrid)
31122991 {
3113 #if defined(USE_OVERBRIGHT)
3114 float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits);
3115 #else
3116 float lightScale = 1.0f;
3117 #endif
31182992 //ri.Printf(PRINT_ALL, "found!\n");
31192993
31202994 if (size != sizeof(float) * 6 * numGridPoints)
3121 {
31222995 ri.Error(ERR_DROP, "Bad size for %s (%i, expected %i)!", filename, size, (int)(sizeof(float)) * 6 * numGridPoints);
3123 }
3124
3125 w->hdrLightGrid = ri.Hunk_Alloc(size, h_low);
2996
2997 w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints, h_low);
31262998
31272999 for (i = 0; i < numGridPoints ; i++)
31283000 {
3129 w->hdrLightGrid[i * 6 ] = hdrLightGrid[i * 6 ] * lightScale;
3130 w->hdrLightGrid[i * 6 + 1] = hdrLightGrid[i * 6 + 1] * lightScale;
3131 w->hdrLightGrid[i * 6 + 2] = hdrLightGrid[i * 6 + 2] * lightScale;
3132 w->hdrLightGrid[i * 6 + 3] = hdrLightGrid[i * 6 + 3] * lightScale;
3133 w->hdrLightGrid[i * 6 + 4] = hdrLightGrid[i * 6 + 4] * lightScale;
3134 w->hdrLightGrid[i * 6 + 5] = hdrLightGrid[i * 6 + 5] * lightScale;
3001 vec4_t c;
3002
3003 c[0] = hdrLightGrid[i * 6];
3004 c[1] = hdrLightGrid[i * 6 + 1];
3005 c[2] = hdrLightGrid[i * 6 + 2];
3006 c[3] = 1.0f;
3007
3008 R_ColorShiftLightingFloats(c, c);
3009 ColorToRGB16(c, &w->lightGrid16[i * 6]);
3010
3011 c[0] = hdrLightGrid[i * 6 + 3];
3012 c[1] = hdrLightGrid[i * 6 + 4];
3013 c[2] = hdrLightGrid[i * 6 + 5];
3014 c[3] = 1.0f;
3015
3016 R_ColorShiftLightingFloats(c, c);
3017 ColorToRGB16(c, &w->lightGrid16[i * 6 + 3]);
3018 }
3019 }
3020 else if (0)
3021 {
3022 // promote 8-bit lightgrid to 16-bit
3023 w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints, h_low);
3024
3025 for (i = 0; i < numGridPoints; i++)
3026 {
3027 w->lightGrid16[i * 6] = w->lightGridData[i * 8] * 257;
3028 w->lightGrid16[i * 6 + 1] = w->lightGridData[i * 8 + 1] * 257;
3029 w->lightGrid16[i * 6 + 2] = w->lightGridData[i * 8 + 2] * 257;
3030 w->lightGrid16[i * 6 + 3] = w->lightGridData[i * 8 + 3] * 257;
3031 w->lightGrid16[i * 6 + 4] = w->lightGridData[i * 8 + 4] * 257;
3032 w->lightGrid16[i * 6 + 5] = w->lightGridData[i * 8 + 5] * 257;
31353033 }
31363034 }
31373035
33223220 return qtrue;
33233221 }
33243222
3223 void R_LoadEnvironmentJson(const char *baseName)
3224 {
3225 char filename[MAX_QPATH];
3226
3227 union {
3228 char *c;
3229 void *v;
3230 } buffer;
3231 char *bufferEnd;
3232
3233 const char *cubemapArrayJson;
3234 int filelen, i;
3235
3236 Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/env.json", baseName);
3237
3238 filelen = ri.FS_ReadFile(filename, &buffer.v);
3239 if (!buffer.c)
3240 return;
3241 bufferEnd = buffer.c + filelen;
3242
3243 if (JSON_ValueGetType(buffer.c, bufferEnd) != JSONTYPE_OBJECT)
3244 {
3245 ri.Printf(PRINT_ALL, "Bad %s: does not start with a object\n", filename);
3246 ri.FS_FreeFile(buffer.v);
3247 return;
3248 }
3249
3250 cubemapArrayJson = JSON_ObjectGetNamedValue(buffer.c, bufferEnd, "Cubemaps");
3251 if (!cubemapArrayJson)
3252 {
3253 ri.Printf(PRINT_ALL, "Bad %s: no Cubemaps\n", filename);
3254 ri.FS_FreeFile(buffer.v);
3255 return;
3256 }
3257
3258 if (JSON_ValueGetType(cubemapArrayJson, bufferEnd) != JSONTYPE_ARRAY)
3259 {
3260 ri.Printf(PRINT_ALL, "Bad %s: Cubemaps not an array\n", filename);
3261 ri.FS_FreeFile(buffer.v);
3262 return;
3263 }
3264
3265 tr.numCubemaps = JSON_ArrayGetIndex(cubemapArrayJson, bufferEnd, NULL, 0);
3266 tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low);
3267 memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps));
3268
3269 for (i = 0; i < tr.numCubemaps; i++)
3270 {
3271 cubemap_t *cubemap = &tr.cubemaps[i];
3272 const char *cubemapJson, *keyValueJson, *indexes[3];
3273 int j;
3274
3275 cubemapJson = JSON_ArrayGetValue(cubemapArrayJson, bufferEnd, i);
3276
3277 keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Name");
3278 if (!JSON_ValueGetString(keyValueJson, bufferEnd, cubemap->name, MAX_QPATH))
3279 cubemap->name[0] = '\0';
3280
3281 keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Position");
3282 JSON_ArrayGetIndex(keyValueJson, bufferEnd, indexes, 3);
3283 for (j = 0; j < 3; j++)
3284 cubemap->origin[j] = JSON_ValueGetFloat(indexes[j], bufferEnd);
3285
3286 cubemap->parallaxRadius = 1000.0f;
3287 keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Radius");
3288 if (keyValueJson)
3289 cubemap->parallaxRadius = JSON_ValueGetFloat(keyValueJson, bufferEnd);
3290 }
3291
3292 ri.FS_FreeFile(buffer.v);
3293 }
3294
33253295 void R_LoadCubemapEntities(char *cubemapEntityName)
33263296 {
33273297 char spawnVarChars[2048];
33533323 while(R_ParseSpawnVars(spawnVarChars, sizeof(spawnVarChars), &numSpawnVars, spawnVars))
33543324 {
33553325 int i;
3326 char name[MAX_QPATH];
33563327 qboolean isCubemap = qfalse;
33573328 qboolean originSet = qfalse;
33583329 vec3_t origin;
33593330 float parallaxRadius = 1000.0f;
33603331
3332 name[0] = '\0';
33613333 for (i = 0; i < numSpawnVars; i++)
33623334 {
33633335 if (!Q_stricmp(spawnVars[i][0], "classname") && !Q_stricmp(spawnVars[i][1], cubemapEntityName))
33643336 isCubemap = qtrue;
3337
3338 if (!Q_stricmp(spawnVars[i][0], "name"))
3339 Q_strncpyz(name, spawnVars[i][1], MAX_QPATH);
33653340
33663341 if (!Q_stricmp(spawnVars[i][0], "origin"))
33673342 {
33763351
33773352 if (isCubemap && originSet)
33783353 {
3379 //ri.Printf(PRINT_ALL, "cubemap at %f %f %f\n", origin[0], origin[1], origin[2]);
3380 VectorCopy(origin, tr.cubemaps[numCubemaps].origin);
3381 tr.cubemaps[numCubemaps].parallaxRadius = parallaxRadius;
3354 cubemap_t *cubemap = &tr.cubemaps[numCubemaps];
3355 Q_strncpyz(cubemap->name, name, MAX_QPATH);
3356 VectorCopy(origin, cubemap->origin);
3357 cubemap->parallaxRadius = parallaxRadius;
33823358 numCubemaps++;
33833359 }
33843360 }
34183394 }
34193395
34203396
3421 void R_RenderAllCubemaps(void)
3397 void R_LoadCubemaps(void)
3398 {
3399 int i;
3400 imgFlags_t flags = IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP;
3401
3402 for (i = 0; i < tr.numCubemaps; i++)
3403 {
3404 char filename[MAX_QPATH];
3405 cubemap_t *cubemap = &tr.cubemaps[i];
3406
3407 Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i);
3408
3409 cubemap->image = R_FindImageFile(filename, IMGTYPE_COLORALPHA, flags);
3410 }
3411 }
3412
3413
3414 void R_RenderMissingCubemaps(void)
34223415 {
34233416 int i, j;
3424
3425 for (i = 0; i < tr.numCubemaps; i++)
3426 {
3427 tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8);
3428 }
3417 imgFlags_t flags = IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP;
34293418
34303419 ri.Printf(PRINT_ALL, "Total cubemaps: %d\n", tr.numCubemaps );
34313420
34323421 for (i = 0; i < tr.numCubemaps; i++)
34333422 {
3434 for (j = 0; j < 6; j++)
3435 {
3436 RE_ClearScene();
3437 R_RenderCubemapSide(i, j, qfalse);
3438 R_IssuePendingRenderCommands();
3439 R_InitNextFrame();
3423 if (!tr.cubemaps[i].image)
3424 {
3425 tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, flags, GL_RGBA8);
3426
3427 for (j = 0; j < 6; j++)
3428 {
3429 RE_ClearScene();
3430 R_RenderCubemapSide(i, j, qfalse);
3431 R_IssuePendingRenderCommands();
3432 R_InitNextFrame();
3433 }
34403434 }
34413435 }
34423436 }
34573451 case SF_GRID:
34583452 case SF_TRIANGLES:
34593453 for(i = 0; i < bspSurf->numVerts; i++)
3460 R_LightDirForPoint( bspSurf->verts[i].xyz, bspSurf->verts[i].lightdir, bspSurf->verts[i].normal, &s_worldData );
3454 {
3455 vec3_t lightDir;
3456 vec3_t normal;
3457
3458 R_VaoUnpackNormal(normal, bspSurf->verts[i].normal);
3459 R_LightDirForPoint( bspSurf->verts[i].xyz, lightDir, normal, &s_worldData );
3460 R_VaoPackNormal(bspSurf->verts[i].lightdir, lightDir);
3461 }
34613462
34623463 break;
34633464
34903491 }
34913492
34923493 // set default map light scale
3493 tr.mapLightScale = 1.0f;
34943494 tr.sunShadowScale = 0.5f;
34953495
34963496 // set default sun direction to be used if it isn't
37773777 // load cubemaps
37783778 if (r_cubeMapping->integer)
37793779 {
3780 R_LoadCubemapEntities("misc_cubemap");
3780 // Try loading an env.json file first
3781 R_LoadEnvironmentJson(s_worldData.baseName);
3782
3783 if (!tr.numCubemaps)
3784 {
3785 R_LoadCubemapEntities("misc_cubemap");
3786 }
3787
37813788 if (!tr.numCubemaps)
37823789 {
37833790 // use locations as cubemaps
38113818 // make sure the VAO glState entry is safe
38123819 R_BindNullVao();
38133820
3814 // Render all cubemaps
3815 if (r_cubeMapping->integer && tr.numCubemaps)
3816 {
3817 R_RenderAllCubemaps();
3821 // Render or load all cubemaps
3822 if (r_cubeMapping->integer && tr.numCubemaps && glRefConfig.framebufferObject)
3823 {
3824 R_LoadCubemaps();
3825 R_RenderMissingCubemaps();
38183826 }
38193827
38203828 ri.FS_FreeFile( buffer.v );
6060 out->lightmap[0] = 0.5f * ( a->lightmap[0] + b->lightmap[0] );
6161 out->lightmap[1] = 0.5f * ( a->lightmap[1] + b->lightmap[1] );
6262
63 out->vertexColors[0] = 0.5f * (a->vertexColors[0] + b->vertexColors[0]);
64 out->vertexColors[1] = 0.5f * (a->vertexColors[1] + b->vertexColors[1]);
65 out->vertexColors[2] = 0.5f * (a->vertexColors[2] + b->vertexColors[2]);
66 out->vertexColors[3] = 0.5f * (a->vertexColors[3] + b->vertexColors[3]);
63 out->color[0] = ((int)a->color[0] + (int)b->color[0]) >> 1;
64 out->color[1] = ((int)a->color[1] + (int)b->color[1]) >> 1;
65 out->color[2] = ((int)a->color[2] + (int)b->color[2]) >> 1;
66 out->color[3] = ((int)a->color[3] + (int)b->color[3]) >> 1;
6767 }
6868
6969 /*
213213 //if ( count == 0 ) {
214214 //printf("bad normal\n");
215215 //}
216 VectorNormalize2( sum, dv->normal );
217 }
218 }
219 }
220
221 #ifdef USE_VERT_TANGENT_SPACE
216 {
217 vec3_t fNormal;
218 VectorNormalize2(sum, fNormal);
219 R_VaoPackNormal(dv->normal, fNormal);
220 }
221 }
222 }
223 }
224
222225 static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numIndexes,
223226 glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
224227 {
257260 }
258261 }
259262 }
260 #endif
261
262 static int MakeMeshIndexes(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
263 glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
263
264 static int MakeMeshIndexes(int width, int height, glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
264265 {
265266 int i, j;
266267 int numIndexes;
267268 int w, h;
268 srfVert_t *dv;
269 static srfVert_t ctrl2[MAX_GRID_SIZE * MAX_GRID_SIZE];
270269
271270 h = height - 1;
272271 w = width - 1;
293292 }
294293 }
295294
296 // FIXME: use more elegant way
297 for(i = 0; i < width; i++)
298 {
299 for(j = 0; j < height; j++)
300 {
301 dv = &ctrl2[j * width + i];
302 *dv = ctrl[j][i];
303 }
304 }
305
306295 return numIndexes;
307296 }
308297
380369 R_CreateSurfaceGridMesh
381370 =================
382371 */
383 srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height,
372 void R_CreateSurfaceGridMesh(srfBspSurface_t *grid, int width, int height,
384373 srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], float errorTable[2][MAX_GRID_SIZE],
385374 int numIndexes, glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]) {
386375
387 int i, j, size;
376 int i, j;
388377 srfVert_t *vert;
389378 vec3_t tmpVec;
390 srfBspSurface_t *grid;
391379
392380 // copy the results out to a grid
393 size = (width * height - 1) * sizeof( srfVert_t ) + sizeof( *grid );
381 Com_Memset(grid, 0, sizeof(*grid));
394382
395383 #ifdef PATCH_STITCHING
396 grid = /*ri.Hunk_Alloc*/ ri.Z_Malloc( size );
397 Com_Memset( grid, 0, size );
398
399384 grid->widthLodError = /*ri.Hunk_Alloc*/ ri.Z_Malloc( width * 4 );
400385 memcpy( grid->widthLodError, errorTable[0], width * 4 );
401386
409394 grid->numVerts = (width * height);
410395 grid->verts = ri.Z_Malloc(grid->numVerts * sizeof(srfVert_t));
411396 #else
412 grid = ri.Hunk_Alloc( size, h_low );
413 memset( grid, 0, size );
414
415397 grid->widthLodError = ri.Hunk_Alloc( width * 4, h_low );
416398 memcpy( grid->widthLodError, errorTable[0], width * 4 );
417399
447429 VectorCopy( grid->cullOrigin, grid->lodOrigin );
448430 grid->lodRadius = grid->cullRadius;
449431 //
450 return grid;
451 }
452
453 /*
454 =================
455 R_FreeSurfaceGridMesh
456 =================
457 */
458 void R_FreeSurfaceGridMesh( srfBspSurface_t *grid ) {
432 }
433
434 /*
435 =================
436 R_FreeSurfaceGridMeshData
437 =================
438 */
439 static void R_FreeSurfaceGridMeshData( srfBspSurface_t *grid ) {
459440 ri.Free( grid->widthLodError );
460441 ri.Free( grid->heightLodError );
461442 ri.Free( grid->indexes );
462443 ri.Free( grid->verts );
463 ri.Free( grid );
464444 }
465445
466446 /*
468448 R_SubdividePatchToGrid
469449 =================
470450 */
471 srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
451 void R_SubdividePatchToGrid( srfBspSurface_t *grid, int width, int height,
472452 srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
473453 int i, j, k, l;
474454 srfVert_t_cleared( prev );
634614 #endif
635615
636616 // calculate indexes
637 numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
617 numIndexes = MakeMeshIndexes(width, height, indexes);
638618
639619 // calculate normals
640620 MakeMeshNormals( width, height, ctrl );
641 #ifdef USE_VERT_TANGENT_SPACE
642621 MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes);
643 #endif
644
645 return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
622
623 R_CreateSurfaceGridMesh(grid, width, height, ctrl, errorTable, numIndexes, indexes);
646624 }
647625
648626 /*
650628 R_GridInsertColumn
651629 ===============
652630 */
653 srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror ) {
631 void R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror ) {
654632 int i, j;
655633 int width, height, oldwidth;
656634 srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
663641 oldwidth = 0;
664642 width = grid->width + 1;
665643 if ( width > MAX_GRID_SIZE ) {
666 return NULL;
644 return;
667645 }
668646 height = grid->height;
669647 for ( i = 0; i < width; i++ ) {
691669 //PutPointsOnCurve( ctrl, width, height );
692670
693671 // calculate indexes
694 numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
672 numIndexes = MakeMeshIndexes(width, height, indexes);
695673
696674 // calculate normals
697675 MakeMeshNormals( width, height, ctrl );
676 MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes);
698677
699678 VectorCopy( grid->lodOrigin, lodOrigin );
700679 lodRadius = grid->lodRadius;
701680 // free the old grid
702 R_FreeSurfaceGridMesh( grid );
681 R_FreeSurfaceGridMeshData(grid);
703682 // create a new grid
704 grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
683 R_CreateSurfaceGridMesh(grid, width, height, ctrl, errorTable, numIndexes, indexes);
705684 grid->lodRadius = lodRadius;
706685 VectorCopy( lodOrigin, grid->lodOrigin );
707 return grid;
708686 }
709687
710688 /*
712690 R_GridInsertRow
713691 ===============
714692 */
715 srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror ) {
693 void R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror ) {
716694 int i, j;
717695 int width, height, oldheight;
718696 srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
726704 width = grid->width;
727705 height = grid->height + 1;
728706 if ( height > MAX_GRID_SIZE ) {
729 return NULL;
707 return;
730708 }
731709 for ( i = 0; i < height; i++ ) {
732710 if ( i == row ) {
753731 //PutPointsOnCurve( ctrl, width, height );
754732
755733 // calculate indexes
756 numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
734 numIndexes = MakeMeshIndexes(width, height, indexes);
757735
758736 // calculate normals
759737 MakeMeshNormals( width, height, ctrl );
738 MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes);
760739
761740 VectorCopy( grid->lodOrigin, lodOrigin );
762741 lodRadius = grid->lodRadius;
763742 // free the old grid
764 R_FreeSurfaceGridMesh( grid );
743 R_FreeSurfaceGridMeshData(grid);
765744 // create a new grid
766 grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
745 R_CreateSurfaceGridMesh(grid, width, height, ctrl, errorTable, numIndexes, indexes);
767746 grid->lodRadius = lodRadius;
768747 VectorCopy( lodOrigin, grid->lodOrigin );
769 return grid;
770 }
748 }
0 /*
1 ===========================================================================
2 Copyright (C) 2016 James Canete
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 ===========================================================================
18 */
19
20 #include "tr_local.h"
21
22 #include "tr_dsa.h"
23
24 static struct
25 {
26 GLuint textures[NUM_TEXTURE_BUNDLES];
27 GLenum texunit;
28
29 GLuint program;
30
31 GLuint drawFramebuffer;
32 GLuint readFramebuffer;
33 GLuint renderbuffer;
34 }
35 glDsaState;
36
37 void GL_BindNullTextures()
38 {
39 int i;
40
41 if (glRefConfig.directStateAccess)
42 {
43 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
44 {
45 qglBindMultiTextureEXT(GL_TEXTURE0_ARB + i, GL_TEXTURE_2D, 0);
46 glDsaState.textures[i] = 0;
47 }
48 }
49 else
50 {
51 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
52 {
53 qglActiveTextureARB(GL_TEXTURE0_ARB + i);
54 qglBindTexture(GL_TEXTURE_2D, 0);
55 glDsaState.textures[i] = 0;
56 }
57
58 qglActiveTextureARB(GL_TEXTURE0_ARB);
59 glDsaState.texunit = GL_TEXTURE0_ARB;
60 }
61 }
62
63 int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture)
64 {
65 GLuint tmu = texunit - GL_TEXTURE0_ARB;
66
67 if (glDsaState.textures[tmu] == texture)
68 return 0;
69
70 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
71 target = GL_TEXTURE_CUBE_MAP;
72
73 qglBindMultiTextureEXT(texunit, target, texture);
74 glDsaState.textures[tmu] = texture;
75 return 1;
76 }
77
78 GLvoid APIENTRY GLDSA_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture)
79 {
80 if (glDsaState.texunit != texunit)
81 {
82 qglActiveTextureARB(texunit);
83 glDsaState.texunit = texunit;
84 }
85
86 qglBindTexture(target, texture);
87 }
88
89 GLvoid APIENTRY GLDSA_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param)
90 {
91 GL_BindMultiTexture(glDsaState.texunit, target, texture);
92 qglTexParameterf(target, pname, param);
93 }
94
95 GLvoid APIENTRY GLDSA_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param)
96 {
97 GL_BindMultiTexture(glDsaState.texunit, target, texture);
98 qglTexParameteri(target, pname, param);
99 }
100
101 GLvoid APIENTRY GLDSA_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat,
102 GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
103 {
104 GL_BindMultiTexture(glDsaState.texunit, target, texture);
105 qglTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
106 }
107
108 GLvoid APIENTRY GLDSA_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
109 GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
110 {
111 GL_BindMultiTexture(glDsaState.texunit, target, texture);
112 qglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
113 }
114
115 GLvoid APIENTRY GLDSA_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
116 GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
117 {
118 GL_BindMultiTexture(glDsaState.texunit, target, texture);
119 qglCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
120 }
121
122 GLvoid APIENTRY GLDSA_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
123 GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
124 {
125 GL_BindMultiTexture(glDsaState.texunit, target, texture);
126 qglCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
127 }
128
129 GLvoid APIENTRY GLDSA_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
130 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
131 GLsizei imageSize, const GLvoid *data)
132 {
133 GL_BindMultiTexture(glDsaState.texunit, target, texture);
134 qglCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
135 }
136
137 GLvoid APIENTRY GLDSA_GenerateTextureMipmapEXT(GLuint texture, GLenum target)
138 {
139 GL_BindMultiTexture(glDsaState.texunit, target, texture);
140 qglGenerateMipmapEXT(target);
141 }
142
143 void GL_BindNullProgram()
144 {
145 qglUseProgram(0);
146 glDsaState.program = 0;
147 }
148
149 int GL_UseProgram(GLuint program)
150 {
151 if (glDsaState.program == program)
152 return 0;
153
154 qglUseProgram(program);
155 glDsaState.program = program;
156 return 1;
157 }
158
159 GLvoid APIENTRY GLDSA_ProgramUniform1iEXT(GLuint program, GLint location, GLint v0)
160 {
161 GL_UseProgram(program);
162 qglUniform1i(location, v0);
163 }
164
165 GLvoid APIENTRY GLDSA_ProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0)
166 {
167 GL_UseProgram(program);
168 qglUniform1f(location, v0);
169 }
170
171 GLvoid APIENTRY GLDSA_ProgramUniform2fEXT(GLuint program, GLint location,
172 GLfloat v0, GLfloat v1)
173 {
174 GL_UseProgram(program);
175 qglUniform2f(location, v0, v1);
176 }
177
178 GLvoid APIENTRY GLDSA_ProgramUniform3fEXT(GLuint program, GLint location,
179 GLfloat v0, GLfloat v1, GLfloat v2)
180 {
181 GL_UseProgram(program);
182 qglUniform3f(location, v0, v1, v2);
183 }
184
185 GLvoid APIENTRY GLDSA_ProgramUniform4fEXT(GLuint program, GLint location,
186 GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
187 {
188 GL_UseProgram(program);
189 qglUniform4f(location, v0, v1, v2, v3);
190 }
191
192 GLvoid APIENTRY GLDSA_ProgramUniform1fvEXT(GLuint program, GLint location,
193 GLsizei count, const GLfloat *value)
194 {
195 GL_UseProgram(program);
196 qglUniform1fv(location, count, value);
197 }
198
199 GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fvEXT(GLuint program, GLint location,
200 GLsizei count, GLboolean transpose,
201 const GLfloat *value)
202 {
203 GL_UseProgram(program);
204 qglUniformMatrix4fv(location, count, transpose, value);
205 }
206
207 void GL_BindNullFramebuffers()
208 {
209 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
210 glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0;
211 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
212 glDsaState.renderbuffer = 0;
213 }
214
215 void GL_BindFramebuffer(GLenum target, GLuint framebuffer)
216 {
217 switch (target)
218 {
219 case GL_FRAMEBUFFER_EXT:
220 if (framebuffer != glDsaState.drawFramebuffer || framebuffer != glDsaState.readFramebuffer)
221 {
222 qglBindFramebufferEXT(target, framebuffer);
223 glDsaState.drawFramebuffer = glDsaState.readFramebuffer = framebuffer;
224 }
225 break;
226
227 case GL_DRAW_FRAMEBUFFER_EXT:
228 if (framebuffer != glDsaState.drawFramebuffer)
229 {
230 qglBindFramebufferEXT(target, framebuffer);
231 glDsaState.drawFramebuffer = framebuffer;
232 }
233 break;
234
235 case GL_READ_FRAMEBUFFER_EXT:
236 if (framebuffer != glDsaState.readFramebuffer)
237 {
238 qglBindFramebufferEXT(target, framebuffer);
239 glDsaState.readFramebuffer = framebuffer;
240 }
241 break;
242 }
243 }
244
245 void GL_BindRenderbuffer(GLuint renderbuffer)
246 {
247 if (renderbuffer != glDsaState.renderbuffer)
248 {
249 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer);
250 glDsaState.renderbuffer = renderbuffer;
251 }
252 }
253
254 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageEXT(GLuint renderbuffer,
255 GLenum internalformat, GLsizei width, GLsizei height)
256 {
257 GL_BindRenderbuffer(renderbuffer);
258 qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalformat, width, height);
259 }
260
261 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer,
262 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
263 {
264 GL_BindRenderbuffer(renderbuffer);
265 qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internalformat, width, height);
266 }
267
268 GLenum APIENTRY GLDSA_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)
269 {
270 GL_BindFramebuffer(target, framebuffer);
271 return qglCheckFramebufferStatusEXT(target);
272 }
273
274 GLvoid APIENTRY GLDSA_NamedFramebufferTexture2DEXT(GLuint framebuffer,
275 GLenum attachment, GLenum textarget, GLuint texture, GLint level)
276 {
277 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
278 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, textarget, texture, level);
279 }
280
281 GLvoid APIENTRY GLDSA_NamedFramebufferRenderbufferEXT(GLuint framebuffer,
282 GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
283 {
284 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
285 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, renderbuffertarget, renderbuffer);
286 }
0 /*
1 ===========================================================================
2 Copyright (C) 2016 James Canete
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 ===========================================================================
18 */
19
20 #ifndef __TR_DSA_H__
21 #define __TR_DSA_H__
22
23 #include "qgl.h"
24
25 void GL_BindNullTextures(void);
26 int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture);
27
28 GLvoid APIENTRY GLDSA_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture);
29 GLvoid APIENTRY GLDSA_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param);
30 GLvoid APIENTRY GLDSA_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param);
31 GLvoid APIENTRY GLDSA_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat,
32 GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
33 GLvoid APIENTRY GLDSA_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
34 GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
35 GLvoid APIENTRY GLDSA_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
36 GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
37 GLvoid APIENTRY GLDSA_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
38 GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
39 GLvoid APIENTRY GLDSA_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
40 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
41 GLsizei imageSize, const GLvoid *data);
42
43 GLvoid APIENTRY GLDSA_GenerateTextureMipmapEXT(GLuint texture, GLenum target);
44
45 void GL_BindNullProgram(void);
46 int GL_UseProgram(GLuint program);
47
48 GLvoid APIENTRY GLDSA_ProgramUniform1iEXT(GLuint program, GLint location, GLint v0);
49 GLvoid APIENTRY GLDSA_ProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0);
50 GLvoid APIENTRY GLDSA_ProgramUniform2fEXT(GLuint program, GLint location,
51 GLfloat v0, GLfloat v1);
52 GLvoid APIENTRY GLDSA_ProgramUniform3fEXT(GLuint program, GLint location,
53 GLfloat v0, GLfloat v1, GLfloat v2);
54 GLvoid APIENTRY GLDSA_ProgramUniform4fEXT(GLuint program, GLint location,
55 GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
56 GLvoid APIENTRY GLDSA_ProgramUniform1fvEXT(GLuint program, GLint location,
57 GLsizei count, const GLfloat *value);
58 GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fvEXT(GLuint program, GLint location,
59 GLsizei count, GLboolean transpose,
60 const GLfloat *value);
61
62 void GL_BindNullFramebuffers(void);
63 void GL_BindFramebuffer(GLenum target, GLuint framebuffer);
64 void GL_BindRenderbuffer(GLuint renderbuffer);
65
66 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageEXT(GLuint renderbuffer,
67 GLenum internalformat, GLsizei width, GLsizei height);
68
69 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer,
70 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
71
72 GLenum APIENTRY GLDSA_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target);
73 GLvoid APIENTRY GLDSA_NamedFramebufferTexture2DEXT(GLuint framebuffer,
74 GLenum attachment, GLenum textarget, GLuint texture, GLint level);
75 GLvoid APIENTRY GLDSA_NamedFramebufferRenderbufferEXT(GLuint framebuffer,
76 GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
77
78
79 #endif
2727 #endif
2828
2929 #include "tr_local.h"
30
31 // GL_EXT_draw_range_elements
32 void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
33
34 // GL_EXT_multi_draw_arrays
35 void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
36 void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
37
38 // GL_ARB_vertex_shader
39 void (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB * name);
40 void (APIENTRY * qglGetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length,
41 GLint * size, GLenum * type, GLcharARB * name);
42 GLint(APIENTRY * qglGetAttribLocationARB) (GLhandleARB programObj, const GLcharARB * name);
43
44 // GL_ARB_vertex_program
45 void (APIENTRY * qglVertexAttrib4fARB) (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
46 void (APIENTRY * qglVertexAttrib4fvARB) (GLuint, const GLfloat *);
47 void (APIENTRY * qglVertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized,
48 GLsizei stride, const GLvoid * pointer);
49 void (APIENTRY * qglEnableVertexAttribArrayARB) (GLuint index);
50 void (APIENTRY * qglDisableVertexAttribArrayARB) (GLuint index);
51
52 // GL_ARB_vertex_buffer_object
53 void (APIENTRY * qglBindBufferARB) (GLenum target, GLuint buffer);
54 void (APIENTRY * qglDeleteBuffersARB) (GLsizei n, const GLuint * buffers);
55 void (APIENTRY * qglGenBuffersARB) (GLsizei n, GLuint * buffers);
56
57 GLboolean(APIENTRY * qglIsBufferARB) (GLuint buffer);
58 void (APIENTRY * qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
59 void (APIENTRY * qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
60 void (APIENTRY * qglGetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data);
61
62 void (APIENTRY * qglGetBufferParameterivARB) (GLenum target, GLenum pname, GLint * params);
63 void (APIENTRY * qglGetBufferPointervARB) (GLenum target, GLenum pname, GLvoid * *params);
64
65 // GL_ARB_shader_objects
66 void (APIENTRY * qglDeleteObjectARB) (GLhandleARB obj);
67
68 GLhandleARB(APIENTRY * qglGetHandleARB) (GLenum pname);
69 void (APIENTRY * qglDetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj);
70
71 GLhandleARB(APIENTRY * qglCreateShaderObjectARB) (GLenum shaderType);
72 void (APIENTRY * qglShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB * *string,
73 const GLint * length);
74 void (APIENTRY * qglCompileShaderARB) (GLhandleARB shaderObj);
75
76 GLhandleARB(APIENTRY * qglCreateProgramObjectARB) (void);
77 void (APIENTRY * qglAttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj);
78 void (APIENTRY * qglLinkProgramARB) (GLhandleARB programObj);
79 void (APIENTRY * qglUseProgramObjectARB) (GLhandleARB programObj);
80 void (APIENTRY * qglValidateProgramARB) (GLhandleARB programObj);
81 void (APIENTRY * qglUniform1fARB) (GLint location, GLfloat v0);
82 void (APIENTRY * qglUniform2fARB) (GLint location, GLfloat v0, GLfloat v1);
83 void (APIENTRY * qglUniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
84 void (APIENTRY * qglUniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
85 void (APIENTRY * qglUniform1iARB) (GLint location, GLint v0);
86 void (APIENTRY * qglUniform2iARB) (GLint location, GLint v0, GLint v1);
87 void (APIENTRY * qglUniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2);
88 void (APIENTRY * qglUniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
89 void (APIENTRY * qglUniform1fvARB) (GLint location, GLsizei count, const GLfloat * value);
90 void (APIENTRY * qglUniform2fvARB) (GLint location, GLsizei count, const GLfloat * value);
91 void (APIENTRY * qglUniform3fvARB) (GLint location, GLsizei count, const GLfloat * value);
92 void (APIENTRY * qglUniform4fvARB) (GLint location, GLsizei count, const GLfloat * value);
93 void (APIENTRY * qglUniform2ivARB) (GLint location, GLsizei count, const GLint * value);
94 void (APIENTRY * qglUniform3ivARB) (GLint location, GLsizei count, const GLint * value);
95 void (APIENTRY * qglUniform4ivARB) (GLint location, GLsizei count, const GLint * value);
96 void (APIENTRY * qglUniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
97 void (APIENTRY * qglUniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
98 void (APIENTRY * qglUniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
99 void (APIENTRY * qglGetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat * params);
100 void (APIENTRY * qglGetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint * params);
101 void (APIENTRY * qglGetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog);
102 void (APIENTRY * qglGetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count,
103 GLhandleARB * obj);
104 GLint(APIENTRY * qglGetUniformLocationARB) (GLhandleARB programObj, const GLcharARB * name);
105 void (APIENTRY * qglGetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxIndex, GLsizei * length,
106 GLint * size, GLenum * type, GLcharARB * name);
107 void (APIENTRY * qglGetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat * params);
108 void (APIENTRY * qglGetUniformivARB) (GLhandleARB programObj, GLint location, GLint * params);
109 void (APIENTRY * qglGetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source);
110
111 // GL_ARB_texture_compression
112 void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
113 GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
114 void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
115 GLint border, GLsizei imageSize, const GLvoid *data);
116 void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
117 GLsizei imageSize, const GLvoid *data);
118 void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
119 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
120 void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
121 GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
122 void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
123 GLsizei imageSize, const GLvoid *data);
124 void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
125 GLvoid *img);
126
127 // GL_EXT_framebuffer_object
128 GLboolean (APIENTRY * qglIsRenderbufferEXT)(GLuint renderbuffer);
129 void (APIENTRY * qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
130 void (APIENTRY * qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
131 void (APIENTRY * qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
132
133 void (APIENTRY * qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
134
135 void (APIENTRY * qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
136
137 GLboolean (APIENTRY * qglIsFramebufferEXT)(GLuint framebuffer);
138 void (APIENTRY * qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
139 void (APIENTRY * qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
140 void (APIENTRY * qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
141
142 GLenum (APIENTRY * qglCheckFramebufferStatusEXT)(GLenum target);
143
144 void (APIENTRY * qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
145 GLint level);
146 void (APIENTRY * qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
147 GLint level);
148 void (APIENTRY * qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
149 GLint level, GLint zoffset);
150
151 void (APIENTRY * qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget,
152 GLuint renderbuffer);
153
154 void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
155
156 void (APIENTRY * qglGenerateMipmapEXT)(GLenum target);
157
158 // GL_ARB_occlusion_query
159 void (APIENTRY * qglGenQueriesARB)(GLsizei n, GLuint *ids);
160 void (APIENTRY * qglDeleteQueriesARB)(GLsizei n, const GLuint *ids);
161 GLboolean (APIENTRY * qglIsQueryARB)(GLuint id);
162 void (APIENTRY * qglBeginQueryARB)(GLenum target, GLuint id);
163 void (APIENTRY * qglEndQueryARB)(GLenum target);
164 void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
165 void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
166 void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
167
168 // GL_EXT_framebuffer_blit
169 void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
170 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
171 GLbitfield mask, GLenum filter);
172
173 // GL_EXT_framebuffer_multisample
174 void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
175 GLenum internalformat, GLsizei width, GLsizei height);
176
177 // GL_ARB_draw_buffers
178 void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
179
180 // GL_ARB_vertex_array_object
181 void (APIENTRY * qglBindVertexArrayARB)(GLuint array);
182 void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays);
183 void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
184 GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
30 #include "tr_dsa.h"
31
32 #define GLE(ret, name, ...) name##proc * qgl##name;
33 QGL_1_2_PROCS;
34 QGL_1_3_PROCS;
35 QGL_1_4_PROCS;
36 QGL_1_5_PROCS;
37 QGL_2_0_PROCS;
38 QGL_EXT_framebuffer_object_PROCS;
39 QGL_EXT_framebuffer_blit_PROCS;
40 QGL_EXT_framebuffer_multisample_PROCS;
41 QGL_ARB_vertex_array_object_PROCS;
42 QGL_EXT_direct_state_access_PROCS;
43 #undef GLE
18544
18645 static qboolean GLimp_HaveExtension(const char *ext)
18746 {
19756 char *extension;
19857 const char* result[3] = { "...ignoring %s\n", "...using %s\n", "...%s not found\n" };
19958
200 // GL_EXT_draw_range_elements
201 extension = "GL_EXT_draw_range_elements";
202 glRefConfig.drawRangeElements = qfalse;
203 qglMultiDrawArraysEXT = NULL;
204 qglMultiDrawElementsEXT = NULL;
205 if( GLimp_HaveExtension( extension ) )
206 {
207 qglDrawRangeElementsEXT = (void *) SDL_GL_GetProcAddress("glDrawRangeElementsEXT");
208
209 if ( r_ext_draw_range_elements->integer)
210 glRefConfig.drawRangeElements = qtrue;
211
212 ri.Printf(PRINT_ALL, result[glRefConfig.drawRangeElements], extension);
213 }
214 else
215 {
216 ri.Printf(PRINT_ALL, result[2], extension);
217 }
218
219 // GL_EXT_multi_draw_arrays
220 extension = "GL_EXT_multi_draw_arrays";
221 glRefConfig.multiDrawArrays = qfalse;
222 qglMultiDrawArraysEXT = NULL;
223 qglMultiDrawElementsEXT = NULL;
224 if( GLimp_HaveExtension( extension ) )
225 {
226 qglMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC) SDL_GL_GetProcAddress("glMultiDrawArraysEXT");
227 qglMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC) SDL_GL_GetProcAddress("glMultiDrawElementsEXT");
228
229 if ( r_ext_multi_draw_arrays->integer )
230 glRefConfig.multiDrawArrays = qtrue;
231
232 ri.Printf(PRINT_ALL, result[glRefConfig.multiDrawArrays], extension);
233 }
234 else
235 {
236 ri.Printf(PRINT_ALL, result[2], extension);
237 }
238
239 // GL_ARB_vertex_program
240 //glRefConfig.vertexProgram = qfalse;
241 extension = "GL_ARB_vertex_program";
242 qglVertexAttrib4fARB = NULL;
243 qglVertexAttrib4fvARB = NULL;
244 qglVertexAttribPointerARB = NULL;
245 qglEnableVertexAttribArrayARB = NULL;
246 qglDisableVertexAttribArrayARB = NULL;
247 if( GLimp_HaveExtension( extension ) )
248 {
249 qglVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) SDL_GL_GetProcAddress("glVertexAttrib4fARB");
250 qglVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) SDL_GL_GetProcAddress("glVertexAttrib4fvARB");
251 qglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) SDL_GL_GetProcAddress("glVertexAttribPointerARB");
252 qglEnableVertexAttribArrayARB =
253 (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) SDL_GL_GetProcAddress("glEnableVertexAttribArrayARB");
254 qglDisableVertexAttribArrayARB =
255 (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) SDL_GL_GetProcAddress("glDisableVertexAttribArrayARB");
59 // Check OpenGL version
60 sscanf(glConfig.version_string, "%d.%d", &glRefConfig.openglMajorVersion, &glRefConfig.openglMinorVersion);
61 if (glRefConfig.openglMajorVersion < 2)
62 ri.Error(ERR_FATAL, "OpenGL 2.0 required!");
63 ri.Printf(PRINT_ALL, "...using OpenGL %s\n", glConfig.version_string);
64
65 // set DSA fallbacks
66 #define GLE(ret, name, ...) qgl##name = GLDSA_##name;
67 QGL_EXT_direct_state_access_PROCS;
68 #undef GLE
69
70 // GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
71 #define GLE(ret, name, ...) qgl##name = (name##proc *) SDL_GL_GetProcAddress("gl" #name);
72
73 // OpenGL 1.2, was GL_EXT_draw_range_elements
74 QGL_1_2_PROCS;
75 glRefConfig.drawRangeElements = !!r_ext_draw_range_elements->integer;
76 ri.Printf(PRINT_ALL, result[glRefConfig.drawRangeElements], "glDrawRangeElements()");
77
78 // OpenGL 1.3, was GL_ARB_texture_compression
79 QGL_1_3_PROCS;
80
81 // OpenGL 1.4, was GL_EXT_multi_draw_arrays
82 QGL_1_4_PROCS;
83 glRefConfig.multiDrawArrays = !!r_ext_multi_draw_arrays->integer;
84 ri.Printf(PRINT_ALL, result[glRefConfig.multiDrawArrays], "glMultiDrawElements()");
85
86 // OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
87 QGL_1_5_PROCS;
88 glRefConfig.occlusionQuery = qtrue;
89
90 // OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
91 QGL_2_0_PROCS;
92
93 // Determine GLSL version
94 if (1)
95 {
96 char version[256];
97
98 Q_strncpyz(version, (char *)qglGetString(GL_SHADING_LANGUAGE_VERSION), sizeof(version));
99
100 sscanf(version, "%d.%d", &glRefConfig.glslMajorVersion, &glRefConfig.glslMinorVersion);
101
102 ri.Printf(PRINT_ALL, "...using GLSL version %s\n", version);
103 }
104
105 glRefConfig.memInfo = MI_NONE;
106
107 // GL_NVX_gpu_memory_info
108 extension = "GL_NVX_gpu_memory_info";
109 if( GLimp_HaveExtension( extension ) )
110 {
111 glRefConfig.memInfo = MI_NVX;
256112
257113 ri.Printf(PRINT_ALL, result[1], extension);
258 //glRefConfig.vertexProgram = qtrue;
259 }
260 else
261 {
262 ri.Error(ERR_FATAL, result[2], extension);
263 }
264
265 // GL_ARB_vertex_buffer_object
266 //glRefConfig.vertexBufferObject = qfalse;
267 extension = "GL_ARB_vertex_buffer_object";
268 qglBindBufferARB = NULL;
269 qglDeleteBuffersARB = NULL;
270 qglGenBuffersARB = NULL;
271 qglIsBufferARB = NULL;
272 qglBufferDataARB = NULL;
273 qglBufferSubDataARB = NULL;
274 qglGetBufferSubDataARB = NULL;
275 qglGetBufferParameterivARB = NULL;
276 qglGetBufferPointervARB = NULL;
277 if( GLimp_HaveExtension( extension ) )
278 {
279 qglBindBufferARB = (PFNGLBINDBUFFERARBPROC) SDL_GL_GetProcAddress("glBindBufferARB");
280 qglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB");
281 qglGenBuffersARB = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress("glGenBuffersARB");
282 qglIsBufferARB = (PFNGLISBUFFERARBPROC) SDL_GL_GetProcAddress("glIsBufferARB");
283 qglBufferDataARB = (PFNGLBUFFERDATAARBPROC) SDL_GL_GetProcAddress("glBufferDataARB");
284 qglBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC) SDL_GL_GetProcAddress("glBufferSubDataARB");
285 qglGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC) SDL_GL_GetProcAddress("glGetBufferSubDataARB");
286 qglGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetBufferParameterivARB");
287 qglGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC) SDL_GL_GetProcAddress("glGetBufferPointervARB");
288 ri.Printf(PRINT_ALL, result[1], extension);
289 //glRefConfig.vertexBufferObject = qtrue;
290 }
291 else
292 {
293 ri.Error(ERR_FATAL, result[2], extension);
294 }
295
296 // GL_ARB_shader_objects
297 extension = "GL_ARB_shader_objects";
298 //glRefConfig.shaderObjects = qfalse;
299 qglDeleteObjectARB = NULL;
300 qglGetHandleARB = NULL;
301 qglDetachObjectARB = NULL;
302 qglCreateShaderObjectARB = NULL;
303 qglShaderSourceARB = NULL;
304 qglCompileShaderARB = NULL;
305 qglCreateProgramObjectARB = NULL;
306 qglAttachObjectARB = NULL;
307 qglLinkProgramARB = NULL;
308 qglUseProgramObjectARB = NULL;
309 qglValidateProgramARB = NULL;
310 qglUniform1fARB = NULL;
311 qglUniform2fARB = NULL;
312 qglUniform3fARB = NULL;
313 qglUniform4fARB = NULL;
314 qglUniform1iARB = NULL;
315 qglUniform2iARB = NULL;
316 qglUniform3iARB = NULL;
317 qglUniform4iARB = NULL;
318 qglUniform1fvARB = NULL;
319 qglUniform2fvARB = NULL;
320 qglUniform3fvARB = NULL;
321 qglUniform4fvARB = NULL;
322 qglUniform2ivARB = NULL;
323 qglUniform3ivARB = NULL;
324 qglUniform4ivARB = NULL;
325 qglUniformMatrix2fvARB = NULL;
326 qglUniformMatrix3fvARB = NULL;
327 qglUniformMatrix4fvARB = NULL;
328 qglGetObjectParameterfvARB = NULL;
329 qglGetObjectParameterivARB = NULL;
330 qglGetInfoLogARB = NULL;
331 qglGetAttachedObjectsARB = NULL;
332 qglGetUniformLocationARB = NULL;
333 qglGetActiveUniformARB = NULL;
334 qglGetUniformfvARB = NULL;
335 qglGetUniformivARB = NULL;
336 qglGetShaderSourceARB = NULL;
337 if( GLimp_HaveExtension( extension ) )
338 {
339 qglDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB");
340 qglGetHandleARB = (PFNGLGETHANDLEARBPROC) SDL_GL_GetProcAddress("glGetHandleARB");
341 qglDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) SDL_GL_GetProcAddress("glDetachObjectARB");
342 qglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB");
343 qglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB");
344 qglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB");
345 qglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB");
346 qglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB");
347 qglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB");
348 qglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB");
349 qglValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) SDL_GL_GetProcAddress("glValidateProgramARB");
350 qglUniform1fARB = (PFNGLUNIFORM1FARBPROC) SDL_GL_GetProcAddress("glUniform1fARB");
351 qglUniform2fARB = (PFNGLUNIFORM2FARBPROC) SDL_GL_GetProcAddress("glUniform2fARB");
352 qglUniform3fARB = (PFNGLUNIFORM3FARBPROC) SDL_GL_GetProcAddress("glUniform3fARB");
353 qglUniform4fARB = (PFNGLUNIFORM4FARBPROC) SDL_GL_GetProcAddress("glUniform4fARB");
354 qglUniform1iARB = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB");
355 qglUniform2iARB = (PFNGLUNIFORM2IARBPROC) SDL_GL_GetProcAddress("glUniform2iARB");
356 qglUniform3iARB = (PFNGLUNIFORM3IARBPROC) SDL_GL_GetProcAddress("glUniform3iARB");
357 qglUniform4iARB = (PFNGLUNIFORM4IARBPROC) SDL_GL_GetProcAddress("glUniform4iARB");
358 qglUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) SDL_GL_GetProcAddress("glUniform1fvARB");
359 qglUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) SDL_GL_GetProcAddress("glUniform2fvARB");
360 qglUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) SDL_GL_GetProcAddress("glUniform3fvARB");
361 qglUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) SDL_GL_GetProcAddress("glUniform4fvARB");
362 qglUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) SDL_GL_GetProcAddress("glUniform2ivARB");
363 qglUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) SDL_GL_GetProcAddress("glUniform3ivARB");
364 qglUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) SDL_GL_GetProcAddress("glUniform4ivARB");
365 qglUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) SDL_GL_GetProcAddress("glUniformMatrix2fvARB");
366 qglUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) SDL_GL_GetProcAddress("glUniformMatrix3fvARB");
367 qglUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) SDL_GL_GetProcAddress("glUniformMatrix4fvARB");
368 qglGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterfvARB");
369 qglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
370 qglGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB");
371 qglGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) SDL_GL_GetProcAddress("glGetAttachedObjectsARB");
372 qglGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB");
373 qglGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) SDL_GL_GetProcAddress("glGetActiveUniformARB");
374 qglGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) SDL_GL_GetProcAddress("glGetUniformfvARB");
375 qglGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) SDL_GL_GetProcAddress("glGetUniformivARB");
376 qglGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glGetShaderSourceARB");
377 ri.Printf(PRINT_ALL, result[1], extension);
378 //glRefConfig.shaderObjects = qtrue;
379 }
380 else
381 {
382 ri.Error(ERR_FATAL, result[2], extension);
383 }
384
385 // GL_ARB_vertex_shader
386 //glRefConfig.vertexShader = qfalse;
387 extension = "GL_ARB_vertex_shader";
388 qglBindAttribLocationARB = NULL;
389 qglGetActiveAttribARB = NULL;
390 qglGetAttribLocationARB = NULL;
391 if( GLimp_HaveExtension( extension ) )
392 {
393 //int reservedComponents;
394
395 //qglGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig.maxVertexUniforms);
396 //qglGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &glConfig.maxVaryingFloats);
397 //qglGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.maxVertexAttribs);
398
399 //reservedComponents = 16 * 10; // approximation how many uniforms we have besides the bone matrices
400
401 #if 0
402 if(glConfig.driverType == GLDRV_MESA)
114 }
115 else
116 {
117 ri.Printf(PRINT_ALL, result[2], extension);
118 }
119
120 // GL_ATI_meminfo
121 extension = "GL_ATI_meminfo";
122 if( GLimp_HaveExtension( extension ) )
123 {
124 if (glRefConfig.memInfo == MI_NONE)
403125 {
404 // HACK
405 // restrict to number of vertex uniforms to 512 because of:
406 // xreal.x86_64: nv50_program.c:4181: nv50_program_validate_data: Assertion `p->param_nr <= 512' failed
407
408 glConfig.maxVertexUniforms = Q_bound(0, glConfig.maxVertexUniforms, 512);
126 glRefConfig.memInfo = MI_ATI;
127
128 ri.Printf(PRINT_ALL, result[1], extension);
409129 }
410 #endif
411
412 //glConfig.maxVertexSkinningBones = (int) Q_bound(0.0, (Q_max(glConfig.maxVertexUniforms - reservedComponents, 0) / 16), MAX_BONES);
413 //glConfig.vboVertexSkinningAvailable = r_vboVertexSkinning->integer && ((glConfig.maxVertexSkinningBones >= 12) ? qtrue : qfalse);
414
415 qglBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) SDL_GL_GetProcAddress("glBindAttribLocationARB");
416 qglGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) SDL_GL_GetProcAddress("glGetActiveAttribARB");
417 qglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetAttribLocationARB");
418 ri.Printf(PRINT_ALL, result[1], extension);
419 //glRefConfig.vertexShader = qtrue;
420 }
421 else
422 {
423 ri.Error(ERR_FATAL, result[2], extension);
424 }
425
426 // GL_ARB_shading_language_100
427 extension = "GL_ARB_shading_language_100";
428 glRefConfig.textureFloat = qfalse;
429 if( GLimp_HaveExtension( extension ) )
430 {
431 char version[256];
432
433 Q_strncpyz( version, (char *) qglGetString (GL_SHADING_LANGUAGE_VERSION_ARB), sizeof( version ) );
434
435 sscanf(version, "%d.%d", &glRefConfig.glslMajorVersion, &glRefConfig.glslMinorVersion);
436
437 ri.Printf(PRINT_ALL, "...using GLSL version %s\n", version);
438 }
439 else
440 {
441 ri.Error(ERR_FATAL, result[2], extension);
442 }
443
444 glRefConfig.memInfo = MI_NONE;
445
446 if( GLimp_HaveExtension( "GL_NVX_gpu_memory_info" ) )
447 {
448 glRefConfig.memInfo = MI_NVX;
449 }
450 else if( GLimp_HaveExtension( "GL_ATI_meminfo" ) )
451 {
452 glRefConfig.memInfo = MI_ATI;
453 }
454
455 extension = "GL_ARB_texture_non_power_of_two";
456 glRefConfig.textureNonPowerOfTwo = qfalse;
457 if( GLimp_HaveExtension( extension ) )
458 {
459 if(1) //(r_ext_texture_non_power_of_two->integer)
130 else
460131 {
461 glRefConfig.textureNonPowerOfTwo = qtrue;
132 ri.Printf(PRINT_ALL, result[0], extension);
462133 }
463
464 ri.Printf(PRINT_ALL, result[glRefConfig.textureNonPowerOfTwo], extension);
465134 }
466135 else
467136 {
473142 glRefConfig.textureFloat = qfalse;
474143 if( GLimp_HaveExtension( extension ) )
475144 {
476 if( r_ext_texture_float->integer )
477 {
478 glRefConfig.textureFloat = qtrue;
479 }
145 glRefConfig.textureFloat = !!r_ext_texture_float->integer;
480146
481147 ri.Printf(PRINT_ALL, result[glRefConfig.textureFloat], extension);
482 }
483 else
484 {
485 ri.Printf(PRINT_ALL, result[2], extension);
486 }
487
488 // GL_ARB_half_float_pixel
489 extension = "GL_ARB_half_float_pixel";
490 glRefConfig.halfFloatPixel = qfalse;
491 if( GLimp_HaveExtension( extension ) )
492 {
493 if( r_arb_half_float_pixel->integer )
494 glRefConfig.halfFloatPixel = qtrue;
495
496 ri.Printf(PRINT_ALL, result[glRefConfig.halfFloatPixel], extension);
497148 }
498149 else
499150 {
505156 glRefConfig.framebufferObject = qfalse;
506157 if( GLimp_HaveExtension( extension ) )
507158 {
159 glRefConfig.framebufferObject = !!r_ext_framebuffer_object->integer;
160
508161 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &glRefConfig.maxRenderbufferSize);
509162 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &glRefConfig.maxColorAttachments);
510163
511 qglIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) SDL_GL_GetProcAddress("glIsRenderbufferEXT");
512 qglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) SDL_GL_GetProcAddress("glBindRenderbufferEXT");
513 qglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) SDL_GL_GetProcAddress("glDeleteRenderbuffersEXT");
514 qglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) SDL_GL_GetProcAddress("glGenRenderbuffersEXT");
515 qglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) SDL_GL_GetProcAddress("glRenderbufferStorageEXT");
516 qglGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) SDL_GL_GetProcAddress("glGetRenderbufferParameterivEXT");
517 qglIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) SDL_GL_GetProcAddress("glIsFramebufferEXT");
518 qglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) SDL_GL_GetProcAddress("glBindFramebufferEXT");
519 qglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
520 qglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) SDL_GL_GetProcAddress("glGenFramebuffersEXT");
521 qglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
522 qglFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) SDL_GL_GetProcAddress("glFramebufferTexture1DEXT");
523 qglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
524 qglFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) SDL_GL_GetProcAddress("glFramebufferTexture3DEXT");
525 qglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) SDL_GL_GetProcAddress("glFramebufferRenderbufferEXT");
526 qglGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameterivEXT");
527 qglGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) SDL_GL_GetProcAddress("glGenerateMipmapEXT");
528
529 if(r_ext_framebuffer_object->value)
530 glRefConfig.framebufferObject = qtrue;
164 QGL_EXT_framebuffer_object_PROCS;
531165
532166 ri.Printf(PRINT_ALL, result[glRefConfig.framebufferObject], extension);
533 }
534 else
535 {
536 ri.Printf(PRINT_ALL, result[2], extension);
537 }
538
539 // GL_EXT_packed_depth_stencil
540 extension = "GL_EXT_packed_depth_stencil";
541 glRefConfig.packedDepthStencil = qfalse;
542 if( GLimp_HaveExtension(extension))
543 {
544 glRefConfig.packedDepthStencil = qtrue;
545 ri.Printf(PRINT_ALL, result[glRefConfig.packedDepthStencil], extension);
546 }
547 else
548 {
549 ri.Printf(PRINT_ALL, result[2], extension);
550 }
551
552 // GL_ARB_occlusion_query
553 extension = "GL_ARB_occlusion_query";
554 glRefConfig.occlusionQuery = qfalse;
555 if (GLimp_HaveExtension(extension))
556 {
557 qglGenQueriesARB = (PFNGLGENQUERIESARBPROC) SDL_GL_GetProcAddress("glGenQueriesARB");
558 qglDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC) SDL_GL_GetProcAddress("glDeleteQueriesARB");
559 qglIsQueryARB = (PFNGLISQUERYARBPROC) SDL_GL_GetProcAddress("glIsQueryARB");
560 qglBeginQueryARB = (PFNGLBEGINQUERYARBPROC) SDL_GL_GetProcAddress("glBeginQueryARB");
561 qglEndQueryARB = (PFNGLENDQUERYARBPROC) SDL_GL_GetProcAddress("glEndQueryARB");
562 qglGetQueryivARB = (PFNGLGETQUERYIVARBPROC) SDL_GL_GetProcAddress("glGetQueryivARB");
563 qglGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC) SDL_GL_GetProcAddress("glGetQueryObjectivARB");
564 qglGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC) SDL_GL_GetProcAddress("glGetQueryObjectuivARB");
565 glRefConfig.occlusionQuery = qtrue;
566 ri.Printf(PRINT_ALL, result[glRefConfig.occlusionQuery], extension);
567167 }
568168 else
569169 {
575175 glRefConfig.framebufferBlit = qfalse;
576176 if (GLimp_HaveExtension(extension))
577177 {
578 qglBlitFramebufferEXT = (void *)SDL_GL_GetProcAddress("glBlitFramebufferEXT");
579178 glRefConfig.framebufferBlit = qtrue;
179
180 QGL_EXT_framebuffer_blit_PROCS;
181
580182 ri.Printf(PRINT_ALL, result[glRefConfig.framebufferBlit], extension);
581183 }
582184 else
583185 {
584186 ri.Printf(PRINT_ALL, result[2], extension);
585 }
586
587 // GL_ARB_texture_compression
588 extension = "GL_ARB_texture_compression";
589 glRefConfig.arbTextureCompression = qfalse;
590 if (GLimp_HaveExtension(extension))
591 {
592 qglCompressedTexImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage3DARB");
593 qglCompressedTexImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage2DARB");
594 qglCompressedTexImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage1DARB");
595 qglCompressedTexSubImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage3DARB");
596 qglCompressedTexSubImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage2DARB");
597 qglCompressedTexSubImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage1DARB");
598 qglGetCompressedTexImageARB = (void *)SDL_GL_GetProcAddress("glGetCompressedTexImageARB");
599 glRefConfig.arbTextureCompression = qtrue;
600 ri.Printf(PRINT_ALL, result[glRefConfig.arbTextureCompression], extension);
601187 }
602188
603189 // GL_EXT_framebuffer_multisample
605191 glRefConfig.framebufferMultisample = qfalse;
606192 if (GLimp_HaveExtension(extension))
607193 {
608 qglRenderbufferStorageMultisampleEXT = (void *)SDL_GL_GetProcAddress("glRenderbufferStorageMultisampleEXT");
609194 glRefConfig.framebufferMultisample = qtrue;
195
196 QGL_EXT_framebuffer_multisample_PROCS;
197
610198 ri.Printf(PRINT_ALL, result[glRefConfig.framebufferMultisample], extension);
611199 }
612200 else
620208 extension = "GL_ARB_texture_compression_rgtc";
621209 if (GLimp_HaveExtension(extension))
622210 {
623 if (r_ext_compressed_textures->integer && glRefConfig.arbTextureCompression)
211 qboolean useRgtc = r_ext_compressed_textures->integer >= 1;
212
213 if (useRgtc)
624214 glRefConfig.textureCompression |= TCR_RGTC;
625215
626 ri.Printf(PRINT_ALL, result[r_ext_compressed_textures->integer ? 1 : 0], extension);
216 ri.Printf(PRINT_ALL, result[useRgtc], extension);
627217 }
628218 else
629219 {
636226 extension = "GL_ARB_texture_compression_bptc";
637227 if (GLimp_HaveExtension(extension))
638228 {
639 if (r_ext_compressed_textures->integer >= 2)
229 qboolean useBptc = r_ext_compressed_textures->integer >= 2;
230
231 if (useBptc)
640232 glRefConfig.textureCompression |= TCR_BPTC;
641233
642 ri.Printf(PRINT_ALL, result[(r_ext_compressed_textures->integer >= 2) ? 1 : 0], extension);
643 }
644 else
645 {
646 ri.Printf(PRINT_ALL, result[2], extension);
647 }
648
649 // GL_ARB_draw_buffers
650 extension = "GL_ARB_draw_buffers";
651 qglDrawBuffersARB = NULL;
652 if( GLimp_HaveExtension( extension ) )
653 {
654 qglDrawBuffersARB = (void *) SDL_GL_GetProcAddress("glDrawBuffersARB");
655
656 ri.Printf(PRINT_ALL, result[1], extension);
234 ri.Printf(PRINT_ALL, result[useBptc], extension);
657235 }
658236 else
659237 {
666244 if( GLimp_HaveExtension( extension ) )
667245 {
668246 glRefConfig.depthClamp = qtrue;
669 ri.Printf(PRINT_ALL, result[1], extension);
247
248 ri.Printf(PRINT_ALL, result[glRefConfig.depthClamp], extension);
670249 }
671250 else
672251 {
678257 glRefConfig.seamlessCubeMap = qfalse;
679258 if( GLimp_HaveExtension( extension ) )
680259 {
681 if (r_arb_seamless_cube_map->integer)
682 glRefConfig.seamlessCubeMap = qtrue;
260 glRefConfig.seamlessCubeMap = !!r_arb_seamless_cube_map->integer;
683261
684262 ri.Printf(PRINT_ALL, result[glRefConfig.seamlessCubeMap], extension);
685263 }
687265 {
688266 ri.Printf(PRINT_ALL, result[2], extension);
689267 }
690
691 // GL_ARB_vertex_type_2_10_10_10_rev
692 extension = "GL_ARB_vertex_type_2_10_10_10_rev";
693 glRefConfig.packedNormalDataType = GL_BYTE;
694 if( GLimp_HaveExtension( extension ) )
695 {
696 if (r_arb_vertex_type_2_10_10_10_rev->integer)
697 glRefConfig.packedNormalDataType = GL_INT_2_10_10_10_REV;
698
699 ri.Printf(PRINT_ALL, result[r_arb_vertex_type_2_10_10_10_rev->integer ? 1 : 0], extension);
700 }
701 else
702 {
703 ri.Printf(PRINT_ALL, result[2], extension);
704 }
705
706 // use float lightmaps?
707 glRefConfig.floatLightmap = (glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer && r_hdr->integer);
708268
709269 // GL_ARB_vertex_array_object
710270 extension = "GL_ARB_vertex_array_object";
711271 glRefConfig.vertexArrayObject = qfalse;
712272 if( GLimp_HaveExtension( extension ) )
713273 {
714 qglBindVertexArrayARB = (void *) SDL_GL_GetProcAddress("glBindVertexArray");
715 qglDeleteVertexArraysARB = (void *) SDL_GL_GetProcAddress("glDeleteVertexArrays");
716 qglGenVertexArraysARB = (void *) SDL_GL_GetProcAddress("glGenVertexArrays");
717 qglIsVertexArrayARB = (void *) SDL_GL_GetProcAddress("glIsVertexArray");
718
719 if (r_arb_vertex_array_object->integer)
720 glRefConfig.vertexArrayObject = qtrue;
721
722 ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject ? 1 : 0], extension);
723 }
724 else
725 {
726 ri.Printf(PRINT_ALL, result[2], extension);
727 }
728
729 // GL_ARB_half_float_vertex
730 extension = "GL_ARB_half_float_vertex";
731 glRefConfig.packedTexcoordDataType = GL_FLOAT;
732 glRefConfig.packedTexcoordDataSize = sizeof(float) * 2;
733 glRefConfig.packedColorDataType = GL_FLOAT;
734 glRefConfig.packedColorDataSize = sizeof(float) * 4;
735 if( GLimp_HaveExtension( extension ) )
736 {
737 if (r_arb_half_float_vertex->integer)
274 glRefConfig.vertexArrayObject = !!r_arb_vertex_array_object->integer;
275
276 QGL_ARB_vertex_array_object_PROCS;
277
278 ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject], extension);
279 }
280 else
281 {
282 ri.Printf(PRINT_ALL, result[2], extension);
283 }
284
285 // GL_EXT_direct_state_access
286 extension = "GL_EXT_direct_state_access";
287 glRefConfig.directStateAccess = qfalse;
288 if (GLimp_HaveExtension(extension))
289 {
290 glRefConfig.directStateAccess = !!r_ext_direct_state_access->integer;
291
292 // QGL_*_PROCS becomes several functions, do not remove {}
293 if (glRefConfig.directStateAccess)
738294 {
739 glRefConfig.packedTexcoordDataType = GL_HALF_FLOAT;
740 glRefConfig.packedTexcoordDataSize = sizeof(uint16_t) * 2;
741 glRefConfig.packedColorDataType = GL_HALF_FLOAT;
742 glRefConfig.packedColorDataSize = sizeof(uint16_t) * 4;
295 QGL_EXT_direct_state_access_PROCS;
743296 }
744297
745 ri.Printf(PRINT_ALL, result[r_arb_half_float_vertex->integer ? 1 : 0], extension);
746 }
747 else
748 {
749 ri.Printf(PRINT_ALL, result[2], extension);
750 }
751
298 ri.Printf(PRINT_ALL, result[glRefConfig.directStateAccess], extension);
299 }
300 else
301 {
302 ri.Printf(PRINT_ALL, result[2], extension);
303 }
304
305 #undef GLE
752306 }
200200
201201 union f32_u {
202202 float f;
203 uint32_t i;
203 uint32_t ui;
204204 struct {
205205 unsigned int fraction:23;
206206 unsigned int exponent:8;
209209 };
210210
211211 union f16_u {
212 uint16_t i;
212 uint16_t ui;
213213 struct {
214214 unsigned int fraction:10;
215215 unsigned int exponent:5;
228228 f16.pack.fraction = f32.pack.fraction >> 13;
229229 f16.pack.sign = f32.pack.sign;
230230
231 return f16.i;
232 }
231 return f16.ui;
232 }
233
234 float HalfToFloat(uint16_t in)
235 {
236 union f32_u f32;
237 union f16_u f16;
238
239 f16.ui = in;
240
241 f32.pack.exponent = (int)(f16.pack.exponent) + 112;
242 f32.pack.fraction = f16.pack.fraction << 13;
243 f32.pack.sign = f16.pack.sign;
244
245 return f32.f;
246 }
9797
9898 int NextPowerOfTwo(int in);
9999 unsigned short FloatToHalf(float in);
100 float HalfToFloat(unsigned short in);
100101
101102 #endif
2222 // tr_fbo.c
2323 #include "tr_local.h"
2424
25 #include "tr_dsa.h"
26
2527 /*
2628 =============
2729 R_CheckFBO
2931 */
3032 qboolean R_CheckFBO(const FBO_t * fbo)
3133 {
32 int code;
33 int id;
34
35 qglGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &id);
36 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer);
37
38 code = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
34 GLenum code = qglCheckNamedFramebufferStatusEXT(fbo->frameBuffer, GL_FRAMEBUFFER_EXT);
3935
4036 if(code == GL_FRAMEBUFFER_COMPLETE_EXT)
41 {
42 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
4337 return qtrue;
44 }
4538
4639 // an error occured
4740 switch (code)
8275
8376 default:
8477 ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) unknown error 0x%X\n", fbo->name, code);
85 //ri.Error(ERR_FATAL, "R_CheckFBO: (%s) unknown error 0x%X", fbo->name, code);
86 //assert(0);
87 break;
88 }
89
90 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
78 break;
79 }
9180
9281 return qfalse;
9382 }
132121 return fbo;
133122 }
134123
124 /*
125 =================
126 FBO_CreateBuffer
127 =================
128 */
135129 void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
136130 {
137131 uint32_t *pRenderBuffer;
188182 if (absent)
189183 qglGenRenderbuffersEXT(1, pRenderBuffer);
190184
191 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *pRenderBuffer);
192185 if (multisample && glRefConfig.framebufferMultisample)
193 {
194 qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, format, fbo->width, fbo->height);
195 }
196 else
197 {
198 qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, fbo->width, fbo->height);
199 }
186 qglNamedRenderbufferStorageMultisampleEXT(*pRenderBuffer, multisample, format, fbo->width, fbo->height);
187 else
188 qglNamedRenderbufferStorageEXT(*pRenderBuffer, format, fbo->width, fbo->height);
200189
201190 if(absent)
202191 {
203192 if (attachment == 0)
204193 {
205 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
206 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
194 qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
195 qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
207196 }
208197 else
209 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer);
198 {
199 qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer);
200 }
210201 }
211202 }
212203
213204
214205 /*
215206 =================
216 R_AttachFBOTexture1D
207 FBO_AttachImage
217208 =================
218209 */
219 void R_AttachFBOTexture1D(int texId, int index)
220 {
221 if(index < 0 || index >= glRefConfig.maxColorAttachments)
222 {
223 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture1D: invalid attachment index %i\n", index);
224 return;
225 }
226
227 qglFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_1D, texId, 0);
228 }
229
230 /*
231 =================
232 R_AttachFBOTexture2D
233 =================
234 */
235 void R_AttachFBOTexture2D(int target, int texId, int index)
236 {
237 if(target != GL_TEXTURE_2D && (target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB))
238 {
239 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid target %i\n", target);
240 return;
241 }
242
243 if(index < 0 || index >= glRefConfig.maxColorAttachments)
244 {
245 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid attachment index %i\n", index);
246 return;
247 }
248
249 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, target, texId, 0);
250 }
251
252 /*
253 =================
254 R_AttachFBOTexture3D
255 =================
256 */
257 void R_AttachFBOTexture3D(int texId, int index, int zOffset)
258 {
259 if(index < 0 || index >= glRefConfig.maxColorAttachments)
260 {
261 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture3D: invalid attachment index %i\n", index);
262 return;
263 }
264
265 qglFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_3D_EXT, texId, 0, zOffset);
266 }
267
268 /*
269 =================
270 R_AttachFBOTextureDepth
271 =================
272 */
273 void R_AttachFBOTextureDepth(int texId)
274 {
275 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0);
276 }
277
278 /*
279 =================
280 R_AttachFBOTexturePackedDepthStencil
281 =================
282 */
283 void R_AttachFBOTexturePackedDepthStencil(int texId)
284 {
285 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0);
286 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0);
287 }
288
289 void FBO_AttachTextureImage(image_t *img, int index)
290 {
291 if (!glState.currentFBO)
292 {
293 ri.Printf(PRINT_WARNING, "FBO: attempted to attach a texture image with no FBO bound!\n");
294 return;
295 }
296
297 R_AttachFBOTexture2D(GL_TEXTURE_2D, img->texnum, index);
298 glState.currentFBO->colorImage[index] = img;
299 }
210 void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside)
211 {
212 GLenum target = GL_TEXTURE_2D;
213 int index;
214
215 if (image->flags & IMGFLAG_CUBEMAP)
216 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cubemapside;
217
218 qglNamedFramebufferTexture2DEXT(fbo->frameBuffer, attachment, target, image->texnum, 0);
219 index = attachment - GL_COLOR_ATTACHMENT0_EXT;
220 if (index >= 0 && index <= 15)
221 fbo->colorImage[index] = image;
222 }
223
300224
301225 /*
302226 ============
311235 if (r_logFile->integer)
312236 {
313237 // don't just call LogComment, or we will get a call to va() every frame!
314 if (fbo)
315 GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo->name));
316 else
317 GLimp_LogComment("--- FBO_Bind ( NULL ) ---\n");
318 }
319
320 if (!fbo)
321 {
322 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
323 //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
324 glState.currentFBO = NULL;
325
326 return;
327 }
328
329 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer);
330
331 /*
332 if(fbo->colorBuffers[0])
333 {
334 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->colorBuffers[0]);
335 }
336 */
337
338 /*
339 if(fbo->depthBuffer)
340 {
341 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->depthBuffer);
342 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depthBuffer);
343 }
344 */
345
238 GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL"));
239 }
240
241 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, fbo ? fbo->frameBuffer : 0);
346242 glState.currentFBO = fbo;
347243 }
348244
354250 void FBO_Init(void)
355251 {
356252 int i;
357 // int width, height, hdrFormat, multisample;
358 int hdrFormat, multisample;
253 int hdrFormat, multisample = 0;
359254
360255 ri.Printf(PRINT_ALL, "------- FBO_Init -------\n");
361256
368263
369264 R_IssuePendingRenderCommands();
370265
371 /* if(glRefConfig.textureNonPowerOfTwo)
372 {
373 width = glConfig.vidWidth;
374 height = glConfig.vidHeight;
375 }
376 else
377 {
378 width = NextPowerOfTwo(glConfig.vidWidth);
379 height = NextPowerOfTwo(glConfig.vidHeight);
380 } */
381
382266 hdrFormat = GL_RGBA8;
383267 if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat)
384 {
385268 hdrFormat = GL_RGBA16F_ARB;
386 }
387
388 qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
269
270 if (glRefConfig.framebufferMultisample)
271 qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
389272
390273 if (r_ext_framebuffer_multisample->integer < multisample)
391 {
392274 multisample = r_ext_framebuffer_multisample->integer;
393 }
394275
395276 if (multisample < 2 || !glRefConfig.framebufferBlit)
396277 multisample = 0;
397278
398279 if (multisample != r_ext_framebuffer_multisample->integer)
399 {
400280 ri.Cvar_SetValue("r_ext_framebuffer_multisample", (float)multisample);
401 }
402281
403282 // only create a render FBO if we need to resolve MSAA or do HDR
404283 // otherwise just render straight to the screen (tr.renderFbo = NULL)
405284 if (multisample && glRefConfig.framebufferMultisample)
406285 {
407286 tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
408 FBO_Bind(tr.renderFbo);
409
410287 FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, multisample);
411288 FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, multisample);
412
413289 R_CheckFBO(tr.renderFbo);
414290
415
416291 tr.msaaResolveFbo = FBO_Create("_msaaResolve", tr.renderDepthImage->width, tr.renderDepthImage->height);
417 FBO_Bind(tr.msaaResolveFbo);
418
419 //FBO_CreateBuffer(tr.msaaResolveFbo, hdrFormat, 0, 0);
420 FBO_AttachTextureImage(tr.renderImage, 0);
421
422 //FBO_CreateBuffer(tr.msaaResolveFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
423 R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
424
292 FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
293 FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
425294 R_CheckFBO(tr.msaaResolveFbo);
426295 }
427296 else if (r_hdr->integer)
428297 {
429298 tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
430 FBO_Bind(tr.renderFbo);
431
432 //FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, 0);
433 FBO_AttachTextureImage(tr.renderImage, 0);
434
435 //FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
436 R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
437
299 FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
300 FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
438301 R_CheckFBO(tr.renderFbo);
439302 }
440303
442305 // this fixes the corrupt screen bug with r_hdr 1 on older hardware
443306 if (tr.renderFbo)
444307 {
445 FBO_Bind(tr.renderFbo);
308 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, tr.renderFbo->frameBuffer);
446309 qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
447 FBO_Bind(NULL);
448 }
449
450 if (r_drawSunRays->integer)
310 }
311
312 if (tr.screenScratchImage)
313 {
314 tr.screenScratchFbo = FBO_Create("screenScratch", tr.screenScratchImage->width, tr.screenScratchImage->height);
315 FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0_EXT, 0);
316 FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
317 R_CheckFBO(tr.screenScratchFbo);
318 }
319
320 if (tr.sunRaysImage)
451321 {
452322 tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height);
453 FBO_Bind(tr.sunRaysFbo);
454
455 FBO_AttachTextureImage(tr.sunRaysImage, 0);
456
457 R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
458
323 FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0);
324 FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
459325 R_CheckFBO(tr.sunRaysFbo);
460326 }
461327
465331 for( i = 0; i < MAX_DRAWN_PSHADOWS; i++)
466332 {
467333 tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height);
468 FBO_Bind(tr.pshadowFbos[i]);
469
470 //FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0);
471 FBO_AttachTextureImage(tr.pshadowMaps[i], 0);
472
334 FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT, 0);
473335 FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0);
474 //R_AttachFBOTextureDepth(tr.textureDepthImage->texnum);
475
476336 R_CheckFBO(tr.pshadowFbos[i]);
477337 }
478338 }
479339
480340 if (tr.sunShadowDepthImage[0])
481341 {
482 for ( i = 0; i < 4; i++)
342 for (i = 0; i < 4; i++)
483343 {
484344 tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height);
485 FBO_Bind(tr.sunShadowFbo[i]);
486
487 //FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
488 //FBO_AttachTextureImage(tr.sunShadowImage, 0);
489 qglDrawBuffer(GL_NONE);
490 qglReadBuffer(GL_NONE);
491
492 //FBO_CreateBuffer(tr.sunShadowFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
493 R_AttachFBOTextureDepth(tr.sunShadowDepthImage[i]->texnum);
494
345 // FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments
346 // This at least gets sun shadows working on older GPUs (Intel)
347 FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
348 FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0);
495349 R_CheckFBO(tr.sunShadowFbo[i]);
496
497350 }
498
351 }
352
353 if (tr.screenShadowImage)
354 {
499355 tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
500 FBO_Bind(tr.screenShadowFbo);
501
502 FBO_AttachTextureImage(tr.screenShadowImage, 0);
503
356 FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0);
504357 R_CheckFBO(tr.screenShadowFbo);
505358 }
506359
507 for (i = 0; i < 2; i++)
508 {
509 tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
510 FBO_Bind(tr.textureScratchFbo[i]);
511
512 //FBO_CreateBuffer(tr.textureScratchFbo[i], GL_RGBA8, 0, 0);
513 FBO_AttachTextureImage(tr.textureScratchImage[i], 0);
514
515 R_CheckFBO(tr.textureScratchFbo[i]);
516 }
517
360 if (tr.textureScratchImage[0])
361 {
362 for (i = 0; i < 2; i++)
363 {
364 tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
365 FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
366 R_CheckFBO(tr.textureScratchFbo[i]);
367 }
368 }
369
370 if (tr.calcLevelsImage)
518371 {
519372 tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height);
520 FBO_Bind(tr.calcLevelsFbo);
521
522 //FBO_CreateBuffer(tr.calcLevelsFbo, hdrFormat, 0, 0);
523 FBO_AttachTextureImage(tr.calcLevelsImage, 0);
524
373 FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
525374 R_CheckFBO(tr.calcLevelsFbo);
526375 }
527376
377 if (tr.targetLevelsImage)
528378 {
529379 tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height);
530 FBO_Bind(tr.targetLevelsFbo);
531
532 //FBO_CreateBuffer(tr.targetLevelsFbo, hdrFormat, 0, 0);
533 FBO_AttachTextureImage(tr.targetLevelsImage, 0);
534
380 FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
535381 R_CheckFBO(tr.targetLevelsFbo);
536382 }
537383
538 for (i = 0; i < 2; i++)
539 {
540 tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
541 FBO_Bind(tr.quarterFbo[i]);
542
543 //FBO_CreateBuffer(tr.quarterFbo[i], hdrFormat, 0, 0);
544 FBO_AttachTextureImage(tr.quarterImage[i], 0);
545
546 R_CheckFBO(tr.quarterFbo[i]);
547 }
548
549 if (r_ssao->integer)
384 if (tr.quarterImage[0])
385 {
386 for (i = 0; i < 2; i++)
387 {
388 tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
389 FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
390 R_CheckFBO(tr.quarterFbo[i]);
391 }
392 }
393
394 if (tr.hdrDepthImage)
550395 {
551396 tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height);
552 FBO_Bind(tr.hdrDepthFbo);
553
554 FBO_AttachTextureImage(tr.hdrDepthImage, 0);
555
397 FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0);
556398 R_CheckFBO(tr.hdrDepthFbo);
557
399 }
400
401 if (tr.screenSsaoImage)
402 {
558403 tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height);
559 FBO_Bind(tr.screenSsaoFbo);
560
561 FBO_AttachTextureImage(tr.screenSsaoImage, 0);
562
404 FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0);
563405 R_CheckFBO(tr.screenSsaoFbo);
564406 }
565407
566408 if (tr.renderCubeImage)
567409 {
568410 tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height);
569 FBO_Bind(tr.renderCubeFbo);
570
571 //FBO_AttachTextureImage(tr.renderCubeImage, 0);
572 R_AttachFBOTexture2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, tr.renderCubeImage->texnum, 0);
573 glState.currentFBO->colorImage[0] = tr.renderCubeImage;
574
411 FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT, 0);
575412 FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
576
577413 R_CheckFBO(tr.renderCubeFbo);
578414 }
579415
580416 GL_CheckErrors();
581417
582 FBO_Bind(NULL);
418 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
419 glState.currentFBO = NULL;
583420 }
584421
585422 /*
649486 ri.Printf(PRINT_ALL, " %i FBOs\n", tr.numFBOs);
650487 }
651488
652 void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend)
653 {
654 ivec4_t dstBox, srcBox;
655 vec2_t srcTexScale;
489 void FBO_BlitFromTexture(struct image_s *src, vec4_t inSrcTexCorners, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend)
490 {
491 ivec4_t dstBox;
656492 vec4_t color;
657493 vec4_t quadVerts[4];
658494 vec2_t texCoords[4];
662498 int width, height;
663499
664500 if (!src)
501 {
502 ri.Printf(PRINT_WARNING, "Tried to blit from a NULL texture!\n");
665503 return;
666
667 if (inSrcBox)
668 {
669 VectorSet4(srcBox, inSrcBox[0], inSrcBox[1], inSrcBox[0] + inSrcBox[2], inSrcBox[1] + inSrcBox[3]);
670 }
671 else
672 {
673 VectorSet4(srcBox, 0, 0, src->width, src->height);
504 }
505
506 width = dst ? dst->width : glConfig.vidWidth;
507 height = dst ? dst->height : glConfig.vidHeight;
508
509 if (inSrcTexCorners)
510 {
511 VectorSet2(texCoords[0], inSrcTexCorners[0], inSrcTexCorners[1]);
512 VectorSet2(texCoords[1], inSrcTexCorners[2], inSrcTexCorners[1]);
513 VectorSet2(texCoords[2], inSrcTexCorners[2], inSrcTexCorners[3]);
514 VectorSet2(texCoords[3], inSrcTexCorners[0], inSrcTexCorners[3]);
515 }
516 else
517 {
518 VectorSet2(texCoords[0], 0.0f, 1.0f);
519 VectorSet2(texCoords[1], 1.0f, 1.0f);
520 VectorSet2(texCoords[2], 1.0f, 0.0f);
521 VectorSet2(texCoords[3], 0.0f, 0.0f);
674522 }
675523
676524 // framebuffers are 0 bottom, Y up.
677525 if (inDstBox)
678526 {
679 if (dst)
680 {
681 dstBox[0] = inDstBox[0];
682 dstBox[1] = dst->height - inDstBox[1] - inDstBox[3];
683 dstBox[2] = inDstBox[0] + inDstBox[2];
684 dstBox[3] = dst->height - inDstBox[1];
685 }
686 else
687 {
688 dstBox[0] = inDstBox[0];
689 dstBox[1] = glConfig.vidHeight - inDstBox[1] - inDstBox[3];
690 dstBox[2] = inDstBox[0] + inDstBox[2];
691 dstBox[3] = glConfig.vidHeight - inDstBox[1];
692 }
693 }
694 else if (dst)
695 {
696 VectorSet4(dstBox, 0, dst->height, dst->width, 0);
697 }
698 else
699 {
700 VectorSet4(dstBox, 0, glConfig.vidHeight, glConfig.vidWidth, 0);
527 dstBox[0] = inDstBox[0];
528 dstBox[1] = height - inDstBox[1] - inDstBox[3];
529 dstBox[2] = inDstBox[0] + inDstBox[2];
530 dstBox[3] = height - inDstBox[1];
531 }
532 else
533 {
534 VectorSet4(dstBox, 0, height, width, 0);
701535 }
702536
703537 if (inSrcTexScale)
704538 {
705 VectorCopy2(inSrcTexScale, srcTexScale);
706 }
707 else
708 {
709 srcTexScale[0] = srcTexScale[1] = 1.0f;
539 VectorCopy2(inSrcTexScale, invTexRes);
540 }
541 else
542 {
543 VectorSet2(invTexRes, 1.0f, 1.0f);
710544 }
711545
712546 if (inColor)
724558 }
725559
726560 FBO_Bind(dst);
727
728 if (glState.currentFBO)
729 {
730 width = glState.currentFBO->width;
731 height = glState.currentFBO->height;
732 }
733 else
734 {
735 width = glConfig.vidWidth;
736 height = glConfig.vidHeight;
737 }
738561
739562 qglViewport( 0, 0, width, height );
740563 qglScissor( 0, 0, width, height );
745568
746569 GL_BindToTMU(src, TB_COLORMAP);
747570
748 VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0, 1);
749 VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0, 1);
750 VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0, 1);
751 VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0, 1);
752
753 texCoords[0][0] = srcBox[0] / (float)src->width; texCoords[0][1] = 1.0f - srcBox[1] / (float)src->height;
754 texCoords[1][0] = srcBox[2] / (float)src->width; texCoords[1][1] = 1.0f - srcBox[1] / (float)src->height;
755 texCoords[2][0] = srcBox[2] / (float)src->width; texCoords[2][1] = 1.0f - srcBox[3] / (float)src->height;
756 texCoords[3][0] = srcBox[0] / (float)src->width; texCoords[3][1] = 1.0f - srcBox[3] / (float)src->height;
757
758 invTexRes[0] = 1.0f / src->width * srcTexScale[0];
759 invTexRes[1] = 1.0f / src->height * srcTexScale[1];
571 VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0.0f, 1.0f);
572 VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0.0f, 1.0f);
573 VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0.0f, 1.0f);
574 VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0.0f, 1.0f);
575
576 invTexRes[0] /= src->width;
577 invTexRes[1] /= src->height;
760578
761579 GL_State( blend );
762580
768586 GLSL_SetUniformVec2(shaderProgram, UNIFORM_AUTOEXPOSUREMINMAX, tr.refdef.autoExposureMinMax);
769587 GLSL_SetUniformVec3(shaderProgram, UNIFORM_TONEMINAVGMAXLINEAR, tr.refdef.toneMinAvgMaxLinear);
770588
771 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
589 RB_InstantQuad2(quadVerts, texCoords);
772590
773591 FBO_Bind(oldFbo);
774592 }
775593
776594 void FBO_Blit(FBO_t *src, ivec4_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend)
777595 {
778 ivec4_t srcBox;
596 vec4_t srcTexCorners;
779597
780598 if (!src)
781599 {
783601 return;
784602 }
785603
786 // framebuffers are 0 bottom, Y up.
787604 if (inSrcBox)
788605 {
789 srcBox[0] = inSrcBox[0];
790 srcBox[1] = src->height - inSrcBox[1] - inSrcBox[3];
791 srcBox[2] = inSrcBox[2];
792 srcBox[3] = inSrcBox[3];
793 }
794 else
795 {
796 VectorSet4(srcBox, 0, src->height, src->width, -src->height);
797 }
798
799 FBO_BlitFromTexture(src->colorImage[0], srcBox, srcTexScale, dst, dstBox, shaderProgram, color, blend | GLS_DEPTHTEST_DISABLE);
606 srcTexCorners[0] = inSrcBox[0] / (float)src->width;
607 srcTexCorners[1] = (inSrcBox[1] + inSrcBox[3]) / (float)src->height;
608 srcTexCorners[2] = (inSrcBox[0] + inSrcBox[2]) / (float)src->width;
609 srcTexCorners[3] = inSrcBox[1] / (float)src->height;
610 }
611 else
612 {
613 VectorSet4(srcTexCorners, 0.0f, 0.0f, 1.0f, 1.0f);
614 }
615
616 FBO_BlitFromTexture(src->colorImage[0], srcTexCorners, srcTexScale, dst, dstBox, shaderProgram, color, blend | GLS_DEPTHTEST_DISABLE);
800617 }
801618
802619 void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter)
810627 return;
811628 }
812629
813 // get to a neutral state first
814 //FBO_Bind(NULL);
815
816630 srcFb = src ? src->frameBuffer : 0;
817631 dstFb = dst ? dst->frameBuffer : 0;
818632
819633 if (!srcBox)
820634 {
821 if (src)
822 {
823 VectorSet4(srcBoxFinal, 0, 0, src->width, src->height);
824 }
825 else
826 {
827 VectorSet4(srcBoxFinal, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
828 }
635 int width = src ? src->width : glConfig.vidWidth;
636 int height = src ? src->height : glConfig.vidHeight;
637
638 VectorSet4(srcBoxFinal, 0, 0, width, height);
829639 }
830640 else
831641 {
834644
835645 if (!dstBox)
836646 {
837 if (dst)
838 {
839 VectorSet4(dstBoxFinal, 0, 0, dst->width, dst->height);
840 }
841 else
842 {
843 VectorSet4(dstBoxFinal, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
844 }
647 int width = dst ? dst->width : glConfig.vidWidth;
648 int height = dst ? dst->height : glConfig.vidHeight;
649
650 VectorSet4(dstBoxFinal, 0, 0, width, height);
845651 }
846652 else
847653 {
848654 VectorSet4(dstBoxFinal, dstBox[0], dstBox[1], dstBox[0] + dstBox[2], dstBox[1] + dstBox[3]);
849655 }
850656
851 qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, srcFb);
852 qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dstFb);
657 GL_BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, srcFb);
658 GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, dstFb);
853659 qglBlitFramebufferEXT(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3],
854660 dstBoxFinal[0], dstBoxFinal[1], dstBoxFinal[2], dstBoxFinal[3],
855661 buffers, filter);
856662
857 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
663 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
858664 glState.currentFBO = NULL;
859665 }
5151 int height;
5252 } FBO_t;
5353
54 void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside);
5455 void FBO_Bind(FBO_t *fbo);
5556 void FBO_Init(void);
5657 void FBO_Shutdown(void);
5758
58 void FBO_BlitFromTexture(struct image_s *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
59 void FBO_BlitFromTexture(struct image_s *src, vec4_t inSrcTexCorners, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend);
5960 void FBO_Blit(FBO_t *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
6061 void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter);
6162
339339 ==================
340340 */
341341 void RB_TestFlare( flare_t *f ) {
342 qboolean visible;
343 float fade;
342 float depth;
343 qboolean visible;
344 float fade;
345 float screenZ;
346 FBO_t *oldFbo;
344347
345348 backEnd.pc.c_flareTests++;
346349
350 // doing a readpixels is as good as doing a glFinish(), so
351 // don't bother with another sync
352 glState.finishCalled = qfalse;
353
354 // if we're doing multisample rendering, read from the correct FBO
355 oldFbo = glState.currentFBO;
356 if (tr.msaaResolveFbo)
357 {
358 FBO_Bind(tr.msaaResolveFbo);
359 }
360
361 // read back the z buffer contents
362 qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
363
364 // if we're doing multisample rendering, switch to the old FBO
365 if (tr.msaaResolveFbo)
366 {
367 FBO_Bind(oldFbo);
368 }
369
370 screenZ = backEnd.viewParms.projectionMatrix[14] /
371 ( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
372
347373 visible = f->cgvisible;
374
375 if ( -f->eyeZ - -screenZ > 24 )
376 visible = qfalse;
348377
349378 if ( visible ) {
350379 if ( !f->visible ) {
351380 f->visible = qtrue;
352381 f->fadeTime = backEnd.refdef.time - 1;
353382 }
354 fade = ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
383 fade = ( ( backEnd.refdef.time - f->fadeTime ) /1000.0f ) * r_flareFade->value;
355384 } else {
356385 if ( f->visible ) {
357386 f->visible = qfalse;
435464 return;
436465 }
437466
438 iColor[0] = color[0] * fogFactors[0];
439 iColor[1] = color[1] * fogFactors[1];
440 iColor[2] = color[2] * fogFactors[2];
467 iColor[0] = color[0] * fogFactors[0] * 257;
468 iColor[1] = color[1] * fogFactors[1] * 257;
469 iColor[2] = color[2] * fogFactors[2] * 257;
441470
442471 RB_BeginSurface( tr.flareShader, f->fogNum, 0 );
443472
446475 tess.xyz[tess.numVertexes][1] = f->windowY - size;
447476 tess.texCoords[tess.numVertexes][0][0] = 0;
448477 tess.texCoords[tess.numVertexes][0][1] = 0;
449 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
450 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
451 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
452 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
453 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
478 tess.color[tess.numVertexes][0] = iColor[0];
479 tess.color[tess.numVertexes][1] = iColor[1];
480 tess.color[tess.numVertexes][2] = iColor[2];
481 // tess.color[tess.numVertexes][3] = 65535; // rend2
482 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
454483 tess.numVertexes++;
455484
456485 tess.xyz[tess.numVertexes][0] = f->windowX - size;
457486 tess.xyz[tess.numVertexes][1] = f->windowY + size;
458487 tess.texCoords[tess.numVertexes][0][0] = 0;
459488 tess.texCoords[tess.numVertexes][0][1] = 1;
460 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
461 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
462 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
463 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
464 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
489 tess.color[tess.numVertexes][0] = iColor[0];
490 tess.color[tess.numVertexes][1] = iColor[1];
491 tess.color[tess.numVertexes][2] = iColor[2];
492 // tess.color[tess.numVertexes][3] = 65535; // rend2
493 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
465494 tess.numVertexes++;
466495
467496 tess.xyz[tess.numVertexes][0] = f->windowX + size;
468497 tess.xyz[tess.numVertexes][1] = f->windowY + size;
469498 tess.texCoords[tess.numVertexes][0][0] = 1;
470499 tess.texCoords[tess.numVertexes][0][1] = 1;
471 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
472 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
473 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
474 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
475 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
500 tess.color[tess.numVertexes][0] = iColor[0];
501 tess.color[tess.numVertexes][1] = iColor[1];
502 tess.color[tess.numVertexes][2] = iColor[2];
503 // tess.color[tess.numVertexes][3] = 65535; // rend2
504 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
476505 tess.numVertexes++;
477506
478507 tess.xyz[tess.numVertexes][0] = f->windowX + size;
479508 tess.xyz[tess.numVertexes][1] = f->windowY - size;
480509 tess.texCoords[tess.numVertexes][0][0] = 1;
481510 tess.texCoords[tess.numVertexes][0][1] = 0;
482 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
483 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
484 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
485 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
486 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
511 tess.color[tess.numVertexes][0] = iColor[0];
512 tess.color[tess.numVertexes][1] = iColor[1];
513 tess.color[tess.numVertexes][2] = iColor[2];
514 // tess.color[tess.numVertexes][3] = 65535; // rend2
515 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
487516 tess.numVertexes++;
488517
489518 tess.indexes[tess.numIndexes++] = 0;
7979 #include "../qcommon/qcommon.h"
8080
8181 #ifdef BUILD_FREETYPE
82 #include <ft2build.h>
82 #ifdef USE_LOCAL_HEADERS
83 #include "../freetype-2.6.4/include/ft2build.h"
84 #else
85 #include <ft2build.h>
86 #endif
8387 #include FT_FREETYPE_H
8488 #include FT_ERRORS_H
8589 #include FT_SYSTEM_H
2121 // tr_glsl.c
2222 #include "tr_local.h"
2323
24 void GLSL_BindNullProgram(void);
24 #include "tr_dsa.h"
2525
2626 extern const char *fallbackShader_bokeh_vp;
2727 extern const char *fallbackShader_bokeh_fp;
151151 { "u_ZFadeHighest", GLSL_FLOAT },
152152 };
153153
154
155 static void GLSL_PrintInfoLog(GLhandleARB object, qboolean developerOnly)
154 typedef enum
155 {
156 GLSL_PRINTLOG_PROGRAM_INFO,
157 GLSL_PRINTLOG_SHADER_INFO,
158 GLSL_PRINTLOG_SHADER_SOURCE
159 }
160 glslPrintLog_t;
161
162 static void GLSL_PrintLog(GLuint programOrShader, glslPrintLog_t type, qboolean developerOnly)
156163 {
157164 char *msg;
158165 static char msgPart[1024];
160167 int i;
161168 int printLevel = developerOnly ? PRINT_DEVELOPER : PRINT_ALL;
162169
163 qglGetObjectParameterivARB(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength);
170 switch (type)
171 {
172 case GLSL_PRINTLOG_PROGRAM_INFO:
173 ri.Printf(printLevel, "Program info log:\n");
174 qglGetProgramiv(programOrShader, GL_INFO_LOG_LENGTH, &maxLength);
175 break;
176
177 case GLSL_PRINTLOG_SHADER_INFO:
178 ri.Printf(printLevel, "Shader info log:\n");
179 qglGetShaderiv(programOrShader, GL_INFO_LOG_LENGTH, &maxLength);
180 break;
181
182 case GLSL_PRINTLOG_SHADER_SOURCE:
183 ri.Printf(printLevel, "Shader source:\n");
184 qglGetShaderiv(programOrShader, GL_SHADER_SOURCE_LENGTH, &maxLength);
185 break;
186 }
164187
165188 if (maxLength <= 0)
166189 {
167 ri.Printf(printLevel, "No compile log.\n");
168 return;
169 }
170
171 ri.Printf(printLevel, "compile log:\n");
190 ri.Printf(printLevel, "None.\n");
191 return;
192 }
172193
173194 if (maxLength < 1023)
174 {
175 qglGetInfoLogARB(object, maxLength, &maxLength, msgPart);
176
195 msg = msgPart;
196 else
197 msg = ri.Z_Malloc(maxLength);
198
199 switch (type)
200 {
201 case GLSL_PRINTLOG_PROGRAM_INFO:
202 qglGetProgramInfoLog(programOrShader, maxLength, &maxLength, msg);
203 break;
204
205 case GLSL_PRINTLOG_SHADER_INFO:
206 qglGetShaderInfoLog(programOrShader, maxLength, &maxLength, msg);
207 break;
208
209 case GLSL_PRINTLOG_SHADER_SOURCE:
210 qglGetShaderSource(programOrShader, maxLength, &maxLength, msg);
211 break;
212 }
213
214 if (maxLength < 1023)
215 {
177216 msgPart[maxLength + 1] = '\0';
178217
179218 ri.Printf(printLevel, "%s\n", msgPart);
180219 }
181220 else
182221 {
183 msg = ri.Z_Malloc(maxLength);
184
185 qglGetInfoLogARB(object, maxLength, &maxLength, msg);
186
187 for(i = 0; i < maxLength; i += 1024)
222 for(i = 0; i < maxLength; i += 1023)
188223 {
189224 Q_strncpyz(msgPart, msg + i, sizeof(msgPart));
190225
191 ri.Printf(printLevel, "%s\n", msgPart);
192 }
226 ri.Printf(printLevel, "%s", msgPart);
227 }
228
229 ri.Printf(printLevel, "\n");
193230
194231 ri.Free(msg);
195232 }
196 }
197
198 static void GLSL_PrintShaderSource(GLhandleARB object)
199 {
200 char *msg;
201 static char msgPart[1024];
202 int maxLength = 0;
203 int i;
204
205 qglGetObjectParameterivARB(object, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &maxLength);
206
207 msg = ri.Z_Malloc(maxLength);
208
209 qglGetShaderSourceARB(object, maxLength, &maxLength, msg);
210
211 for(i = 0; i < maxLength; i += 1024)
212 {
213 Q_strncpyz(msgPart, msg + i, sizeof(msgPart));
214 ri.Printf(PRINT_ALL, "%s\n", msgPart);
215 }
216
217 ri.Free(msg);
218 }
219
220 static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, char *dest, int size )
233
234 }
235
236 static void GLSL_GetShaderHeader( GLenum shaderType, const GLchar *extra, char *dest, int size )
221237 {
222238 float fbufWidthScale, fbufHeightScale;
223239
228244 {
229245 Q_strcat(dest, size, "#version 130\n");
230246
231 if(shaderType == GL_VERTEX_SHADER_ARB)
247 if(shaderType == GL_VERTEX_SHADER)
232248 {
233249 Q_strcat(dest, size, "#define attribute in\n");
234250 Q_strcat(dest, size, "#define varying out\n");
327343 Q_strcat(dest, size,
328344 va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale));
329345
330 if (r_materialGamma->value != 1.0f)
331 Q_strcat(dest, size, va("#ifndef r_materialGamma\n#define r_materialGamma %f\n#endif\n", r_materialGamma->value));
332
333 if (r_lightGamma->value != 1.0f)
334 Q_strcat(dest, size, va("#ifndef r_lightGamma\n#define r_lightGamma %f\n#endif\n", r_lightGamma->value));
335
336 if (r_framebufferGamma->value != 1.0f)
337 Q_strcat(dest, size, va("#ifndef r_framebufferGamma\n#define r_framebufferGamma %f\n#endif\n", r_framebufferGamma->value));
338
339 if (r_tonemapGamma->value != 1.0f)
340 Q_strcat(dest, size, va("#ifndef r_tonemapGamma\n#define r_tonemapGamma %f\n#endif\n", r_tonemapGamma->value));
346 if (r_pbr->integer)
347 Q_strcat(dest, size, "#define USE_PBR\n");
348
349 if (r_cubeMapping->integer)
350 {
351 int cubeMipSize = r_cubemapSize->integer;
352 int numRoughnessMips = 0;
353
354 while (cubeMipSize)
355 {
356 cubeMipSize >>= 1;
357 numRoughnessMips++;
358 }
359 numRoughnessMips = MAX(1, numRoughnessMips - 2);
360 Q_strcat(dest, size, va("#define ROUGHNESS_MIPS float(%d)\n", numRoughnessMips));
361 }
341362
342363 if (extra)
343364 {
349370 Q_strcat(dest, size, "#line 0\n");
350371 }
351372
352 static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, const GLcharARB *buffer, int size, GLenum shaderType)
373 static int GLSL_CompileGPUShader(GLuint program, GLuint *prevShader, const GLchar *buffer, int size, GLenum shaderType)
353374 {
354375 GLint compiled;
355 GLhandleARB shader;
356
357 shader = qglCreateShaderObjectARB(shaderType);
358
359 qglShaderSourceARB(shader, 1, (const GLcharARB **)&buffer, &size);
376 GLuint shader;
377
378 shader = qglCreateShader(shaderType);
379
380 qglShaderSource(shader, 1, (const GLchar **)&buffer, &size);
360381
361382 // compile shader
362 qglCompileShaderARB(shader);
383 qglCompileShader(shader);
363384
364385 // check if shader compiled
365 qglGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
386 qglGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
366387 if(!compiled)
367388 {
368 GLSL_PrintShaderSource(shader);
369 GLSL_PrintInfoLog(shader, qfalse);
389 GLSL_PrintLog(shader, GLSL_PRINTLOG_SHADER_SOURCE, qfalse);
390 GLSL_PrintLog(shader, GLSL_PRINTLOG_SHADER_INFO, qfalse);
370391 ri.Error(ERR_DROP, "Couldn't compile shader");
371392 return 0;
372393 }
373394
374 //GLSL_PrintInfoLog(shader, qtrue);
375 //GLSL_PrintShaderSource(shader);
376
377395 if (*prevShader)
378396 {
379 qglDetachObjectARB(program, *prevShader);
380 qglDeleteObjectARB(*prevShader);
397 qglDetachShader(program, *prevShader);
398 qglDeleteShader(*prevShader);
381399 }
382400
383401 // attach shader to program
384 qglAttachObjectARB(program, shader);
402 qglAttachShader(program, shader);
385403
386404 *prevShader = shader;
387405
392410 GLenum shaderType, char *dest, int destSize)
393411 {
394412 char filename[MAX_QPATH];
395 GLcharARB *buffer = NULL;
396 const GLcharARB *shaderText = NULL;
413 GLchar *buffer = NULL;
414 const GLchar *shaderText = NULL;
397415 int size;
398416 int result;
399417
400 if(shaderType == GL_VERTEX_SHADER_ARB)
418 if(shaderType == GL_VERTEX_SHADER)
401419 {
402420 Com_sprintf(filename, sizeof(filename), "glsl/%s_vp.glsl", name);
403421 }
451469 return result;
452470 }
453471
454 static void GLSL_LinkProgram(GLhandleARB program)
472 static void GLSL_LinkProgram(GLuint program)
455473 {
456474 GLint linked;
457475
458 qglLinkProgramARB(program);
459
460 qglGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
476 qglLinkProgram(program);
477
478 qglGetProgramiv(program, GL_LINK_STATUS, &linked);
461479 if(!linked)
462480 {
463 GLSL_PrintInfoLog(program, qfalse);
464 ri.Printf(PRINT_ALL, "\n");
481 GLSL_PrintLog(program, GLSL_PRINTLOG_PROGRAM_INFO, qfalse);
465482 ri.Error(ERR_DROP, "shaders failed to link");
466483 }
467484 }
468485
469 static void GLSL_ValidateProgram(GLhandleARB program)
486 static void GLSL_ValidateProgram(GLuint program)
470487 {
471488 GLint validated;
472489
473 qglValidateProgramARB(program);
474
475 qglGetObjectParameterivARB(program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated);
490 qglValidateProgram(program);
491
492 qglGetProgramiv(program, GL_VALIDATE_STATUS, &validated);
476493 if(!validated)
477494 {
478 GLSL_PrintInfoLog(program, qfalse);
479 ri.Printf(PRINT_ALL, "\n");
495 GLSL_PrintLog(program, GLSL_PRINTLOG_PROGRAM_INFO, qfalse);
480496 ri.Error(ERR_DROP, "shaders failed to validate");
481497 }
482498 }
483499
484 static void GLSL_ShowProgramUniforms(GLhandleARB program)
500 static void GLSL_ShowProgramUniforms(GLuint program)
485501 {
486502 int i, count, size;
487503 GLenum type;
488504 char uniformName[1000];
489505
490 // install the executables in the program object as part of current state.
491 qglUseProgramObjectARB(program);
492
493 // check for GL Errors
494
495506 // query the number of active uniforms
496 qglGetObjectParameterivARB(program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count);
507 qglGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count);
497508
498509 // Loop over each of the active uniforms, and set their value
499510 for(i = 0; i < count; i++)
500511 {
501 qglGetActiveUniformARB(program, i, sizeof(uniformName), NULL, &size, &type, uniformName);
512 qglGetActiveUniform(program, i, sizeof(uniformName), NULL, &size, &type, uniformName);
502513
503514 ri.Printf(PRINT_DEVELOPER, "active uniform: '%s'\n", uniformName);
504515 }
505
506 qglUseProgramObjectARB(0);
507516 }
508517
509518 static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int attribs, const char *vpCode, const char *fpCode)
517526
518527 Q_strncpyz(program->name, name, sizeof(program->name));
519528
520 program->program = qglCreateProgramObjectARB();
529 program->program = qglCreateProgram();
521530 program->attribs = attribs;
522531
523 if (!(GLSL_CompileGPUShader(program->program, &program->vertexShader, vpCode, strlen(vpCode), GL_VERTEX_SHADER_ARB)))
524 {
525 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name);
526 qglDeleteObjectARB(program->program);
532 if (!(GLSL_CompileGPUShader(program->program, &program->vertexShader, vpCode, strlen(vpCode), GL_VERTEX_SHADER)))
533 {
534 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_VERTEX_SHADER\n", name);
535 qglDeleteProgram(program->program);
527536 return 0;
528537 }
529538
530539 if(fpCode)
531540 {
532 if(!(GLSL_CompileGPUShader(program->program, &program->fragmentShader, fpCode, strlen(fpCode), GL_FRAGMENT_SHADER_ARB)))
533 {
534 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name);
535 qglDeleteObjectARB(program->program);
541 if(!(GLSL_CompileGPUShader(program->program, &program->fragmentShader, fpCode, strlen(fpCode), GL_FRAGMENT_SHADER)))
542 {
543 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_FRAGMENT_SHADER\n", name);
544 qglDeleteProgram(program->program);
536545 return 0;
537546 }
538547 }
539548
540549 if(attribs & ATTR_POSITION)
541 qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position");
550 qglBindAttribLocation(program->program, ATTR_INDEX_POSITION, "attr_Position");
542551
543552 if(attribs & ATTR_TEXCOORD)
544 qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD, "attr_TexCoord0");
553 qglBindAttribLocation(program->program, ATTR_INDEX_TEXCOORD, "attr_TexCoord0");
545554
546555 if(attribs & ATTR_LIGHTCOORD)
547 qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTCOORD, "attr_TexCoord1");
556 qglBindAttribLocation(program->program, ATTR_INDEX_LIGHTCOORD, "attr_TexCoord1");
548557
549558 // if(attribs & ATTR_TEXCOORD2)
550 // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD2, "attr_TexCoord2");
559 // qglBindAttribLocation(program->program, ATTR_INDEX_TEXCOORD2, "attr_TexCoord2");
551560
552561 // if(attribs & ATTR_TEXCOORD3)
553 // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3");
562 // qglBindAttribLocation(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3");
554563
555564 if(attribs & ATTR_TANGENT)
556 qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
565 qglBindAttribLocation(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
557566
558567 if(attribs & ATTR_NORMAL)
559 qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal");
568 qglBindAttribLocation(program->program, ATTR_INDEX_NORMAL, "attr_Normal");
560569
561570 if(attribs & ATTR_COLOR)
562 qglBindAttribLocationARB(program->program, ATTR_INDEX_COLOR, "attr_Color");
571 qglBindAttribLocation(program->program, ATTR_INDEX_COLOR, "attr_Color");
563572
564573 if(attribs & ATTR_PAINTCOLOR)
565 qglBindAttribLocationARB(program->program, ATTR_INDEX_PAINTCOLOR, "attr_PaintColor");
574 qglBindAttribLocation(program->program, ATTR_INDEX_PAINTCOLOR, "attr_PaintColor");
566575
567576 if(attribs & ATTR_LIGHTDIRECTION)
568 qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTDIRECTION, "attr_LightDirection");
577 qglBindAttribLocation(program->program, ATTR_INDEX_LIGHTDIRECTION, "attr_LightDirection");
569578
570579 if(attribs & ATTR_POSITION2)
571 qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION2, "attr_Position2");
580 qglBindAttribLocation(program->program, ATTR_INDEX_POSITION2, "attr_Position2");
572581
573582 if(attribs & ATTR_NORMAL2)
574 qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2");
583 qglBindAttribLocation(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2");
575584
576585 if(attribs & ATTR_TANGENT2)
577 qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
586 qglBindAttribLocation(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
578587
579588 GLSL_LinkProgram(program->program);
580589
582591 }
583592
584593 static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name,
585 int attribs, qboolean fragmentShader, const GLcharARB *extra, qboolean addHeader,
594 int attribs, qboolean fragmentShader, const GLchar *extra, qboolean addHeader,
586595 const char *fallback_vp, const char *fallback_fp)
587596 {
588597 char vpCode[32000];
594603 size = sizeof(vpCode);
595604 if (addHeader)
596605 {
597 GLSL_GetShaderHeader(GL_VERTEX_SHADER_ARB, extra, vpCode, size);
606 GLSL_GetShaderHeader(GL_VERTEX_SHADER, extra, vpCode, size);
598607 postHeader = &vpCode[strlen(vpCode)];
599608 size -= strlen(vpCode);
600609 }
603612 postHeader = &vpCode[0];
604613 }
605614
606 if (!GLSL_LoadGPUShaderText(name, fallback_vp, GL_VERTEX_SHADER_ARB, postHeader, size))
615 if (!GLSL_LoadGPUShaderText(name, fallback_vp, GL_VERTEX_SHADER, postHeader, size))
607616 {
608617 return 0;
609618 }
613622 size = sizeof(fpCode);
614623 if (addHeader)
615624 {
616 GLSL_GetShaderHeader(GL_FRAGMENT_SHADER_ARB, extra, fpCode, size);
625 GLSL_GetShaderHeader(GL_FRAGMENT_SHADER, extra, fpCode, size);
617626 postHeader = &fpCode[strlen(fpCode)];
618627 size -= strlen(fpCode);
619628 }
622631 postHeader = &fpCode[0];
623632 }
624633
625 if (!GLSL_LoadGPUShaderText(name, fallback_fp, GL_FRAGMENT_SHADER_ARB, postHeader, size))
634 if (!GLSL_LoadGPUShaderText(name, fallback_fp, GL_FRAGMENT_SHADER, postHeader, size))
626635 {
627636 return 0;
628637 }
642651 size = 0;
643652 for (i = 0; i < UNIFORM_COUNT; i++)
644653 {
645 uniforms[i] = qglGetUniformLocationARB(program->program, uniformsInfo[i].name);
654 uniforms[i] = qglGetUniformLocation(program->program, uniformsInfo[i].name);
646655
647656 if (uniforms[i] == -1)
648657 continue;
708717
709718 *compare = value;
710719
711 qglUniform1iARB(uniforms[uniformNum], value);
720 qglProgramUniform1iEXT(program->program, uniforms[uniformNum], value);
712721 }
713722
714723 void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value)
732741
733742 *compare = value;
734743
735 qglUniform1fARB(uniforms[uniformNum], value);
744 qglProgramUniform1fEXT(program->program, uniforms[uniformNum], value);
736745 }
737746
738747 void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t v)
757766 compare[0] = v[0];
758767 compare[1] = v[1];
759768
760 qglUniform2fARB(uniforms[uniformNum], v[0], v[1]);
769 qglProgramUniform2fEXT(program->program, uniforms[uniformNum], v[0], v[1]);
761770 }
762771
763772 void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v)
781790
782791 VectorCopy(v, compare);
783792
784 qglUniform3fARB(uniforms[uniformNum], v[0], v[1], v[2]);
793 qglProgramUniform3fEXT(program->program, uniforms[uniformNum], v[0], v[1], v[2]);
785794 }
786795
787796 void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v)
805814
806815 VectorCopy4(v, compare);
807816
808 qglUniform4fARB(uniforms[uniformNum], v[0], v[1], v[2], v[3]);
817 qglProgramUniform4fEXT(program->program, uniforms[uniformNum], v[0], v[1], v[2], v[3]);
809818 }
810819
811820 void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_t v)
829838
830839 VectorCopy5(v, compare);
831840
832 qglUniform1fvARB(uniforms[uniformNum], 5, v);
841 qglProgramUniform1fvEXT(program->program, uniforms[uniformNum], 5, v);
833842 }
834843
835844 void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix)
853862
854863 Mat4Copy(matrix, compare);
855864
856 qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix);
865 qglProgramUniformMatrix4fvEXT(program->program, uniforms[uniformNum], 1, GL_FALSE, matrix);
857866 }
858867
859868 void GLSL_DeleteGPUShader(shaderProgram_t *program)
862871 {
863872 if (program->vertexShader)
864873 {
865 qglDetachObjectARB(program->program, program->vertexShader);
866 qglDeleteObjectARB(program->vertexShader);
874 qglDetachShader(program->program, program->vertexShader);
875 qglDeleteShader(program->vertexShader);
867876 }
868877
869878 if (program->fragmentShader)
870879 {
871 qglDetachObjectARB(program->program, program->fragmentShader);
872 qglDeleteObjectARB(program->fragmentShader);
873 }
874
875 qglDeleteObjectARB(program->program);
880 qglDetachShader(program->program, program->fragmentShader);
881 qglDeleteShader(program->fragmentShader);
882 }
883
884 qglDeleteProgram(program->program);
876885
877886 if (program->uniformBuffer)
878887 {
936945
937946 GLSL_InitUniforms(&tr.genericShader[i]);
938947
939 qglUseProgramObjectARB(tr.genericShader[i].program);
940948 GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
941949 GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP);
942 qglUseProgramObjectARB(0);
943950
944951 GLSL_FinishGPUShader(&tr.genericShader[i]);
945952
956963
957964 GLSL_InitUniforms(&tr.textureColorShader);
958965
959 qglUseProgramObjectARB(tr.textureColorShader.program);
960966 GLSL_SetUniformInt(&tr.textureColorShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
961 qglUseProgramObjectARB(0);
962967
963968 GLSL_FinishGPUShader(&tr.textureColorShader);
964969
10101015
10111016 GLSL_InitUniforms(&tr.dlightShader[i]);
10121017
1013 qglUseProgramObjectARB(tr.dlightShader[i].program);
10141018 GLSL_SetUniformInt(&tr.dlightShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
1015 qglUseProgramObjectARB(0);
10161019
10171020 GLSL_FinishGPUShader(&tr.dlightShader[i]);
10181021
10291032 if ((i & LIGHTDEF_USE_PARALLAXMAP) && !r_parallaxMapping->integer)
10301033 continue;
10311034
1032 if (!lightType && (i & LIGHTDEF_USE_PARALLAXMAP))
1033 continue;
1034
10351035 if (!lightType && (i & LIGHTDEF_USE_SHADOWMAP))
10361036 continue;
10371037
10391039
10401040 extradefines[0] = '\0';
10411041
1042 if (r_specularIsMetallic->value)
1043 Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n");
1044
1045 if (r_glossIsRoughness->value)
1046 Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n");
1047
10481042 if (r_dlightMode->integer >= 2)
10491043 Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
10501044
10511045 if (glRefConfig.swizzleNormalmap)
10521046 Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n");
1053
1054 if (r_hdr->integer && !glRefConfig.floatLightmap)
1055 Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n");
10561047
10571048 if (lightType)
10581049 {
10841075 {
10851076 Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n");
10861077
1087 #ifdef USE_VERT_TANGENT_SPACE
1088 Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n");
10891078 attribs |= ATTR_TANGENT;
1090 #endif
10911079
10921080 if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
10931081 {
11021090
11031091 if (r_cubeMapping->integer)
11041092 Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
1093
1094 switch (r_glossType->integer)
1095 {
1096 case 0:
1097 default:
1098 Q_strcat(extradefines, 1024, "#define GLOSS_IS_GLOSS\n");
1099 break;
1100 case 1:
1101 Q_strcat(extradefines, 1024, "#define GLOSS_IS_SMOOTHNESS\n");
1102 break;
1103 case 2:
1104 Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n");
1105 break;
1106 case 3:
1107 Q_strcat(extradefines, 1024, "#define GLOSS_IS_SHININESS\n");
1108 break;
1109 }
11051110 }
11061111
11071112 if (i & LIGHTDEF_USE_SHADOWMAP)
11251130 Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n");
11261131 attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
11271132
1128 #ifdef USE_VERT_TANGENT_SPACE
11291133 if (r_normalMapping->integer)
11301134 {
11311135 attribs |= ATTR_TANGENT2;
11321136 }
1133 #endif
11341137 }
11351138
11361139 if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackShader_lightall_vp, fallbackShader_lightall_fp))
11401143
11411144 GLSL_InitUniforms(&tr.lightallShader[i]);
11421145
1143 qglUseProgramObjectARB(tr.lightallShader[i].program);
11441146 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
11451147 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP);
11461148 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_NORMALMAP, TB_NORMALMAP);
11481150 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SPECULARMAP, TB_SPECULARMAP);
11491151 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SHADOWMAP, TB_SHADOWMAP);
11501152 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_CUBEMAP, TB_CUBEMAP);
1151 qglUseProgramObjectARB(0);
11521153
11531154 GLSL_FinishGPUShader(&tr.lightallShader[i]);
11541155
11811182
11821183 GLSL_InitUniforms(&tr.pshadowShader);
11831184
1184 qglUseProgramObjectARB(tr.pshadowShader.program);
11851185 GLSL_SetUniformInt(&tr.pshadowShader, UNIFORM_SHADOWMAP, TB_DIFFUSEMAP);
1186 qglUseProgramObjectARB(0);
11871186
11881187 GLSL_FinishGPUShader(&tr.pshadowShader);
11891188
12001199
12011200 GLSL_InitUniforms(&tr.down4xShader);
12021201
1203 qglUseProgramObjectARB(tr.down4xShader.program);
12041202 GLSL_SetUniformInt(&tr.down4xShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
1205 qglUseProgramObjectARB(0);
12061203
12071204 GLSL_FinishGPUShader(&tr.down4xShader);
12081205
12191216
12201217 GLSL_InitUniforms(&tr.bokehShader);
12211218
1222 qglUseProgramObjectARB(tr.bokehShader.program);
12231219 GLSL_SetUniformInt(&tr.bokehShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
1224 qglUseProgramObjectARB(0);
12251220
12261221 GLSL_FinishGPUShader(&tr.bokehShader);
12271222
12381233
12391234 GLSL_InitUniforms(&tr.tonemapShader);
12401235
1241 qglUseProgramObjectARB(tr.tonemapShader.program);
12421236 GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_TEXTUREMAP, TB_COLORMAP);
12431237 GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_LEVELSMAP, TB_LEVELSMAP);
1244 qglUseProgramObjectARB(0);
12451238
12461239 GLSL_FinishGPUShader(&tr.tonemapShader);
12471240
12631256
12641257 GLSL_InitUniforms(&tr.calclevels4xShader[i]);
12651258
1266 qglUseProgramObjectARB(tr.calclevels4xShader[i].program);
12671259 GLSL_SetUniformInt(&tr.calclevels4xShader[i], UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
1268 qglUseProgramObjectARB(0);
12691260
12701261 GLSL_FinishGPUShader(&tr.calclevels4xShader[i]);
12711262
12961287
12971288 GLSL_InitUniforms(&tr.shadowmaskShader);
12981289
1299 qglUseProgramObjectARB(tr.shadowmaskShader.program);
13001290 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP);
13011291 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP, TB_SHADOWMAP);
13021292 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2);
13031293 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3);
13041294 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4);
1305 qglUseProgramObjectARB(0);
13061295
13071296 GLSL_FinishGPUShader(&tr.shadowmaskShader);
13081297
13191308
13201309 GLSL_InitUniforms(&tr.ssaoShader);
13211310
1322 qglUseProgramObjectARB(tr.ssaoShader.program);
13231311 GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP);
1324 qglUseProgramObjectARB(0);
13251312
13261313 GLSL_FinishGPUShader(&tr.ssaoShader);
13271314
13281315 numEtcShaders++;
13291316
13301317
1331 for (i = 0; i < 2; i++)
1318 for (i = 0; i < 4; i++)
13321319 {
13331320 attribs = ATTR_POSITION | ATTR_TEXCOORD;
13341321 extradefines[0] = '\0';
13381325 else
13391326 Q_strcat(extradefines, 1024, "#define USE_HORIZONTAL_BLUR\n");
13401327
1328 if (!(i & 2))
1329 Q_strcat(extradefines, 1024, "#define USE_DEPTH\n");
1330
13411331
13421332 if (!GLSL_InitGPUShader(&tr.depthBlurShader[i], "depthBlur", attribs, qtrue, extradefines, qtrue, fallbackShader_depthblur_vp, fallbackShader_depthblur_fp))
13431333 {
13461336
13471337 GLSL_InitUniforms(&tr.depthBlurShader[i]);
13481338
1349 qglUseProgramObjectARB(tr.depthBlurShader[i].program);
13501339 GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENIMAGEMAP, TB_COLORMAP);
13511340 GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENDEPTHMAP, TB_LIGHTMAP);
1352 qglUseProgramObjectARB(0);
13531341
13541342 GLSL_FinishGPUShader(&tr.depthBlurShader[i]);
13551343
13671355
13681356 GLSL_InitUniforms(&tr.testcubeShader);
13691357
1370 qglUseProgramObjectARB(tr.testcubeShader.program);
13711358 GLSL_SetUniformInt(&tr.testcubeShader, UNIFORM_TEXTUREMAP, TB_COLORMAP);
1372 qglUseProgramObjectARB(0);
13731359
13741360 GLSL_FinishGPUShader(&tr.testcubeShader);
13751361
13911377 ri.Printf(PRINT_ALL, "------- GLSL_ShutdownGPUShaders -------\n");
13921378
13931379 for (i = 0; i < ATTR_INDEX_COUNT; i++)
1394 qglDisableVertexAttribArrayARB(i);
1395
1396 GLSL_BindNullProgram();
1380 qglDisableVertexAttribArray(i);
1381
1382 GL_BindNullProgram();
13971383
13981384 for ( i = 0; i < GENERICDEF_COUNT; i++)
13991385 GLSL_DeleteGPUShader(&tr.genericShader[i]);
14211407 GLSL_DeleteGPUShader(&tr.shadowmaskShader);
14221408 GLSL_DeleteGPUShader(&tr.ssaoShader);
14231409
1424 for ( i = 0; i < 2; i++)
1410 for ( i = 0; i < 4; i++)
14251411 GLSL_DeleteGPUShader(&tr.depthBlurShader[i]);
1426
1427 glState.currentProgram = 0;
1428 qglUseProgramObjectARB(0);
14291412 }
14301413
14311414
14321415 void GLSL_BindProgram(shaderProgram_t * program)
14331416 {
1434 if(!program)
1435 {
1436 GLSL_BindNullProgram();
1437 return;
1438 }
1417 GLuint programObject = program ? program->program : 0;
1418 char *name = program ? program->name : "NULL";
14391419
14401420 if(r_logFile->integer)
14411421 {
14421422 // don't just call LogComment, or we will get a call to va() every frame!
1443 GLimp_LogComment(va("--- GL_BindProgram( %s ) ---\n", program->name));
1444 }
1445
1446 if(glState.currentProgram != program)
1447 {
1448 qglUseProgramObjectARB(program->program);
1449 glState.currentProgram = program;
1423 GLimp_LogComment(va("--- GLSL_BindProgram( %s ) ---\n", name));
1424 }
1425
1426 if (GL_UseProgram(programObject))
14501427 backEnd.pc.c_glslShaderBinds++;
1451 }
1452 }
1453
1454
1455 void GLSL_BindNullProgram(void)
1456 {
1457 if(r_logFile->integer)
1458 {
1459 GLimp_LogComment("--- GL_BindNullProgram ---\n");
1460 }
1461
1462 if(glState.currentProgram)
1463 {
1464 qglUseProgramObjectARB(0);
1465 glState.currentProgram = NULL;
1466 }
1467 }
1428 }
1429
14681430
14691431
14701432 shaderProgram_t *GLSL_GetGenericShaderProgram(int stage, glfog_t *glFog)
3434
3535 #include "tr_local.h"
3636
37 #include "tr_dsa.h"
3738
3839 static byte s_intensitytable[256];
3940 static unsigned char s_gammatable[256];
130131 // change all the existing mipmap texture objects
131132 for ( i = 0 ; i < tr.numImages ; i++ ) {
132133 glt = tr.images[ i ];
133 if ( glt->flags & IMGFLAG_MIPMAP ) {
134 GL_Bind( glt );
135 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min );
136 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max );
134 if ( glt->flags & IMGFLAG_MIPMAP && !(glt->flags & IMGFLAG_CUBEMAP) ) {
135 qglTextureParameterfEXT(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
136 qglTextureParameterfEXT(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
137137 }
138138 }
139139 }
163163 ===============
164164 */
165165 void R_ImageList_f( void ) {
166 #if 1
167166 int i;
168167 int estTotalSize = 0;
169168
170 ri.Printf(PRINT_ALL, "\n -w-- -h-- type -size- --name-------\n");
169 ri.Printf(PRINT_ALL, "\n -w-- -h-- -type-- -size- --name-------\n");
171170
172171 for ( i = 0 ; i < tr.numImages ; i++ )
173172 {
174173 image_t *image = tr.images[i];
175 char *format = "???? ";
174 char *format = "???? ";
176175 char *sizeSuffix;
177176 int estSize;
178177 int displaySize;
182181 switch(image->internalFormat)
183182 {
184183 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
185 format = "sDXT1";
184 format = "sDXT1 ";
186185 // 64 bits per 16 pixels, so 4 bits per pixel
187186 estSize /= 2;
188187 break;
189188 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
190 format = "sDXT5";
189 format = "sDXT5 ";
191190 // 128 bits per 16 pixels, so 1 byte per pixel
192191 break;
193192 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
194 format = "sBPTC";
193 format = "sBPTC ";
195194 // 128 bits per 16 pixels, so 1 byte per pixel
196195 break;
197196 case GL_COMPRESSED_RG_RGTC2:
198 format = "RGTC2";
197 format = "RGTC2 ";
199198 // 128 bits per 16 pixels, so 1 byte per pixel
200199 break;
201200 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
202 format = "DXT1 ";
201 format = "DXT1 ";
203202 // 64 bits per 16 pixels, so 4 bits per pixel
204203 estSize /= 2;
205204 break;
206205 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
207 format = "DXT1a";
206 format = "DXT1a ";
208207 // 64 bits per 16 pixels, so 4 bits per pixel
209208 estSize /= 2;
210209 break;
211210 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
212 format = "DXT5 ";
211 format = "DXT5 ";
213212 // 128 bits per 16 pixels, so 1 byte per pixel
214213 break;
215214 case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
216 format = "BPTC ";
215 format = "BPTC ";
217216 // 128 bits per 16 pixels, so 1 byte per pixel
218217 break;
219218 case GL_RGB4_S3TC:
220 format = "S3TC ";
219 format = "S3TC ";
221220 // same as DXT1?
222221 estSize /= 2;
222 break;
223 case GL_RGBA16F:
224 format = "RGBA16F";
225 // 8 bytes per pixel
226 estSize *= 8;
227 break;
228 case GL_RGBA16:
229 format = "RGBA16 ";
230 // 8 bytes per pixel
231 estSize *= 8;
223232 break;
224233 case GL_RGBA4:
225234 case GL_RGBA8:
226235 case GL_RGBA:
227 format = "RGBA ";
236 format = "RGBA ";
228237 // 4 bytes per pixel
229238 estSize *= 4;
230239 break;
231240 case GL_LUMINANCE8:
232241 case GL_LUMINANCE16:
233242 case GL_LUMINANCE:
234 format = "L ";
243 format = "L ";
235244 // 1 byte per pixel?
236245 break;
237246 case GL_RGB5:
238247 case GL_RGB8:
239248 case GL_RGB:
240 format = "RGB ";
249 format = "RGB ";
241250 // 3 bytes per pixel?
242251 estSize *= 3;
243252 break;
244253 case GL_LUMINANCE8_ALPHA8:
245254 case GL_LUMINANCE16_ALPHA16:
246255 case GL_LUMINANCE_ALPHA:
247 format = "LA ";
256 format = "LA ";
248257 // 2 bytes per pixel?
249258 estSize *= 2;
250259 break;
251260 case GL_SRGB_EXT:
252261 case GL_SRGB8_EXT:
253 format = "sRGB ";
262 format = "sRGB ";
254263 // 3 bytes per pixel?
255264 estSize *= 3;
256265 break;
257266 case GL_SRGB_ALPHA_EXT:
258267 case GL_SRGB8_ALPHA8_EXT:
259 format = "sRGBA";
268 format = "sRGBA ";
260269 // 4 bytes per pixel?
261270 estSize *= 4;
262271 break;
263272 case GL_SLUMINANCE_EXT:
264273 case GL_SLUMINANCE8_EXT:
265 format = "sL ";
274 format = "sL ";
266275 // 1 byte per pixel?
267276 break;
268277 case GL_SLUMINANCE_ALPHA_EXT:
269278 case GL_SLUMINANCE8_ALPHA8_EXT:
270 format = "sLA ";
279 format = "sLA ";
271280 // 2 byte per pixel?
272281 estSize *= 2;
273282 break;
283 case GL_DEPTH_COMPONENT16:
284 format = "Depth16";
285 // 2 bytes per pixel
286 estSize *= 2;
287 break;
288 case GL_DEPTH_COMPONENT24:
289 format = "Depth24";
290 // 3 bytes per pixel
291 estSize *= 3;
292 break;
293 case GL_DEPTH_COMPONENT:
294 case GL_DEPTH_COMPONENT32:
295 format = "Depth32";
296 // 4 bytes per pixel
297 estSize *= 4;
298 break;
274299 }
275300
276301 // mipmap adds about 50%
305330 ri.Printf (PRINT_ALL, " ---------\n");
306331 ri.Printf (PRINT_ALL, " approx %i bytes\n", estTotalSize);
307332 ri.Printf (PRINT_ALL, " %i total images\n\n", tr.numImages );
308 #else
309 int i;
310 image_t *image;
311 int texels;
312 const char *yesno[] = {
313 "no ", "yes"
314 };
315
316 ri.Printf( PRINT_ALL, "\n -w-- -h-- -mm- -TMU- -if-- wrap --name-------\n" );
317 texels = 0;
318
319 for ( i = 0 ; i < tr.numImages ; i++ ) {
320 image = tr.images[ i ];
321
322 texels += image->uploadWidth * image->uploadHeight;
323 ri.Printf( PRINT_ALL, "%4i: %4i %4i %s %d ",
324 i, image->uploadWidth, image->uploadHeight, yesno[(image->flags & IMGFLAG_MIPMAP) ? 1 : 0], image->TMU );
325 switch ( image->internalFormat ) {
326 case 1:
327 ri.Printf( PRINT_ALL, "I " );
328 break;
329 case 2:
330 ri.Printf( PRINT_ALL, "IA " );
331 break;
332 case 3:
333 ri.Printf( PRINT_ALL, "RGB " );
334 break;
335 case 4:
336 ri.Printf( PRINT_ALL, "RGBA " );
337 break;
338 case GL_RGBA8:
339 ri.Printf( PRINT_ALL, "RGBA8" );
340 break;
341 case GL_RGB8:
342 ri.Printf( PRINT_ALL, "RGB8" );
343 break;
344 case GL_RGB4_S3TC:
345 ri.Printf( PRINT_ALL, "S3TC4" );
346 break;
347 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
348 ri.Printf( PRINT_ALL, "DXT1 " );
349 break;
350 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
351 ri.Printf( PRINT_ALL, "DXT5 " );
352 break;
353 case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
354 ri.Printf( PRINT_ALL, "LATC " );
355 break;
356 case GL_RGBA4:
357 ri.Printf( PRINT_ALL, "RGBA4" );
358 break;
359 case GL_RGB5:
360 ri.Printf( PRINT_ALL, "RGB5 " );
361 break;
362 case GL_SRGB_EXT:
363 ri.Printf( PRINT_ALL, "sRGB " );
364 break;
365 case GL_SRGB8_EXT:
366 ri.Printf( PRINT_ALL, "sRGB8" );
367 break;
368 case GL_SRGB_ALPHA_EXT:
369 case GL_SRGB8_ALPHA8_EXT:
370 ri.Printf( PRINT_ALL, "sRGBA" );
371 break;
372 /*
373 case GL_SLUMINANCE_EXT:
374 break;
375 case GL_SLUMINANCE8_EXT:
376 break;
377 case GL_SLUMINANCE_ALPHA_EXT:
378 break;
379 case GL_SLUMINANCE8_ALPHA8_EXT:
380 break;
381 */
382 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
383 ri.Printf( PRINT_ALL, "sDXT1" );
384 break;
385 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
386 ri.Printf( PRINT_ALL, "sDXT5" );
387 break;
388 case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
389 ri.Printf( PRINT_ALL, "BPTC " );
390 break;
391 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
392 ri.Printf( PRINT_ALL, "sBPTC" );
393 break;
394 default:
395 ri.Printf( PRINT_ALL, "???? " );
396 }
397
398 if (image->flags & IMGFLAG_CLAMPTOEDGE)
399 ri.Printf( PRINT_ALL, "clmp " );
400 else
401 ri.Printf( PRINT_ALL, "rept " );
402
403 ri.Printf( PRINT_ALL, " %s\n", image->imgName );
404 }
405 ri.Printf( PRINT_ALL, " ---------\n" );
406 ri.Printf( PRINT_ALL, " %i total texels (not including mipmaps)\n", texels );
407 ri.Printf( PRINT_ALL, " %i total images\n\n", tr.numImages );
408 #endif
409333 }
410334
411335 //=======================================================================
15061430 R_RMSE
15071431 ================
15081432 */
1433 #if 0 // FIXME
15091434 static float R_RMSE( byte *in, int width, int height ) {
15101435 int i, j;
15111436 float out, rmse, rtemp;
15451470 rmse = sqrt( rmse / ( height * width * 4 ) );
15461471 return rmse;
15471472 }
1473 #endif
15481474
15491475
15501476 /*
16201546 qboolean picmip = flags & IMGFLAG_PICMIP;
16211547 qboolean mipmap = flags & IMGFLAG_MIPMAP;
16221548 qboolean clampToEdge = flags & IMGFLAG_CLAMPTOEDGE;
1623 qboolean notScaled;
1549 qboolean scaled;
1550 #if 0
1551 static int rmse_saved = 0;
1552
1553 // do the root mean square error stuff first
1554 if ( r_rmse->value ) {
1555 while ( R_RMSE( *data, width, height ) < r_rmse->value ) {
1556 rmse_saved += ( height * width * 4 ) - ( ( width >> 1 ) * ( height >> 1 ) * 4 );
1557 *resampledBuffer = ri.Hunk_AllocateTempMemory( ( width >> 1 ) * ( height >> 1 ) * 4 );
1558 ResampleTexture( *data, width, height, *resampledBuffer, width >> 1, height >> 1 );
1559 *data = *resampledBuffer;
1560 width = width >> 1;
1561 height = height >> 1;
1562 ri.Printf( PRINT_ALL, "r_rmse of %f has saved %dkb\n", r_rmse->value, ( rmse_saved / 1024 ) );
1563 }
1564 }
1565 #endif
16241566
16251567 //
16261568 // convert to exact power of 2 sizes
16271569 //
1628 if (glRefConfig.textureNonPowerOfTwo && !mipmap)
1570 if (!mipmap)
16291571 {
16301572 scaled_width = width;
16311573 scaled_height = height;
16861628 YCoCgAtoRGBA(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height);
16871629 else if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
16881630 FillInNormalizedZ(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height);
1689
16901631
16911632 //endTime = ri.Milliseconds();
16921633
17321673 scaled_width = MAX(1, scaled_width);
17331674 scaled_height = MAX(1, scaled_height);
17341675
1735 notScaled = (width == scaled_width) && (height == scaled_height);
1676 scaled = (width != scaled_width) || (height != scaled_height);
17361677
17371678 //
17381679 // rescale texture to new size using existing mipmap functions
17541695 *inout_width = width;
17551696 *inout_height = height;
17561697
1757 return notScaled;
1698 return scaled;
17581699 }
17591700
17601701
17761717 return qfalse;
17771718 }
17781719
1779 static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean lightMap, imgType_t type, imgFlags_t flags)
1720 static GLenum RawImage_GetFormat(const byte *data, int numPixels, GLenum picFormat, qboolean lightMap, imgType_t type, imgFlags_t flags)
17801721 {
17811722 int samples = 3;
17821723 GLenum internalFormat = GL_RGB;
17831724 qboolean forceNoCompression = (flags & IMGFLAG_NO_COMPRESSION);
17841725 qboolean normalmap = (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT);
17851726
1727 if (picFormat != GL_RGBA8)
1728 return picFormat;
1729
17861730 if(normalmap)
17871731 {
1788 if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels))
1732 if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels) && r_parallaxMapping->integer)
17891733 {
17901734 if (!forceNoCompression && glRefConfig.textureCompression & TCR_BPTC)
17911735 {
19751919 }
19761920 }
19771921
1978 static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip)
1922 static void RawImage_UploadToRgtc2Texture(GLuint texture, int miplevel, int x, int y, int width, int height, byte *data)
19791923 {
1980 int wBlocks, hBlocks, y, x, size;
1924 int wBlocks, hBlocks, iy, ix, size;
19811925 byte *compressedData, *p;
19821926
19831927 wBlocks = (width + 3) / 4;
19851929 size = wBlocks * hBlocks * 16;
19861930
19871931 p = compressedData = ri.Hunk_AllocateTempMemory(size);
1988 for (y = 0; y < height; y += 4)
1989 {
1990 int oh = MIN(4, height - y);
1991
1992 for (x = 0; x < width; x += 4)
1932 for (iy = 0; iy < height; iy += 4)
1933 {
1934 int oh = MIN(4, height - iy);
1935
1936 for (ix = 0; ix < width; ix += 4)
19931937 {
19941938 byte workingData[16];
19951939 int component;
19961940
1997 int ow = MIN(4, width - x);
1941 int ow = MIN(4, width - ix);
19981942
19991943 for (component = 0; component < 2; component++)
20001944 {
20021946
20031947 for (oy = 0; oy < oh; oy++)
20041948 for (ox = 0; ox < ow; ox++)
2005 workingData[oy * 4 + ox] = data[((y + oy) * width + x + ox) * 4 + component];
1949 workingData[oy * 4 + ox] = data[((iy + oy) * width + ix + ox) * 4 + component];
20061950
20071951 // dupe data to fill
20081952 for (oy = 0; oy < 4; oy++)
20151959 }
20161960 }
20171961
2018 qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData);
1962 // FIXME: Won't work for x/y that aren't multiples of 4.
1963 qglCompressedTextureSubImage2DEXT(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, GL_COMPRESSED_RG_RGTC2, size, compressedData);
20191964
20201965 ri.Hunk_FreeTempMemory(compressedData);
20211966 }
20221967
2023 static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture )
1968 static int CalculateMipSize(int width, int height, GLenum picFormat)
20241969 {
2025 int dataFormat, dataType;
2026 qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2);
2027
2028 switch(internalFormat)
1970 int numBlocks = ((width + 3) / 4) * ((height + 3) / 4);
1971 int numPixels = width * height;
1972
1973 switch (picFormat)
1974 {
1975 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1976 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1977 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1978 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1979 case GL_COMPRESSED_RED_RGTC1:
1980 case GL_COMPRESSED_SIGNED_RED_RGTC1:
1981 return numBlocks * 8;
1982
1983 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1984 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1985 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1986 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1987 case GL_COMPRESSED_RG_RGTC2:
1988 case GL_COMPRESSED_SIGNED_RG_RGTC2:
1989 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
1990 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
1991 case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
1992 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
1993 return numBlocks * 16;
1994
1995 case GL_RGBA8:
1996 case GL_SRGB8_ALPHA8_EXT:
1997 return numPixels * 4;
1998
1999 case GL_RGBA16:
2000 return numPixels * 8;
2001
2002 default:
2003 ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat);
2004 return 0;
2005 }
2006
2007 return 0;
2008 }
2009
2010
2011 static GLenum PixelDataFormatFromInternalFormat(GLenum internalFormat)
2012 {
2013 switch (internalFormat)
20292014 {
20302015 case GL_DEPTH_COMPONENT:
20312016 case GL_DEPTH_COMPONENT16_ARB:
20322017 case GL_DEPTH_COMPONENT24_ARB:
20332018 case GL_DEPTH_COMPONENT32_ARB:
2034 dataFormat = GL_DEPTH_COMPONENT;
2035 dataType = GL_UNSIGNED_BYTE;
2019 return GL_DEPTH_COMPONENT;
2020 default:
2021 return GL_RGBA;
20362022 break;
2037 case GL_RGBA16F_ARB:
2038 dataFormat = GL_RGBA;
2039 dataType = GL_HALF_FLOAT_ARB;
2040 break;
2041 default:
2042 dataFormat = GL_RGBA;
2043 dataType = GL_UNSIGNED_BYTE;
2044 break;
2045 }
2046
2047 if ( subtexture )
2048 qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data );
2049 else
2050 {
2051 if (rgtc)
2052 RawImage_UploadToRgtc2Texture(data, width, height, 0);
2023 }
2024 }
2025
2026 static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum target, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture )
2027 {
2028 GLenum dataFormat, dataType;
2029 qboolean rgtc = internalFormat == GL_COMPRESSED_RG_RGTC2;
2030 qboolean rgba8 = picFormat == GL_RGBA8 || picFormat == GL_SRGB8_ALPHA8_EXT;
2031 qboolean rgba = rgba8 || picFormat == GL_RGBA16;
2032 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP);
2033 int size, miplevel;
2034 qboolean lastMip = qfalse;
2035
2036 dataFormat = PixelDataFormatFromInternalFormat(internalFormat);
2037 dataType = picFormat == GL_RGBA16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
2038
2039 miplevel = 0;
2040 do
2041 {
2042 lastMip = (width == 1 && height == 1) || !mipmap;
2043 size = CalculateMipSize(width, height, picFormat);
2044
2045 if (!rgba)
2046 {
2047 qglCompressedTextureSubImage2DEXT(texture, target, miplevel, x, y, width, height, picFormat, size, data);
2048 }
20532049 else
2054 qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data);
2055 }
2056
2057 if (flags & IMGFLAG_MIPMAP)
2058 {
2059 int miplevel;
2060
2061 miplevel = 0;
2062 while (width > 1 || height > 1)
2063 {
2064 if (data)
2050 {
2051 if (rgba8 && miplevel != 0 && r_colorMipLevels->integer)
2052 R_BlendOverTexture((byte *)data, width * height, mipBlendColors[miplevel]);
2053
2054 if (rgba8 && rgtc)
2055 RawImage_UploadToRgtc2Texture(texture, miplevel, x, y, width, height, data);
2056 else
2057 qglTextureSubImage2DEXT(texture, target, miplevel, x, y, width, height, dataFormat, dataType, data);
2058 }
2059
2060 if (!lastMip && numMips < 2)
2061 {
2062 if (glRefConfig.framebufferObject)
2063 {
2064 qglGenerateTextureMipmapEXT(texture, target);
2065 break;
2066 }
2067 else if (rgba8)
20652068 {
20662069 if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
2067 {
2068 R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap );
2069 }
2070 R_MipMapNormalHeight(data, data, width, height, glRefConfig.swizzleNormalmap);
20702071 else
2071 {
2072 R_MipMapsRGB( data, width, height );
2073 }
2074 }
2075
2076 width >>= 1;
2077 height >>= 1;
2078 if (width < 1)
2079 width = 1;
2080 if (height < 1)
2081 height = 1;
2082 miplevel++;
2083
2084 if ( data && r_colorMipLevels->integer )
2085 R_BlendOverTexture( (byte *)data, width * height, mipBlendColors[miplevel] );
2086
2087 if ( subtexture )
2088 {
2089 x >>= 1;
2090 y >>= 1;
2091 qglTexSubImage2D( GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data );
2092 }
2093 else
2094 {
2095 if (rgtc)
2096 RawImage_UploadToRgtc2Texture(data, width, height, miplevel);
2097 else
2098 qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data);
2099 }
2100 }
2101 }
2102 }
2072 R_MipMapsRGB(data, width, height);
2073 }
2074 }
2075
2076 x >>= 1;
2077 y >>= 1;
2078 width = MAX(1, width >> 1);
2079 height = MAX(1, height >> 1);
2080 miplevel++;
2081
2082 if (numMips > 1)
2083 {
2084 data += size;
2085 numMips--;
2086 }
2087 }
2088 while (!lastMip);
2089 }
2090
21032091
21042092 /*
21052093 ===============
21072095
21082096 ===============
21092097 */
2110 static void Upload32(byte *data, int x, int y, int width, int height, image_t *image)
2098 static void Upload32(byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, image_t *image, qboolean scaled)
21112099 {
2112 byte *resampledBuffer = NULL;
21132100 int i, c;
21142101 byte *scan;
2115 static int rmse_saved = 0;
2116
2117 // do the root mean square error stuff first
2118 if ( r_rmse->value ) {
2119 while ( R_RMSE( (byte *)data, width, height ) < r_rmse->value ) {
2120 rmse_saved += ( height * width * 4 ) - ( ( width >> 1 ) * ( height >> 1 ) * 4 );
2121 resampledBuffer = ri.Hunk_AllocateTempMemory( ( width >> 1 ) * ( height >> 1 ) * 4 );
2122 ResampleTexture( data, width, height, resampledBuffer, width >> 1, height >> 1 );
2123 data = resampledBuffer;
2124 width = width >> 1;
2125 height = height >> 1;
2126 ri.Printf( PRINT_ALL, "r_rmse of %f has saved %dkb\n", r_rmse->value, ( rmse_saved / 1024 ) );
2127 }
2128 }
21292102
21302103 imgType_t type = image->type;
21312104 imgFlags_t flags = image->flags;
21322105 GLenum internalFormat = image->internalFormat;
2133 qboolean subtexture = (x != 0) || (y != 0) || (width != image->width) || (height != image->height);
2134 qboolean notScaled = qtrue;
2135 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP);
2136
2137 if (!data)
2138 {
2139 RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL);
2140 RawImage_UploadTexture(NULL, 0, 0, width, height, internalFormat, type, flags, qfalse);
2141 goto done;
2142 }
2143 else if (!subtexture)
2144 {
2145 notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer);
2146 }
2147
2148 c = width*height;
2149 scan = data;
2150
2151 if( r_greyscale->integer )
2152 {
2153 for ( i = 0; i < c; i++ )
2154 {
2155 byte luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2156 scan[i*4] = luma;
2157 scan[i*4 + 1] = luma;
2158 scan[i*4 + 2] = luma;
2159 }
2160 }
2161 else if( r_greyscale->value )
2162 {
2163 for ( i = 0; i < c; i++ )
2164 {
2165 float luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2166 scan[i*4] = LERP(scan[i*4], luma, r_greyscale->value);
2167 scan[i*4 + 1] = LERP(scan[i*4 + 1], luma, r_greyscale->value);
2168 scan[i*4 + 2] = LERP(scan[i*4 + 2], luma, r_greyscale->value);
2169 }
2170 }
2171
2172 if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT))
2173 RawImage_SwizzleRA(data, width, height);
2174
2175 // This corresponds to what the OpenGL1 renderer does
2176 if (!(flags & IMGFLAG_NOLIGHTSCALE) && (!notScaled || mipmap))
2177 R_LightScaleTexture(data, width, height, !mipmap);
2178
2179 if (subtexture)
2180 {
2181 // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped
2182 RawImage_UploadTexture(data, x, y, width, height, internalFormat, type, flags, qtrue);
2183 GL_CheckErrors();
2184 return;
2185 }
2186
2187 RawImage_UploadTexture(data, 0, 0, width, height, internalFormat, type, flags, qfalse);
2188
2189 done:
2190
2191 image->uploadWidth = width;
2192 image->uploadHeight = height;
2193
2194 if (mipmap)
2195 {
2196 if ( textureFilterAnisotropic )
2197 qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
2198 (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) );
2199
2200 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
2201 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
2106 qboolean rgba8 = picFormat == GL_RGBA8 || picFormat == GL_SRGB8_ALPHA8_EXT;
2107 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP) && (rgba8 || numMips > 1);
2108 qboolean cubemap = !!(flags & IMGFLAG_CUBEMAP);
2109
2110 // These operations cannot be performed on non-rgba8 images.
2111 if (rgba8 && !cubemap)
2112 {
2113 c = width*height;
2114 scan = data;
2115
2116 if (type == IMGTYPE_COLORALPHA)
2117 {
2118 if( r_greyscale->integer )
2119 {
2120 for ( i = 0; i < c; i++ )
2121 {
2122 byte luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2123 scan[i*4] = luma;
2124 scan[i*4 + 1] = luma;
2125 scan[i*4 + 2] = luma;
2126 }
2127 }
2128 else if( r_greyscale->value )
2129 {
2130 for ( i = 0; i < c; i++ )
2131 {
2132 float luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2133 scan[i*4] = LERP(scan[i*4], luma, r_greyscale->value);
2134 scan[i*4 + 1] = LERP(scan[i*4 + 1], luma, r_greyscale->value);
2135 scan[i*4 + 2] = LERP(scan[i*4 + 2], luma, r_greyscale->value);
2136 }
2137 }
2138
2139 // This corresponds to what the OpenGL1 renderer does.
2140 if (!(flags & IMGFLAG_NOLIGHTSCALE) && (scaled || mipmap))
2141 R_LightScaleTexture(data, width, height, !mipmap);
2142 }
2143
2144 if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT))
2145 RawImage_SwizzleRA(data, width, height);
2146 }
2147
2148 if (cubemap)
2149 {
2150 for (i = 0; i < 6; i++)
2151 {
2152 int w2 = width, h2 = height;
2153 RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, picFormat, numMips, internalFormat, type, flags, qfalse);
2154 for (c = numMips; c; c--)
2155 {
2156 data += CalculateMipSize(w2, h2, picFormat);
2157 w2 = MAX(1, w2 >> 1);
2158 h2 = MAX(1, h2 >> 1);
2159 }
2160 }
22022161 }
22032162 else
22042163 {
2205 if ( textureFilterAnisotropic )
2206 qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
2207
2208 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
2209 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
2210 }
2211
2212 // Fix for sampling depth buffer on old nVidia cards
2213 // from http://www.idevgames.com/forums/thread-4141-post-34844.html#pid34844
2214 switch(internalFormat)
2215 {
2216 case GL_DEPTH_COMPONENT:
2217 case GL_DEPTH_COMPONENT16_ARB:
2218 case GL_DEPTH_COMPONENT24_ARB:
2219 case GL_DEPTH_COMPONENT32_ARB:
2220 qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
2221 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2222 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2223 break;
2224 default:
2225 break;
2164 RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_TEXTURE_2D, picFormat, numMips, internalFormat, type, flags, qfalse);
22262165 }
22272166
22282167 GL_CheckErrors();
2229
2230 if ( resampledBuffer != NULL )
2231 ri.Hunk_FreeTempMemory( resampledBuffer );
2232 }
2168 }
2169
22332170
22342171 /*
22352172 ================
2236 R_CreateImage
2173 R_CreateImage2
22372174
22382175 This is the only way any image_t are created
22392176 ================
22402177 */
2241 image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat ) {
2242 image_t *image;
2243 qboolean isLightmap = qfalse;
2244 long hash;
2245 int glWrapClampMode;
2178 image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLenum picFormat, int numMips, imgType_t type, imgFlags_t flags, int internalFormat ) {
2179 byte *resampledBuffer = NULL;
2180 image_t *image;
2181 qboolean isLightmap = qfalse, scaled = qfalse;
2182 long hash;
2183 int glWrapClampMode, mipWidth, mipHeight, miplevel;
2184 qboolean rgba8 = picFormat == GL_RGBA8 || picFormat == GL_SRGB8_ALPHA8_EXT;
2185 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP);
2186 qboolean cubemap = !!(flags & IMGFLAG_CUBEMAP);
2187 qboolean picmip = !!(flags & IMGFLAG_PICMIP);
2188 qboolean lastMip;
2189 GLenum textureTarget = cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
2190 GLenum dataFormat;
22462191
22472192 if ( strlen( name ) >= MAX_QPATH ) {
22482193 ri.Error( ERR_DROP, "R_CreateImage: \"%s\" is too long", name );
22722217 glWrapClampMode = GL_REPEAT;
22732218
22742219 if (!internalFormat)
2275 {
2276 if (image->flags & IMGFLAG_CUBEMAP)
2277 internalFormat = GL_RGBA8;
2220 internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags);
2221
2222 image->internalFormat = internalFormat;
2223
2224 // Possibly scale image before uploading.
2225 // if not rgba8 and uploading an image, skip picmips.
2226 if (!cubemap)
2227 {
2228 if (rgba8)
2229 scaled = RawImage_ScaleToPower2(&pic, &width, &height, type, flags, &resampledBuffer);
2230 else if (pic && picmip)
2231 {
2232 for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--)
2233 {
2234 int size = CalculateMipSize(width, height, picFormat);
2235 width = MAX(1, width >> 1);
2236 height = MAX(1, height >> 1);
2237 pic += size;
2238 }
2239 }
2240 }
2241
2242 image->uploadWidth = width;
2243 image->uploadHeight = height;
2244
2245 // Allocate texture storage so we don't have to worry about it later.
2246 dataFormat = PixelDataFormatFromInternalFormat(internalFormat);
2247 mipWidth = width;
2248 mipHeight = height;
2249 miplevel = 0;
2250 do
2251 {
2252 lastMip = !mipmap || (mipWidth == 1 && mipHeight == 1);
2253 if (cubemap)
2254 {
2255 int i;
2256
2257 for (i = 0; i < 6; i++)
2258 qglTextureImage2DEXT(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, miplevel, internalFormat, mipWidth, mipHeight, 0, dataFormat, GL_UNSIGNED_BYTE, NULL);
2259 }
22782260 else
2279 internalFormat = RawImage_GetFormat(pic, width * height, isLightmap, image->type, image->flags);
2280 }
2281
2282 image->internalFormat = internalFormat;
2283
2284 // lightmaps are always allocated on TMU 1
2285 if ( qglActiveTextureARB && isLightmap ) {
2286 image->TMU = 1;
2287 } else {
2288 image->TMU = 0;
2289 }
2290
2291 if ( qglActiveTextureARB ) {
2292 GL_SelectTexture( image->TMU );
2293 }
2294
2295 GL_Bind(image);
2296
2297 if (image->flags & IMGFLAG_CUBEMAP)
2298 {
2299 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2300 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2301 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
2302
2303 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2304
2305 if (image->flags & IMGFLAG_MIPMAP)
2306 {
2307 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2308 }
2309 else
2310 {
2311 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2312 }
2313
2314 qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2315 qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2316 qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2317 qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2318 qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2319 qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2320
2321 if (image->flags & IMGFLAG_MIPMAP)
2322 qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
2323
2324 image->uploadWidth = width;
2325 image->uploadHeight = height;
2326 }
2327 else
2328 {
2329 Upload32( pic, 0, 0, image->width, image->height, image );
2330
2331 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode );
2332 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode );
2333 }
2334
2335 GL_SelectTexture( 0 );
2261 {
2262 qglTextureImage2DEXT(image->texnum, GL_TEXTURE_2D, miplevel, internalFormat, mipWidth, mipHeight, 0, dataFormat, GL_UNSIGNED_BYTE, NULL);
2263 }
2264
2265 mipWidth = MAX(1, mipWidth >> 1);
2266 mipHeight = MAX(1, mipHeight >> 1);
2267 miplevel++;
2268 }
2269 while (!lastMip);
2270
2271 // Upload data.
2272 if (pic)
2273 Upload32(pic, 0, 0, width, height, picFormat, numMips, image, scaled);
2274
2275 if (resampledBuffer != NULL)
2276 ri.Hunk_FreeTempMemory(resampledBuffer);
2277
2278 // Set all necessary texture parameters.
2279 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_WRAP_S, glWrapClampMode);
2280 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_WRAP_T, glWrapClampMode);
2281
2282 if (cubemap)
2283 qglTextureParameteriEXT(image->texnum, textureTarget, GL_TEXTURE_WRAP_R, glWrapClampMode);
2284
2285 if (textureFilterAnisotropic && !cubemap)
2286 qglTextureParameteriEXT(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT,
2287 mipmap ? (GLint)Com_Clamp(1, maxAnisotropy, r_ext_max_anisotropy->integer) : 1);
2288
2289 switch(internalFormat)
2290 {
2291 case GL_DEPTH_COMPONENT:
2292 case GL_DEPTH_COMPONENT16_ARB:
2293 case GL_DEPTH_COMPONENT24_ARB:
2294 case GL_DEPTH_COMPONENT32_ARB:
2295 // Fix for sampling depth buffer on old nVidia cards.
2296 // from http://www.idevgames.com/forums/thread-4141-post-34844.html#pid34844
2297 qglTextureParameterfEXT(image->texnum, textureTarget, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
2298 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2299 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2300 break;
2301 default:
2302 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, mipmap ? gl_filter_min : GL_LINEAR);
2303 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, mipmap ? gl_filter_max : GL_LINEAR);
2304 break;
2305 }
2306
2307 GL_CheckErrors();
23362308
23372309 hash = generateHashValue( name );
23382310 image->next = hashTable[hash];
23442316 return image;
23452317 }
23462318
2347 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height )
2319
2320 /*
2321 ================
2322 R_CreateImage
2323
2324 Wrapper for R_CreateImage2(), for the old parameters.
2325 ================
2326 */
2327 image_t *R_CreateImage(const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat)
23482328 {
2349 if (qglActiveTextureARB) {
2350 GL_SelectTexture(image->TMU);
2351 }
2352
2353 GL_Bind(image);
2354
2355 Upload32(pic, x, y, width, height, image);
2356
2357 GL_SelectTexture(0);
2329 return R_CreateImage2(name, pic, width, height, GL_RGBA8, 0, type, flags, internalFormat);
2330 }
2331
2332
2333 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height, GLenum picFormat )
2334 {
2335 Upload32(pic, x, y, width, height, picFormat, 0, image, qfalse);
23582336 }
23592337
23602338 //===================================================================
2339
2340 // Prototype for dds loader function which isn't common to both renderers
2341 void R_LoadDDS(const char *filename, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips);
23612342
23622343 typedef struct
23632344 {
23692350 // when there are multiple images of different formats available
23702351 static imageExtToLoaderMap_t imageLoaders[ ] =
23712352 {
2353 { "png", R_LoadPNG },
23722354 { "tga", R_LoadTGA },
23732355 { "jpg", R_LoadJPG },
23742356 { "jpeg", R_LoadJPG },
2375 { "png", R_LoadPNG },
23762357 { "pcx", R_LoadPCX },
23772358 { "bmp", R_LoadBMP }
23782359 };
23792360
23802361 static int numImageLoaders = ARRAY_LEN( imageLoaders );
23812362
2382
23832363 /*
23842364 =================
23852365 R_LoadImage
23882368 32 bit format.
23892369 =================
23902370 */
2391 void R_LoadImage( const char *name, byte **pic, int *width, int *height )
2371 void R_LoadImage( const char *name, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips )
23922372 {
23932373 qboolean orgNameFailed = qfalse;
23942374 int orgLoader = -1;
24002380 *pic = NULL;
24012381 *width = 0;
24022382 *height = 0;
2383 *picFormat = GL_RGBA8;
2384 *numMips = 0;
24032385
24042386 Q_strncpyz( localName, name, MAX_QPATH );
24052387
24062388 ext = COM_GetExtension( localName );
2389
2390 // If compressed textures are enabled, try loading a DDS first, it'll load fastest
2391 if (r_ext_compressed_textures->integer)
2392 {
2393 char ddsName[MAX_QPATH];
2394
2395 COM_StripExtension(name, ddsName, MAX_QPATH);
2396 Q_strcat(ddsName, MAX_QPATH, ".dds");
2397
2398 R_LoadDDS(ddsName, pic, width, height, picFormat, numMips);
2399
2400 // If loaded, we're done.
2401 if (*pic)
2402 return;
2403 }
24072404
24082405 if( *ext )
24092406 {
24622459 }
24632460 }
24642461
2462
24652463 /*
24662464 ===============
24672465 R_FindImageFile
24752473 image_t *image;
24762474 int width, height;
24772475 byte *pic;
2476 GLenum picFormat;
2477 int picNumMips;
24782478 long hash;
2479 imgFlags_t checkFlagsTrue, checkFlagsFalse;
24792480
24802481 if ( !name ) {
24812482 return NULL;
25012502 //
25022503 // load the pic from disk
25032504 //
2504 R_LoadImage( name, &pic, &width, &height );
2505 R_LoadImage( name, &pic, &width, &height, &picFormat, &picNumMips );
25052506 if ( pic == NULL ) {
25062507 return NULL;
25072508 }
25082509
2509 if (r_normalMapping->integer && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP))
2510 checkFlagsTrue = IMGFLAG_PICMIP | IMGFLAG_MIPMAP | IMGFLAG_GENNORMALMAP;
2511 checkFlagsFalse = IMGFLAG_CUBEMAP;
2512 if (r_normalMapping->integer && (picFormat == GL_RGBA8) && (type == IMGTYPE_COLORALPHA) &&
2513 ((flags & checkFlagsTrue) == checkFlagsTrue) && !(flags & checkFlagsFalse))
25102514 {
25112515 char normalName[MAX_QPATH];
25122516 image_t *normalImage;
26092613 }
26102614 }
26112615
2612 image = R_CreateImage( ( char * ) name, pic, width, height, type, flags, 0 );
2616 // force mipmaps off if image is compressed but doesn't have enough mips
2617 if ((flags & IMGFLAG_MIPMAP) && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT)
2618 {
2619 int wh = MAX(width, height);
2620 int neededMips = 0;
2621 while (wh)
2622 {
2623 neededMips++;
2624 wh >>= 1;
2625 }
2626 if (neededMips > picNumMips)
2627 flags &= ~IMGFLAG_MIPMAP;
2628 }
2629
2630 image = R_CreateImage2( ( char * ) name, pic, width, height, picFormat, picNumMips, type, flags, 0 );
26132631 ri.Free( pic );
26142632 return image;
26152633 }
28172835 {
28182836 int width, height, hdrFormat, rgbFormat;
28192837
2820 if(glRefConfig.textureNonPowerOfTwo)
2821 {
2822 width = glConfig.vidWidth;
2823 height = glConfig.vidHeight;
2824 }
2825 else
2826 {
2827 width = NextPowerOfTwo(glConfig.vidWidth);
2828 height = NextPowerOfTwo(glConfig.vidHeight);
2829 }
2838 width = glConfig.vidWidth;
2839 height = glConfig.vidHeight;
28302840
28312841 hdrFormat = GL_RGBA8;
28322842 if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat)
28362846
28372847 tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
28382848
2849 if (r_shadowBlur->integer)
2850 tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
2851
2852 if (r_shadowBlur->integer || r_ssao->integer)
2853 tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
2854
28392855 if (r_drawSunRays->integer)
28402856 tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
28412857
2842 if (glRefConfig.framebufferObject)
2843 {
2844 tr.renderDepthImage = R_CreateImage("*renderdepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2845 tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2846 }
2847
2848 {
2849 unsigned short sdata[4];
2858 tr.renderDepthImage = R_CreateImage("*renderdepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2859 tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2860
2861 {
28502862 void *p;
28512863
2852 if (hdrFormat == GL_RGBA16F_ARB)
2853 {
2854 sdata[0] = FloatToHalf(0.0f);
2855 sdata[1] = FloatToHalf(0.45f);
2856 sdata[2] = FloatToHalf(1.0f);
2857 sdata[3] = FloatToHalf(1.0f);
2858 p = &sdata[0];
2859 }
2860 else
2861 {
2862 data[0][0][0] = 0;
2863 data[0][0][1] = 0.45f * 255;
2864 data[0][0][2] = 255;
2865 data[0][0][3] = 255;
2866 p = data;
2867 }
2864 data[0][0][0] = 0;
2865 data[0][0][1] = 0.45f * 255;
2866 data[0][0][2] = 255;
2867 data[0][0][3] = 255;
2868 p = data;
28682869
28692870 tr.calcLevelsImage = R_CreateImage("*calcLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
28702871 tr.targetLevelsImage = R_CreateImage("*targetLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
28832884 if (r_ssao->integer)
28842885 {
28852886 tr.screenSsaoImage = R_CreateImage("*screenSsao", NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
2886 tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
28872887 }
28882888
28892889 if (r_shadows->integer == 4)
28992899 for ( x = 0; x < 4; x++)
29002900 {
29012901 tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2902 GL_Bind(tr.sunShadowDepthImage[x]);
2903 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
2904 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
2905 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
2906 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2902 qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
2903 qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
29072904 }
29082905
29092906 tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
29112908
29122909 if (r_cubeMapping->integer)
29132910 {
2914 tr.renderCubeImage = R_CreateImage("*renderCube", NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
2911 tr.renderCubeImage = R_CreateImage("*renderCube", NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
29152912 }
29162913 }
29172914 }
29282925 int inf;
29292926
29302927 // setup the overbright lighting
2931 #if defined(USE_OVERBRIGHT)
29322928 tr.overbrightBits = r_overBrightBits->integer;
2933 #else
2934 tr.overbrightBits = 0;
2935 #endif
29362929
29372930 // allow 2 overbright bits
29382931 if ( tr.overbrightBits > 2 ) {
29412934 tr.overbrightBits = 0;
29422935 }
29432936
2937 // don't allow more overbright bits than map overbright bits
2938 if ( tr.overbrightBits > r_mapOverBrightBits->integer ) {
2939 tr.overbrightBits = r_mapOverBrightBits->integer;
2940 }
2941
29442942 tr.identityLight = 1.0f / ( 1 << tr.overbrightBits );
29452943 tr.identityLightByte = 255 * tr.identityLight;
29462944
30123010 for ( i = 0; i < tr.numImages ; i++ ) {
30133011 qglDeleteTextures( 1, &tr.images[i]->texnum );
30143012 }
3015 memset( tr.images, 0, sizeof( tr.images ) );
3016
3017 memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
3018 if ( qglActiveTextureARB ) {
3019 GL_SelectTexture( 1 );
3020 qglBindTexture( GL_TEXTURE_2D, 0 );
3021 GL_SelectTexture( 0 );
3022 qglBindTexture( GL_TEXTURE_2D, 0 );
3023 } else {
3024 qglBindTexture( GL_TEXTURE_2D, 0 );
3025 }
3013 Com_Memset( tr.images, 0, sizeof( tr.images ) );
3014
3015 tr.numImages = 0;
3016
3017 GL_BindNullTextures();
30263018 }
30273019
30283020 /*
38803872 #endif
38813873 byte *pic, *temppic;
38823874 int width, height, newWidth, newHeight;
3875 GLenum picFormat;
3876 int picNumMips;
38833877 char *pch;
38843878 int b,c,d,lastNumber;
38853879 int lastBox[2] = {0,0};
39033897 Com_sprintf( filename, sizeof( filename ), "%s/%s", dir, fileList[j] );
39043898 ri.Printf( PRINT_ALL, "...cropping '%s'.. ", filename );
39053899
3906 R_LoadImage( filename, &pic, &width, &height );
3900 R_LoadImage( filename, &pic, &width, &height, &picFormat, &picNumMips );
39073901 if ( !pic ) {
39083902 ri.Printf( PRINT_ALL, "error reading file, ignoring.\n" );
39093903 continue;
0 /*
1 ===========================================================================
2 Copyright (C) 1999-2005 Id Software, Inc.
3 2015 James Canete
4
5 This file is part of Quake III Arena source code.
6
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
21 */
22
23 #include "tr_local.h"
24
25 typedef unsigned int ui32_t;
26
27 typedef struct ddsHeader_s
28 {
29 ui32_t headerSize;
30 ui32_t flags;
31 ui32_t height;
32 ui32_t width;
33 ui32_t pitchOrFirstMipSize;
34 ui32_t volumeDepth;
35 ui32_t numMips;
36 ui32_t reserved1[11];
37 ui32_t always_0x00000020;
38 ui32_t pixelFormatFlags;
39 ui32_t fourCC;
40 ui32_t rgbBitCount;
41 ui32_t rBitMask;
42 ui32_t gBitMask;
43 ui32_t bBitMask;
44 ui32_t aBitMask;
45 ui32_t caps;
46 ui32_t caps2;
47 ui32_t caps3;
48 ui32_t caps4;
49 ui32_t reserved2;
50 }
51 ddsHeader_t;
52
53 // flags:
54 #define _DDSFLAGS_REQUIRED 0x001007
55 #define _DDSFLAGS_PITCH 0x8
56 #define _DDSFLAGS_MIPMAPCOUNT 0x20000
57 #define _DDSFLAGS_FIRSTMIPSIZE 0x80000
58 #define _DDSFLAGS_VOLUMEDEPTH 0x800000
59
60 // pixelFormatFlags:
61 #define DDSPF_ALPHAPIXELS 0x1
62 #define DDSPF_ALPHA 0x2
63 #define DDSPF_FOURCC 0x4
64 #define DDSPF_RGB 0x40
65 #define DDSPF_YUV 0x200
66 #define DDSPF_LUMINANCE 0x20000
67
68 // caps:
69 #define DDSCAPS_COMPLEX 0x8
70 #define DDSCAPS_MIPMAP 0x400000
71 #define DDSCAPS_REQUIRED 0x1000
72
73 // caps2:
74 #define DDSCAPS2_CUBEMAP 0xFE00
75 #define DDSCAPS2_VOLUME 0x200000
76
77 typedef struct ddsHeaderDxt10_s
78 {
79 ui32_t dxgiFormat;
80 ui32_t dimensions;
81 ui32_t miscFlags;
82 ui32_t arraySize;
83 ui32_t miscFlags2;
84 }
85 ddsHeaderDxt10_t;
86
87 // dxgiFormat
88 // from http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx
89 typedef enum DXGI_FORMAT {
90 DXGI_FORMAT_UNKNOWN = 0,
91 DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
92 DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
93 DXGI_FORMAT_R32G32B32A32_UINT = 3,
94 DXGI_FORMAT_R32G32B32A32_SINT = 4,
95 DXGI_FORMAT_R32G32B32_TYPELESS = 5,
96 DXGI_FORMAT_R32G32B32_FLOAT = 6,
97 DXGI_FORMAT_R32G32B32_UINT = 7,
98 DXGI_FORMAT_R32G32B32_SINT = 8,
99 DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
100 DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
101 DXGI_FORMAT_R16G16B16A16_UNORM = 11,
102 DXGI_FORMAT_R16G16B16A16_UINT = 12,
103 DXGI_FORMAT_R16G16B16A16_SNORM = 13,
104 DXGI_FORMAT_R16G16B16A16_SINT = 14,
105 DXGI_FORMAT_R32G32_TYPELESS = 15,
106 DXGI_FORMAT_R32G32_FLOAT = 16,
107 DXGI_FORMAT_R32G32_UINT = 17,
108 DXGI_FORMAT_R32G32_SINT = 18,
109 DXGI_FORMAT_R32G8X24_TYPELESS = 19,
110 DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
111 DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
112 DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
113 DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
114 DXGI_FORMAT_R10G10B10A2_UNORM = 24,
115 DXGI_FORMAT_R10G10B10A2_UINT = 25,
116 DXGI_FORMAT_R11G11B10_FLOAT = 26,
117 DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
118 DXGI_FORMAT_R8G8B8A8_UNORM = 28,
119 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
120 DXGI_FORMAT_R8G8B8A8_UINT = 30,
121 DXGI_FORMAT_R8G8B8A8_SNORM = 31,
122 DXGI_FORMAT_R8G8B8A8_SINT = 32,
123 DXGI_FORMAT_R16G16_TYPELESS = 33,
124 DXGI_FORMAT_R16G16_FLOAT = 34,
125 DXGI_FORMAT_R16G16_UNORM = 35,
126 DXGI_FORMAT_R16G16_UINT = 36,
127 DXGI_FORMAT_R16G16_SNORM = 37,
128 DXGI_FORMAT_R16G16_SINT = 38,
129 DXGI_FORMAT_R32_TYPELESS = 39,
130 DXGI_FORMAT_D32_FLOAT = 40,
131 DXGI_FORMAT_R32_FLOAT = 41,
132 DXGI_FORMAT_R32_UINT = 42,
133 DXGI_FORMAT_R32_SINT = 43,
134 DXGI_FORMAT_R24G8_TYPELESS = 44,
135 DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
136 DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
137 DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
138 DXGI_FORMAT_R8G8_TYPELESS = 48,
139 DXGI_FORMAT_R8G8_UNORM = 49,
140 DXGI_FORMAT_R8G8_UINT = 50,
141 DXGI_FORMAT_R8G8_SNORM = 51,
142 DXGI_FORMAT_R8G8_SINT = 52,
143 DXGI_FORMAT_R16_TYPELESS = 53,
144 DXGI_FORMAT_R16_FLOAT = 54,
145 DXGI_FORMAT_D16_UNORM = 55,
146 DXGI_FORMAT_R16_UNORM = 56,
147 DXGI_FORMAT_R16_UINT = 57,
148 DXGI_FORMAT_R16_SNORM = 58,
149 DXGI_FORMAT_R16_SINT = 59,
150 DXGI_FORMAT_R8_TYPELESS = 60,
151 DXGI_FORMAT_R8_UNORM = 61,
152 DXGI_FORMAT_R8_UINT = 62,
153 DXGI_FORMAT_R8_SNORM = 63,
154 DXGI_FORMAT_R8_SINT = 64,
155 DXGI_FORMAT_A8_UNORM = 65,
156 DXGI_FORMAT_R1_UNORM = 66,
157 DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
158 DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
159 DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
160 DXGI_FORMAT_BC1_TYPELESS = 70,
161 DXGI_FORMAT_BC1_UNORM = 71,
162 DXGI_FORMAT_BC1_UNORM_SRGB = 72,
163 DXGI_FORMAT_BC2_TYPELESS = 73,
164 DXGI_FORMAT_BC2_UNORM = 74,
165 DXGI_FORMAT_BC2_UNORM_SRGB = 75,
166 DXGI_FORMAT_BC3_TYPELESS = 76,
167 DXGI_FORMAT_BC3_UNORM = 77,
168 DXGI_FORMAT_BC3_UNORM_SRGB = 78,
169 DXGI_FORMAT_BC4_TYPELESS = 79,
170 DXGI_FORMAT_BC4_UNORM = 80,
171 DXGI_FORMAT_BC4_SNORM = 81,
172 DXGI_FORMAT_BC5_TYPELESS = 82,
173 DXGI_FORMAT_BC5_UNORM = 83,
174 DXGI_FORMAT_BC5_SNORM = 84,
175 DXGI_FORMAT_B5G6R5_UNORM = 85,
176 DXGI_FORMAT_B5G5R5A1_UNORM = 86,
177 DXGI_FORMAT_B8G8R8A8_UNORM = 87,
178 DXGI_FORMAT_B8G8R8X8_UNORM = 88,
179 DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
180 DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
181 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
182 DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
183 DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
184 DXGI_FORMAT_BC6H_TYPELESS = 94,
185 DXGI_FORMAT_BC6H_UF16 = 95,
186 DXGI_FORMAT_BC6H_SF16 = 96,
187 DXGI_FORMAT_BC7_TYPELESS = 97,
188 DXGI_FORMAT_BC7_UNORM = 98,
189 DXGI_FORMAT_BC7_UNORM_SRGB = 99,
190 DXGI_FORMAT_AYUV = 100,
191 DXGI_FORMAT_Y410 = 101,
192 DXGI_FORMAT_Y416 = 102,
193 DXGI_FORMAT_NV12 = 103,
194 DXGI_FORMAT_P010 = 104,
195 DXGI_FORMAT_P016 = 105,
196 DXGI_FORMAT_420_OPAQUE = 106,
197 DXGI_FORMAT_YUY2 = 107,
198 DXGI_FORMAT_Y210 = 108,
199 DXGI_FORMAT_Y216 = 109,
200 DXGI_FORMAT_NV11 = 110,
201 DXGI_FORMAT_AI44 = 111,
202 DXGI_FORMAT_IA44 = 112,
203 DXGI_FORMAT_P8 = 113,
204 DXGI_FORMAT_A8P8 = 114,
205 DXGI_FORMAT_B4G4R4A4_UNORM = 115,
206 DXGI_FORMAT_FORCE_UINT = 0xffffffffUL
207 } DXGI_FORMAT;
208
209 #define EncodeFourCC(x) ((((ui32_t)((x)[0])) ) | \
210 (((ui32_t)((x)[1])) << 8 ) | \
211 (((ui32_t)((x)[2])) << 16) | \
212 (((ui32_t)((x)[3])) << 24) )
213
214
215 void R_LoadDDS ( const char *filename, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips )
216 {
217 union {
218 byte *b;
219 void *v;
220 } buffer;
221 int len;
222 ddsHeader_t *ddsHeader = NULL;
223 ddsHeaderDxt10_t *ddsHeaderDxt10 = NULL;
224 byte *data;
225
226 if (!picFormat)
227 {
228 ri.Printf(PRINT_ERROR, "R_LoadDDS() called without picFormat parameter!");
229 return;
230 }
231
232 if (width)
233 *width = 0;
234 if (height)
235 *height = 0;
236 if (picFormat)
237 *picFormat = GL_RGBA8;
238 if (numMips)
239 *numMips = 1;
240
241 *pic = NULL;
242
243 //
244 // load the file
245 //
246 len = ri.FS_ReadFile( ( char * ) filename, &buffer.v);
247 if (!buffer.b || len < 0) {
248 return;
249 }
250
251 //
252 // reject files that are too small to hold even a header
253 //
254 if (len < 4 + sizeof(*ddsHeader))
255 {
256 ri.Printf(PRINT_ALL, "File %s is too small to be a DDS file.\n", filename);
257 ri.FS_FreeFile(buffer.v);
258 return;
259 }
260
261 //
262 // reject files that don't start with "DDS "
263 //
264 if (*((ui32_t *)(buffer.b)) != EncodeFourCC("DDS "))
265 {
266 ri.Printf(PRINT_ALL, "File %s is not a DDS file.\n", filename);
267 ri.FS_FreeFile(buffer.v);
268 return;
269 }
270
271 //
272 // parse header and dx10 header if available
273 //
274 ddsHeader = (ddsHeader_t *)(buffer.b + 4);
275 if ((ddsHeader->pixelFormatFlags & DDSPF_FOURCC) && ddsHeader->fourCC == EncodeFourCC("DX10"))
276 {
277 if (len < 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10))
278 {
279 ri.Printf(PRINT_ALL, "File %s indicates a DX10 header it is too small to contain.\n", filename);
280 ri.FS_FreeFile(buffer.v);
281 return;
282 }
283
284 ddsHeaderDxt10 = (ddsHeaderDxt10_t *)(buffer.b + 4 + sizeof(ddsHeader_t));
285 data = buffer.b + 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10);
286 len -= 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10);
287 }
288 else
289 {
290 data = buffer.b + 4 + sizeof(*ddsHeader);
291 len -= 4 + sizeof(*ddsHeader);
292 }
293
294 if (width)
295 *width = ddsHeader->width;
296 if (height)
297 *height = ddsHeader->height;
298
299 if (numMips)
300 {
301 if (ddsHeader->flags & _DDSFLAGS_MIPMAPCOUNT)
302 *numMips = ddsHeader->numMips;
303 else
304 *numMips = 1;
305 }
306
307 // FIXME: handle cube map
308 //if ((ddsHeader->caps2 & DDSCAPS2_CUBEMAP) == DDSCAPS2_CUBEMAP)
309
310 //
311 // Convert DXGI format/FourCC into OpenGL format
312 //
313 if (ddsHeaderDxt10)
314 {
315 switch (ddsHeaderDxt10->dxgiFormat)
316 {
317 case DXGI_FORMAT_BC1_TYPELESS:
318 case DXGI_FORMAT_BC1_UNORM:
319 // FIXME: check for GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
320 *picFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
321 break;
322
323 case DXGI_FORMAT_BC1_UNORM_SRGB:
324 // FIXME: check for GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
325 *picFormat = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
326 break;
327
328 case DXGI_FORMAT_BC2_TYPELESS:
329 case DXGI_FORMAT_BC2_UNORM:
330 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
331 break;
332
333 case DXGI_FORMAT_BC2_UNORM_SRGB:
334 *picFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
335 break;
336
337 case DXGI_FORMAT_BC3_TYPELESS:
338 case DXGI_FORMAT_BC3_UNORM:
339 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
340 break;
341
342 case DXGI_FORMAT_BC3_UNORM_SRGB:
343 *picFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
344 break;
345
346 case DXGI_FORMAT_BC4_TYPELESS:
347 case DXGI_FORMAT_BC4_UNORM:
348 *picFormat = GL_COMPRESSED_RED_RGTC1;
349 break;
350
351 case DXGI_FORMAT_BC4_SNORM:
352 *picFormat = GL_COMPRESSED_SIGNED_RED_RGTC1;
353 break;
354
355 case DXGI_FORMAT_BC5_TYPELESS:
356 case DXGI_FORMAT_BC5_UNORM:
357 *picFormat = GL_COMPRESSED_RG_RGTC2;
358 break;
359
360 case DXGI_FORMAT_BC5_SNORM:
361 *picFormat = GL_COMPRESSED_SIGNED_RG_RGTC2;
362 break;
363
364 case DXGI_FORMAT_BC6H_TYPELESS:
365 case DXGI_FORMAT_BC6H_UF16:
366 *picFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB;
367 break;
368
369 case DXGI_FORMAT_BC6H_SF16:
370 *picFormat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB;
371 break;
372
373 case DXGI_FORMAT_BC7_TYPELESS:
374 case DXGI_FORMAT_BC7_UNORM:
375 *picFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
376 break;
377
378 case DXGI_FORMAT_BC7_UNORM_SRGB:
379 *picFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB;
380 break;
381
382 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
383 *picFormat = GL_SRGB8_ALPHA8_EXT;
384 break;
385
386 case DXGI_FORMAT_R8G8B8A8_UNORM:
387 case DXGI_FORMAT_R8G8B8A8_SNORM:
388 *picFormat = GL_RGBA8;
389 break;
390
391 default:
392 ri.Printf(PRINT_ALL, "DDS File %s has unsupported DXGI format %d.", filename, ddsHeaderDxt10->dxgiFormat);
393 ri.FS_FreeFile(buffer.v);
394 return;
395 break;
396 }
397 }
398 else
399 {
400 if (ddsHeader->pixelFormatFlags & DDSPF_FOURCC)
401 {
402 if (ddsHeader->fourCC == EncodeFourCC("DXT1"))
403 *picFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
404 else if (ddsHeader->fourCC == EncodeFourCC("DXT2"))
405 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
406 else if (ddsHeader->fourCC == EncodeFourCC("DXT3"))
407 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
408 else if (ddsHeader->fourCC == EncodeFourCC("DXT4"))
409 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
410 else if (ddsHeader->fourCC == EncodeFourCC("DXT5"))
411 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
412 else if (ddsHeader->fourCC == EncodeFourCC("ATI1"))
413 *picFormat = GL_COMPRESSED_RED_RGTC1;
414 else if (ddsHeader->fourCC == EncodeFourCC("BC4U"))
415 *picFormat = GL_COMPRESSED_RED_RGTC1;
416 else if (ddsHeader->fourCC == EncodeFourCC("BC4S"))
417 *picFormat = GL_COMPRESSED_SIGNED_RED_RGTC1;
418 else if (ddsHeader->fourCC == EncodeFourCC("ATI2"))
419 *picFormat = GL_COMPRESSED_RG_RGTC2;
420 else if (ddsHeader->fourCC == EncodeFourCC("BC5U"))
421 *picFormat = GL_COMPRESSED_RG_RGTC2;
422 else if (ddsHeader->fourCC == EncodeFourCC("BC5S"))
423 *picFormat = GL_COMPRESSED_SIGNED_RG_RGTC2;
424 else
425 {
426 ri.Printf(PRINT_ALL, "DDS File %s has unsupported FourCC.", filename);
427 ri.FS_FreeFile(buffer.v);
428 return;
429 }
430 }
431 else if (ddsHeader->pixelFormatFlags == (DDSPF_RGB | DDSPF_ALPHAPIXELS)
432 && ddsHeader->rgbBitCount == 32
433 && ddsHeader->rBitMask == 0x000000ff
434 && ddsHeader->gBitMask == 0x0000ff00
435 && ddsHeader->bBitMask == 0x00ff0000
436 && ddsHeader->aBitMask == 0xff000000)
437 {
438 *picFormat = GL_RGBA8;
439 }
440 else
441 {
442 ri.Printf(PRINT_ALL, "DDS File %s has unsupported RGBA format.", filename);
443 ri.FS_FreeFile(buffer.v);
444 return;
445 }
446 }
447
448 *pic = ri.Z_Malloc(len);
449 Com_Memcpy(*pic, data, len);
450
451 ri.FS_FreeFile(buffer.v);
452 }
453
454 void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth)
455 {
456 byte *data;
457 ddsHeader_t *ddsHeader;
458 int picSize, size;
459
460 if (!depth)
461 depth = 1;
462
463 picSize = width * height * depth * 4;
464 size = 4 + sizeof(*ddsHeader) + picSize;
465 data = ri.Z_Malloc(size);
466
467 data[0] = 'D';
468 data[1] = 'D';
469 data[2] = 'S';
470 data[3] = ' ';
471
472 ddsHeader = (ddsHeader_t *)(data + 4);
473 memset(ddsHeader, 0, sizeof(ddsHeader_t));
474
475 ddsHeader->headerSize = 0x7c;
476 ddsHeader->flags = _DDSFLAGS_REQUIRED;
477 ddsHeader->height = height;
478 ddsHeader->width = width;
479 ddsHeader->always_0x00000020 = 0x00000020;
480 ddsHeader->caps = DDSCAPS_COMPLEX | DDSCAPS_REQUIRED;
481
482 if (depth == 6)
483 ddsHeader->caps2 = DDSCAPS2_CUBEMAP;
484
485 ddsHeader->pixelFormatFlags = DDSPF_RGB | DDSPF_ALPHAPIXELS;
486 ddsHeader->rgbBitCount = 32;
487 ddsHeader->rBitMask = 0x000000ff;
488 ddsHeader->gBitMask = 0x0000ff00;
489 ddsHeader->bBitMask = 0x00ff0000;
490 ddsHeader->aBitMask = 0xff000000;
491
492 Com_Memcpy(data + 4 + sizeof(*ddsHeader), pic, picSize);
493
494 ri.FS_WriteFile(filename, data, size);
495
496 ri.Free(data);
497 }
2828 // tr_init.c -- functions that are not called every frame
2929
3030 #include "tr_local.h"
31
32 #include "tr_dsa.h"
3133
3234 glconfig_t glConfig;
3335 glRefConfig_t glRefConfig;
118120 cvar_t *r_ext_multi_draw_arrays;
119121 cvar_t *r_ext_framebuffer_object;
120122 cvar_t *r_ext_texture_float;
121 cvar_t *r_arb_half_float_pixel;
122 cvar_t *r_arb_half_float_vertex;
123123 cvar_t *r_ext_framebuffer_multisample;
124124 cvar_t *r_arb_seamless_cube_map;
125 cvar_t *r_arb_vertex_type_2_10_10_10_rev;
126125 cvar_t *r_arb_vertex_array_object;
126 cvar_t *r_ext_direct_state_access;
127127
128128 cvar_t *r_mergeMultidraws;
129129 cvar_t *r_mergeLeafSurfaces;
147147 cvar_t *r_forceAutoExposureMin;
148148 cvar_t *r_forceAutoExposureMax;
149149
150 cvar_t *r_materialGamma;
151 cvar_t *r_lightGamma;
152 cvar_t *r_framebufferGamma;
153 cvar_t *r_tonemapGamma;
154
155150 cvar_t *r_depthPrepass;
156151 cvar_t *r_ssao;
157152
160155 cvar_t *r_deluxeMapping;
161156 cvar_t *r_parallaxMapping;
162157 cvar_t *r_cubeMapping;
163 cvar_t *r_specularIsMetallic;
164 cvar_t *r_glossIsRoughness;
158 cvar_t *r_cubemapSize;
159 cvar_t *r_pbr;
165160 cvar_t *r_baseNormalX;
166161 cvar_t *r_baseNormalY;
167162 cvar_t *r_baseParallax;
168163 cvar_t *r_baseSpecular;
169164 cvar_t *r_baseGloss;
165 cvar_t *r_glossType;
170166 cvar_t *r_mergeLightmaps;
171167 cvar_t *r_dlightMode;
172168 cvar_t *r_pshadowDist;
175171 cvar_t *r_imageUpsampleType;
176172 cvar_t *r_genNormalMaps;
177173 cvar_t *r_forceSun;
178 cvar_t *r_forceSunMapLightScale;
179174 cvar_t *r_forceSunLightScale;
180175 cvar_t *r_forceSunAmbientScale;
181176 cvar_t *r_sunlightMode;
182177 cvar_t *r_drawSunRays;
183178 cvar_t *r_sunShadows;
184179 cvar_t *r_shadowFilter;
180 cvar_t *r_shadowBlur;
185181 cvar_t *r_shadowMapSize;
186182 cvar_t *r_shadowCascadeZNear;
187183 cvar_t *r_shadowCascadeZFar;
200196 cvar_t *r_drawBuffer;
201197 cvar_t *r_glIgnoreWicked3D;
202198 cvar_t *r_lightmap;
203 cvar_t *r_cgenVertexLit;
204199 cvar_t *r_vertexLight;
205200 cvar_t *r_uiFullScreen;
206201 cvar_t *r_shadows;
901896 ri.Printf (PRINT_ALL, "Wrote %s\n", checkname);
902897 }
903898 }
899
900 /*
901 ==================
902 R_ExportCubemaps
903 ==================
904 */
905 void R_ExportCubemaps(void)
906 {
907 exportCubemapsCommand_t *cmd;
908
909 cmd = R_GetCommandBuffer(sizeof(*cmd));
910 if (!cmd) {
911 return;
912 }
913 cmd->commandId = RC_EXPORT_CUBEMAPS;
914 }
915
916
917 /*
918 ==================
919 R_ExportCubemaps_f
920 ==================
921 */
922 void R_ExportCubemaps_f(void)
923 {
924 R_ExportCubemaps();
925 }
904926
905927 //============================================================================
906928
9971019
9981020 qglColor4f( 1,1,1,1 );
9991021
1000 // initialize downstream texture unit if we're running
1001 // in a multitexture environment
1002 if ( qglActiveTextureARB ) {
1003 GL_SelectTexture( 1 );
1004 GL_TextureMode( r_textureMode->string );
1005 GL_TexEnv( GL_MODULATE );
1006 qglDisable( GL_TEXTURE_2D );
1007 GL_SelectTexture( 0 );
1008 }
1022 GL_BindNullTextures();
1023 GL_BindNullFramebuffers();
10091024
10101025 qglEnable( GL_TEXTURE_2D );
10111026 GL_TextureMode( r_textureMode->string );
1012 GL_TexEnv( GL_MODULATE );
10131027
10141028 //qglShadeModel( GL_SMOOTH );
10151029 qglDepthFunc( GL_LEQUAL );
10221036 glState.faceCulling = CT_TWO_SIDED;
10231037 glState.faceCullFront = qtrue;
10241038
1025 glState.currentProgram = 0;
1026 qglUseProgramObjectARB(0);
1039 GL_BindNullProgram();
10271040
10281041 if (glRefConfig.vertexArrayObject)
1029 qglBindVertexArrayARB(0);
1030
1031 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1032 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1042 qglBindVertexArray(0);
1043
1044 qglBindBuffer(GL_ARRAY_BUFFER, 0);
1045 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
10331046 glState.currentVao = NULL;
10341047 glState.vertexAttribsEnabled = 0;
10351048
10861099 */
10871100 void R_PrintLongString(const char *string) {
10881101 char buffer[1024];
1089 const char *p;
1090 int size = strlen(string);
1091
1092 p = string;
1093 while(size > 0)
1102 const char *p = string;
1103 int remainingLength = strlen(string);
1104
1105 while (remainingLength > 0)
10941106 {
1095 Q_strncpyz(buffer, p, sizeof (buffer) );
1107 // Take as much characters as possible from the string without splitting words between buffers
1108 // This avoids the client console splitting a word up when one half fits on the current line,
1109 // but the second half would have to be written on a new line
1110 int charsToTake = sizeof(buffer) - 1;
1111 if (remainingLength > charsToTake) {
1112 while (p[charsToTake - 1] > ' ' && p[charsToTake] > ' ') {
1113 charsToTake--;
1114 if (charsToTake == 0) {
1115 charsToTake = sizeof(buffer) - 1;
1116 break;
1117 }
1118 }
1119 } else if (remainingLength < charsToTake) {
1120 charsToTake = remainingLength;
1121 }
1122
1123 Q_strncpyz( buffer, p, charsToTake + 1 );
10961124 ri.Printf( PRINT_ALL, "%s", buffer );
1097 p += 1023;
1098 size -= 1023;
1125 remainingLength -= charsToTake;
1126 p += charsToTake;
10991127 }
11001128 }
11011129
12561284 r_ext_multi_draw_arrays = ri.Cvar_Get( "r_ext_multi_draw_arrays", "1", CVAR_ARCHIVE | CVAR_LATCH);
12571285 r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", "1", CVAR_ARCHIVE | CVAR_LATCH);
12581286 r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH);
1259 r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH);
1260 r_arb_half_float_vertex = ri.Cvar_Get( "r_arb_half_float_vertex", "1", CVAR_ARCHIVE | CVAR_LATCH);
12611287 r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
12621288 r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH);
1263 r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( "r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH);
12641289 r_arb_vertex_array_object = ri.Cvar_Get( "r_arb_vertex_array_object", "1", CVAR_ARCHIVE | CVAR_LATCH);
1290 r_ext_direct_state_access = ri.Cvar_Get("r_ext_direct_state_access", "1", CVAR_ARCHIVE | CVAR_LATCH);
12651291
12661292 r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "0", CVAR_ARCHIVE | CVAR_LATCH );
12671293 r_ext_max_anisotropy = ri.Cvar_Get( "r_ext_max_anisotropy", "2", CVAR_ARCHIVE | CVAR_LATCH );
12811307 r_overBrightBits = ri.Cvar_Get( "r_overBrightBits", "0", CVAR_ARCHIVE | CVAR_LATCH );
12821308 r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH );
12831309 r_mode = ri.Cvar_Get( "r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH );
1284 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
1310 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "0", CVAR_ARCHIVE | CVAR_LATCH );
12851311 r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE | CVAR_LATCH );
12861312 r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
12871313 r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
13001326 r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH );
13011327 r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE );
13021328
1303 r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH );
1329 r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE );
13041330 r_forceToneMap = ri.Cvar_Get( "r_forceToneMap", "0", CVAR_CHEAT );
13051331 r_forceToneMapMin = ri.Cvar_Get( "r_forceToneMapMin", "-8.0", CVAR_CHEAT );
13061332 r_forceToneMapAvg = ri.Cvar_Get( "r_forceToneMapAvg", "-2.0", CVAR_CHEAT );
13121338 r_forceAutoExposureMax = ri.Cvar_Get( "r_forceAutoExposureMax", "2.0", CVAR_CHEAT );
13131339
13141340 r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT );
1315
1316 r_materialGamma = ri.Cvar_Get( "r_materialGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
1317 r_lightGamma = ri.Cvar_Get( "r_lightGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
1318 r_framebufferGamma = ri.Cvar_Get( "r_framebufferGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
1319 r_tonemapGamma = ri.Cvar_Get( "r_tonemapGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
13201341
13211342 r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE );
13221343 r_ssao = ri.Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE );
13261347 r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
13271348 r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
13281349 r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
1329 r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH );
1330 r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH);
1350 r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH );
1351 r_pbr = ri.Cvar_Get("r_pbr", "0", CVAR_ARCHIVE | CVAR_LATCH);
13311352 r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
13321353 r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
13331354 r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH );
13341355 r_baseSpecular = ri.Cvar_Get( "r_baseSpecular", "0.04", CVAR_ARCHIVE | CVAR_LATCH );
13351356 r_baseGloss = ri.Cvar_Get( "r_baseGloss", "0.1", CVAR_ARCHIVE | CVAR_LATCH );
1357 r_glossType = ri.Cvar_Get("r_glossType", "1", CVAR_ARCHIVE | CVAR_LATCH);
13361358 r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH );
13371359 r_pshadowDist = ri.Cvar_Get( "r_pshadowDist", "128", CVAR_ARCHIVE );
13381360 r_mergeLightmaps = ri.Cvar_Get( "r_mergeLightmaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
13421364 r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH );
13431365
13441366 r_forceSun = ri.Cvar_Get( "r_forceSun", "0", CVAR_ARCHIVE );
1345 r_forceSunMapLightScale = ri.Cvar_Get( "r_forceSunMapLightScale", "1.0", CVAR_CHEAT );
13461367 r_forceSunLightScale = ri.Cvar_Get( "r_forceSunLightScale", "1.0", CVAR_CHEAT );
13471368 r_forceSunAmbientScale = ri.Cvar_Get( "r_forceSunAmbientScale", "0.5", CVAR_CHEAT );
13481369 r_drawSunRays = ri.Cvar_Get( "r_drawSunRays", "0", CVAR_ARCHIVE | CVAR_LATCH );
13501371
13511372 r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH );
13521373 r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH );
1353 r_shadowMapSize = ri.Cvar_Get( "r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH );
1374 r_shadowBlur = ri.Cvar_Get("r_shadowBlur", "0", CVAR_ARCHIVE | CVAR_LATCH);
1375 r_shadowMapSize = ri.Cvar_Get("r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH);
13541376 r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "8", CVAR_ARCHIVE | CVAR_LATCH );
13551377 r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH );
13561378 r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH );
14301452 r_drawworld = ri.Cvar_Get( "r_drawworld", "1", CVAR_CHEAT );
14311453 r_lightmap = ri.Cvar_Get( "r_lightmap", "0", CVAR_CHEAT ); // DHM - NERVE :: cheat protect
14321454 r_portalOnly = ri.Cvar_Get( "r_portalOnly", "0", CVAR_CHEAT );
1433
1434 r_cgenVertexLit = ri.Cvar_Get( "r_cgenVertexLit", "1", CVAR_ARCHIVE | CVAR_LATCH );
14351455
14361456 r_flareSize = ri.Cvar_Get( "r_flareSize", "40", CVAR_CHEAT );
14371457 ri.Cvar_Set( "r_flareFade", "5" ); // to force this when people already have "7" in their config
14861506 ri.Cmd_AddCommand( "gfxinfo", GfxInfo_f );
14871507 ri.Cmd_AddCommand( "minimize", GLimp_Minimize );
14881508 ri.Cmd_AddCommand( "gfxmeminfo", GfxMemInfo_f );
1509 ri.Cmd_AddCommand( "exportCubemaps", R_ExportCubemaps_f );
14891510 ri.Cmd_AddCommand( "taginfo", R_TagInfo_f );
14901511
14911512 // Ridah
15021523 return;
15031524
15041525 if (r_drawSunRays->integer)
1505 qglGenQueriesARB(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
1526 qglGenQueries(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
15061527 }
15071528
15081529 void R_ShutDownQueries(void)
15111532 return;
15121533
15131534 if (r_drawSunRays->integer)
1514 qglDeleteQueriesARB(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
1535 qglDeleteQueries(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
15151536 }
15161537
15171538 /*
16391660 ri.Cmd_RemoveCommand( "modelist" );
16401661 ri.Cmd_RemoveCommand( "shaderstate" );
16411662 ri.Cmd_RemoveCommand( "gfxmeminfo" );
1663 ri.Cmd_RemoveCommand( "exportCubemaps" );
16421664 ri.Cmd_RemoveCommand( "taginfo" );
16431665
16441666 // Ridah
194194 byte *data;
195195 int lat, lng;
196196 vec3_t normal;
197 #if idppc
198 float d0, d1, d2, d3, d4, d5;
199 #endif
197200 factor = 1.0;
198201 data = gridData;
199202 for ( j = 0 ; j < 3 ; j++ ) {
211214 if ( j != 3 )
212215 continue;
213216
214 if (world->hdrLightGrid)
215 {
216 float *hdrData = world->hdrLightGrid + (int)(data - world->lightGridData) / 8 * 6;
217 if (!(hdrData[0]+hdrData[1]+hdrData[2]+hdrData[3]+hdrData[4]+hdrData[5]) ) {
217 if (world->lightGrid16)
218 {
219 uint16_t *data16 = world->lightGrid16 + (int)(data - world->lightGridData) / 8 * 6;
220 if (!(data16[0]+data16[1]+data16[2]+data16[3]+data16[4]+data16[5])) {
218221 continue; // ignore samples in walls
219222 }
220223 }
225228 }
226229 }
227230 totalFactor += factor;
228
229 if (world->hdrLightGrid)
231 #if idppc
232 d0 = data[0]; d1 = data[1]; d2 = data[2];
233 d3 = data[3]; d4 = data[4]; d5 = data[5];
234
235 ent->ambientLight[0] += factor * d0;
236 ent->ambientLight[1] += factor * d1;
237 ent->ambientLight[2] += factor * d2;
238
239 ent->directedLight[0] += factor * d3;
240 ent->directedLight[1] += factor * d4;
241 ent->directedLight[2] += factor * d5;
242 #else
243 if (world->lightGrid16)
230244 {
231245 // FIXME: this is hideous
232 float *hdrData = world->hdrLightGrid + (int)(data - world->lightGridData) / 8 * 6;
233
234 ent->ambientLight[0] += factor * hdrData[0];
235 ent->ambientLight[1] += factor * hdrData[1];
236 ent->ambientLight[2] += factor * hdrData[2];
237
238 ent->directedLight[0] += factor * hdrData[3];
239 ent->directedLight[1] += factor * hdrData[4];
240 ent->directedLight[2] += factor * hdrData[5];
246 uint16_t *data16 = world->lightGrid16 + (int)(data - world->lightGridData) / 8 * 6;
247
248 ent->ambientLight[0] += factor * data16[0] / 257.0f;
249 ent->ambientLight[1] += factor * data16[1] / 257.0f;
250 ent->ambientLight[2] += factor * data16[2] / 257.0f;
251
252 ent->directedLight[0] += factor * data16[3] / 257.0f;
253 ent->directedLight[1] += factor * data16[4] / 257.0f;
254 ent->directedLight[2] += factor * data16[5] / 257.0f;
241255 }
242256 else
243257 {
249263 ent->directedLight[1] += factor * data[4];
250264 ent->directedLight[2] += factor * data[5];
251265 }
252
266 #endif
253267 lat = data[7];
254268 lng = data[6];
255269 lat *= ( FUNCTABLE_SIZE / 256 );
411425 VectorMA( lightDir, d, dir, lightDir );
412426 }
413427
414 // clamp ambient
415 if ( !r_hdr->integer )
428 // clamp lights
429 // FIXME: old renderer clamps (ambient + NL * directed) per vertex
430 // check if that's worth implementing
416431 {
417 for ( i = 0 ; i < 3 ; i++ ) {
418 if ( ent->ambientLight[i] > tr.identityLightByte ) {
419 ent->ambientLight[i] = tr.identityLightByte;
420 }
432 float r, g, b, max;
433
434 r = ent->ambientLight[0];
435 g = ent->ambientLight[1];
436 b = ent->ambientLight[2];
437
438 max = MAX(MAX(r, g), b);
439
440 if (max > 255.0f)
441 {
442 max = 255.0f / max;
443 ent->ambientLight[0] *= max;
444 ent->ambientLight[1] *= max;
445 ent->ambientLight[2] *= max;
446 }
447
448 r = ent->directedLight[0];
449 g = ent->directedLight[1];
450 b = ent->directedLight[2];
451
452 max = MAX(MAX(r, g), b);
453
454 if (max > 255.0f)
455 {
456 max = 255.0f / max;
457 ent->directedLight[0] *= max;
458 ent->directedLight[1] *= max;
459 ent->directedLight[2] *= max;
421460 }
422461 }
423462
424463 if ( r_debugLight->integer ) {
425464 LogLight( ent );
426465 }
427
428 // save out the byte packet version
429 ( (byte *)&ent->ambientLightInt )[0] = ri.ftol( ent->ambientLight[0] );
430 ( (byte *)&ent->ambientLightInt )[1] = ri.ftol( ent->ambientLight[1] );
431 ( (byte *)&ent->ambientLightInt )[2] = ri.ftol( ent->ambientLight[2] );
432 ( (byte *)&ent->ambientLightInt )[3] = 0xff;
433466
434467 // transform the direction to local space
435468 VectorNormalize( lightDir );
2626 */
2727
2828
29
3029 #ifndef TR_LOCAL_H
3130 #define TR_LOCAL_H
3231
3433 #include "../qcommon/qfiles.h"
3534 #include "../qcommon/qcommon.h"
3635 #include "../renderer/tr_public.h"
37 #include "tr_extratypes.h"
38 #include "tr_extramath.h"
39 #include "tr_fbo.h"
40 #include "tr_postprocess.h"
4136 #include "qgl.h"
4237 #include "../renderer/iqm.h"
4338
6055 #define MAX_CALC_PSHADOWS 64
6156 #define MAX_DRAWN_PSHADOWS 32 // do not increase past 32, because bit flags are used on surfaces
6257 #define PSHADOW_MAP_SIZE 512
63 #define CUBE_MAP_MIPS 7
64 #define CUBE_MAP_SIZE (1 << CUBE_MAP_MIPS)
6558
66 #define USE_VERT_TANGENT_SPACE
67 #define USE_OVERBRIGHT
68
6959 // a trRefEntity_t has all the information passed in by
7060 // the client game, as well as some locally derived info
7161 typedef struct {
7969 vec3_t lightDir; // normalized direction towards light, in world space
8070 vec3_t modelLightDir; // normalized direction towards light, in model space
8171 vec3_t ambientLight; // color normalized to 0-255
82 int ambientLightInt; // 32 bit rgba packed
8372 vec3_t directedLight;
8473 float brightness;
8574 } trRefEntity_t;
131120
132121 struct image_s* next;
133122 } image_t;
123
124 #include "tr_extratypes.h"
125 #include "tr_extramath.h"
126 #include "tr_fbo.h"
127 #include "tr_postprocess.h"
134128
135129 // Ensure this is >= the ATTR_INDEX_COUNT enum below
136130 #define VAO_MAX_ATTRIBS 16
272266 CGEN_IDENTITY, // always (1,1,1,1)
273267 CGEN_ENTITY, // grabbed from entity's modulate field
274268 CGEN_ONE_MINUS_ENTITY, // grabbed from 1 - entity.modulate
275 CGEN_EXACT_VERTEX, // tess.vertexColors
276 CGEN_VERTEX, // tess.vertexColors * tr.identityLight
269 CGEN_EXACT_VERTEX, // tess.color
270 CGEN_VERTEX, // tess.color * tr.identityLight
277271 CGEN_EXACT_VERTEX_LIT, // like CGEN_EXACT_VERTEX but takes a light direction from the lightgrid
278272 CGEN_VERTEX_LIT, // like CGEN_VERTEX but takes a light direction from the lightgrid
279273 CGEN_ONE_MINUS_VERTEX,
556550 }
557551
558552 typedef struct cubemap_s {
553 char name[MAX_QPATH];
559554 vec3_t origin;
560555 float parallaxRadius;
561556 image_t *image;
797792 {
798793 char name[MAX_QPATH];
799794
800 GLhandleARB program;
801 GLhandleARB vertexShader;
802 GLhandleARB fragmentShader;
795 GLuint program;
796 GLuint vertexShader;
797 GLuint fragmentShader;
803798 uint32_t attribs; // vertex array attributes
804799
805800 // uniform parameters
856851 float sunDir[4];
857852 float sunCol[4];
858853 float sunAmbCol[4];
859 float colorScale;
860854
861855 float autoExposureMinMax[2];
862856 float toneMinAvgMaxLinear[3];
961955 SF_TRIANGLES,
962956 SF_POLY,
963957 SF_MDV,
964 SF_MDC,
965958 SF_MDS,
966959 SF_MDR,
967960 SF_IQM,
10091002 vec3_t xyz;
10101003 vec2_t st;
10111004 vec2_t lightmap;
1012 vec3_t normal;
1013 #ifdef USE_VERT_TANGENT_SPACE
1014 vec4_t tangent;
1015 #endif
1016 vec3_t lightdir;
1017 vec4_t vertexColors;
1005 int16_t normal[4];
1006 int16_t tangent[4];
1007 int16_t lightdir[4];
1008 uint16_t color[4];
10181009
10191010 #if DEBUG_OPTIMIZEVERTICES
10201011 unsigned int id;
10211012 #endif
10221013 } srfVert_t;
10231014
1024 #ifdef USE_VERT_TANGENT_SPACE
1025 #define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
1026 #else
1027 #define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
1028 #endif
1015 #define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}
10291016
10301017 // srfBspSurface_t covers SF_GRID, SF_TRIANGLES, SF_POLY, and SF_VAO_MESH
10311018 typedef struct srfBspSurface_s
12771264 vec3_t lightGridInverseSize;
12781265 int lightGridBounds[3];
12791266 byte *lightGridData;
1280 float *hdrLightGrid;
1267 uint16_t *lightGrid16;
12811268
12821269 int numClusters;
12831270 int clusterBytes;
13131300 typedef struct
13141301 {
13151302 vec3_t xyz;
1316 vec3_t normal;
1317 #ifdef USE_VERT_TANGENT_SPACE
1318 vec3_t tangent;
1319 vec3_t bitangent;
1320 #endif
1303 int16_t normal[4];
1304 int16_t tangent[4];
13211305 } mdvVertex_t;
13221306
13231307 typedef struct
14851469
14861470 // the renderer front end should never modify glstate_t
14871471 typedef struct {
1488 int currenttextures[NUM_TEXTURE_BUNDLES];
1489 int currenttmu;
14901472 qboolean finishCalled;
14911473 int texEnv[2];
14921474 int faceCulling;
14961478 float vertexAttribsInterpolation;
14971479 qboolean vertexAnimation;
14981480 uint32_t vertexAttribsEnabled; // global if no VAOs, tess only otherwise
1499 shaderProgram_t *currentProgram;
15001481 FBO_t *currentFBO;
15011482 vao_t *currentVao;
15021483 mat4_t modelview;
15191500 // We can't change glConfig_t without breaking DLL/vms compatibility, so
15201501 // store extensions we have here.
15211502 typedef struct {
1503 int openglMajorVersion;
1504 int openglMinorVersion;
1505
15221506 qboolean drawRangeElements;
15231507 qboolean multiDrawArrays;
15241508 qboolean occlusionQuery;
15321516 int maxRenderbufferSize;
15331517 int maxColorAttachments;
15341518
1535 qboolean textureNonPowerOfTwo;
15361519 qboolean textureFloat;
1537 qboolean halfFloatPixel;
1538 qboolean packedDepthStencil;
1539 qboolean arbTextureCompression;
15401520 textureCompressionRef_t textureCompression;
15411521 qboolean swizzleNormalmap;
15421522
15461526 qboolean depthClamp;
15471527 qboolean seamlessCubeMap;
15481528
1549 GLenum packedNormalDataType;
1550 GLenum packedTexcoordDataType;
1551 GLenum packedColorDataType;
1552 int packedTexcoordDataSize;
1553 int packedColorDataSize;
1554
1555 qboolean floatLightmap;
15561529 qboolean vertexArrayObject;
1530 qboolean directStateAccess;
15571531 } glRefConfig_t;
15581532
15591533 typedef struct {
16541628 image_t *sunRaysImage;
16551629 image_t *renderDepthImage;
16561630 image_t *pshadowMaps[MAX_DRAWN_PSHADOWS];
1631 image_t *screenScratchImage;
16571632 image_t *textureScratchImage[2];
16581633 image_t *quarterImage[2];
16591634 image_t *calcLevelsImage;
16721647 FBO_t *sunRaysFbo;
16731648 FBO_t *depthFbo;
16741649 FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS];
1650 FBO_t *screenScratchFbo;
16751651 FBO_t *textureScratchFbo[2];
16761652 FBO_t *quarterFbo[2];
16771653 FBO_t *calcLevelsFbo;
16981674 image_t **lightmaps;
16991675 image_t **deluxemaps;
17001676
1701 int fatLightmapSize;
1702 int fatLightmapStep;
1677 int fatLightmapCols;
1678 int fatLightmapRows;
17031679
17041680 int numCubemaps;
17051681 cubemap_t *cubemaps;
17261702 shaderProgram_t calclevels4xShader[2];
17271703 shaderProgram_t shadowmaskShader;
17281704 shaderProgram_t ssaoShader;
1729 shaderProgram_t depthBlurShader[2];
1705 shaderProgram_t depthBlurShader[4];
17301706 shaderProgram_t testcubeShader;
17311707
17321708
17441720
17451721 int viewCluster;
17461722
1747 float mapLightScale;
17481723 float sunShadowScale;
17491724
17501725 qboolean sunShadows;
18941869 extern cvar_t *r_ext_multi_draw_arrays;
18951870 extern cvar_t *r_ext_framebuffer_object;
18961871 extern cvar_t *r_ext_texture_float;
1897 extern cvar_t *r_arb_half_float_pixel;
1898 extern cvar_t *r_arb_half_float_vertex;
18991872 extern cvar_t *r_ext_framebuffer_multisample;
19001873 extern cvar_t *r_arb_seamless_cube_map;
1901 extern cvar_t *r_arb_vertex_type_2_10_10_10_rev;
19021874 extern cvar_t *r_arb_vertex_array_object;
1875 extern cvar_t *r_ext_direct_state_access;
19031876
19041877 //----(SA) added
19051878 extern cvar_t *r_ext_NV_fog_dist;
19291902
19301903 extern cvar_t *r_fullbright; // avoid lightmap pass // JPW NERVE removed per atvi request
19311904 extern cvar_t *r_lightmap; // render lightmaps only
1932 extern cvar_t *r_cgenVertexLit; // Use CGEN_VERTEX_LIT and CGEN_EXACT_VERTEX_LIT instead of CGEN_VERTEX and CGEN_EXACT_VERTEX
19331905 extern cvar_t *r_vertexLight; // vertex lighting mode for better performance
19341906 extern cvar_t *r_uiFullScreen; // ui is running fullscreen
19351907
19781950
19791951 extern cvar_t *r_cameraExposure;
19801952
1981 extern cvar_t *r_materialGamma;
1982 extern cvar_t *r_lightGamma;
1983 extern cvar_t *r_framebufferGamma;
1984 extern cvar_t *r_tonemapGamma;
1985
19861953 extern cvar_t *r_depthPrepass;
19871954 extern cvar_t *r_ssao;
19881955
19911958 extern cvar_t *r_deluxeMapping;
19921959 extern cvar_t *r_parallaxMapping;
19931960 extern cvar_t *r_cubeMapping;
1994 extern cvar_t *r_specularIsMetallic;
1995 extern cvar_t *r_glossIsRoughness;
1961 extern cvar_t *r_cubemapSize;
1962 extern cvar_t *r_pbr;
19961963 extern cvar_t *r_baseNormalX;
19971964 extern cvar_t *r_baseNormalY;
19981965 extern cvar_t *r_baseParallax;
19991966 extern cvar_t *r_baseSpecular;
20001967 extern cvar_t *r_baseGloss;
1968 extern cvar_t *r_glossType;
20011969 extern cvar_t *r_dlightMode;
20021970 extern cvar_t *r_pshadowDist;
20031971 extern cvar_t *r_mergeLightmaps;
20061974 extern cvar_t *r_imageUpsampleType;
20071975 extern cvar_t *r_genNormalMaps;
20081976 extern cvar_t *r_forceSun;
2009 extern cvar_t *r_forceSunMapLightScale;
20101977 extern cvar_t *r_forceSunLightScale;
20111978 extern cvar_t *r_forceSunAmbientScale;
20121979 extern cvar_t *r_sunlightMode;
20131980 extern cvar_t *r_drawSunRays;
20141981 extern cvar_t *r_sunShadows;
20151982 extern cvar_t *r_shadowFilter;
1983 extern cvar_t *r_shadowBlur;
20161984 extern cvar_t *r_shadowMapSize;
20171985 extern cvar_t *r_shadowCascadeZNear;
20181986 extern cvar_t *r_shadowCascadeZFar;
20772045
20782046 void R_CalcTexDirs(vec3_t sdir, vec3_t tdir, const vec3_t v1, const vec3_t v2,
20792047 const vec3_t v3, const vec2_t w1, const vec2_t w2, const vec2_t w3);
2080 void R_CalcTbnFromNormalAndTexDirs(vec3_t tangent, vec3_t bitangent, vec3_t normal, vec3_t sdir, vec3_t tdir);
2048 vec_t R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, const vec3_t normal, const vec3_t sdir, const vec3_t tdir);
20812049 qboolean R_CalcTangentVectors(srfVert_t * dv[3]);
20822050
20832051 #define CULL_IN 0 // completely unclipped
20972065 /*
20982066 ** GL wrapper/helper functions
20992067 */
2100 void GL_Bind( image_t *image );
21012068 void GL_BindToTMU( image_t *image, int tmu );
21022069 void GL_SetDefaultState( void );
2103 void GL_SelectTexture( int unit );
21042070 void GL_TextureMode( const char *string );
21052071 void GL_CheckErrs( char *file, int line );
21062072 #define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__)
21072073 void GL_State( unsigned long stateVector );
21082074 void GL_SetProjectionMatrix(mat4_t matrix);
21092075 void GL_SetModelviewMatrix(mat4_t matrix);
2110 void GL_TexEnv( int env );
21112076 void GL_Cull( int cullType );
21122077
21132078 #define GLS_SRCBLEND_ZERO 0x00000001
21692134
21702135 void R_Init( void );
21712136 image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags );
2172 image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat );
2173 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height );
2137 image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat );
2138 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height, GLenum picFormat );
21742139 qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
21752140
21762141 void R_SetColorMappings( void );
22522217 {
22532218 glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16);
22542219 vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16);
2255 uint32_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
2256 #ifdef USE_VERT_TANGENT_SPACE
2257 uint32_t tangent[SHADER_MAX_VERTEXES] QALIGN(16);
2258 #endif
2220 int16_t normal[SHADER_MAX_VERTEXES][4] QALIGN(16);
2221 int16_t tangent[SHADER_MAX_VERTEXES][4] QALIGN(16);
22592222 vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16);
2260 vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16);
2261 uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);
2223 uint16_t color[SHADER_MAX_VERTEXES][4] QALIGN(16);
2224 int16_t lightdir[SHADER_MAX_VERTEXES][4] QALIGN(16);
22622225 //int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16);
22632226
22642227 void *attribPointers[ATTR_INDEX_COUNT];
23962359
23972360 #define PATCH_STITCHING
23982361
2399 srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
2362 void R_SubdividePatchToGrid( srfBspSurface_t *grid, int width, int height,
24002363 srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] );
2401 srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror );
2402 srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror );
2403 void R_FreeSurfaceGridMesh( srfBspSurface_t *grid );
2364 void R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror );
2365 void R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror );
24042366
24052367 /*
24062368 ============================================================
24222384 ============================================================
24232385 */
24242386
2425 int R_VaoPackTangent(byte *out, vec4_t v);
2426 int R_VaoPackNormal(byte *out, vec3_t v);
2427 int R_VaoPackTexCoord(byte *out, vec2_t st);
2428 int R_VaoPackColors(byte *out, vec4_t color);
2429 void R_VaoUnpackTangent(vec4_t v, uint32_t b);
2430 void R_VaoUnpackNormal(vec3_t v, uint32_t b);
2387 void R_VaoPackTangent(int16_t *out, vec4_t v);
2388 void R_VaoPackNormal(int16_t *out, vec3_t v);
2389 void R_VaoPackColor(uint16_t *out, vec4_t c);
2390 void R_VaoUnpackTangent(vec4_t v, int16_t *pack);
2391 void R_VaoUnpackNormal(vec3_t v, int16_t *pack);
24312392
24322393 vao_t *R_CreateVao(const char *name, byte *vertexes, int vertexesSize, byte *indexes, int indexesSize, vaoUsage_t usage);
24332394 vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int numIndexes, glIndex_t *inIndexes);
24552416 void GLSL_ShutdownGPUShaders(void);
24562417 void GLSL_VertexAttribPointers(uint32_t attribBits);
24572418 void GLSL_BindProgram(shaderProgram_t * program);
2458 void GLSL_BindNullProgram(void);
24592419
24602420 void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value);
24612421 void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value);
26882648 viewParms_t viewParms;
26892649 } postProcessCommand_t;
26902650
2651 typedef struct {
2652 int commandId;
2653 } exportCubemapsCommand_t;
2654
26912655 typedef enum {
26922656 RC_END_OF_LIST,
26932657 RC_SET_COLOR,
27022666 RC_COLORMASK,
27032667 RC_CLEARDEPTH,
27042668 RC_CAPSHADOWMAP,
2705 RC_POSTPROCESS
2669 RC_POSTPROCESS,
2670 RC_EXPORT_CUBEMAPS
27062671 } renderCommand_t;
27072672
27082673
27992764 // done.
28002765 //------------------------------------------------------------------------------
28012766
2802 void R_LatLongToNormal( vec3_t outNormal, short latLong );
2803
28042767
28052768 /*
28062769 ============================================================
28142777 extern glfog_t glfogsettings[NUM_FOGS]; // [0] never used (FOG_NONE)
28152778 extern glfogType_t glfogNum; // fog type to use (from the fog_t enum list)
28162779
2817 extern qboolean fogIsOn;
2818
2819 extern void R_FogOff( void );
2820 extern void R_FogOn( void );
2821
28222780 extern void R_SetFog( int fogvar, int var1, int var2, float r, float g, float b, float density );
28232781
28242782 extern int skyboxportal;
5757 // fog stuff
5858 glfog_t glfogsettings[NUM_FOGS];
5959 glfogType_t glfogNum = FOG_NONE;
60 qboolean fogIsOn = qfalse;
61
62
63 /*
64 =================
65 R_Fog (void)
66 =================
67 */
68 void R_Fog( glfog_t *curfog ) {
69
70 if ( !r_wolffog->integer ) {
71 R_FogOff();
72 return;
73 }
74
75 if ( !curfog->registered ) { //----(SA)
76 R_FogOff();
77 return;
78 }
79
80 //----(SA) assme values of '0' for these parameters means 'use default'
81 if ( !curfog->density ) {
82 curfog->density = 1;
83 }
84 if ( !curfog->hint ) {
85 curfog->hint = GL_DONT_CARE;
86 }
87 if ( !curfog->mode ) {
88 curfog->mode = GL_LINEAR;
89 }
90 //----(SA) end
91
92 R_FogOn();
93 }
94
95 // Ridah, allow disabling fog temporarily
96 void R_FogOff( void ) {
97 if ( !fogIsOn ) {
98 return;
99 }
100 //qglDisable( GL_FOG );
101 fogIsOn = qfalse;
102 }
103
104 void R_FogOn( void ) {
105 if ( fogIsOn ) {
106 return;
107 }
108
109 if ( r_uiFullScreen->integer ) { // don't fog in the menu
110 R_FogOff();
111 return;
112 }
113
114 if ( !r_wolffog->integer ) {
115 return;
116 }
117
118 // if(backEnd.viewParms.isGLFogged) {
119 // if(!(backEnd.viewParms.glFog.registered))
120 // return;
121 // }
122
123 if ( backEnd.refdef.rdflags & RDF_SKYBOXPORTAL ) { // don't force world fog on portal sky
124 if ( !( glfogsettings[FOG_PORTALVIEW].registered ) ) {
125 return;
126 }
127 } else if ( !glfogNum ) {
128 return;
129 }
130
131 //qglEnable( GL_FOG );
132 fogIsOn = qtrue;
133 }
134 // done.
135
136
13760
13861 //----(SA)
13962 /*
237160 return qtrue;
238161 }
239162
163
240164 /*
241165 =============
242 R_CalcNormalForTriangle
166 R_CalcTexDirs
167
168 Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
243169 =============
244 */
245 void R_CalcNormalForTriangle(vec3_t normal, const vec3_t v0, const vec3_t v1, const vec3_t v2)
246 {
247 vec3_t udir, vdir;
248
249 // compute the face normal based on vertex points
250 VectorSubtract(v2, v0, udir);
251 VectorSubtract(v1, v0, vdir);
252 CrossProduct(udir, vdir, normal);
253
254 VectorNormalize(normal);
255 }
256
257 /*
258 =============
259 R_CalcTangentsForTriangle
260 http://members.rogers.com/deseric/tangentspace.htm
261 =============
262 */
263 void R_CalcTangentsForTriangle(vec3_t tangent, vec3_t bitangent,
264 const vec3_t v0, const vec3_t v1, const vec3_t v2,
265 const vec2_t t0, const vec2_t t1, const vec2_t t2)
266 {
267 int i;
268 vec3_t planes[3];
269 vec3_t u, v;
270
271 for(i = 0; i < 3; i++)
272 {
273 VectorSet(u, v1[i] - v0[i], t1[0] - t0[0], t1[1] - t0[1]);
274 VectorSet(v, v2[i] - v0[i], t2[0] - t0[0], t2[1] - t0[1]);
275
276 VectorNormalize(u);
277 VectorNormalize(v);
278
279 CrossProduct(u, v, planes[i]);
280 }
281
282 //So your tangent space will be defined by this :
283 //Normal = Normal of the triangle or Tangent X Bitangent (careful with the cross product,
284 // you have to make sure the normal points in the right direction)
285 //Tangent = ( dp(Fx(s,t)) / ds, dp(Fy(s,t)) / ds, dp(Fz(s,t)) / ds ) or ( -Bx/Ax, -By/Ay, - Bz/Az )
286 //Bitangent = ( dp(Fx(s,t)) / dt, dp(Fy(s,t)) / dt, dp(Fz(s,t)) / dt ) or ( -Cx/Ax, -Cy/Ay, -Cz/Az )
287
288 // tangent...
289 tangent[0] = -planes[0][1] / planes[0][0];
290 tangent[1] = -planes[1][1] / planes[1][0];
291 tangent[2] = -planes[2][1] / planes[2][0];
292 VectorNormalize(tangent);
293
294 // bitangent...
295 bitangent[0] = -planes[0][2] / planes[0][0];
296 bitangent[1] = -planes[1][2] / planes[1][0];
297 bitangent[2] = -planes[2][2] / planes[2][0];
298 VectorNormalize(bitangent);
299 }
300
301
302
303
304 /*
305 =============
306 R_CalcTangentSpace
307 =============
308 */
309 void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal,
310 const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2)
311 {
312 vec3_t cp, u, v;
313 vec3_t faceNormal;
314
315 VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]);
316 VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]);
317
318 CrossProduct(u, v, cp);
319 if(fabs(cp[0]) > 10e-6)
320 {
321 tangent[0] = -cp[1] / cp[0];
322 bitangent[0] = -cp[2] / cp[0];
323 }
324
325 u[0] = v1[1] - v0[1];
326 v[0] = v2[1] - v0[1];
327
328 CrossProduct(u, v, cp);
329 if(fabs(cp[0]) > 10e-6)
330 {
331 tangent[1] = -cp[1] / cp[0];
332 bitangent[1] = -cp[2] / cp[0];
333 }
334
335 u[0] = v1[2] - v0[2];
336 v[0] = v2[2] - v0[2];
337
338 CrossProduct(u, v, cp);
339 if(fabs(cp[0]) > 10e-6)
340 {
341 tangent[2] = -cp[1] / cp[0];
342 bitangent[2] = -cp[2] / cp[0];
343 }
344
345 VectorNormalize(tangent);
346 VectorNormalize(bitangent);
347
348 // compute the face normal based on vertex points
349 if ( normal[0] == 0.0f && normal[1] == 0.0f && normal[2] == 0.0f )
350 {
351 VectorSubtract(v2, v0, u);
352 VectorSubtract(v1, v0, v);
353 CrossProduct(u, v, faceNormal);
354 }
355 else
356 {
357 VectorCopy(normal, faceNormal);
358 }
359
360 VectorNormalize(faceNormal);
361
362 #if 1
363 // Gram-Schmidt orthogonalize
364 //tangent[a] = (t - n * Dot(n, t)).Normalize();
365 VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent);
366 VectorNormalize(tangent);
367
368 // compute the cross product B=NxT
369 //CrossProduct(normal, tangent, bitangent);
370 #else
371 // normal, compute the cross product N=TxB
372 CrossProduct(tangent, bitangent, normal);
373 VectorNormalize(normal);
374
375 if(DotProduct(normal, faceNormal) < 0)
376 {
377 //VectorInverse(normal);
378 //VectorInverse(tangent);
379 //VectorInverse(bitangent);
380
381 // compute the cross product T=BxN
382 CrossProduct(bitangent, faceNormal, tangent);
383
384 // compute the cross product B=NxT
385 //CrossProduct(normal, tangent, bitangent);
386 }
387 #endif
388
389 VectorCopy(faceNormal, normal);
390 }
391
392 void R_CalcTangentSpaceFast(vec3_t tangent, vec3_t bitangent, vec3_t normal,
393 const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2)
394 {
395 vec3_t cp, u, v;
396 vec3_t faceNormal;
397
398 VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]);
399 VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]);
400
401 CrossProduct(u, v, cp);
402 if(fabs(cp[0]) > 10e-6)
403 {
404 tangent[0] = -cp[1] / cp[0];
405 bitangent[0] = -cp[2] / cp[0];
406 }
407
408 u[0] = v1[1] - v0[1];
409 v[0] = v2[1] - v0[1];
410
411 CrossProduct(u, v, cp);
412 if(fabs(cp[0]) > 10e-6)
413 {
414 tangent[1] = -cp[1] / cp[0];
415 bitangent[1] = -cp[2] / cp[0];
416 }
417
418 u[0] = v1[2] - v0[2];
419 v[0] = v2[2] - v0[2];
420
421 CrossProduct(u, v, cp);
422 if(fabs(cp[0]) > 10e-6)
423 {
424 tangent[2] = -cp[1] / cp[0];
425 bitangent[2] = -cp[2] / cp[0];
426 }
427
428 VectorNormalizeFast(tangent);
429 VectorNormalizeFast(bitangent);
430
431 // compute the face normal based on vertex points
432 VectorSubtract(v2, v0, u);
433 VectorSubtract(v1, v0, v);
434 CrossProduct(u, v, faceNormal);
435
436 VectorNormalizeFast(faceNormal);
437
438 #if 0
439 // normal, compute the cross product N=TxB
440 CrossProduct(tangent, bitangent, normal);
441 VectorNormalizeFast(normal);
442
443 if(DotProduct(normal, faceNormal) < 0)
444 {
445 VectorInverse(normal);
446 //VectorInverse(tangent);
447 //VectorInverse(bitangent);
448
449 CrossProduct(normal, tangent, bitangent);
450 }
451
452 VectorCopy(faceNormal, normal);
453 #else
454 // Gram-Schmidt orthogonalize
455 //tangent[a] = (t - n * Dot(n, t)).Normalize();
456 VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent);
457 VectorNormalizeFast(tangent);
458 #endif
459
460 VectorCopy(faceNormal, normal);
461 }
462
463 /*
464 http://www.terathon.com/code/tangent.html
465170 */
466171 void R_CalcTexDirs(vec3_t sdir, vec3_t tdir, const vec3_t v1, const vec3_t v2,
467172 const vec3_t v3, const vec2_t w1, const vec2_t w2, const vec2_t w3)
481186 t1 = w2[1] - w1[1];
482187 t2 = w3[1] - w1[1];
483188
484 r = 1.0f / (s1 * t2 - s2 * t1);
189 r = s1 * t2 - s2 * t1;
190 if (r) r = 1.0f / r;
485191
486192 VectorSet(sdir, (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
487193 VectorSet(tdir, (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
488194 }
489195
490
491 void R_CalcTbnFromNormalAndTexDirs(vec3_t tangent, vec3_t bitangent, vec3_t normal, vec3_t sdir, vec3_t tdir)
196 /*
197 =============
198 R_CalcTangentSpace
199
200 Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
201 =============
202 */
203 vec_t R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, const vec3_t normal, const vec3_t sdir, const vec3_t tdir)
492204 {
493205 vec3_t n_cross_t;
494206 vec_t n_dot_t, handedness;
502214 CrossProduct(normal, sdir, n_cross_t);
503215 handedness = (DotProduct(n_cross_t, tdir) < 0.0f) ? -1.0f : 1.0f;
504216
505 // Calculate bitangent
506 CrossProduct(normal, tangent, bitangent);
507 VectorScale(bitangent, handedness, bitangent);
508 }
509
510 void R_CalcTBN2(vec3_t tangent, vec3_t bitangent, vec3_t normal,
511 const vec3_t v1, const vec3_t v2, const vec3_t v3, const vec2_t t1, const vec2_t t2, const vec2_t t3)
512 {
513 vec3_t v2v1;
514 vec3_t v3v1;
515
516 float c2c1_T;
517 float c2c1_B;
518
519 float c3c1_T;
520 float c3c1_B;
521
522 float denominator;
523 float scale1, scale2;
524
525 vec3_t T, B, N, C;
526
527
528 // Calculate the tangent basis for each vertex of the triangle
529 // UPDATE: In the 3rd edition of the accompanying article, the for-loop located here has
530 // been removed as it was redundant (the entire TBN matrix was calculated three times
531 // instead of just one).
532 //
533 // Please note, that this function relies on the fact that the input geometry are triangles
534 // and the tangent basis for each vertex thus is identical!
535 //
536
537 // Calculate the vectors from the current vertex to the two other vertices in the triangle
538 VectorSubtract(v2, v1, v2v1);
539 VectorSubtract(v3, v1, v3v1);
540
541 // The equation presented in the article states that:
542 // c2c1_T = V2.texcoord.x - V1.texcoord.x
543 // c2c1_B = V2.texcoord.y - V1.texcoord.y
544 // c3c1_T = V3.texcoord.x - V1.texcoord.x
545 // c3c1_B = V3.texcoord.y - V1.texcoord.y
546
547 // Calculate c2c1_T and c2c1_B
548 c2c1_T = t2[0] - t1[0];
549 c2c1_B = t2[1] - t2[1];
550
551 // Calculate c3c1_T and c3c1_B
552 c3c1_T = t3[0] - t1[0];
553 c3c1_B = t3[1] - t1[1];
554
555 denominator = c2c1_T * c3c1_B - c3c1_T * c2c1_B;
556 //if(ROUNDOFF(fDenominator) == 0.0f)
557 if(denominator == 0.0f)
558 {
559 // We won't risk a divide by zero, so set the tangent matrix to the identity matrix
560 VectorSet(tangent, 1, 0, 0);
561 VectorSet(bitangent, 0, 1, 0);
562 VectorSet(normal, 0, 0, 1);
563 }
564 else
565 {
566 // Calculate the reciprocal value once and for all (to achieve speed)
567 scale1 = 1.0f / denominator;
568
569 // T and B are calculated just as the equation in the article states
570 VectorSet(T, (c3c1_B * v2v1[0] - c2c1_B * v3v1[0]) * scale1,
571 (c3c1_B * v2v1[1] - c2c1_B * v3v1[1]) * scale1,
572 (c3c1_B * v2v1[2] - c2c1_B * v3v1[2]) * scale1);
573
574 VectorSet(B, (-c3c1_T * v2v1[0] + c2c1_T * v3v1[0]) * scale1,
575 (-c3c1_T * v2v1[1] + c2c1_T * v3v1[1]) * scale1,
576 (-c3c1_T * v2v1[2] + c2c1_T * v3v1[2]) * scale1);
577
578 // The normal N is calculated as the cross product between T and B
579 CrossProduct(T, B, N);
580
581 #if 0
582 VectorCopy(T, tangent);
583 VectorCopy(B, bitangent);
584 VectorCopy(N, normal);
585 #else
586 // Calculate the reciprocal value once and for all (to achieve speed)
587 scale2 = 1.0f / ((T[0] * B[1] * N[2] - T[2] * B[1] * N[0]) +
588 (B[0] * N[1] * T[2] - B[2] * N[1] * T[0]) +
589 (N[0] * T[1] * B[2] - N[2] * T[1] * B[0]));
590
591 // Calculate the inverse if the TBN matrix using the formula described in the article.
592 // We store the basis vectors directly in the provided TBN matrix: pvTBNMatrix
593 CrossProduct(B, N, C); tangent[0] = C[0] * scale2;
594 CrossProduct(N, T, C); tangent[1] = -C[0] * scale2;
595 CrossProduct(T, B, C); tangent[2] = C[0] * scale2;
596 VectorNormalize(tangent);
597
598 CrossProduct(B, N, C); bitangent[0] = -C[1] * scale2;
599 CrossProduct(N, T, C); bitangent[1] = C[1] * scale2;
600 CrossProduct(T, B, C); bitangent[2] = -C[1] * scale2;
601 VectorNormalize(bitangent);
602
603 CrossProduct(B, N, C); normal[0] = C[2] * scale2;
604 CrossProduct(N, T, C); normal[1] = -C[2] * scale2;
605 CrossProduct(T, B, C); normal[2] = C[2] * scale2;
606 VectorNormalize(normal);
607 #endif
608 }
609 }
610
611
612 #ifdef USE_VERT_TANGENT_SPACE
217 // Calculate orthogonal bitangent, if necessary
218 if (bitangent)
219 CrossProduct(normal, tangent, bitangent);
220
221 return handedness;
222 }
223
224
613225 qboolean R_CalcTangentVectors(srfVert_t * dv[3])
614226 {
615227 int i;
625237 /* do each vertex */
626238 for(i = 0; i < 3; i++)
627239 {
628 vec3_t bitangent, nxt;
240 vec4_t tangent;
241 vec3_t normal, bitangent, nxt;
629242
630243 // calculate s tangent vector
631244 s = dv[i]->st[0] + 10.0f;
634247 bary[1] = ((dv[2]->st[0] - s) * (dv[0]->st[1] - t) - (dv[0]->st[0] - s) * (dv[2]->st[1] - t)) / bb;
635248 bary[2] = ((dv[0]->st[0] - s) * (dv[1]->st[1] - t) - (dv[1]->st[0] - s) * (dv[0]->st[1] - t)) / bb;
636249
637 dv[i]->tangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
638 dv[i]->tangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
639 dv[i]->tangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
640
641 VectorSubtract(dv[i]->tangent, dv[i]->xyz, dv[i]->tangent);
642 VectorNormalize(dv[i]->tangent);
250 tangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
251 tangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
252 tangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
253
254 VectorSubtract(tangent, dv[i]->xyz, tangent);
255 VectorNormalize(tangent);
643256
644257 // calculate t tangent vector
645258 s = dv[i]->st[0];
656269 VectorNormalize(bitangent);
657270
658271 // store bitangent handedness
659 CrossProduct(dv[i]->normal, dv[i]->tangent, nxt);
660 dv[i]->tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f;
272 R_VaoUnpackNormal(normal, dv[i]->normal);
273 CrossProduct(normal, tangent, nxt);
274 tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f;
275
276 R_VaoPackTangent(dv[i]->tangent, tangent);
661277
662278 // debug code
663279 //% Sys_FPrintf( SYS_VRB, "%d S: (%f %f %f) T: (%f %f %f)\n", i,
666282
667283 return qtrue;
668284 }
669 #endif
670285
671286 /*
672287 =================
22941909 return;
22951910 }
22961911
2297 R_FogOff(); // moved this in here to keep from /always/ doing the fog state change
2298
22991912 R_IssuePendingRenderCommands();
23001913
2301 GL_Bind( tr.whiteImage );
1914 GL_BindToTMU(tr.whiteImage, TB_COLORMAP);
23021915 GL_Cull( CT_FRONT_SIDED );
23031916 ri.CM_DrawDebugSurface( R_DebugPolygon );
23041917 }
23481961 R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, numDrawSurfs - firstDrawSurf );
23491962
23501963 // draw main system development information (surface outlines, etc)
2351 R_FogOff();
23521964 R_DebugGraphics();
2353 R_FogOn();
2354
23551965 }
23561966
23571967
31372747 {
31382748 refdef_t refdef;
31392749 viewParms_t parms;
3140 float oldColorScale = tr.refdef.colorScale;
31412750
31422751 memset( &refdef, 0, sizeof( refdef ) );
31432752 refdef.rdflags = 0;
32102819
32112820 {
32122821 vec3_t ambient, directed, lightDir;
2822 float scale;
2823
32132824 R_LightForPoint(tr.refdef.vieworg, ambient, directed, lightDir);
3214 tr.refdef.colorScale = 1.0f; //766.0f / (directed[0] + directed[1] + directed[2] + 1.0f);
2825 scale = directed[0] + directed[1] + directed[2] + ambient[0] + ambient[1] + ambient[2] + 1.0f;
2826
32152827 // only print message for first side
3216 if (directed[0] + directed[1] + directed[2] == 0 && cubemapSide == 0)
3217 {
3218 ri.Printf(PRINT_ALL, "cubemap %d (%f, %f, %f) is outside the lightgrid!\n", cubemapIndex, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]);
2828 if (scale < 1.0001f && cubemapSide == 0)
2829 {
2830 ri.Printf(PRINT_ALL, "cubemap %d %s (%f, %f, %f) is outside the lightgrid or inside a wall!\n", cubemapIndex, tr.cubemaps[cubemapIndex].name, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]);
32192831 }
32202832 }
32212833
32522864
32532865 R_RenderView(&parms);
32542866
3255 if (subscene)
3256 {
3257 tr.refdef.colorScale = oldColorScale;
3258 }
3259 else
3260 {
2867 if (!subscene)
32612868 RE_EndScene();
3262 }
3263 }
3264
2869 }
2870
372372 // The offset is added in the vertex normal vector direction
373373 // so all triangles will still fit together.
374374 // The 2 unit offset should avoid pretty much all LOD problems.
375 vec3_t fNormal;
375376
376377 numClipPoints = 3;
377378
378379 dv = cv->verts + m * cv->width + n;
379380
380381 VectorCopy( dv[0].xyz, clipPoints[0][0] );
381 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0] );
382 R_VaoUnpackNormal(fNormal, dv[0].normal);
383 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
382384 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
383 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
385 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
386 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
384387 VectorCopy( dv[1].xyz, clipPoints[0][2] );
385 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2] );
388 R_VaoUnpackNormal(fNormal, dv[1].normal);
389 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
386390 // check the normal of this triangle
387391 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
388392 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
402406 }
403407
404408 VectorCopy( dv[1].xyz, clipPoints[0][0] );
405 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0] );
409 R_VaoUnpackNormal(fNormal, dv[1].normal);
410 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
406411 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
407 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
412 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
413 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
408414 VectorCopy( dv[cv->width + 1].xyz, clipPoints[0][2] );
409 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[cv->width + 1].normal, clipPoints[0][2] );
415 R_VaoUnpackNormal(fNormal, dv[cv->width + 1].normal);
416 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
410417 // check the normal of this triangle
411418 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
412419 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
462469 {
463470 for(j = 0; j < 3; j++)
464471 {
472 vec3_t fNormal;
465473 v = surf->verts[tri[j]].xyz;
466 VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]);
474 R_VaoUnpackNormal(fNormal, surf->verts[tri[j]].normal);
475 VectorMA(v, MARKER_OFFSET, fNormal, clipPoints[0][j]);
467476 }
468477
469478 // add the fragments of this face
632641 // The offset is added in the vertex normal vector direction
633642 // so all triangles will still fit together.
634643 // The 2 unit offset should avoid pretty much all LOD problems.
644 vec3_t fNormal;
635645
636646 numClipPoints = 3;
637647
638648 dv = cv->verts + m * cv->width + n;
639649
640650 VectorCopy( dv[0].xyz, clipPoints[0][0] );
641 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0] );
651 R_VaoUnpackNormal(fNormal, dv[0].normal);
652 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
642653 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
643 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
654 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
655 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
644656 VectorCopy( dv[1].xyz, clipPoints[0][2] );
645 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2] );
657 R_VaoUnpackNormal(fNormal, dv[1].normal);
658 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
646659 // check the normal of this triangle
647660 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
648661 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
662675 }
663676
664677 VectorCopy( dv[1].xyz, clipPoints[0][0] );
665 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0] );
678 R_VaoUnpackNormal(fNormal, dv[1].normal);
679 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
666680 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
667 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
681 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
682 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
668683 VectorCopy( dv[cv->width + 1].xyz, clipPoints[0][2] );
669 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[cv->width + 1].normal, clipPoints[0][2] );
684 R_VaoUnpackNormal(fNormal, dv[cv->width + 1].normal);
685 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
670686 // check the normal of this triangle
671687 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
672688 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
830846 {
831847 for(j = 0; j < 3; j++)
832848 {
849 vec3_t fNormal;
833850 v = surf->verts[tri[j]].xyz;
834 VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]);
851 R_VaoUnpackNormal(fNormal, surf->verts[tri[j]].normal);
852 VectorMA(v, MARKER_OFFSET, fNormal, clipPoints[0][j]);
835853 }
836854
837855 // add the fragments of this face
821821 {
822822 unsigned lat, lng;
823823 unsigned short normal;
824 vec3_t fNormal;
824825
825826 v->xyz[0] = md3xyz->xyz[0] * MD3_XYZ_SCALE;
826827 v->xyz[1] = md3xyz->xyz[1] * MD3_XYZ_SCALE;
833834 lat *= (FUNCTABLE_SIZE/256);
834835 lng *= (FUNCTABLE_SIZE/256);
835836
836 v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
837 v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
838 v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
837 // decode X as cos( lat ) * sin( long )
838 // decode Y as sin( lat ) * sin( long )
839 // decode Z as cos( long )
840
841 fNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
842 fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
843 fNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
844
845 R_VaoPackNormal(v->normal, fNormal);
839846 }
840847 }
841848
854861 for(k = 0; k < mdcSurf->numVerts; k++, mdcxyzComp++, v++)
855862 {
856863 vec3_t ofsVec;
857 R_MDC_DecodeXyzCompressed( mdcxyzComp->ofsVec, ofsVec, v->normal );
864 vec3_t fNormal;
865
866 R_MDC_DecodeXyzCompressed(mdcxyzComp->ofsVec, ofsVec, fNormal);
858867 VectorAdd( v->xyz, ofsVec, v->xyz );
859868
869 R_VaoPackNormal(v->normal, fNormal);
860870 }
861871 }
862872 }
863873
864 #ifdef USE_VERT_TANGENT_SPACE
865874 // calc tangent spaces
866875 {
876 vec3_t *sdirs = ri.Z_Malloc(sizeof(*sdirs) * surf->numVerts * mdvModel->numFrames);
877 vec3_t *tdirs = ri.Z_Malloc(sizeof(*tdirs) * surf->numVerts * mdvModel->numFrames);
878
867879 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
868880 {
869 VectorClear(v->tangent);
870 VectorClear(v->bitangent);
881 VectorClear(sdirs[j]);
882 VectorClear(tdirs[j]);
871883 }
872884
873885 for(f = 0; f < mdvModel->numFrames; f++)
892904
893905 R_CalcTexDirs(sdir, tdir, v0, v1, v2, t0, t1, t2);
894906
895 VectorAdd(sdir, surf->verts[index0].tangent, surf->verts[index0].tangent);
896 VectorAdd(sdir, surf->verts[index1].tangent, surf->verts[index1].tangent);
897 VectorAdd(sdir, surf->verts[index2].tangent, surf->verts[index2].tangent);
898 VectorAdd(tdir, surf->verts[index0].bitangent, surf->verts[index0].bitangent);
899 VectorAdd(tdir, surf->verts[index1].bitangent, surf->verts[index1].bitangent);
900 VectorAdd(tdir, surf->verts[index2].bitangent, surf->verts[index2].bitangent);
907 VectorAdd(sdir, sdirs[index0], sdirs[index0]);
908 VectorAdd(sdir, sdirs[index1], sdirs[index1]);
909 VectorAdd(sdir, sdirs[index2], sdirs[index2]);
910 VectorAdd(tdir, tdirs[index0], tdirs[index0]);
911 VectorAdd(tdir, tdirs[index1], tdirs[index1]);
912 VectorAdd(tdir, tdirs[index2], tdirs[index2]);
901913 }
902914 }
903915
904916 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
905917 {
906 vec3_t sdir, tdir;
907
908 VectorCopy(v->tangent, sdir);
909 VectorCopy(v->bitangent, tdir);
910
911 VectorNormalize(sdir);
912 VectorNormalize(tdir);
913
914 R_CalcTbnFromNormalAndTexDirs(v->tangent, v->bitangent, v->normal, sdir, tdir);
915 }
916 }
917 #endif
918 vec3_t normal;
919 vec4_t tangent;
920
921 VectorNormalize(sdirs[j]);
922 VectorNormalize(tdirs[j]);
923
924 R_VaoUnpackNormal(normal, v->normal);
925
926 tangent[3] = R_CalcTangentSpace(tangent, NULL, normal, sdirs[j], tdirs[j]);
927
928 R_VaoPackTangent(v->tangent, tangent);
929 }
930
931 ri.Free(sdirs);
932 ri.Free(tdirs);
933 }
918934
919935 // find the next surface
920936 mdcSurf = (mdcSurface_t *) ((byte *) mdcSurf + mdcSurf->ofsEnd);
940956 {
941957 // vertex animation, store texcoords first, then position/normal/tangents
942958 offset_st = 0;
943 offset_xyz = surf->numVerts * glRefConfig.packedTexcoordDataSize;
959 offset_xyz = surf->numVerts * sizeof(vec2_t);
944960 offset_normal = offset_xyz + sizeof(vec3_t);
945 offset_tangent = offset_normal + sizeof(uint32_t);
946 stride_st = glRefConfig.packedTexcoordDataSize;
947 stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
948 #ifdef USE_VERT_TANGENT_SPACE
949 stride_xyz += sizeof(uint32_t);
950 #endif
961 offset_tangent = offset_normal + sizeof(int16_t) * 4;
962 stride_st = sizeof(vec2_t);
963 stride_xyz = sizeof(vec3_t) + sizeof(int16_t) * 4;
964 stride_xyz += sizeof(int16_t) * 4;
951965 stride_normal = stride_tangent = stride_xyz;
952966
953967 dataSize = offset_xyz + surf->numVerts * mdvModel->numFrames * stride_xyz;
957971 // no animation, interleave everything
958972 offset_xyz = 0;
959973 offset_st = offset_xyz + sizeof(vec3_t);
960 offset_normal = offset_st + glRefConfig.packedTexcoordDataSize;
961 offset_tangent = offset_normal + sizeof(uint32_t);
962 #ifdef USE_VERT_TANGENT_SPACE
963 stride_xyz = offset_tangent + sizeof(uint32_t);
964 #else
965 stride_xyz = offset_normal + sizeof(uint32_t);
966 #endif
974 offset_normal = offset_st + sizeof(vec2_t);
975 offset_tangent = offset_normal + sizeof(int16_t) * 4;
976 stride_xyz = offset_tangent + sizeof(int16_t) * 4;
967977 stride_st = stride_normal = stride_tangent = stride_xyz;
968978
969979 dataSize = surf->numVerts * stride_xyz;
977987 {
978988 st = surf->st;
979989 for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
980 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
990 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
991 dataOfs += sizeof(st->st);
981992 }
982993
983994 v = surf->verts;
984995 for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ )
985996 {
986 #ifdef USE_VERT_TANGENT_SPACE
987 vec3_t nxt;
988 vec4_t tangent;
989 #endif
990997 // xyz
991998 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
992999 dataOfs += sizeof(vec3_t);
9931000
9941001 // normal
995 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
996
997 #ifdef USE_VERT_TANGENT_SPACE
998 CrossProduct(v->normal, v->tangent, nxt);
999 VectorCopy(v->tangent, tangent);
1000 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1002 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1003 dataOfs += sizeof(int16_t) * 4;
10011004
10021005 // tangent
1003 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1004 #endif
1006 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1007 dataOfs += sizeof(int16_t) * 4;
10051008 }
10061009 }
10071010 else
10101013 st = surf->st;
10111014 for ( j = 0; j < surf->numVerts; j++, v++, st++ )
10121015 {
1013 #ifdef USE_VERT_TANGENT_SPACE
1014 vec3_t nxt;
1015 vec4_t tangent;
1016 #endif
10171016 // xyz
10181017 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
10191018 dataOfs += sizeof(v->xyz);
10201019
10211020 // st
1022 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
1021 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
1022 dataOfs += sizeof(st->st);
10231023
10241024 // normal
1025 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
1026
1027 #ifdef USE_VERT_TANGENT_SPACE
1028 CrossProduct(v->normal, v->tangent, nxt);
1029 VectorCopy(v->tangent, tangent);
1030 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1025 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1026 dataOfs += sizeof(int16_t) * 4;
10311027
10321028 // tangent
1033 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1034 #endif
1029 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1030 dataOfs += sizeof(int16_t) * 4;
10351031 }
10361032 }
10371033
10491045 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
10501046 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
10511047 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
1052 #ifdef USE_VERT_TANGENT_SPACE
10531048 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
1054 #endif
10551049 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
10561050 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
10571051 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].count = 4;
10581052 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
10591053
10601054 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = GL_FLOAT;
1061 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = glRefConfig.packedTexcoordDataType;
1062 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
1063 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
1055 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = GL_FLOAT;
1056 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
1057 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
10641058
10651059 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = GL_FALSE;
10661060 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = GL_FALSE;
13261320 {
13271321 unsigned lat, lng;
13281322 unsigned short normal;
1323 vec3_t fNormal;
13291324
13301325 v->xyz[0] = LittleShort(md3xyz->xyz[0]) * MD3_XYZ_SCALE;
13311326 v->xyz[1] = LittleShort(md3xyz->xyz[1]) * MD3_XYZ_SCALE;
13381333 lat *= (FUNCTABLE_SIZE/256);
13391334 lng *= (FUNCTABLE_SIZE/256);
13401335
1341
1342
1343 v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1344 v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1345 v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1336 // decode X as cos( lat ) * sin( long )
1337 // decode Y as sin( lat ) * sin( long )
1338 // decode Z as cos( long )
1339
1340 fNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1341 fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1342 fNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1343
1344 R_VaoPackNormal(v->normal, fNormal);
13461345 }
13471346
13481347 // swap all the ST
13551354 st->st[1] = LittleFloat(md3st->st[1]);
13561355 }
13571356
1358 #ifdef USE_VERT_TANGENT_SPACE
13591357 // calc tangent spaces
13601358 {
1359 vec3_t *sdirs = ri.Z_Malloc(sizeof(*sdirs) * surf->numVerts * mdvModel->numFrames);
1360 vec3_t *tdirs = ri.Z_Malloc(sizeof(*tdirs) * surf->numVerts * mdvModel->numFrames);
1361
13611362 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
13621363 {
1363 VectorClear(v->tangent);
1364 VectorClear(v->bitangent);
1364 VectorClear(sdirs[j]);
1365 VectorClear(tdirs[j]);
13651366 }
13661367
13671368 for(f = 0; f < mdvModel->numFrames; f++)
13861387
13871388 R_CalcTexDirs(sdir, tdir, v0, v1, v2, t0, t1, t2);
13881389
1389 VectorAdd(sdir, surf->verts[index0].tangent, surf->verts[index0].tangent);
1390 VectorAdd(sdir, surf->verts[index1].tangent, surf->verts[index1].tangent);
1391 VectorAdd(sdir, surf->verts[index2].tangent, surf->verts[index2].tangent);
1392 VectorAdd(tdir, surf->verts[index0].bitangent, surf->verts[index0].bitangent);
1393 VectorAdd(tdir, surf->verts[index1].bitangent, surf->verts[index1].bitangent);
1394 VectorAdd(tdir, surf->verts[index2].bitangent, surf->verts[index2].bitangent);
1390 VectorAdd(sdir, sdirs[index0], sdirs[index0]);
1391 VectorAdd(sdir, sdirs[index1], sdirs[index1]);
1392 VectorAdd(sdir, sdirs[index2], sdirs[index2]);
1393 VectorAdd(tdir, tdirs[index0], tdirs[index0]);
1394 VectorAdd(tdir, tdirs[index1], tdirs[index1]);
1395 VectorAdd(tdir, tdirs[index2], tdirs[index2]);
13951396 }
13961397 }
13971398
13981399 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
13991400 {
1400 vec3_t sdir, tdir;
1401
1402 VectorCopy(v->tangent, sdir);
1403 VectorCopy(v->bitangent, tdir);
1404
1405 VectorNormalize(sdir);
1406 VectorNormalize(tdir);
1407
1408 R_CalcTbnFromNormalAndTexDirs(v->tangent, v->bitangent, v->normal, sdir, tdir);
1409 }
1410 }
1411 #endif
1401 vec3_t normal;
1402 vec4_t tangent;
1403
1404 VectorNormalize(sdirs[j]);
1405 VectorNormalize(tdirs[j]);
1406
1407 R_VaoUnpackNormal(normal, v->normal);
1408
1409 tangent[3] = R_CalcTangentSpace(tangent, NULL, normal, sdirs[j], tdirs[j]);
1410
1411 R_VaoPackTangent(v->tangent, tangent);
1412 }
1413
1414 ri.Free(sdirs);
1415 ri.Free(tdirs);
1416 }
14121417
14131418 // find the next surface
14141419 md3Surf = (md3Surface_t *) ((byte *) md3Surf + md3Surf->ofsEnd);
14341439 {
14351440 // vertex animation, store texcoords first, then position/normal/tangents
14361441 offset_st = 0;
1437 offset_xyz = surf->numVerts * glRefConfig.packedTexcoordDataSize;
1442 offset_xyz = surf->numVerts * sizeof(vec2_t);
14381443 offset_normal = offset_xyz + sizeof(vec3_t);
1439 offset_tangent = offset_normal + sizeof(uint32_t);
1440 stride_st = glRefConfig.packedTexcoordDataSize;
1441 stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
1442 #ifdef USE_VERT_TANGENT_SPACE
1443 stride_xyz += sizeof(uint32_t);
1444 #endif
1444 offset_tangent = offset_normal + sizeof(int16_t) * 4;
1445 stride_st = sizeof(vec2_t);
1446 stride_xyz = sizeof(vec3_t) + sizeof(int16_t) * 4;
1447 stride_xyz += sizeof(int16_t) * 4;
14451448 stride_normal = stride_tangent = stride_xyz;
14461449
14471450 dataSize = offset_xyz + surf->numVerts * mdvModel->numFrames * stride_xyz;
14511454 // no animation, interleave everything
14521455 offset_xyz = 0;
14531456 offset_st = offset_xyz + sizeof(vec3_t);
1454 offset_normal = offset_st + glRefConfig.packedTexcoordDataSize;
1455 offset_tangent = offset_normal + sizeof(uint32_t);
1456 #ifdef USE_VERT_TANGENT_SPACE
1457 stride_xyz = offset_tangent + sizeof(uint32_t);
1458 #else
1459 stride_xyz = offset_normal + sizeof(uint32_t);
1460 #endif
1457 offset_normal = offset_st + sizeof(vec2_t);
1458 offset_tangent = offset_normal + sizeof(int16_t) * 4;
1459 stride_xyz = offset_tangent + sizeof(int16_t) * 4;
14611460 stride_st = stride_normal = stride_tangent = stride_xyz;
14621461
14631462 dataSize = surf->numVerts * stride_xyz;
14711470 {
14721471 st = surf->st;
14731472 for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
1474 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
1473 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
1474 dataOfs += sizeof(st->st);
14751475 }
14761476
14771477 v = surf->verts;
14781478 for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ )
14791479 {
1480 #ifdef USE_VERT_TANGENT_SPACE
1481 vec3_t nxt;
1482 vec4_t tangent;
1483 #endif
14841480 // xyz
14851481 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
14861482 dataOfs += sizeof(vec3_t);
14871483
14881484 // normal
1489 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
1490
1491 #ifdef USE_VERT_TANGENT_SPACE
1492 CrossProduct(v->normal, v->tangent, nxt);
1493 VectorCopy(v->tangent, tangent);
1494 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1485 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1486 dataOfs += sizeof(int16_t) * 4;
14951487
14961488 // tangent
1497 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1498 #endif
1489 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1490 dataOfs += sizeof(int16_t) * 4;
14991491 }
15001492 }
15011493 else
15041496 st = surf->st;
15051497 for ( j = 0; j < surf->numVerts; j++, v++, st++ )
15061498 {
1507 #ifdef USE_VERT_TANGENT_SPACE
1508 vec3_t nxt;
1509 vec4_t tangent;
1510 #endif
15111499 // xyz
15121500 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
15131501 dataOfs += sizeof(v->xyz);
15141502
15151503 // st
1516 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
1504 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
1505 dataOfs += sizeof(st->st);
15171506
15181507 // normal
1519 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
1520
1521 #ifdef USE_VERT_TANGENT_SPACE
1522 CrossProduct(v->normal, v->tangent, nxt);
1523 VectorCopy(v->tangent, tangent);
1524 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1508 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1509 dataOfs += sizeof(int16_t) * 4;
15251510
15261511 // tangent
1527 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1528 #endif
1512 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1513 dataOfs += sizeof(int16_t) * 4;
15291514 }
15301515 }
15311516
15431528 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
15441529 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
15451530 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
1546 #ifdef USE_VERT_TANGENT_SPACE
15471531 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
1548 #endif
15491532 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
15501533 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
15511534 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].count = 4;
15521535 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
15531536
15541537 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = GL_FLOAT;
1555 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = glRefConfig.packedTexcoordDataType;
1556 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
1557 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
1538 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = GL_FLOAT;
1539 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
1540 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
15581541
15591542 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = GL_FALSE;
15601543 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = GL_FALSE;
20352018 LL( surf->ofsBoneReferences );
20362019 LL( surf->ofsEnd );
20372020
2021 // change to surface identifier
2022 surf->ident = SF_MDS;
2023
20382024 if ( surf->numVerts >= SHADER_MAX_VERTEXES ) {
20392025 ri.Printf(PRINT_WARNING, "R_LoadMDS: %s has more than %i verts on %s (%i).\n",
20402026 mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
10231023 int i;
10241024
10251025 vec4_t *outXYZ;
1026 uint32_t *outNormal;
1027 #ifdef USE_VERT_TANGENT_SPACE
1028 uint32_t *outTangent;
1029 #endif
1026 int16_t *outNormal;
1027 int16_t *outTangent;
10301028 vec2_t (*outTexCoord)[2];
1031 vec4_t *outColor;
1029 uint16_t *outColor;
10321030
10331031 int frame = data->num_frames ? backEnd.currentEntity->e.frame % data->num_frames : 0;
10341032 int oldframe = data->num_frames ? backEnd.currentEntity->e.oldframe % data->num_frames : 0;
10411039 RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
10421040
10431041 outXYZ = &tess.xyz[tess.numVertexes];
1044 outNormal = &tess.normal[tess.numVertexes];
1045 #ifdef USE_VERT_TANGENT_SPACE
1046 outTangent = &tess.tangent[tess.numVertexes];
1047 #endif
1042 outNormal = tess.normal[tess.numVertexes];
1043 outTangent = tess.tangent[tess.numVertexes];
10481044 outTexCoord = &tess.texCoords[tess.numVertexes];
1049 outColor = &tess.vertexColors[tess.numVertexes];
1045 outColor = tess.color[tess.numVertexes];
10501046
10511047 // compute interpolated joint matrices
10521048 if ( data->num_poses > 0 ) {
10551051
10561052 // transform vertexes and fill other data
10571053 for( i = 0; i < surf->num_vertexes;
1058 i++, outXYZ++, outNormal++, outTexCoord++, outColor++ ) {
1054 i++, outXYZ++, outNormal+=4, outTexCoord++, outColor+=4 ) {
10591055 int j, k;
10601056 float vtxMat[12];
10611057 float nrmMat[9];
11291125 normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]);
11301126 normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]);
11311127
1132 R_VaoPackNormal((byte *)outNormal, normal);
1133
1134 #ifdef USE_VERT_TANGENT_SPACE
1128 R_VaoPackNormal(outNormal, normal);
1129
11351130 tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]);
11361131 tangent[1] = DotProduct(&nrmMat[3], &data->tangents[4*vtx]);
11371132 tangent[2] = DotProduct(&nrmMat[6], &data->tangents[4*vtx]);
11381133 tangent[3] = data->tangents[4*vtx+3];
11391134
1140 R_VaoPackTangent((byte *)outTangent++, tangent);
1141 #endif
1142 }
1143
1144 (*outColor)[0] = data->colors[4*vtx+0] / 255.0f;
1145 (*outColor)[1] = data->colors[4*vtx+1] / 255.0f;
1146 (*outColor)[2] = data->colors[4*vtx+2] / 255.0f;
1147 (*outColor)[3] = data->colors[4*vtx+3] / 255.0f;
1135 R_VaoPackTangent(outTangent, tangent);
1136 outTangent+=4;
1137 }
1138
1139 outColor[0] = data->colors[4*vtx+0] * 257;
1140 outColor[1] = data->colors[4*vtx+1] * 257;
1141 outColor[2] = data->colors[4*vtx+2] * 257;
1142 outColor[3] = data->colors[4*vtx+3] * 257;
11481143 }
11491144
11501145 tri = data->triangles + 3 * surf->first_triangle;
182182 FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, 0);
183183 }
184184
185 FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, &tr.textureColorShader, NULL, 0);
185 FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0);
186186 }
187187 #else // higher quality blur, but slower
188188 else if (blur > 1.0f)
216216 FBO_Blit(tr.quarterFbo[0], NULL, blurTexScale, tr.quarterFbo[1], NULL, &tr.bokehShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
217217 }
218218
219 FBO_Blit(tr.quarterFbo[1], NULL, NULL, dst, dstBox, &tr.textureColorShader, NULL, 0);
219 FBO_Blit(tr.quarterFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0);
220220 }
221221 #endif
222222 }
226226 static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretch, float x, float y, float w, float h, float xcenter, float ycenter, float alpha)
227227 {
228228 ivec4_t srcBox, dstBox;
229 int srcWidth, srcHeight;
229230 vec4_t color;
230231 const float inc = 1.f / passes;
231232 const float mul = powf(stretch, inc);
232233 float scale;
233234
234 {
235 vec2_t texScale;
236
237 texScale[0] =
238 texScale[1] = 1.0f;
239
240 alpha *= inc;
241 VectorSet4(color, alpha, alpha, alpha, 1.0f);
242
243 VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height);
244 VectorSet4(dstBox, x, y, w, h);
245 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0);
246
235 alpha *= inc;
236 VectorSet4(color, alpha, alpha, alpha, 1.0f);
237
238 srcWidth = srcFbo ? srcFbo->width : glConfig.vidWidth;
239 srcHeight = srcFbo ? srcFbo->height : glConfig.vidHeight;
240
241 VectorSet4(srcBox, 0, 0, srcWidth, srcHeight);
242
243 VectorSet4(dstBox, x, y, w, h);
244 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0);
245
246 --passes;
247 scale = mul;
248 while (passes > 0)
249 {
250 float iscale = 1.f / scale;
251 float s0 = xcenter * (1.f - iscale);
252 float t0 = (1.0f - ycenter) * (1.f - iscale);
253
254 srcBox[0] = s0 * srcWidth;
255 srcBox[1] = t0 * srcHeight;
256 srcBox[2] = iscale * srcWidth;
257 srcBox[3] = iscale * srcHeight;
258
259 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
260
261 scale *= mul;
247262 --passes;
248 scale = mul;
249 while (passes > 0)
250 {
251 float iscale = 1.f / scale;
252 float s0 = xcenter * (1.f - iscale);
253 float t0 = (1.0f - ycenter) * (1.f - iscale);
254 float s1 = iscale + s0;
255 float t1 = iscale + t0;
256
257 if (srcFbo)
258 {
259 srcBox[0] = s0 * srcFbo->width;
260 srcBox[1] = t0 * srcFbo->height;
261 srcBox[2] = (s1 - s0) * srcFbo->width;
262 srcBox[3] = (t1 - t0) * srcFbo->height;
263 }
264 else
265 {
266 srcBox[0] = s0 * glConfig.vidWidth;
267 srcBox[1] = t0 * glConfig.vidHeight;
268 srcBox[2] = (s1 - s0) * glConfig.vidWidth;
269 srcBox[3] = (t1 - t0) * glConfig.vidHeight;
270 }
271
272 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
273
274 scale *= mul;
275 --passes;
276 }
277263 }
278264 }
279265
295281 for (iter=0 ; ; ++iter)
296282 {
297283 GLint available = 0;
298 qglGetQueryObjectivARB(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
284 qglGetQueryObjectiv(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_AVAILABLE, &available);
299285 if (available)
300286 break;
301287 }
303289 ri.Printf(PRINT_DEVELOPER, "Waited %d iterations\n", iter);
304290 }
305291
306 qglGetQueryObjectuivARB(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_ARB, &sampleCount);
292 qglGetQueryObjectuiv(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT, &sampleCount);
307293 return sampleCount > 0;
308294 }
309295
328314 // From RB_DrawSun()
329315 {
330316 float dist;
331 mat4_t trans, model, mvp;
317 mat4_t trans, model;
332318
333319 Mat4Translation( backEnd.viewParms.or.origin, trans );
334320 Mat4Multiply( backEnd.viewParms.world.modelMatrix, trans, model );
352338 // initialize quarter buffers
353339 {
354340 float mul = 1.f;
355 vec2_t texScale;
356341 ivec4_t rayBox, quarterBox;
357
358 texScale[0] =
359 texScale[1] = 1.0f;
342 int srcWidth = srcFbo ? srcFbo->width : glConfig.vidWidth;
343 int srcHeight = srcFbo ? srcFbo->height : glConfig.vidHeight;
360344
361345 VectorSet4(color, mul, mul, mul, 1);
362346
363 if (srcFbo)
364 {
365 rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcFbo->width;
366 rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcFbo->height;
367 rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcFbo->width;
368 rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcFbo->height;
369 }
370 else
371 {
372 rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / glConfig.vidWidth;
373 rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / glConfig.vidHeight;
374 rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / glConfig.vidWidth;
375 rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / glConfig.vidHeight;
376 }
347 rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcWidth;
348 rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcHeight;
349 rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcWidth;
350 rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcHeight;
377351
378352 quarterBox[0] = 0;
379353 quarterBox[1] = tr.quarterFbo[0]->height;
407381 // add result back on top of the main buffer
408382 {
409383 float mul = 1.f;
410 vec2_t texScale;
411
412 texScale[0] =
413 texScale[1] = 1.0f;
414384
415385 VectorSet4(color, mul, mul, mul, 1);
416386
417 FBO_Blit(tr.quarterFbo[0], NULL, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
387 FBO_Blit(tr.quarterFbo[0], NULL, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
418388 }
419389 }
420390
442412 {
443413 ivec4_t srcBox, dstBox;
444414 vec4_t color;
445 vec2_t texScale;
446
447 texScale[0] =
448 texScale[1] = 1.0f;
449415
450416 VectorSet4(color, weights[0], weights[0], weights[0], 1.0f);
451417 VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height);
452418 VectorSet4(dstBox, 0, 0, dstFbo->width, dstFbo->height);
453 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0 );
419 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0);
454420
455421 VectorSet4(color, weights[1], weights[1], weights[1], 1.0f);
456422 dx = offsets[1] * xmul;
457423 dy = offsets[1] * ymul;
458424 VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height);
459 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
425 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
460426 VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height);
461 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
427 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
462428
463429 VectorSet4(color, weights[2], weights[2], weights[2], 1.0f);
464430 dx = offsets[2] * xmul;
465431 dy = offsets[2] * ymul;
466432 VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height);
467 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
433 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
468434 VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height);
469 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
435 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
470436 }
471437 }
472438
491457 {
492458 ivec4_t srcBox, dstBox;
493459 vec4_t color;
494 vec2_t texScale;
495
496 texScale[0] =
497 texScale[1] = 1.0f;
498460
499461 VectorSet4(color, 1, 1, 1, 1);
500462
503465 FBO_FastBlit(tr.quarterFbo[0], NULL, tr.textureScratchFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
504466
505467 // set the alpha channel
506 VectorSet4(srcBox, 0, 0, tr.whiteImage->width, tr.whiteImage->height);
507 VectorSet4(dstBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height);
508468 qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
509 FBO_BlitFromTexture(tr.whiteImage, srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.textureColorShader, color, GLS_DEPTHTEST_DISABLE);
469 FBO_BlitFromTexture(tr.whiteImage, NULL, NULL, tr.textureScratchFbo[0], NULL, NULL, color, GLS_DEPTHTEST_DISABLE);
510470 qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
511471
512472 // blur the tiny buffer horizontally and vertically
517477 VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height);
518478 VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
519479 color[3] = factor;
520 FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
521 }
522 }
480 FBO_Blit(tr.textureScratchFbo[0], srcBox, NULL, NULL, dstBox, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
481 }
482 }
444444
445445 VectorCopy(tr.sunDirection, tr.refdef.sunDir);
446446 if ( (tr.refdef.rdflags & RDF_NOWORLDMODEL) || !(r_depthPrepass->value) ){
447 tr.refdef.colorScale = 1.0f;
448447 VectorSet(tr.refdef.sunCol, 0, 0, 0);
449448 VectorSet(tr.refdef.sunAmbCol, 0, 0, 0);
450449 }
451450 else
452451 {
453 #if defined(USE_OVERBRIGHT)
454 float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8);
455 #else
456452 float scale = (1 << r_mapOverBrightBits->integer) / 255.0f;
457 #endif
458 tr.refdef.colorScale = r_forceSun->integer ? r_forceSunMapLightScale->value : tr.mapLightScale;
459453
460454 if (r_forceSun->integer)
461455 VectorScale(tr.sunLight, scale * r_forceSunLightScale->value, tr.refdef.sunCol);
2727 // tr_shade.c
2828
2929 #include "tr_local.h"
30 #if idppc_altivec && !defined(MACOS_X)
30 #if idppc_altivec && !defined(__APPLE__)
3131 #include <altivec.h>
3232 #endif
3333
4949 void R_DrawElementsVao( int numIndexes, glIndex_t firstIndex, glIndex_t minIndex, glIndex_t maxIndex )
5050 {
5151 if (glRefConfig.drawRangeElements)
52 qglDrawRangeElementsEXT(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
52 qglDrawRangeElements(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
5353 else
5454 qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
5555
6161 {
6262 if (glRefConfig.multiDrawArrays && multiDrawPrimitives > 1)
6363 {
64 qglMultiDrawElementsEXT(GL_TRIANGLES, multiDrawNumIndexes, GL_INDEX_TYPE, (const GLvoid **)multiDrawFirstIndex, multiDrawPrimitives);
64 qglMultiDrawElements(GL_TRIANGLES, multiDrawNumIndexes, GL_INDEX_TYPE, (const GLvoid **)multiDrawFirstIndex, multiDrawPrimitives);
6565 }
6666 else
6767 {
7171 {
7272 for (i = 0; i < multiDrawPrimitives; i++)
7373 {
74 qglDrawRangeElementsEXT(GL_TRIANGLES, multiDrawMinIndex[i], multiDrawMaxIndex[i], multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]);
74 qglDrawRangeElements(GL_TRIANGLES, multiDrawMinIndex[i], multiDrawMaxIndex[i], multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]);
7575 }
7676 }
7777 else
106106 int index;
107107
108108 if ( bundle->isVideoMap ) {
109 int oldtmu = glState.currenttmu;
110 GL_SelectTexture(tmu);
111109 ri.CIN_RunCinematic(bundle->videoMapHandle);
112110 ri.CIN_UploadCinematic(bundle->videoMapHandle);
113 GL_SelectTexture(oldtmu);
111 GL_BindToTMU(tr.scratchImage[bundle->videoMapHandle], tmu);
114112 return;
115113 }
116114
149147 ================
150148 */
151149 static void DrawTris (shaderCommands_t *input) {
152 GL_Bind( tr.whiteImage );
150 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
153151
154152 GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
155153 qglDepthRange( 0, 0 );
448446 vector[3] = scale;
449447 GLSL_SetUniformVec4(sp, UNIFORM_DLIGHTINFO, vector);
450448
451 GL_Bind( tr.dlightImage );
449 GL_BindToTMU( tr.dlightImage, TB_COLORMAP );
452450
453451 // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
454452 // where they aren't rendered
483481 || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR)
484482 || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR);
485483
486 #if defined(USE_OVERBRIGHT)
487 float exactLight = 1.0f;
488 #else
489 qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL);
490 float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer);
491 #endif
484 qboolean is2DDraw = backEnd.currentEntity == &backEnd.entity2D;
485
486 float overbright = (isBlend || is2DDraw) ? 1.0f : (float)(1 << tr.overbrightBits);
487
488 fog_t *fog;
492489
493490 baseColor[0] =
494491 baseColor[1] =
495 baseColor[2] = exactLight;
492 baseColor[2] =
496493 baseColor[3] = 1.0f;
497494
498495 vertColor[0] =
505502 //
506503 switch ( pStage->rgbGen )
507504 {
508 case CGEN_IDENTITY_LIGHTING:
509 baseColor[0] =
510 baseColor[1] =
511 baseColor[2] = tr.identityLight;
512 break;
513505 case CGEN_EXACT_VERTEX:
514506 case CGEN_EXACT_VERTEX_LIT:
515507 baseColor[0] =
519511
520512 vertColor[0] =
521513 vertColor[1] =
522 vertColor[2] = exactLight;
514 vertColor[2] = overbright;
523515 vertColor[3] = 1.0f;
524516 break;
525517 case CGEN_CONST:
529521 baseColor[3] = pStage->constantColor[3] / 255.0f;
530522 break;
531523 case CGEN_VERTEX:
532 baseColor[0] =
524 case CGEN_VERTEX_LIT:
525 baseColor[0] =
533526 baseColor[1] =
534527 baseColor[2] =
535528 baseColor[3] = 0.0f;
536529
537530 vertColor[0] =
538531 vertColor[1] =
539 vertColor[2] = tr.identityLight;
532 vertColor[2] =
540533 vertColor[3] = 1.0f;
541 break;
542 case CGEN_VERTEX_LIT:
543 baseColor[0] =
544 baseColor[1] =
545 baseColor[2] =
546 baseColor[3] = 0.0f;
547
548 vertColor[0] =
549 vertColor[1] =
550 vertColor[2] =
551 vertColor[3] = tr.identityLight;
552534 break;
553535 case CGEN_ONE_MINUS_VERTEX:
554536 baseColor[0] =
555537 baseColor[1] =
556 baseColor[2] = tr.identityLight;
538 baseColor[2] = 1.0f;
557539
558540 vertColor[0] =
559541 vertColor[1] =
560 vertColor[2] = -tr.identityLight;
542 vertColor[2] = -1.0f;
561543 break;
562544 case CGEN_FOG:
563 {
564 fog_t *fog;
565
566 fog = tr.world->fogs + tess.fogNum;
567
568 baseColor[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f;
569 baseColor[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f;
570 baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
571 baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
572 }
545 fog = tr.world->fogs + tess.fogNum;
546
547 baseColor[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f;
548 baseColor[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f;
549 baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
550 baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
573551 break;
574552 case CGEN_WAVEFORM:
575553 baseColor[0] =
596574 break;
597575 case CGEN_IDENTITY:
598576 case CGEN_LIGHTING_DIFFUSE:
577 baseColor[0] =
578 baseColor[1] =
579 baseColor[2] = overbright;
580 break;
581 case CGEN_IDENTITY_LIGHTING:
599582 case CGEN_BAD:
600583 break;
601584 }
652635 baseColor[3] = 1.0f;
653636 vertColor[3] = 0.0f;
654637 break;
655 }
656
657 // multiply color by overbrightbits if this isn't a blend
658 if (tr.overbrightBits && !isBlend)
659 {
660 float scale = 1 << tr.overbrightBits;
661
662 baseColor[0] *= scale;
663 baseColor[1] *= scale;
664 baseColor[2] *= scale;
665 vertColor[0] *= scale;
666 vertColor[1] *= scale;
667 vertColor[2] *= scale;
668638 }
669639
670640 // FIXME: find some way to implement this.
959929 }
960930
961931 if (r_dlightMode->integer >= 2)
962 {
963 GL_SelectTexture(TB_SHADOWMAP);
964 GL_Bind(tr.shadowCubemaps[l]);
965 GL_SelectTexture(0);
966 }
932 GL_BindToTMU(tr.shadowCubemaps[l], TB_SHADOWMAP);
967933
968934 ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
969935 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
10641030 //backEnd.pc.c_dlightIndexes += tess.numIndexes;
10651031 }
10661032 }
1067
1068 extern qboolean fogIsOn;
10691033
10701034 /*
10711035 ===================
10891053 return;
10901054 }
10911055
1092 if (!fogIsOn)
1093 return;
1094
10951056 if (wolfFog)
10961057 {
1097 // from R_Fog(), altered slightly
10981058 if ( backEnd.projection2D ) {
10991059 return;
11001060 }
12261186 if (vertexAttribs & ATTR_NORMAL)
12271187 {
12281188 vertexAttribs |= ATTR_NORMAL2;
1229 #ifdef USE_VERT_TANGENT_SPACE
12301189 vertexAttribs |= ATTR_TANGENT2;
1231 #endif
12321190 }
12331191 }
12341192
12461204 int deformGen;
12471205 vec5_t deformParams;
12481206
1207 qboolean renderToCubemap = tr.renderCubeFbo && glState.currentFBO == tr.renderCubeFbo;
1208
12491209 ComputeDeformValues(&deformGen, deformParams);
12501210
12511211 for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
13161276 index |= LIGHTDEF_USE_SHADOWMAP;
13171277 }
13181278
1319 if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP)
1320 {
1321 index = LIGHTDEF_USE_LIGHTMAP;
1279 if (r_lightmap->integer && ((index & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHTMAP))
1280 {
1281 index = LIGHTDEF_USE_TCGEN_AND_TCMOD;
13221282 }
13231283
13241284 sp = &pStage->glslShaderGroup[index];
14511411 }
14521412 //----(SA) end
14531413
1454 if ((backEnd.refdef.colorScale != 1.0f) && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL))
1455 {
1456 // use VectorScale to only scale first three values, not alpha
1457 VectorScale(baseColor, backEnd.refdef.colorScale, baseColor);
1458 VectorScale(vertColor, backEnd.refdef.colorScale, vertColor);
1459 }
1460
14611414 GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor);
14621415 GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor);
14631416 }
14651418 if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE)
14661419 {
14671420 vec4_t vec;
1468 vec_t cap = 1.0f / (1 << tr.overbrightBits);
14691421
14701422 VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec);
1471 if ((vec[0] > cap) || (vec[1] > cap) || (vec[2] > cap))
1472 {
1473 vec_t hi = MAX(vec[0], vec[1]);
1474 hi = MAX(hi, vec[2]);
1475
1476 VectorScale(vec, cap / hi, vec);
1477 }
14781423 GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, vec);
14791424
14801425 VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec);
1481 if ((vec[0] > cap) || (vec[1] > cap) || (vec[2] > cap))
1482 {
1483 vec_t hi = MAX(vec[0], vec[1]);
1484 hi = MAX(hi, vec[2]);
1485
1486 VectorScale(vec, cap / hi, vec);
1487 }
14881426 GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, vec);
14891427
14901428 VectorCopy(backEnd.currentEntity->lightDir, vec);
15331471 GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask);
15341472 }
15351473
1536 ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
1537 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
1538 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
1539
1540 GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
1541 if (pStage->bundle[0].tcGen == TCGEN_VECTOR)
1542 {
1543 vec3_t vec;
1544
1545 VectorCopy(pStage->bundle[0].tcGenVectors[0], vec);
1546 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec);
1547 VectorCopy(pStage->bundle[0].tcGenVectors[1], vec);
1548 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec);
1474 if (r_lightmap->integer)
1475 {
1476 vec4_t v;
1477 VectorSet4(v, 1.0f, 0.0f, 0.0f, 1.0f);
1478 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, v);
1479 VectorSet4(v, 0.0f, 0.0f, 0.0f, 0.0f);
1480 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, v);
1481
1482 GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, TCGEN_LIGHTMAP);
1483 }
1484 else
1485 {
1486 ComputeTexMods(pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb);
1487 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
1488 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
1489
1490 GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
1491 if (pStage->bundle[0].tcGen == TCGEN_VECTOR)
1492 {
1493 vec3_t vec;
1494
1495 VectorCopy(pStage->bundle[0].tcGenVectors[0], vec);
1496 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec);
1497 VectorCopy(pStage->bundle[0].tcGenVectors[1], vec);
1498 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec);
1499 }
15491500 }
15501501
15511502 GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
15521503
15531504 GLSL_SetUniformVec4(sp, UNIFORM_NORMALSCALE, pStage->normalScale);
1554 GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale);
1505
1506 {
1507 vec4_t specularScale;
1508 Vector4Copy(pStage->specularScale, specularScale);
1509
1510 if (renderToCubemap)
1511 {
1512 // force specular to nonmetal if rendering cubemaps
1513 if (r_pbr->integer)
1514 specularScale[1] = 0.0f;
1515 }
1516
1517 GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, specularScale);
1518 }
15551519
15561520 //GLSL_SetUniformFloat(sp, UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale);
15571521
15611525 if ( backEnd.depthFill )
15621526 {
15631527 if (!(pStage->stateBits & GLS_ATEST_BITS))
1564 GL_BindToTMU( tr.whiteImage, 0 );
1528 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
15651529 else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 )
15661530 R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP );
15671531 }
15721536
15731537 if (r_sunlightMode->integer && (backEnd.viewParms.flags & VPF_USESUNLIGHT) && (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK))
15741538 {
1575 GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
1539 // FIXME: screenShadowImage is NULL if no framebuffers
1540 if (tr.screenShadowImage)
1541 GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
15761542 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol);
1577 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol);
1543 if (r_pbr->integer)
1544 {
1545 vec3_t color;
1546
1547 color[0] = backEnd.refdef.sunCol[0] * backEnd.refdef.sunCol[0];
1548 color[1] = backEnd.refdef.sunCol[1] * backEnd.refdef.sunCol[1];
1549 color[2] = backEnd.refdef.sunCol[2] * backEnd.refdef.sunCol[2];
1550 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, color);
1551 }
1552 else
1553 {
1554 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol);
1555 }
15781556 GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir);
15791557 }
15801558
15831561 {
15841562 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
15851563 {
1586 if (i == TB_LIGHTMAP)
1564 if (i == TB_COLORMAP)
15871565 R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i);
15881566 else
15891567 GL_BindToTMU( tr.whiteImage, i );
15931571 {
15941572 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
15951573 {
1596 if (i == TB_LIGHTMAP)
1574 if (i == TB_COLORMAP)
15971575 R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i);
15981576 else
15991577 GL_BindToTMU( tr.whiteImage, i );
16731651 vec4_t vec;
16741652 cubemap_t *cubemap = &tr.cubemaps[input->cubemapIndex - 1];
16751653
1676 GL_BindToTMU( cubemap->image, TB_CUBEMAP);
1654 // FIXME: cubemap image could be NULL if cubemap isn't renderer or loaded
1655 if (cubemap->image)
1656 GL_BindToTMU( cubemap->image, TB_CUBEMAP);
16771657
16781658 VectorSubtract(cubemap->origin, backEnd.viewParms.or.origin, vec);
16791659 vec[3] = 1.0f;
116116 vec3_t offset;
117117 float scale;
118118 float *xyz = ( float * ) tess.xyz;
119 uint32_t *normal = tess.normal;
119 int16_t *normal = tess.normal[0];
120120 float *table;
121121
122122 // Ridah
146146
147147 table = TableForFunc( ds->deformationWave.func );
148148
149 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
149 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
150150 {
151151 float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
152152 float dot;
153153 vec3_t fNormal;
154154
155 R_VaoUnpackNormal(fNormal, *normal);
155 R_VaoUnpackNormal(fNormal, normal);
156156
157157 scale = WAVEVALUE( table, ds->deformationWave.base,
158158 ds->deformationWave.amplitude,
178178 else if ( ds->deformationWave.frequency == 0 ) {
179179 scale = EvalWaveForm( &ds->deformationWave );
180180
181 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
181 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
182182 {
183 R_VaoUnpackNormal(offset, *normal);
183 R_VaoUnpackNormal(offset, normal);
184184
185185 xyz[0] += offset[0] * scale;
186186 xyz[1] += offset[1] * scale;
187187 xyz[2] += offset[2] * scale;
188188 }
189 } else
190 {
189 }
190 else {
191191 table = TableForFunc( ds->deformationWave.func );
192192
193 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
193 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
194194 {
195195 float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
196196
199199 ds->deformationWave.phase + off,
200200 ds->deformationWave.frequency );
201201
202 R_VaoUnpackNormal(offset, *normal);
202 R_VaoUnpackNormal(offset, normal);
203203
204204 xyz[0] += offset[0] * scale;
205205 xyz[1] += offset[1] * scale;
219219 int i;
220220 float scale;
221221 float *xyz = ( float * ) tess.xyz;
222 uint32_t *normal = tess.normal;
223
224 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) {
222 int16_t *normal = tess.normal[0];
223
224 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) {
225225 vec3_t fNormal;
226226
227 R_VaoUnpackNormal(fNormal, *normal);
227 R_VaoUnpackNormal(fNormal, normal);
228228
229229 scale = 0.98f;
230230 scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
243243
244244 VectorNormalizeFast( fNormal );
245245
246 R_VaoPackNormal((byte *)normal, fNormal);
246 R_VaoPackNormal(normal, fNormal);
247247 }
248248 }
249249
257257 int i;
258258 const float *st = ( const float * ) tess.texCoords[0];
259259 float *xyz = ( float * ) tess.xyz;
260 uint32_t *normal = tess.normal;
260 int16_t *normal = tess.normal[0];
261261 float now;
262262
263263 now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
264264
265 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal++ ) {
265 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
266266 int off;
267267 float scale;
268268 vec3_t fNormal;
269269
270 R_VaoUnpackNormal(fNormal, *normal);
270 R_VaoUnpackNormal(fNormal, normal);
271271
272272 off = (float)( FUNCTABLE_SIZE / ( M_PI * 2 ) ) * ( st[0] * ds->bulgeWidth + now );
273273
438438 }
439439
440440 for ( i = 0 ; i < oldVerts ; i += 4 ) {
441 vec4_t color;
441442 // find the midpoint
442443 xyz = tess.xyz[i];
443444
468469 VectorScale( up, axisLength, up );
469470 }
470471
471 RB_AddQuadStamp( mid, left, up, tess.vertexColors[i] );
472 VectorScale4(tess.color[i], 1.0f / 65535.0f, color);
473 RB_AddQuadStamp( mid, left, up, color );
472474 }
473475 }
474476
809811 void RB_CalcFireRiseEnvTexCoords( float *st ) {
810812 int i;
811813 float *v;
812 uint32_t *normal = tess.normal;
814 int16_t *normal = tess.normal[0];
813815 vec3_t fNormal, viewer, reflected;
814816 float d;
815817
816818 v = tess.xyz[0];
817819 VectorNegate( backEnd.currentEntity->e.fireRiseDir, viewer );
818820
819 for ( i = 0 ; i < tess.numVertexes ; i++, v += 4, normal++, st += 2 )
821 for ( i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
820822 {
821823 VectorNormalizeFast( viewer );
822824
823 R_VaoUnpackNormal(fNormal, *normal);
825 R_VaoUnpackNormal(fNormal, normal);
824826
825827 d = DotProduct( fNormal, viewer );
826828
3838 static texModInfo_t texMods[MAX_SHADER_STAGES][TR_MAX_TEXMODS];
3939
4040 #define FILE_HASH_SIZE 4096
41
4241 static shader_t* hashTable[FILE_HASH_SIZE];
43
44 // Ridah
45 // Table containing string indexes for each shader found in the scripts, referenced by their checksum
46 // values.
47 typedef struct shaderStringPointer_s
48 {
49 char *pStr;
50 struct shaderStringPointer_s *next;
51 } shaderStringPointer_t;
52 //
53 shaderStringPointer_t shaderChecksumLookup[FILE_HASH_SIZE];
54 // done.
5542
5643 /*
5744 ================
911898 ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name );
912899 continue;
913900 }
914 stage->specularScale[0] =
915 stage->specularScale[1] =
916 stage->specularScale[2] = atof( token );
901
902 if (r_pbr->integer)
903 {
904 // interpret specularReflectance < 0.5 as nonmetal
905 stage->specularScale[1] = (atof(token) < 0.5f) ? 0.0f : 1.0f;
906 }
907 else
908 {
909 stage->specularScale[0] =
910 stage->specularScale[1] =
911 stage->specularScale[2] = atof( token );
912 }
917913 }
918914 //
919915 // specularExponent <value>
931927
932928 exponent = atof( token );
933929
934 if (r_glossIsRoughness->integer)
935 stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25);
930 if (r_pbr->integer)
931 stage->specularScale[0] = 1.0f - powf(2.0f / (exponent + 2.0), 0.25);
936932 else
937933 {
938934 // Change shininess to gloss
957953
958954 gloss = atof(token);
959955
960 if (r_glossIsRoughness->integer)
961 stage->specularScale[3] = exp2f(-3.0f * gloss);
956 if (r_pbr->integer)
957 stage->specularScale[0] = 1.0f - exp2f(-3.0f * gloss);
962958 else
963959 stage->specularScale[3] = gloss;
964960 }
978974
979975 roughness = atof(token);
980976
981 if (r_glossIsRoughness->integer)
982 stage->specularScale[3] = roughness;
977 if (r_pbr->integer)
978 stage->specularScale[0] = 1.0 - roughness;
983979 else
984980 {
985981 if (roughness >= 0.125)
10391035 }
10401036 //
10411037 // specularScale <rgb> <gloss>
1038 // or specularScale <metallic> <smoothness> with r_pbr 1
10421039 // or specularScale <r> <g> <b>
10431040 // or specularScale <r> <g> <b> <gloss>
10441041 //
10651062 token = COM_ParseExt(text, qfalse);
10661063 if ( token[0] == 0 )
10671064 {
1068 // two values, rgb then gloss
1069 stage->specularScale[3] = stage->specularScale[1];
1070 stage->specularScale[1] =
1071 stage->specularScale[2] = stage->specularScale[0];
1065 if (r_pbr->integer)
1066 {
1067 // two values, metallic then smoothness
1068 float smoothness = stage->specularScale[1];
1069 stage->specularScale[1] = (stage->specularScale[0] < 0.5f) ? 0.0f : 1.0f;
1070 stage->specularScale[0] = smoothness;
1071 }
1072 {
1073 // two values, rgb then gloss
1074 stage->specularScale[3] = stage->specularScale[1];
1075 stage->specularScale[1] =
1076 stage->specularScale[2] = stage->specularScale[0];
1077 }
10721078 continue;
10731079 }
10741080
11171123 } else if ( !Q_stricmp( token, "oneMinusEntity" ) ) {
11181124 stage->rgbGen = CGEN_ONE_MINUS_ENTITY;
11191125 } else if ( !Q_stricmp( token, "vertex" ) ) {
1120 if ( r_cgenVertexLit->integer ) {
1121 stage->rgbGen = CGEN_VERTEX_LIT;
1122 } else {
1123 stage->rgbGen = CGEN_VERTEX;
1124 }
1126 stage->rgbGen = CGEN_VERTEX;
11251127 if ( stage->alphaGen == 0 ) {
11261128 stage->alphaGen = AGEN_VERTEX;
11271129 }
11281130 } else if ( !Q_stricmp( token, "exactVertex" ) ) {
1129 if ( r_cgenVertexLit->integer ) {
1130 stage->rgbGen = CGEN_EXACT_VERTEX_LIT;
1131 } else {
1132 stage->rgbGen = CGEN_EXACT_VERTEX;
1133 }
1131 stage->rgbGen = CGEN_EXACT_VERTEX;
11341132 } else if ( !Q_stricmp( token, "vertexLit" ) ) {
11351133 stage->rgbGen = CGEN_VERTEX_LIT;
1136 if ( stage->alphaGen == 0 )
1134 if ( stage->alphaGen == 0 ) {
11371135 stage->alphaGen = AGEN_VERTEX;
1136 }
11381137 } else if ( !Q_stricmp( token, "exactVertexLit" ) ) {
11391138 stage->rgbGen = CGEN_EXACT_VERTEX_LIT;
11401139 } else if ( !Q_stricmp( token, "lightingDiffuse" ) ) {
12911290 }
12921291 }
12931292
1293 // allow crosshairs to be colorized for cg_crosshairHealth
1294 if ( strstr( shader.name, "crosshair" ) && shader.lightmapIndex == LIGHTMAP_2D ) {
1295 if ( stage->rgbGen == CGEN_IDENTITY || stage->rgbGen == CGEN_IDENTITY_LIGHTING ) {
1296 stage->rgbGen = CGEN_VERTEX;
1297 }
1298 }
12941299
12951300 //
12961301 // implicitly assume that a GL_ONE GL_ZERO blend mask disables blending
17691774 if (isGL2Sun)
17701775 {
17711776 token = COM_ParseExt( text, qfalse );
1772 tr.mapLightScale = atof(token);
1773
1777 tr.sunShadowScale = atof(token);
1778
1779 // parse twice, since older shaders may include mapLightScale before sunShadowScale
17741780 token = COM_ParseExt( text, qfalse );
1775 tr.sunShadowScale = atof(token);
1781 if (token[0])
1782 tr.sunShadowScale = atof(token);
17761783 }
17771784
17781785 SkipRestOfLine( text );
21722179 {
21732180 shader.vertexAttribs |= ATTR_NORMAL;
21742181
2175 #ifdef USE_VERT_TANGENT_SPACE
21762182 if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && !(r_normalMapping->integer == 0 && r_specularMapping->integer == 0))
21772183 {
21782184 shader.vertexAttribs |= ATTR_TANGENT;
21792185 }
2180 #endif
21812186
21822187 switch (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK)
21832188 {
23032308 image_t *normalImg;
23042309 imgFlags_t normalFlags = (diffuseImg->flags & ~(IMGFLAG_GENNORMALMAP | IMGFLAG_SRGB)) | IMGFLAG_NOLIGHTSCALE;
23052310
2311 // try a normalheight image first
23062312 COM_StripExtension(diffuseImg->imgName, normalName, MAX_QPATH);
2307 Q_strcat(normalName, MAX_QPATH, "_n");
2308
2309 normalImg = R_FindImageFile(normalName, IMGTYPE_NORMAL, normalFlags);
2313 Q_strcat(normalName, MAX_QPATH, "_nh");
2314
2315 normalImg = R_FindImageFile(normalName, IMGTYPE_NORMALHEIGHT, normalFlags);
2316
2317 if (normalImg)
2318 {
2319 parallax = qtrue;
2320 }
2321 else
2322 {
2323 // try a normal image ("_n" suffix)
2324 normalName[strlen(normalName) - 1] = '\0';
2325 normalImg = R_FindImageFile(normalName, IMGTYPE_NORMAL, normalFlags);
2326 }
23102327
23112328 if (normalImg)
23122329 {
29392956
29402957 // default normal/specular
29412958 VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f);
2942 stages[i].specularScale[0] =
2943 stages[i].specularScale[1] =
2944 stages[i].specularScale[2] = r_baseSpecular->value;
2945 stages[i].specularScale[3] = r_baseGloss->value;
2959 if (r_pbr->integer)
2960 {
2961 stages[i].specularScale[0] = r_baseGloss->value;
2962 }
2963 else
2964 {
2965 stages[i].specularScale[0] =
2966 stages[i].specularScale[1] =
2967 stages[i].specularScale[2] = r_baseSpecular->value;
2968 stages[i].specularScale[3] = r_baseGloss->value;
2969 }
29462970 }
29472971 }
29482972
31763200
31773201 if ( token[0] == '{' ) {
31783202 // skip the definition
3179 // SkipBracedSection_Depth( &p, 1 );
3180 SkipBracedSection( &p );
3203 SkipBracedSection( &p, 0 );
31813204 } else if ( !Q_stricmp( token, shadername ) ) {
31823205 return p;
31833206 } else {
36773700 char *p;
36783701 int numShaderFiles;
36793702 int i;
3680 char *oldp, *token, *textEnd;
3703 char *token, *textEnd;
3704 char shaderName[MAX_QPATH];
3705 int shaderLine;
36813706
36823707 long sum = 0, summand;
36833708 // scan for shader files
37193744
37203745 // Do a simple check on the shader structure in that file to make sure one bad shader file cannot fuck up all other shaders.
37213746 p = buffers[i];
3747 COM_BeginParseSession(filename);
37223748 while(1)
37233749 {
37243750 token = COM_ParseExt(&p, qtrue);
37253751
37263752 if(!*token)
37273753 break;
3728
3729 oldp = p;
3730
3754
3755 Q_strncpyz(shaderName, token, sizeof(shaderName));
3756 shaderLine = COM_GetCurrentParseLine();
3757
37313758 token = COM_ParseExt(&p, qtrue);
3732 if(token[0] != '{' && token[1] != '\0')
3733 {
3734 ri.Printf(PRINT_WARNING, "WARNING: Bad shader file %s has incorrect syntax.\n", filename);
3759 if( !Q_stricmp( shaderName, token ) ) {
3760 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Invalid shader name \"%s\" on line %d.\n",
3761 filename, shaderName, shaderLine);
3762 break;
3763 }
3764
3765 if(token[0] != '{' || token[1] != '\0')
3766 {
3767 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing opening brace",
3768 filename, shaderName, shaderLine);
3769 if (token[0])
3770 {
3771 ri.Printf(PRINT_WARNING, " (found \"%s\" on line %d)", token, COM_GetCurrentParseLine());
3772 }
3773 ri.Printf(PRINT_WARNING, "...Ignored\n");
37353774 ri.FS_FreeFile(buffers[i]);
37363775 buffers[i] = NULL;
37373776 break;
37383777 }
37393778
3740 SkipBracedSection(&oldp);
3741 p = oldp;
3779 if(!SkipBracedSection(&p, 1))
3780 {
3781 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing closing brace",
3782 filename, shaderName, shaderLine);
3783 if( !Q_stricmp( filename, "common.shader" ) ) { // HACK...Broken shader in pak0.pk3
3784 ri.Printf(PRINT_WARNING, "...Ignored\n");
3785 ri.FS_FreeFile(buffers[i]);
3786 buffers[i] = NULL;
3787 break;
3788 } else {
3789 ri.Printf(PRINT_WARNING, ".\n");
3790 }
3791 }
37423792 }
37433793
37443794 if (buffers[i])
212212
213213 // draw the silhouette edges
214214
215 GL_Bind( tr.whiteImage );
215 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
216216 GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
217217 qglColor3f( 0.2f, 0.2f, 0.2f );
218218
261261 qglDisable( GL_CLIP_PLANE0 );
262262 GL_Cull( CT_TWO_SIDED );
263263
264 GL_Bind( tr.whiteImage );
264 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
265265
266266 qglLoadIdentity();
267267
387387 //tess.numIndexes = 0;
388388 tess.firstIndex = tess.numIndexes;
389389
390 GL_Bind( image );
390 GL_BindToTMU( image, TB_COLORMAP );
391391 GL_Cull( CT_TWO_SIDED );
392392
393393 for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
460460
461461 color[0] =
462462 color[1] =
463 color[2] = backEnd.refdef.colorScale;
463 color[2] =
464464 color[3] = 1.0f;
465465 GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, color);
466466
504504 //tess.numIndexes = 0;
505505 tess.firstIndex = tess.numIndexes;
506506
507 GL_Bind( image );
507 GL_BindToTMU( image, TB_COLORMAP );
508508 GL_Cull( CT_TWO_SIDED );
509509
510510 for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
577577
578578 color[0] =
579579 color[1] =
580 color[2] = backEnd.refdef.colorScale;
580 color[2] =
581581 color[3] = 1.0f;
582582 GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, color);
583583
10751075 qglDepthRange( 0.0, 1.0 );
10761076 }
10771077
1078 extern void R_Fog( glfog_t *curfog );
1079
10801078 /*
10811079 ================
10821080 RB_StageIteratorSky
11301128 mat4_t oldmodelview;
11311129
11321130 GL_State( 0 );
1131 GL_Cull( CT_FRONT_SIDED );
11331132 //qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
11341133
11351134 {
11601159 mat4_t oldmodelview;
11611160
11621161 GL_State( 0 );
1162 GL_Cull( CT_FRONT_SIDED );
11631163 //qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
11641164
11651165 {
2727
2828 // tr_surf.c
2929 #include "tr_local.h"
30 #if idppc_altivec && !defined(MACOS_X)
30 #if idppc_altivec && !defined(__APPLE__)
3131 #include <altivec.h>
3232 #endif
3333
9393 */
9494 void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 ) {
9595 vec3_t normal;
96 uint32_t pNormal;
96 int16_t iNormal[4];
97 uint16_t iColor[4];
9798 int ndx;
9899
99100 RB_CheckVao(tess.vao);
131132 // constant normal all the way around
132133 VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );
133134
134 R_VaoPackNormal((byte *)&pNormal, normal);
135 tess.normal[ndx] =
136 tess.normal[ndx+1] =
137 tess.normal[ndx+2] =
138 tess.normal[ndx+3] = pNormal;
135 R_VaoPackNormal(iNormal, normal);
136
137 VectorCopy4(iNormal, tess.normal[ndx]);
138 VectorCopy4(iNormal, tess.normal[ndx + 1]);
139 VectorCopy4(iNormal, tess.normal[ndx + 2]);
140 VectorCopy4(iNormal, tess.normal[ndx + 3]);
139141
140142 // standard square texture coordinates
141143 VectorSet2(tess.texCoords[ndx ][0], s1, t1);
152154
153155 // constant color all the way around
154156 // should this be identity and let the shader specify from entity?
155 VectorCopy4(color, tess.vertexColors[ndx]);
156 VectorCopy4(color, tess.vertexColors[ndx+1]);
157 VectorCopy4(color, tess.vertexColors[ndx+2]);
158 VectorCopy4(color, tess.vertexColors[ndx+3]);
157
158 R_VaoPackColor(iColor, color);
159
160 VectorCopy4(iColor, tess.color[ndx]);
161 VectorCopy4(iColor, tess.color[ndx + 1]);
162 VectorCopy4(iColor, tess.color[ndx + 2]);
163 VectorCopy4(iColor, tess.color[ndx + 3]);
159164
160165 tess.numVertexes += 4;
161166 tess.numIndexes += 6;
322327 VectorCopy( p->verts[i].xyz, tess.xyz[numv] );
323328 tess.texCoords[numv][0][0] = p->verts[i].st[0];
324329 tess.texCoords[numv][0][1] = p->verts[i].st[1];
325 tess.vertexColors[numv][0] = p->verts[ i ].modulate[0] / 255.0f;
326 tess.vertexColors[numv][1] = p->verts[ i ].modulate[1] / 255.0f;
327 tess.vertexColors[numv][2] = p->verts[ i ].modulate[2] / 255.0f;
328 tess.vertexColors[numv][3] = p->verts[ i ].modulate[3] / 255.0f;
330 tess.color[numv][0] = (int)p->verts[i].modulate[0] * 257;
331 tess.color[numv][1] = (int)p->verts[i].modulate[1] * 257;
332 tess.color[numv][2] = (int)p->verts[i].modulate[2] * 257;
333 tess.color[numv][3] = (int)p->verts[i].modulate[3] * 257;
329334
330335 numv++;
331336 }
347352 glIndex_t *inIndex;
348353 srfVert_t *dv;
349354 float *xyz, *texCoords, *lightCoords;
350 uint32_t *lightdir;
351 uint32_t *normal;
352 #ifdef USE_VERT_TANGENT_SPACE
353 uint32_t *tangent;
354 #endif
355 int16_t *lightdir;
356 int16_t *normal;
357 int16_t *tangent;
355358 glIndex_t *outIndex;
356 float *color;
359 uint16_t *color;
357360
358361 RB_CheckVao(tess.vao);
359362
377380 if ( tess.shader->vertexAttribs & ATTR_NORMAL )
378381 {
379382 dv = verts;
380 normal = &tess.normal[ tess.numVertexes ];
381 for ( i = 0 ; i < numVerts ; i++, dv++, normal++ )
382 R_VaoPackNormal((byte *)normal, dv->normal);
383 }
384
385 #ifdef USE_VERT_TANGENT_SPACE
383 normal = tess.normal[ tess.numVertexes ];
384 for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 )
385 VectorCopy4(dv->normal, normal);
386 }
387
386388 if ( tess.shader->vertexAttribs & ATTR_TANGENT )
387389 {
388390 dv = verts;
389 tangent = &tess.tangent[ tess.numVertexes ];
390 for ( i = 0 ; i < numVerts ; i++, dv++, tangent++ )
391 R_VaoPackTangent((byte *)tangent, dv->tangent);
392 }
393 #endif
391 tangent = tess.tangent[ tess.numVertexes ];
392 for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 )
393 VectorCopy4(dv->tangent, tangent);
394 }
394395
395396 if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
396397 {
411412 if ( tess.shader->vertexAttribs & ATTR_COLOR )
412413 {
413414 dv = verts;
414 color = tess.vertexColors[ tess.numVertexes ];
415 color = tess.color[ tess.numVertexes ];
415416 for ( i = 0 ; i < numVerts ; i++, dv++, color+=4 )
416 VectorCopy4(dv->vertexColors, color);
417 VectorCopy4(dv->color, color);
417418 }
418419
419420 if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
420421 {
421422 dv = verts;
422 lightdir = &tess.lightdir[ tess.numVertexes ];
423 for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ )
424 R_VaoPackNormal((byte *)lightdir, dv->lightdir);
423 lightdir = tess.lightdir[ tess.numVertexes ];
424 for ( i = 0 ; i < numVerts ; i++, dv++, lightdir+=4 )
425 VectorCopy4(dv->lightdir, lightdir);
425426 }
426427
427428 #if 0 // nothing even uses vertex dlightbits
602603 VectorAdd( start_points[i], direction, end_points[i] );
603604 }
604605
605 GL_Bind( tr.whiteImage );
606 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
606607
607608 GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
608609
668669 VectorMA( start, spanWidth, up, tess.xyz[tess.numVertexes] );
669670 tess.texCoords[tess.numVertexes][0][0] = 0;
670671 tess.texCoords[tess.numVertexes][0][1] = 0;
671 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25 / 255.0f;
672 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25 / 255.0f;
673 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25 / 255.0f;
672 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25f * 257.0f;
673 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25f * 257.0f;
674 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25f * 257.0f;
674675 tess.numVertexes++;
675676
676677 VectorMA( start, spanWidth2, up, tess.xyz[tess.numVertexes] );
677678 tess.texCoords[tess.numVertexes][0][0] = 0;
678679 tess.texCoords[tess.numVertexes][0][1] = 1;
679 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
680 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
681 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
680 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
681 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
682 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
682683 tess.numVertexes++;
683684
684685 VectorMA( end, spanWidth, up, tess.xyz[tess.numVertexes] );
685686
686687 tess.texCoords[tess.numVertexes][0][0] = t;
687688 tess.texCoords[tess.numVertexes][0][1] = 0;
688 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
689 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
690 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
689 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
690 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
691 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
691692 tess.numVertexes++;
692693
693694 VectorMA( end, spanWidth2, up, tess.xyz[tess.numVertexes] );
694695 tess.texCoords[tess.numVertexes][0][0] = t;
695696 tess.texCoords[tess.numVertexes][0][1] = 1;
696 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
697 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
698 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
697 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
698 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
699 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
699700 tess.numVertexes++;
700701
701702 tess.indexes[tess.numIndexes++] = vbase;
752753 VectorCopy( pos[j], tess.xyz[tess.numVertexes] );
753754 tess.texCoords[tess.numVertexes][0][0] = ( j < 2 );
754755 tess.texCoords[tess.numVertexes][0][1] = ( j && j != 3 );
755 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
756 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
757 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
756 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
757 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
758 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
758759 tess.numVertexes++;
759760
760761 VectorAdd( pos[j], dir, pos[j] );
867868 }
868869 }
869870
870 /*
871 ** VectorArrayNormalize
872 *
873 * The inputs to this routing seem to always be close to length = 1.0 (about 0.6 to 2.0)
874 * This means that we don't have to worry about zero length or enormously long vectors.
875 */
876 #if 0 // Unused in rend2
877 static void VectorArrayNormalize( vec4_t *normals, unsigned int count ) {
878 // assert(count);
879
880 #if idppc
881 {
882 register float half = 0.5;
883 register float one = 1.0;
884 float *components = (float *)normals;
885
886 // Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction,
887 // runs *much* faster than calling sqrt(). We'll use a single Newton-Raphson
888 // refinement step to get a little more precision. This seems to yeild results
889 // that are correct to 3 decimal places and usually correct to at least 4 (sometimes 5).
890 // (That is, for the given input range of about 0.6 to 2.0).
891 do {
892 float x, y, z;
893 float B, y0, y1;
894
895 x = components[0];
896 y = components[1];
897 z = components[2];
898 components += 4;
899 B = x * x + y * y + z * z;
900
901 #ifdef __GNUC__
902 asm ( "frsqrte %0,%1" : "=f" ( y0 ) : "f" ( B ) );
903 #else
904 y0 = __frsqrte( B );
905 #endif
906 y1 = y0 + half * y0 * ( one - B * y0 * y0 );
907
908 x = x * y1;
909 y = y * y1;
910 components[-4] = x;
911 z = z * y1;
912 components[-3] = y;
913 components[-2] = z;
914 } while ( count-- );
915 }
916 #else // No assembly version for this architecture, or C_ONLY defined
917 // given the input, it's safe to call VectorNormalizeFast
918 while ( count-- ) {
919 VectorNormalizeFast( normals[0] );
920 normals++;
921 }
922 #endif
923 }
924 #endif
925
926
927
928 /*
929 ** LerpMeshVertexes
930 */
931 #if 0 // Unused
932 #if idppc_altivec
933 static void LerpMeshVertexes_altivec(md3Surface_t *surf, float backlerp)
871 static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp)
934872 {
935 short *oldXyz, *newXyz, *oldNormals, *newNormals;
936 float *outXyz, *outNormal;
937 float oldXyzScale QALIGN(16);
938 float newXyzScale QALIGN(16);
939 float oldNormalScale QALIGN(16);
940 float newNormalScale QALIGN(16);
873 float *outXyz;
874 int16_t *outNormal, *outTangent;
875 mdvVertex_t *newVerts;
941876 int vertNum;
942 unsigned lat, lng;
943 int numVerts;
944
945 outXyz = tess.xyz[tess.numVertexes];
946 outNormal = tess.normal[tess.numVertexes];
947
948 newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
949 + (backEnd.currentEntity->e.frame * surf->numVerts * 4);
950 newNormals = newXyz + 3;
951
952 newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
953 newNormalScale = 1.0 - backlerp;
954
955 numVerts = surf->numVerts;
956
957 if ( backlerp == 0 ) {
958 vector signed short newNormalsVec0;
959 vector signed short newNormalsVec1;
960 vector signed int newNormalsIntVec;
961 vector float newNormalsFloatVec;
962 vector float newXyzScaleVec;
963 vector unsigned char newNormalsLoadPermute;
964 vector unsigned char newNormalsStorePermute;
965 vector float zero;
966
967 newNormalsStorePermute = vec_lvsl(0,(float *)&newXyzScaleVec);
968 newXyzScaleVec = *(vector float *)&newXyzScale;
969 newXyzScaleVec = vec_perm(newXyzScaleVec,newXyzScaleVec,newNormalsStorePermute);
970 newXyzScaleVec = vec_splat(newXyzScaleVec,0);
971 newNormalsLoadPermute = vec_lvsl(0,newXyz);
972 newNormalsStorePermute = vec_lvsr(0,outXyz);
973 zero = (vector float)vec_splat_s8(0);
877
878 newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts;
879
880 outXyz = tess.xyz[tess.numVertexes];
881 outNormal = tess.normal[tess.numVertexes];
882 outTangent = tess.tangent[tess.numVertexes];
883
884 if (backlerp == 0)
885 {
974886 //
975887 // just copy the vertexes
976888 //
977 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
978 newXyz += 4, newNormals += 4,
979 outXyz += 4, outNormal += 4)
889
890 for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
980891 {
981 newNormalsLoadPermute = vec_lvsl(0,newXyz);
982 newNormalsStorePermute = vec_lvsr(0,outXyz);
983 newNormalsVec0 = vec_ld(0,newXyz);
984 newNormalsVec1 = vec_ld(16,newXyz);
985 newNormalsVec0 = vec_perm(newNormalsVec0,newNormalsVec1,newNormalsLoadPermute);
986 newNormalsIntVec = vec_unpackh(newNormalsVec0);
987 newNormalsFloatVec = vec_ctf(newNormalsIntVec,0);
988 newNormalsFloatVec = vec_madd(newNormalsFloatVec,newXyzScaleVec,zero);
989 newNormalsFloatVec = vec_perm(newNormalsFloatVec,newNormalsFloatVec,newNormalsStorePermute);
990 //outXyz[0] = newXyz[0] * newXyzScale;
991 //outXyz[1] = newXyz[1] * newXyzScale;
992 //outXyz[2] = newXyz[2] * newXyzScale;
993
994 lat = ( newNormals[0] >> 8 ) & 0xff;
995 lng = ( newNormals[0] & 0xff );
996 lat *= (FUNCTABLE_SIZE/256);
997 lng *= (FUNCTABLE_SIZE/256);
998
999 // decode X as cos( lat ) * sin( long )
1000 // decode Y as sin( lat ) * sin( long )
1001 // decode Z as cos( long )
1002
1003 outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1004 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1005 outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1006
1007 vec_ste(newNormalsFloatVec,0,outXyz);
1008 vec_ste(newNormalsFloatVec,4,outXyz);
1009 vec_ste(newNormalsFloatVec,8,outXyz);
1010 }
1011 } else {
892 VectorCopy(newVerts->xyz, outXyz);
893
894 VectorCopy4(newVerts->normal, outNormal);
895 VectorCopy4(newVerts->tangent, outTangent);
896
897 newVerts++;
898 outXyz += 4;
899 outNormal += 4;
900 outTangent += 4;
901 }
902 }
903 else
904 {
1012905 //
1013906 // interpolate and copy the vertex and normal
1014907 //
1015 oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
1016 + (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
1017 oldNormals = oldXyz + 3;
1018
1019 oldXyzScale = MD3_XYZ_SCALE * backlerp;
1020 oldNormalScale = backlerp;
1021
1022 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
1023 oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
1024 outXyz += 4, outNormal += 4)
1025 {
1026 vec3_t uncompressedOldNormal, uncompressedNewNormal;
1027
1028 // interpolate the xyz
1029 outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
1030 outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
1031 outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
1032
1033 // FIXME: interpolate lat/long instead?
1034 lat = ( newNormals[0] >> 8 ) & 0xff;
1035 lng = ( newNormals[0] & 0xff );
1036 lat *= 4;
1037 lng *= 4;
1038 uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1039 uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1040 uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1041
1042 lat = ( oldNormals[0] >> 8 ) & 0xff;
1043 lng = ( oldNormals[0] & 0xff );
1044 lat *= 4;
1045 lng *= 4;
1046
1047 uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1048 uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1049 uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1050
1051 outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
1052 outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
1053 outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
1054
1055 // VectorNormalize (outNormal);
1056 }
1057 VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
1058 }
1059 }
1060 #endif
1061 #endif
1062
1063 static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
1064 {
1065 #if 0
1066 short *oldXyz, *newXyz, *oldNormals, *newNormals;
1067 float *outXyz, *outNormal;
1068 float oldXyzScale, newXyzScale;
1069 float oldNormalScale, newNormalScale;
1070 int vertNum;
1071 unsigned lat, lng;
1072 int numVerts;
1073
1074 outXyz = tess.xyz[tess.numVertexes];
1075 outNormal = tess.normal[tess.numVertexes];
1076
1077 newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
1078 + (backEnd.currentEntity->e.frame * surf->numVerts * 4);
1079 newNormals = newXyz + 3;
1080
1081 newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
1082 newNormalScale = 1.0 - backlerp;
1083
1084 numVerts = surf->numVerts;
1085
1086 if ( backlerp == 0 ) {
1087 //
1088 // just copy the vertexes
1089 //
1090 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
1091 newXyz += 4, newNormals += 4,
1092 outXyz += 4, outNormal += 4)
1093 {
1094
1095 outXyz[0] = newXyz[0] * newXyzScale;
1096 outXyz[1] = newXyz[1] * newXyzScale;
1097 outXyz[2] = newXyz[2] * newXyzScale;
1098
1099 lat = ( newNormals[0] >> 8 ) & 0xff;
1100 lng = ( newNormals[0] & 0xff );
1101 lat *= (FUNCTABLE_SIZE/256);
1102 lng *= (FUNCTABLE_SIZE/256);
1103
1104 // decode X as cos( lat ) * sin( long )
1105 // decode Y as sin( lat ) * sin( long )
1106 // decode Z as cos( long )
1107
1108 outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1109 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1110 outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1111 }
1112 } else {
1113 //
1114 // interpolate and copy the vertex and normal
1115 //
1116 oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
1117 + (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
1118 oldNormals = oldXyz + 3;
1119
1120 oldXyzScale = MD3_XYZ_SCALE * backlerp;
1121 oldNormalScale = backlerp;
1122
1123 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
1124 oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
1125 outXyz += 4, outNormal += 4)
1126 {
1127 vec3_t uncompressedOldNormal, uncompressedNewNormal;
1128
1129 // interpolate the xyz
1130 outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
1131 outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
1132 outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
1133
1134 // FIXME: interpolate lat/long instead?
1135 lat = ( newNormals[0] >> 8 ) & 0xff;
1136 lng = ( newNormals[0] & 0xff );
1137 lat *= 4;
1138 lng *= 4;
1139 uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1140 uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1141 uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1142
1143 lat = ( oldNormals[0] >> 8 ) & 0xff;
1144 lng = ( oldNormals[0] & 0xff );
1145 lat *= 4;
1146 lng *= 4;
1147
1148 uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1149 uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1150 uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1151
1152 outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
1153 outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
1154 outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
1155
1156 // VectorNormalize (outNormal);
1157 }
1158 VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
1159 }
1160 #endif
1161 float *outXyz;
1162 uint32_t *outNormal;
1163 mdvVertex_t *newVerts;
1164 int vertNum;
1165
1166 newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts;
1167
1168 outXyz = tess.xyz[tess.numVertexes];
1169 outNormal = &tess.normal[tess.numVertexes];
1170
1171 if (backlerp == 0)
1172 {
1173 //
1174 // just copy the vertexes
1175 //
908
909 mdvVertex_t *oldVerts;
910
911 oldVerts = surf->verts + backEnd.currentEntity->e.oldframe * surf->numVerts;
1176912
1177913 for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
1178914 {
1179 vec3_t normal;
1180
1181 VectorCopy(newVerts->xyz, outXyz);
1182 VectorCopy(newVerts->normal, normal);
1183
1184 R_VaoPackNormal((byte *)outNormal, normal);
1185
1186 newVerts++;
1187 outXyz += 4;
1188 outNormal++;
1189 }
1190 }
1191 else
1192 {
1193 //
1194 // interpolate and copy the vertex and normal
1195 //
1196
1197 mdvVertex_t *oldVerts;
1198
1199 oldVerts = surf->verts + backEnd.currentEntity->e.oldframe * surf->numVerts;
1200
1201 for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
1202 {
1203 vec3_t normal;
1204
1205915 VectorLerp(newVerts->xyz, oldVerts->xyz, backlerp, outXyz);
1206 VectorLerp(newVerts->normal, oldVerts->normal, backlerp, normal);
1207 VectorNormalize(normal);
1208
1209 R_VaoPackNormal((byte *)outNormal, normal);
916
917 outNormal[0] = (int16_t)(newVerts->normal[0] * (1.0f - backlerp) + oldVerts->normal[0] * backlerp);
918 outNormal[1] = (int16_t)(newVerts->normal[1] * (1.0f - backlerp) + oldVerts->normal[1] * backlerp);
919 outNormal[2] = (int16_t)(newVerts->normal[2] * (1.0f - backlerp) + oldVerts->normal[2] * backlerp);
920 outNormal[3] = 0;
921
922 outTangent[0] = (int16_t)(newVerts->tangent[0] * (1.0f - backlerp) + oldVerts->tangent[0] * backlerp);
923 outTangent[1] = (int16_t)(newVerts->tangent[1] * (1.0f - backlerp) + oldVerts->tangent[1] * backlerp);
924 outTangent[2] = (int16_t)(newVerts->tangent[2] * (1.0f - backlerp) + oldVerts->tangent[2] * backlerp);
925 outTangent[3] = newVerts->tangent[3];
1210926
1211927 newVerts++;
1212928 oldVerts++;
1213929 outXyz += 4;
1214 outNormal++;
1215 }
1216 }
1217 }
1218
1219 static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp)
1220 {
1221 #if 0
1222 #if idppc_altivec
1223 if (com_altivec->integer) {
1224 // must be in a seperate function or G3 systems will crash.
1225 LerpMeshVertexes_altivec( surf, backlerp );
1226 return;
1227 }
1228 #endif // idppc_altivec
1229 #endif
1230 LerpMeshVertexes_scalar( surf, backlerp );
930 outNormal += 4;
931 outTangent += 4;
932 }
933 }
1231934 }
1232935
1233936
1282985
1283986 }
1284987
1285 /*
1286 ** R_LatLongToNormal
1287 */
1288 void R_LatLongToNormal( vec3_t outNormal, short latLong ) {
1289 unsigned lat, lng;
1290
1291 lat = ( latLong >> 8 ) & 0xff;
1292 lng = ( latLong & 0xff );
1293 lat *= ( FUNCTABLE_SIZE / 256 );
1294 lng *= ( FUNCTABLE_SIZE / 256 );
1295
1296 // decode X as cos( lat ) * sin( long )
1297 // decode Y as sin( lat ) * sin( long )
1298 // decode Z as cos( long )
1299
1300 outNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1301 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1302 outNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1303 }
1304
1305 // Ridah
1306 /*
1307 ** LerpCMeshVertexes
1308 */
1309 static void LerpCMeshVertexes( mdcSurface_t *surf, float backlerp ) {
1310 short *oldXyz, *newXyz, *oldNormals, *newNormals;
1311 float *outXyz;
1312 uint32_t *outNormal;
1313 vec3_t fNormal;
1314 float oldXyzScale, newXyzScale;
1315 float oldNormalScale, newNormalScale;
1316 int vertNum;
1317 unsigned lat, lng;
1318 int numVerts;
1319
1320 int oldBase, newBase;
1321 short *oldComp = NULL, *newComp = NULL; // TTimo: init
1322 mdcXyzCompressed_t *oldXyzComp = NULL, *newXyzComp = NULL; // TTimo: init
1323 vec3_t oldOfsVec, newOfsVec;
1324
1325 qboolean hasComp;
1326
1327 outXyz = tess.xyz[tess.numVertexes];
1328 outNormal = &tess.normal[tess.numVertexes];
1329
1330 newBase = (int)*( ( short * )( (byte *)surf + surf->ofsFrameBaseFrames ) + backEnd.currentEntity->e.frame );
1331 newXyz = ( short * )( (byte *)surf + surf->ofsXyzNormals )
1332 + ( newBase * surf->numVerts * 4 );
1333 newNormals = newXyz + 3;
1334
1335 hasComp = ( surf->numCompFrames > 0 );
1336 if ( hasComp ) {
1337 newComp = ( ( short * )( (byte *)surf + surf->ofsFrameCompFrames ) + backEnd.currentEntity->e.frame );
1338 if ( *newComp >= 0 ) {
1339 newXyzComp = ( mdcXyzCompressed_t * )( (byte *)surf + surf->ofsXyzCompressed )
1340 + ( *newComp * surf->numVerts );
1341 }
1342 }
1343
1344 newXyzScale = MD3_XYZ_SCALE * ( 1.0 - backlerp );
1345 newNormalScale = 1.0 - backlerp;
1346
1347 numVerts = surf->numVerts;
1348
1349 if ( backlerp == 0 ) {
1350 //
1351 // just copy the vertexes
1352 //
1353 for ( vertNum = 0 ; vertNum < numVerts ; vertNum++,
1354 newXyz += 4, newNormals += 4,
1355 outXyz += 4, outNormal++ )
1356 {
1357
1358 outXyz[0] = newXyz[0] * newXyzScale;
1359 outXyz[1] = newXyz[1] * newXyzScale;
1360 outXyz[2] = newXyz[2] * newXyzScale;
1361
1362 // add the compressed ofsVec
1363 if ( hasComp && *newComp >= 0 ) {
1364 R_MDC_DecodeXyzCompressed( newXyzComp->ofsVec, newOfsVec, fNormal );
1365 newXyzComp++;
1366 VectorAdd( outXyz, newOfsVec, outXyz );
1367 } else {
1368 lat = ( newNormals[0] >> 8 ) & 0xff;
1369 lng = ( newNormals[0] & 0xff );
1370 lat *= 4;
1371 lng *= 4;
1372
1373 fNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1374 fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1375 fNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1376 }
1377
1378 R_VaoPackNormal((byte *)outNormal, fNormal);
1379 }
1380 } else {
1381 //
1382 // interpolate and copy the vertex and normal
1383 //
1384 oldBase = (int)*( ( short * )( (byte *)surf + surf->ofsFrameBaseFrames ) + backEnd.currentEntity->e.oldframe );
1385 oldXyz = ( short * )( (byte *)surf + surf->ofsXyzNormals )
1386 + ( oldBase * surf->numVerts * 4 );
1387 oldNormals = oldXyz + 3;
1388
1389 if ( hasComp ) {
1390 oldComp = ( ( short * )( (byte *)surf + surf->ofsFrameCompFrames ) + backEnd.currentEntity->e.oldframe );
1391 if ( *oldComp >= 0 ) {
1392 oldXyzComp = ( mdcXyzCompressed_t * )( (byte *)surf + surf->ofsXyzCompressed )
1393 + ( *oldComp * surf->numVerts );
1394 }
1395 }
1396
1397 oldXyzScale = MD3_XYZ_SCALE * backlerp;
1398 oldNormalScale = backlerp;
1399
1400 for ( vertNum = 0 ; vertNum < numVerts ; vertNum++,
1401 oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
1402 outXyz += 4, outNormal++ )
1403 {
1404 vec3_t uncompressedOldNormal, uncompressedNewNormal;
1405
1406 // interpolate the xyz
1407 outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
1408 outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
1409 outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
1410
1411 // add the compressed ofsVec
1412 if ( hasComp && *newComp >= 0 ) {
1413 R_MDC_DecodeXyzCompressed( newXyzComp->ofsVec, newOfsVec, uncompressedNewNormal );
1414 newXyzComp++;
1415 VectorMA( outXyz, 1.0 - backlerp, newOfsVec, outXyz );
1416 } else {
1417 lat = ( newNormals[0] >> 8 ) & 0xff;
1418 lng = ( newNormals[0] & 0xff );
1419 lat *= 4;
1420 lng *= 4;
1421
1422 uncompressedNewNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1423 uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1424 uncompressedNewNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1425 }
1426
1427 if ( hasComp && *oldComp >= 0 ) {
1428 R_MDC_DecodeXyzCompressed( oldXyzComp->ofsVec, oldOfsVec, uncompressedOldNormal );
1429 oldXyzComp++;
1430 VectorMA( outXyz, backlerp, oldOfsVec, outXyz );
1431 } else {
1432 lat = ( oldNormals[0] >> 8 ) & 0xff;
1433 lng = ( oldNormals[0] & 0xff );
1434 lat *= 4;
1435 lng *= 4;
1436
1437 uncompressedOldNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1438 uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1439 uncompressedOldNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1440 }
1441
1442 fNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
1443 fNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
1444 fNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
1445
1446 VectorNormalize( fNormal );
1447
1448 R_VaoPackNormal((byte *)outNormal, fNormal);
1449 }
1450 }
1451 }
1452
1453 /*
1454 =============
1455 RB_SurfaceCMesh
1456 =============
1457 */
1458 void RB_SurfaceCMesh( mdcSurface_t *surface ) {
1459 int j;
1460 float backlerp;
1461 int *triangles;
1462 float *texCoords;
1463 int indexes;
1464 int Bob, Doug;
1465 int numVerts;
1466
1467 // RF, check for REFLAG_HANDONLY
1468 if ( backEnd.currentEntity->e.reFlags & REFLAG_ONLYHAND ) {
1469 if ( !strstr( surface->name, "hand" ) ) {
1470 return;
1471 }
1472 }
1473
1474 if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
1475 backlerp = 0;
1476 } else {
1477 backlerp = backEnd.currentEntity->e.backlerp;
1478 }
1479
1480 RB_CheckVao(tess.vao);
1481
1482 RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles * 3 );
1483
1484 LerpCMeshVertexes( surface, backlerp );
1485
1486 triangles = ( int * )( (byte *)surface + surface->ofsTriangles );
1487 indexes = surface->numTriangles * 3;
1488 Bob = tess.numIndexes;
1489 Doug = tess.numVertexes;
1490 for ( j = 0 ; j < indexes ; j++ ) {
1491 tess.indexes[Bob + j] = Doug + triangles[j];
1492 }
1493 tess.numIndexes += indexes;
1494
1495 texCoords = ( float * )( (byte *)surface + surface->ofsSt );
1496
1497 numVerts = surface->numVerts;
1498 for ( j = 0; j < numVerts; j++ ) {
1499 tess.texCoords[Doug + j][0][0] = texCoords[j * 2 + 0];
1500 tess.texCoords[Doug + j][0][1] = texCoords[j * 2 + 1];
1501 // FIXME: fill in lightmapST for completeness?
1502 }
1503
1504 tess.numVertexes += surface->numVerts;
1505
1506 }
1507 // done.
1508988
1509989 /*
1510990 ==============
15641044 int i, j;
15651045 float *xyz;
15661046 float *texCoords, *lightCoords;
1567 uint32_t *normal;
1568 #ifdef USE_VERT_TANGENT_SPACE
1569 uint32_t *tangent;
1570 #endif
1571 float *color;
1572 uint32_t *lightdir;
1047 int16_t *normal;
1048 int16_t *tangent;
1049 uint16_t *color;
1050 int16_t *lightdir;
15731051 srfVert_t *dv;
15741052 int rows, irows, vrows;
15751053 int used;
16541132 numVertexes = tess.numVertexes;
16551133
16561134 xyz = tess.xyz[numVertexes];
1657 normal = &tess.normal[numVertexes];
1658 #ifdef USE_VERT_TANGENT_SPACE
1659 tangent = &tess.tangent[numVertexes];
1660 #endif
1135 normal = tess.normal[numVertexes];
1136 tangent = tess.tangent[numVertexes];
16611137 texCoords = tess.texCoords[numVertexes][0];
16621138 lightCoords = tess.texCoords[numVertexes][1];
1663 color = tess.vertexColors[numVertexes];
1664 lightdir = &tess.lightdir[numVertexes];
1139 color = tess.color[numVertexes];
1140 lightdir = tess.lightdir[numVertexes];
16651141 //vDlightBits = &tess.vertexDlightBits[numVertexes];
16661142
16671143 for ( i = 0 ; i < rows ; i++ ) {
16771153
16781154 if ( tess.shader->vertexAttribs & ATTR_NORMAL )
16791155 {
1680 R_VaoPackNormal((byte *)normal++, dv->normal);
1156 VectorCopy4(dv->normal, normal);
1157 normal += 4;
16811158 }
16821159
1683 #ifdef USE_VERT_TANGENT_SPACE
16841160 if ( tess.shader->vertexAttribs & ATTR_TANGENT )
16851161 {
1686 R_VaoPackTangent((byte *)tangent++, dv->tangent);
1162 VectorCopy4(dv->tangent, tangent);
1163 tangent += 4;
16871164 }
1688 #endif
16891165
16901166 if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
16911167 {
17011177
17021178 if ( tess.shader->vertexAttribs & ATTR_COLOR )
17031179 {
1704 VectorCopy4(dv->vertexColors, color);
1180 VectorCopy4(dv->color, color);
17051181 color += 4;
17061182 }
17071183
17081184 if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
17091185 {
1710 R_VaoPackNormal((byte *)lightdir++, dv->lightdir);
1186 VectorCopy4(dv->lightdir, lightdir);
1187 lightdir += 4;
17111188 }
17121189
17131190 //*vDlightBits++ = dlightBits;
17711248 */
17721249 static void RB_SurfaceAxis( void ) {
17731250 #if 0
1774 GL_Bind( tr.whiteImage );
1251 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
17751252 GL_State( GLS_DEFAULT );
17761253 qglLineWidth( 3 );
17771254 qglBegin( GL_LINES );
18471324
18481325 GLimp_LogComment("--- RB_SurfaceVaoMdvMesh ---\n");
18491326
1327 if (ShaderRequiresCPUDeforms(tess.shader))
1328 {
1329 RB_SurfaceMesh(surface->mdvSurface);
1330 return;
1331 }
1332
18501333 if(!surface->vao)
18511334 return;
18521335
18791362
18801363 if (glRefConfig.vertexArrayObject)
18811364 {
1882 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, surface->vao->vertexesVBO);
1365 qglBindBuffer(GL_ARRAY_BUFFER, surface->vao->vertexesVBO);
18831366 }
18841367
18851368 frameOffset = refEnt->frame * surface->vao->frameSize;
18861369
18871370 attribIndex = ATTR_INDEX_POSITION;
18881371 vAtb = &surface->vao->attribs[attribIndex];
1889 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1372 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
18901373
18911374 attribIndex = ATTR_INDEX_NORMAL;
18921375 vAtb = &surface->vao->attribs[attribIndex];
1893 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1376 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
18941377
18951378 attribIndex = ATTR_INDEX_TANGENT;
18961379 vAtb = &surface->vao->attribs[attribIndex];
1897 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1380 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
18981381
18991382 frameOffset = refEnt->oldframe * surface->vao->frameSize;
19001383
19011384 attribIndex = ATTR_INDEX_POSITION2;
19021385 vAtb = &surface->vao->attribs[attribIndex];
1903 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1386 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
19041387
19051388 attribIndex = ATTR_INDEX_NORMAL2;
19061389 vAtb = &surface->vao->attribs[attribIndex];
1907 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1390 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
19081391
19091392 attribIndex = ATTR_INDEX_TANGENT2;
19101393 vAtb = &surface->vao->attribs[attribIndex];
1911 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1394 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
19121395
19131396
19141397 if (!glRefConfig.vertexArrayObject)
19151398 {
19161399 attribIndex = ATTR_INDEX_TEXCOORD;
19171400 vAtb = &surface->vao->attribs[attribIndex];
1918 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
1401 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
19191402 }
19201403 }
19211404
19371420 ( void( * ) ( void* ) )RB_SurfaceTriangles, // SF_TRIANGLES,
19381421 ( void( * ) ( void* ) )RB_SurfacePolychain, // SF_POLY,
19391422 ( void( * ) ( void* ) )RB_SurfaceMesh, // SF_MDV,
1940 ( void( * ) ( void* ) )RB_SurfaceCMesh, // SF_MDC,
19411423 ( void( * ) ( void* ) )RB_SurfaceAnim, // SF_MDS,
19421424 ( void( * ) ( void* ) )RB_MDRSurfaceAnim, // SF_MDR,
19431425 ( void( * ) ( void* ) )RB_IQMSurfaceAnim, // SF_IQM,
2222 #include "tr_local.h"
2323
2424
25 union pack10_u {
26 struct {
27 signed int x:10;
28 signed int y:10;
29 signed int z:10;
30 signed int w:2;
31 } pack;
32 uint32_t i;
33 };
34
35 union pack8_u {
36 struct {
37 signed int x:8;
38 signed int y:8;
39 signed int z:8;
40 signed int w:8;
41 } pack;
42 uint32_t i;
43 };
44
45
46 int R_VaoPackTangent(byte *out, vec4_t v)
47 {
48 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
49 {
50 union pack10_u *num = (union pack10_u *)out;
51
52 num->pack.x = v[0] * 511.0f;
53 num->pack.y = v[1] * 511.0f;
54 num->pack.z = v[2] * 511.0f;
55 num->pack.w = v[3];
56 }
57 else
58 {
59 union pack8_u *num = (union pack8_u *)out;
60
61 num->pack.x = v[0] * 127.0f;
62 num->pack.y = v[1] * 127.0f;
63 num->pack.z = v[2] * 127.0f;
64 num->pack.w = v[3] * 127.0f;
65 }
66
67 return 4;
68 }
69
70 int R_VaoPackNormal(byte *out, vec3_t v)
71 {
72 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
73 {
74 union pack10_u *num = (union pack10_u *)out;
75
76 num->pack.x = v[0] * 511.0f;
77 num->pack.y = v[1] * 511.0f;
78 num->pack.z = v[2] * 511.0f;
79 num->pack.w = 0;
80 }
81 else
82 {
83 union pack8_u *num = (union pack8_u *)out;
84
85 num->pack.x = v[0] * 127.0f;
86 num->pack.y = v[1] * 127.0f;
87 num->pack.z = v[2] * 127.0f;
88 num->pack.w = 0;
89 }
90
91 return 4;
92 }
93
94 int R_VaoPackTexCoord(byte *out, vec2_t st)
95 {
96 if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
97 {
98 uint16_t *num = (uint16_t *)out;
99
100 *num++ = FloatToHalf(st[0]);
101 *num++ = FloatToHalf(st[1]);
102
103 return sizeof(*num) * 2;
104 }
105 else
106 {
107 float *num = (float *)out;
108
109 *num++ = st[0];
110 *num++ = st[1];
111
112 return sizeof(*num) * 2;
113 }
114 }
115
116 int R_VaoPackColors(byte *out, vec4_t color)
117 {
118 if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
119 {
120 uint16_t *num = (uint16_t *)out;
121
122 *num++ = FloatToHalf(color[0]);
123 *num++ = FloatToHalf(color[1]);
124 *num++ = FloatToHalf(color[2]);
125 *num++ = FloatToHalf(color[3]);
126
127 return sizeof(*num) * 4;
128 }
129 else
130 {
131 float *num = (float *)out;
132
133 *num++ = color[0];
134 *num++ = color[1];
135 *num++ = color[2];
136 *num++ = color[3];
137
138 return sizeof(*num) * 4;
139 }
140 }
141
142
143 void R_VaoUnpackTangent(vec4_t v, uint32_t b)
144 {
145 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
146 {
147 union pack10_u *num = (union pack10_u *)&b;
148
149 v[0] = num->pack.x / 511.0f;
150 v[1] = num->pack.y / 511.0f;
151 v[2] = num->pack.z / 511.0f;
152 v[3] = num->pack.w;
153 }
154 else
155 {
156 union pack8_u *num = (union pack8_u *)&b;
157
158 v[0] = num->pack.x / 127.0f;
159 v[1] = num->pack.y / 127.0f;
160 v[2] = num->pack.z / 127.0f;
161 v[3] = num->pack.w / 127.0f;
162 }
163 }
164
165 void R_VaoUnpackNormal(vec3_t v, uint32_t b)
166 {
167 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
168 {
169 union pack10_u *num = (union pack10_u *)&b;
170
171 v[0] = num->pack.x / 511.0f;
172 v[1] = num->pack.y / 511.0f;
173 v[2] = num->pack.z / 511.0f;
174 }
175 else
176 {
177 union pack8_u *num = (union pack8_u *)&b;
178
179 v[0] = num->pack.x / 127.0f;
180 v[1] = num->pack.y / 127.0f;
181 v[2] = num->pack.z / 127.0f;
182 }
183 }
184
25 void R_VaoPackTangent(int16_t *out, vec4_t v)
26 {
27 out[0] = v[0] * 32767.0f + (v[0] > 0.0f ? 0.5f : -0.5f);
28 out[1] = v[1] * 32767.0f + (v[1] > 0.0f ? 0.5f : -0.5f);
29 out[2] = v[2] * 32767.0f + (v[2] > 0.0f ? 0.5f : -0.5f);
30 out[3] = v[3] * 32767.0f + (v[3] > 0.0f ? 0.5f : -0.5f);
31 }
32
33 void R_VaoPackNormal(int16_t *out, vec3_t v)
34 {
35 out[0] = v[0] * 32767.0f + (v[0] > 0.0f ? 0.5f : -0.5f);
36 out[1] = v[1] * 32767.0f + (v[1] > 0.0f ? 0.5f : -0.5f);
37 out[2] = v[2] * 32767.0f + (v[2] > 0.0f ? 0.5f : -0.5f);
38 out[3] = 0;
39 }
40
41 void R_VaoPackColor(uint16_t *out, vec4_t c)
42 {
43 out[0] = c[0] * 65535.0f + 0.5f;
44 out[1] = c[1] * 65535.0f + 0.5f;
45 out[2] = c[2] * 65535.0f + 0.5f;
46 out[3] = c[3] * 65535.0f + 0.5f;
47 }
48
49 void R_VaoUnpackTangent(vec4_t v, int16_t *pack)
50 {
51 v[0] = pack[0] / 32767.0f;
52 v[1] = pack[1] / 32767.0f;
53 v[2] = pack[2] / 32767.0f;
54 v[3] = pack[3] / 32767.0f;
55 }
56
57 void R_VaoUnpackNormal(vec3_t v, int16_t *pack)
58 {
59 v[0] = pack[0] / 32767.0f;
60 v[1] = pack[1] / 32767.0f;
61 v[2] = pack[2] / 32767.0f;
62 }
18563
18664 void Vao_SetVertexPointers(vao_t *vao)
18765 {
19573
19674 if (vAtb->enabled)
19775 {
198 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
76 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
19977 if (glRefConfig.vertexArrayObject || !(glState.vertexAttribsEnabled & attribBit))
200 qglEnableVertexAttribArrayARB(attribIndex);
78 qglEnableVertexAttribArray(attribIndex);
20179
20280 if (!glRefConfig.vertexArrayObject || vao == tess.vao)
20381 glState.vertexAttribsEnabled |= attribBit;
20785 // don't disable vertex attribs when using vertex array objects
20886 // Vao_SetVertexPointers is only called during init when using VAOs, and vertex attribs start disabled anyway
20987 if (!glRefConfig.vertexArrayObject && (glState.vertexAttribsEnabled & attribBit))
210 qglDisableVertexAttribArrayARB(attribIndex);
88 qglDisableVertexAttribArray(attribIndex);
21189
21290 if (!glRefConfig.vertexArrayObject || vao == tess.vao)
21391 glState.vertexAttribsEnabled &= ~attribBit;
228106 switch (usage)
229107 {
230108 case VAO_USAGE_STATIC:
231 glUsage = GL_STATIC_DRAW_ARB;
109 glUsage = GL_STATIC_DRAW;
232110 break;
233111
234112 case VAO_USAGE_DYNAMIC:
235 glUsage = GL_DYNAMIC_DRAW_ARB;
113 glUsage = GL_DYNAMIC_DRAW;
236114 break;
237115
238116 default:
261139
262140 if (glRefConfig.vertexArrayObject)
263141 {
264 qglGenVertexArraysARB(1, &vao->vao);
265 qglBindVertexArrayARB(vao->vao);
142 qglGenVertexArrays(1, &vao->vao);
143 qglBindVertexArray(vao->vao);
266144 }
267145
268146
269147 vao->vertexesSize = vertexesSize;
270148
271 qglGenBuffersARB(1, &vao->vertexesVBO);
272
273 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
274 qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexesSize, vertexes, glUsage);
149 qglGenBuffers(1, &vao->vertexesVBO);
150
151 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
152 qglBufferData(GL_ARRAY_BUFFER, vertexesSize, vertexes, glUsage);
275153
276154
277155 vao->indexesSize = indexesSize;
278156
279 qglGenBuffersARB(1, &vao->indexesIBO);
280
281 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesIBO);
282 qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexesSize, indexes, glUsage);
157 qglGenBuffers(1, &vao->indexesIBO);
158
159 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
160 qglBufferData(GL_ELEMENT_ARRAY_BUFFER, indexesSize, indexes, glUsage);
283161
284162
285163 glState.currentVao = vao;
303181 int dataSize;
304182 int dataOfs;
305183
306 int glUsage = GL_STATIC_DRAW_ARB;
184 int glUsage = GL_STATIC_DRAW;
307185
308186 if(!numVertexes || !numIndexes)
309187 return NULL;
329207 // since these vertex attributes are never altered, interleave them
330208 vao->attribs[ATTR_INDEX_POSITION ].enabled = 1;
331209 vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
332 #ifdef USE_VERT_TANGENT_SPACE
333210 vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
334 #endif
335211 vao->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1;
336212 vao->attribs[ATTR_INDEX_LIGHTCOORD ].enabled = 1;
337213 vao->attribs[ATTR_INDEX_COLOR ].enabled = 1;
346222 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4;
347223
348224 vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT;
349 vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
350 vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
351 vao->attribs[ATTR_INDEX_TEXCOORD ].type = glRefConfig.packedTexcoordDataType;
352 vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = glRefConfig.packedTexcoordDataType;
353 vao->attribs[ATTR_INDEX_COLOR ].type = glRefConfig.packedColorDataType;
354 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType;
225 vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
226 vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
227 vao->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT;
228 vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT;
229 vao->attribs[ATTR_INDEX_COLOR ].type = GL_UNSIGNED_SHORT;
230 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = GL_SHORT;
355231
356232 vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE;
357233 vao->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE;
358234 vao->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE;
359235 vao->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE;
360236 vao->attribs[ATTR_INDEX_LIGHTCOORD ].normalized = GL_FALSE;
361 vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_FALSE;
237 vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_TRUE;
362238 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE;
363239
364240 vao->attribs[ATTR_INDEX_POSITION ].offset = 0; dataSize = sizeof(verts[0].xyz);
365 vao->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(uint32_t);
366 #ifdef USE_VERT_TANGENT_SPACE
367 vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(uint32_t);
368 #endif
369 vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize;
370 vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize;
371 vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += glRefConfig.packedColorDataSize;
372 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(uint32_t);
241 vao->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(verts[0].normal);
242 vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(verts[0].tangent);
243 vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += sizeof(verts[0].st);
244 vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += sizeof(verts[0].lightmap);
245 vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += sizeof(verts[0].color);
246 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(verts[0].lightdir);
373247
374248 vao->attribs[ATTR_INDEX_POSITION ].stride = dataSize;
375249 vao->attribs[ATTR_INDEX_NORMAL ].stride = dataSize;
382256
383257 if (glRefConfig.vertexArrayObject)
384258 {
385 qglGenVertexArraysARB(1, &vao->vao);
386 qglBindVertexArrayARB(vao->vao);
259 qglGenVertexArrays(1, &vao->vao);
260 qglBindVertexArray(vao->vao);
387261 }
388262
389263
399273 dataOfs += sizeof(verts[i].xyz);
400274
401275 // normal
402 dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].normal);
403
404 #ifdef USE_VERT_TANGENT_SPACE
276 memcpy(data + dataOfs, &verts[i].normal, sizeof(verts[i].normal));
277 dataOfs += sizeof(verts[i].normal);
278
405279 // tangent
406 dataOfs += R_VaoPackTangent(data + dataOfs, verts[i].tangent);
407 #endif
280 memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent));
281 dataOfs += sizeof(verts[i].tangent);
408282
409283 // texcoords
410 dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].st);
284 memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st));
285 dataOfs += sizeof(verts[i].st);
411286
412287 // lightmap texcoords
413 dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].lightmap);
288 memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap));
289 dataOfs += sizeof(verts[i].lightmap);
414290
415291 // colors
416 dataOfs += R_VaoPackColors(data + dataOfs, verts[i].vertexColors);
292 memcpy(data + dataOfs, &verts[i].color, sizeof(verts[i].color));
293 dataOfs += sizeof(verts[i].color);
417294
418295 // light directions
419 dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].lightdir);
296 memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
297 dataOfs += sizeof(verts[i].lightdir);
420298 }
421299
422300 vao->vertexesSize = dataSize;
423301
424 qglGenBuffersARB(1, &vao->vertexesVBO);
425
426 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
427 qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vao->vertexesSize, data, glUsage);
302 qglGenBuffers(1, &vao->vertexesVBO);
303
304 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
305 qglBufferData(GL_ARRAY_BUFFER, vao->vertexesSize, data, glUsage);
428306
429307
430308 // create IBO
431309 vao->indexesSize = numIndexes * sizeof(glIndex_t);
432310
433 qglGenBuffersARB(1, &vao->indexesIBO);
434
435 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesIBO);
436 qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesSize, indexes, glUsage);
311 qglGenBuffers(1, &vao->indexesIBO);
312
313 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
314 qglBufferData(GL_ELEMENT_ARRAY_BUFFER, vao->indexesSize, indexes, glUsage);
437315
438316
439317 Vao_SetVertexPointers(vao);
479357
480358 if (glRefConfig.vertexArrayObject)
481359 {
482 qglBindVertexArrayARB(vao->vao);
360 qglBindVertexArray(vao->vao);
483361
484362 // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel?
485363 if (1)
486 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
364 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
487365
488366 // tess VAO always has buffers bound
489367 if (vao == tess.vao)
490 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
368 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
491369 }
492370 else
493371 {
494 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
495 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesIBO);
372 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
373 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
496374
497375 // tess VAO doesn't have vertex pointers set until data is uploaded
498376 if (vao != tess.vao)
514392 {
515393 if (glRefConfig.vertexArrayObject)
516394 {
517 qglBindVertexArrayARB(0);
395 qglBindVertexArray(0);
518396
519397 // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel?
520 if (1) qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
398 if (1) qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
521399 }
522400 else
523401 {
524 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
525 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
402 qglBindBuffer(GL_ARRAY_BUFFER, 0);
403 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
526404 }
527405 glState.currentVao = NULL;
528406 }
547425
548426 vertexesSize = sizeof(tess.xyz[0]);
549427 vertexesSize += sizeof(tess.normal[0]);
550 #ifdef USE_VERT_TANGENT_SPACE
551428 vertexesSize += sizeof(tess.tangent[0]);
552 #endif
553 vertexesSize += sizeof(tess.vertexColors[0]);
429 vertexesSize += sizeof(tess.color[0]);
554430 vertexesSize += sizeof(tess.texCoords[0][0]) * 2;
555431 vertexesSize += sizeof(tess.lightdir[0]);
556432 vertexesSize *= SHADER_MAX_VERTEXES;
563439
564440 tess.vao->attribs[ATTR_INDEX_POSITION ].enabled = 1;
565441 tess.vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
566 #ifdef USE_VERT_TANGENT_SPACE
567442 tess.vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
568 #endif
569443 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1;
570444 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].enabled = 1;
571445 tess.vao->attribs[ATTR_INDEX_COLOR ].enabled = 1;
580454 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4;
581455
582456 tess.vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT;
583 tess.vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
584 tess.vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
457 tess.vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
458 tess.vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
585459 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT;
586460 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT;
587 tess.vao->attribs[ATTR_INDEX_COLOR ].type = GL_FLOAT;
588 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType;
461 tess.vao->attribs[ATTR_INDEX_COLOR ].type = GL_UNSIGNED_SHORT;
462 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = GL_SHORT;
589463
590464 tess.vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE;
591465 tess.vao->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE;
592466 tess.vao->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE;
593467 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE;
594468 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].normalized = GL_FALSE;
595 tess.vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_FALSE;
469 tess.vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_TRUE;
596470 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE;
597471
598472 tess.vao->attribs[ATTR_INDEX_POSITION ].offset = offset; offset += sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES;
599473 tess.vao->attribs[ATTR_INDEX_NORMAL ].offset = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES;
600 #ifdef USE_VERT_TANGENT_SPACE
601474 tess.vao->attribs[ATTR_INDEX_TANGENT ].offset = offset; offset += sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES;
602 #endif
603475 // these next two are actually interleaved
604476 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].offset = offset;
605477 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = offset + sizeof(tess.texCoords[0][0]);
606478 offset += sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES;
607479
608 tess.vao->attribs[ATTR_INDEX_COLOR ].offset = offset; offset += sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES;
480 tess.vao->attribs[ATTR_INDEX_COLOR ].offset = offset; offset += sizeof(tess.color[0]) * SHADER_MAX_VERTEXES;
609481 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = offset;
610482
611483 tess.vao->attribs[ATTR_INDEX_POSITION ].stride = sizeof(tess.xyz[0]);
612484 tess.vao->attribs[ATTR_INDEX_NORMAL ].stride = sizeof(tess.normal[0]);
613 #ifdef USE_VERT_TANGENT_SPACE
614485 tess.vao->attribs[ATTR_INDEX_TANGENT ].stride = sizeof(tess.tangent[0]);
615 #endif
616 tess.vao->attribs[ATTR_INDEX_COLOR ].stride = sizeof(tess.vertexColors[0]);
486 tess.vao->attribs[ATTR_INDEX_COLOR ].stride = sizeof(tess.color[0]);
617487 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2;
618488 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2;
619489 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].stride = sizeof(tess.lightdir[0]);
621491 tess.attribPointers[ATTR_INDEX_POSITION] = tess.xyz;
622492 tess.attribPointers[ATTR_INDEX_TEXCOORD] = tess.texCoords;
623493 tess.attribPointers[ATTR_INDEX_NORMAL] = tess.normal;
624 #ifdef USE_VERT_TANGENT_SPACE
625494 tess.attribPointers[ATTR_INDEX_TANGENT] = tess.tangent;
626 #endif
627 tess.attribPointers[ATTR_INDEX_COLOR] = tess.vertexColors;
495 tess.attribPointers[ATTR_INDEX_COLOR] = tess.color;
628496 tess.attribPointers[ATTR_INDEX_LIGHTDIRECTION] = tess.lightdir;
629497
630498 Vao_SetVertexPointers(tess.vao);
653521 vao = tr.vaos[i];
654522
655523 if(vao->vao)
656 qglDeleteVertexArraysARB(1, &vao->vao);
524 qglDeleteVertexArrays(1, &vao->vao);
657525
658526 if(vao->vertexesVBO)
659527 {
660 qglDeleteBuffersARB(1, &vao->vertexesVBO);
528 qglDeleteBuffers(1, &vao->vertexesVBO);
661529 }
662530
663531 if(vao->indexesIBO)
664532 {
665 qglDeleteBuffersARB(1, &vao->indexesIBO);
533 qglDeleteBuffers(1, &vao->indexesIBO);
666534 }
667535 }
668536
736604 R_BindVao(tess.vao);
737605
738606 // orphan old vertex buffer so we don't stall on it
739 qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vao->vertexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
607 qglBufferData(GL_ARRAY_BUFFER, tess.vao->vertexesSize, NULL, GL_DYNAMIC_DRAW);
740608
741609 // if nothing to set, set everything
742610 if(!(attribBits & ATTR_BITS))
760628 if (attribUpload & attribBit)
761629 {
762630 // note: tess has a VBO where stride == size
763 qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vAtb->offset, tess.numVertexes * vAtb->stride, tess.attribPointers[attribIndex]);
631 qglBufferSubData(GL_ARRAY_BUFFER, vAtb->offset, tess.numVertexes * vAtb->stride, tess.attribPointers[attribIndex]);
764632 }
765633
766634 if (attribBits & attribBit)
767635 {
768636 if (!glRefConfig.vertexArrayObject)
769 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
637 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
770638
771639 if (!(glState.vertexAttribsEnabled & attribBit))
772640 {
773 qglEnableVertexAttribArrayARB(attribIndex);
641 qglEnableVertexAttribArray(attribIndex);
774642 glState.vertexAttribsEnabled |= attribBit;
775643 }
776644 }
778646 {
779647 if ((glState.vertexAttribsEnabled & attribBit))
780648 {
781 qglDisableVertexAttribArrayARB(attribIndex);
649 qglDisableVertexAttribArray(attribIndex);
782650 glState.vertexAttribsEnabled &= ~attribBit;
783651 }
784652 }
785653 }
786654
787655 // orphan old index buffer so we don't stall on it
788 qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, tess.vao->indexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
789
790 qglBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes);
791 }
792 }
656 qglBufferData(GL_ELEMENT_ARRAY_BUFFER, tess.vao->indexesSize, NULL, GL_DYNAMIC_DRAW);
657
658 qglBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes);
659 }
660 }
463463 R_RecursiveWorldNode
464464 ================
465465 */
466 static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits, int pshadowBits ) {
466 static void R_RecursiveWorldNode( mnode_t *node, uint32_t planeBits, uint32_t dlightBits, uint32_t pshadowBits ) {
467467
468468 do {
469 int newDlights[2];
470 unsigned int newPShadows[2];
469 uint32_t newDlights[2];
470 uint32_t newPShadows[2];
471471
472472 // if the node wasn't marked as potentially visible, exit
473473 // pvs is skipped for depth shadows
809809 =============
810810 */
811811 void R_AddWorldSurfaces( void ) {
812 int planeBits, dlightBits, pshadowBits;
812 uint32_t planeBits, dlightBits, pshadowBits;
813813
814814 if ( !r_drawworld->integer ) {
815815 return;
830830 ClearBounds( tr.viewParms.visBounds[0], tr.viewParms.visBounds[1] );
831831
832832 // perform frustum culling and flag all the potentially visible surfaces
833 if ( tr.refdef.num_dlights > 32 ) {
834 tr.refdef.num_dlights = 32 ;
835 }
836
837 if ( tr.refdef.num_pshadows > 32 ) {
838 tr.refdef.num_pshadows = 32 ;
833 if ( tr.refdef.num_dlights > MAX_DLIGHTS ) {
834 tr.refdef.num_dlights = MAX_DLIGHTS ;
835 }
836
837 if ( tr.refdef.num_pshadows > MAX_DRAWN_PSHADOWS ) {
838 tr.refdef.num_pshadows = MAX_DRAWN_PSHADOWS;
839839 }
840840
841841 planeBits = (tr.viewParms.flags & VPF_FARPLANEFRUSTUM) ? 31 : 15;
847847 }
848848 else if ( !(tr.viewParms.flags & VPF_SHADOWMAP) )
849849 {
850 dlightBits = ( 1 << tr.refdef.num_dlights ) - 1;
851 pshadowBits = ( 1 << tr.refdef.num_pshadows ) - 1;
850 dlightBits = ( 1ULL << tr.refdef.num_dlights ) - 1;
851 pshadowBits = ( 1ULL << tr.refdef.num_pshadows ) - 1;
852852 }
853853 else
854854 {
855 dlightBits = ( 1 << tr.refdef.num_dlights ) - 1;
855 dlightBits = ( 1ULL << tr.refdef.num_dlights ) - 1;
856856 pshadowBits = 0;
857857 }
858858
00 /*
11 ===========================================================================
2 Copyright (C) 1999-2005 Id Software, Inc.
3
4 This file is part of Quake III Arena source code.
5
6 Quake III Arena source code is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 Quake III Arena source code is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
2
3 Return to Castle Wolfenstein multiplayer GPL Source Code
4 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
5
6 This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (“RTCW MP Source Code”).
7
8 RTCW MP Source Code is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 RTCW MP Source Code is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
1315 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1416 GNU General Public License for more details.
1517
1618 You should have received a copy of the GNU General Public License
17 along with Quake III Arena source code; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 along with RTCW MP Source Code. If not, see <http://www.gnu.org/licenses/>.
20
21 In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code. If not, please request a copy in writing from id Software at the address below.
22
23 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
24
1925 ===========================================================================
2026 */
27
2128 /*
2229 ** QGL.H
2330 */
4451 #endif
4552 #endif
4653
47 extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
48 extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
49 extern void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
50
51 extern void ( APIENTRY * qglLockArraysEXT )( GLint, GLint );
52 extern void ( APIENTRY * qglUnlockArraysEXT )( void );
54 extern void (APIENTRYP qglActiveTextureARB) (GLenum texture);
55 extern void (APIENTRYP qglClientActiveTextureARB) (GLenum texture);
56 extern void (APIENTRYP qglMultiTexCoord2fARB) (GLenum target, GLfloat s, GLfloat t);
57
58 extern void (APIENTRYP qglLockArraysEXT) (GLint first, GLsizei count);
59 extern void (APIENTRYP qglUnlockArraysEXT) (void);
5360
5461 #ifdef USE_OPENGLES
5562 #define GLdouble GLfloat
8491 // GL_ATI_pn_triangles
8592 #ifndef GL_ATI_pn_triangles
8693 #define GL_ATI_pn_triangles 1
87 #ifndef MACOS_X //DAJ BUGFIX changed the numbers
94 #ifndef __APPLE__ //DAJ BUGFIX changed the numbers
8895 #define GL_PN_TRIANGLES_ATI 0x6090
8996 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x6091
9097 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x6092
105112 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
106113 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
107114 #endif
108 typedef void ( APIENTRY * PFNGLPNTRIANGLESIATIPROC )( GLenum pname, GLint param );
109 typedef void ( APIENTRY * PFNGLPNTRIANGLESFATIPROC )( GLenum pname, GLfloat param );
115 typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC)(GLenum pname, GLint param);
116 typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param);
110117 #endif
111118
112119 //----(SA) added
113 extern void ( APIENTRY * qglPNTrianglesiATI )( GLenum pname, GLint param );
114 extern void ( APIENTRY * qglPNTrianglesfATI )( GLenum pname, GLfloat param );
120 extern void (APIENTRYP qglPNTrianglesiATI)(GLenum pname, GLint param);
121 extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
115122 //----(SA) end
116123
117124 // for NV fog distance
511518 #define qglVertexPointer glVertexPointer
512519 #define qglViewport glViewport
513520
514 // GL_EXT_draw_range_elements
515 extern void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
516
517 // GL_EXT_multi_draw_arrays
518 extern void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
519 extern void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
520
521 #ifndef USE_OPENGLES
522 // rend2
523
524 // GL_ARB_shading_language_100
525 #ifndef GL_ARB_shading_language_100
526 #define GL_ARB_shading_language_100
527 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
528 #endif
529
530 // GL_ARB_vertex_program
531 extern void (APIENTRY * qglVertexAttrib4fARB) (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
532 extern void (APIENTRY * qglVertexAttrib4fvARB) (GLuint, const GLfloat *);
533 extern void (APIENTRY * qglVertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized,
534 GLsizei stride, const GLvoid * pointer);
535 extern void (APIENTRY * qglEnableVertexAttribArrayARB) (GLuint index);
536 extern void (APIENTRY * qglDisableVertexAttribArrayARB) (GLuint index);
537
538 // GL_ARB_vertex_buffer_object
539 extern void (APIENTRY * qglBindBufferARB) (GLenum target, GLuint buffer);
540 extern void (APIENTRY * qglDeleteBuffersARB) (GLsizei n, const GLuint * buffers);
541 extern void (APIENTRY * qglGenBuffersARB) (GLsizei n, GLuint * buffers);
542 extern GLboolean(APIENTRY * qglIsBufferARB) (GLuint buffer);
543 extern void (APIENTRY * qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
544 extern void (APIENTRY * qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
545 extern void (APIENTRY * qglGetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data);
546 extern void (APIENTRY * qglGetBufferParameterivARB) (GLenum target, GLenum pname, GLint * params);
547 extern void (APIENTRY * qglGetBufferPointervARB) (GLenum target, GLenum pname, GLvoid * *params);
548
549 // GL_ARB_shader_objects
550 extern void (APIENTRY * qglDeleteObjectARB) (GLhandleARB obj);
551 extern GLhandleARB(APIENTRY * qglGetHandleARB) (GLenum pname);
552 extern void (APIENTRY * qglDetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj);
553 extern GLhandleARB(APIENTRY * qglCreateShaderObjectARB) (GLenum shaderType);
554 extern void (APIENTRY * qglShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB * *string,
555 const GLint * length);
556 extern void (APIENTRY * qglCompileShaderARB) (GLhandleARB shaderObj);
557 extern GLhandleARB(APIENTRY * qglCreateProgramObjectARB) (void);
558 extern void (APIENTRY * qglAttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj);
559 extern void (APIENTRY * qglLinkProgramARB) (GLhandleARB programObj);
560 extern void (APIENTRY * qglUseProgramObjectARB) (GLhandleARB programObj);
561 extern void (APIENTRY * qglValidateProgramARB) (GLhandleARB programObj);
562 extern void (APIENTRY * qglUniform1fARB) (GLint location, GLfloat v0);
563 extern void (APIENTRY * qglUniform2fARB) (GLint location, GLfloat v0, GLfloat v1);
564 extern void (APIENTRY * qglUniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
565 extern void (APIENTRY * qglUniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
566 extern void (APIENTRY * qglUniform1iARB) (GLint location, GLint v0);
567 extern void (APIENTRY * qglUniform2iARB) (GLint location, GLint v0, GLint v1);
568 extern void (APIENTRY * qglUniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2);
569 extern void (APIENTRY * qglUniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
570 extern void (APIENTRY * qglUniform1fvARB) (GLint location, GLsizei count, const GLfloat * value);
571 extern void (APIENTRY * qglUniform2fvARB) (GLint location, GLsizei count, const GLfloat * value);
572 extern void (APIENTRY * qglUniform3fvARB) (GLint location, GLsizei count, const GLfloat * value);
573 extern void (APIENTRY * qglUniform4fvARB) (GLint location, GLsizei count, const GLfloat * value);
574 extern void (APIENTRY * qglUniform2ivARB) (GLint location, GLsizei count, const GLint * value);
575 extern void (APIENTRY * qglUniform3ivARB) (GLint location, GLsizei count, const GLint * value);
576 extern void (APIENTRY * qglUniform4ivARB) (GLint location, GLsizei count, const GLint * value);
577 extern void (APIENTRY * qglUniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
578 extern void (APIENTRY * qglUniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
579 extern void (APIENTRY * qglUniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
580 extern void (APIENTRY * qglGetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat * params);
581 extern void (APIENTRY * qglGetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint * params);
582 extern void (APIENTRY * qglGetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog);
583 extern void (APIENTRY * qglGetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count,
584 GLhandleARB * obj);
585 extern GLint(APIENTRY * qglGetUniformLocationARB) (GLhandleARB programObj, const GLcharARB * name);
586 extern void (APIENTRY * qglGetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxIndex, GLsizei * length,
587 GLint * size, GLenum * type, GLcharARB * name);
588 extern void (APIENTRY * qglGetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat * params);
589 extern void (APIENTRY * qglGetUniformivARB) (GLhandleARB programObj, GLint location, GLint * params);
590 extern void (APIENTRY * qglGetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source);
591
592 // GL_ARB_vertex_shader
593 extern void (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB * name);
594 extern void (APIENTRY * qglGetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length,
595 GLint * size, GLenum * type, GLcharARB * name);
596 extern GLint(APIENTRY * qglGetAttribLocationARB) (GLhandleARB programObj, const GLcharARB * name);
597
598 // GL_ARB_texture_compression
599 extern void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
600 GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
601 extern void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
602 GLint border, GLsizei imageSize, const GLvoid *data);
603 extern void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
604 GLsizei imageSize, const GLvoid *data);
605 extern void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
606 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
607 extern void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
608 GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
609 extern void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
610 GLsizei imageSize, const GLvoid *data);
611 extern void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
612 GLvoid *img);
521 // GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
522
523 // OpenGL 1.2, was GL_EXT_draw_range_elements
524 #define QGL_1_2_PROCS \
525 GLE(void, DrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) \
526
527 // OpenGL 1.3, was GL_ARB_texture_compression
528 #define QGL_1_3_PROCS \
529 GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
530 GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
531
532 // OpenGL 1.4, was GL_EXT_multi_draw_arrays
533 #define QGL_1_4_PROCS \
534 GLE(void, MultiDrawElements, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) \
535
536 // OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
537 #define QGL_1_5_PROCS \
538 GLE(void, GenQueries, GLsizei n, GLuint *ids) \
539 GLE(void, DeleteQueries, GLsizei n, const GLuint *ids) \
540 GLE(void, BeginQuery, GLenum target, GLuint id) \
541 GLE(void, EndQuery, GLenum target) \
542 GLE(void, GetQueryObjectiv, GLuint id, GLenum pname, GLint *params) \
543 GLE(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params) \
544 GLE(void, BindBuffer, GLenum target, GLuint buffer) \
545 GLE(void, DeleteBuffers, GLsizei n, const GLuint *buffers) \
546 GLE(void, GenBuffers, GLsizei n, GLuint *buffers) \
547 GLE(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) \
548 GLE(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) \
549
550 // OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
551 #define QGL_2_0_PROCS \
552 GLE(void, AttachShader, GLuint program, GLuint shader) \
553 GLE(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) \
554 GLE(void, CompileShader, GLuint shader) \
555 GLE(GLuint, CreateProgram, void) \
556 GLE(GLuint, CreateShader, GLenum type) \
557 GLE(void, DeleteProgram, GLuint program) \
558 GLE(void, DeleteShader, GLuint shader) \
559 GLE(void, DetachShader, GLuint program, GLuint shader) \
560 GLE(void, DisableVertexAttribArray, GLuint index) \
561 GLE(void, EnableVertexAttribArray, GLuint index) \
562 GLE(void, GetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) \
563 GLE(void, GetProgramiv, GLuint program, GLenum pname, GLint *params) \
564 GLE(void, GetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
565 GLE(void, GetShaderiv, GLuint shader, GLenum pname, GLint *params) \
566 GLE(void, GetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
567 GLE(void, GetShaderSource, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) \
568 GLE(GLint, GetUniformLocation, GLuint program, const GLchar *name) \
569 GLE(void, LinkProgram, GLuint program) \
570 GLE(void, ShaderSource, GLuint shader, GLsizei count, const GLchar* *string, const GLint *length) \
571 GLE(void, UseProgram, GLuint program) \
572 GLE(void, Uniform1f, GLint location, GLfloat v0) \
573 GLE(void, Uniform2f, GLint location, GLfloat v0, GLfloat v1) \
574 GLE(void, Uniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
575 GLE(void, Uniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
576 GLE(void, Uniform1i, GLint location, GLint v0) \
577 GLE(void, Uniform1fv, GLint location, GLsizei count, const GLfloat *value) \
578 GLE(void, UniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
579 GLE(void, ValidateProgram, GLuint program) \
580 GLE(void, VertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) \
613581
614582 // GL_NVX_gpu_memory_info
615583 #ifndef GL_NVX_gpu_memory_info
660628 #endif
661629
662630 // GL_EXT_framebuffer_object
663 extern GLboolean (APIENTRY * qglIsRenderbufferEXT)(GLuint renderbuffer);
664 extern void (APIENTRY * qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
665 extern void (APIENTRY * qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
666 extern void (APIENTRY * qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
667 extern void (APIENTRY * qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
668 extern void (APIENTRY * qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
669 extern GLboolean (APIENTRY * qglIsFramebufferEXT)(GLuint framebuffer);
670 extern void (APIENTRY * qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
671 extern void (APIENTRY * qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
672 extern void (APIENTRY * qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
673 extern GLenum (APIENTRY * qglCheckFramebufferStatusEXT)(GLenum target);
674 extern void (APIENTRY * qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
675 GLint level);
676 extern void (APIENTRY * qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
677 GLint level);
678 extern void (APIENTRY * qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
679 GLint level, GLint zoffset);
680 extern void (APIENTRY * qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget,
681 GLuint renderbuffer);
682 extern void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
683 extern void (APIENTRY * qglGenerateMipmapEXT)(GLenum target);
631 #define QGL_EXT_framebuffer_object_PROCS \
632 GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
633 GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
634 GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
635 GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
636 GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
637 GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
638 GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
639 GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
640 GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
641 GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
642 GLE(void, GenerateMipmapEXT, GLenum target) \
684643
685644 #ifndef GL_EXT_framebuffer_object
686645 #define GL_EXT_framebuffer_object
737696 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
738697 #endif
739698
740 // GL_EXT_packed_depth_stencil
741 #ifndef GL_EXT_packed_depth_stencil
742 #define GL_EXT_packed_depth_stencil
743 #define GL_DEPTH_STENCIL_EXT 0x84F9
744 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA
745 #define GL_DEPTH24_STENCIL8_EXT 0x88F0
746 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
747 #endif
748
749 // GL_ARB_occlusion_query
750 extern void (APIENTRY * qglGenQueriesARB)(GLsizei n, GLuint *ids);
751 extern void (APIENTRY * qglDeleteQueriesARB)(GLsizei n, const GLuint *ids);
752 extern GLboolean (APIENTRY * qglIsQueryARB)(GLuint id);
753 extern void (APIENTRY * qglBeginQueryARB)(GLenum target, GLuint id);
754 extern void (APIENTRY * qglEndQueryARB)(GLenum target);
755 extern void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
756 extern void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
757 extern void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
758
759 #ifndef GL_ARB_occlusion_query
760 #define GL_ARB_occlusion_query
761 #define GL_SAMPLES_PASSED_ARB 0x8914
762 #define GL_QUERY_COUNTER_BITS_ARB 0x8864
763 #define GL_CURRENT_QUERY_ARB 0x8865
764 #define GL_QUERY_RESULT_ARB 0x8866
765 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
766 #endif
767
768699 // GL_EXT_framebuffer_blit
769 extern void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
770 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
771 GLbitfield mask, GLenum filter);
700 #define QGL_EXT_framebuffer_blit_PROCS \
701 GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
772702
773703 #ifndef GL_EXT_framebuffer_blit
774704 #define GL_EXT_framebuffer_blit
779709 #endif
780710
781711 // GL_EXT_framebuffer_multisample
782 extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
783 GLenum internalformat, GLsizei width, GLsizei height);
712 #define QGL_EXT_framebuffer_multisample_PROCS \
713 GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
784714
785715 #ifndef GL_EXT_framebuffer_multisample
786716 #define GL_EXT_framebuffer_multisample
789719 #define GL_MAX_SAMPLES_EXT 0x8D57
790720 #endif
791721
792 #ifndef GL_EXT_texture_sRGB
793 #define GL_EXT_texture_sRGB
794 #define GL_SRGB_EXT 0x8C40
795 #define GL_SRGB8_EXT 0x8C41
796 #define GL_SRGB_ALPHA_EXT 0x8C42
797 #define GL_SRGB8_ALPHA8_EXT 0x8C43
798 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44
799 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
800 #define GL_SLUMINANCE_EXT 0x8C46
801 #define GL_SLUMINANCE8_EXT 0x8C47
802 #define GL_COMPRESSED_SRGB_EXT 0x8C48
803 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
804 #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
805 #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
806 #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
807 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
808 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
809 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
810 #endif
811
812 #ifndef GL_EXT_framebuffer_sRGB
813 #define GL_EXT_framebuffer_sRGB
814 #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
815 #endif
816
817 #ifndef GL_EXT_texture_compression_latc
818 #define GL_EXT_texture_compression_latc
819 #define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
820 #define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
821 #define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
822 #define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
722 #ifndef GL_ARB_texture_compression_rgtc
723 #define GL_ARB_texture_compression_rgtc
724 #define GL_COMPRESSED_RED_RGTC1 0x8DBB
725 #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
726 #define GL_COMPRESSED_RG_RGTC2 0x8DBD
727 #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
823728 #endif
824729
825730 #ifndef GL_ARB_texture_compression_bptc
830735 #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
831736 #endif
832737
833 // GL_ARB_draw_buffers
834 extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
835 #ifndef GL_ARB_draw_buffers
836 #define GL_ARB_draw_buffers
837 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824
838 #define GL_DRAW_BUFFER0_ARB 0x8825
839 #define GL_DRAW_BUFFER1_ARB 0x8826
840 #define GL_DRAW_BUFFER2_ARB 0x8827
841 #define GL_DRAW_BUFFER3_ARB 0x8828
842 #define GL_DRAW_BUFFER4_ARB 0x8829
843 #define GL_DRAW_BUFFER5_ARB 0x882A
844 #define GL_DRAW_BUFFER6_ARB 0x882B
845 #define GL_DRAW_BUFFER7_ARB 0x882C
846 #define GL_DRAW_BUFFER8_ARB 0x882D
847 #define GL_DRAW_BUFFER9_ARB 0x882E
848 #define GL_DRAW_BUFFER10_ARB 0x882F
849 #define GL_DRAW_BUFFER11_ARB 0x8830
850 #define GL_DRAW_BUFFER12_ARB 0x8831
851 #define GL_DRAW_BUFFER13_ARB 0x8832
852 #define GL_DRAW_BUFFER14_ARB 0x8833
853 #define GL_DRAW_BUFFER15_ARB 0x8834
854 #endif
855
856738 #ifndef GL_ARB_depth_clamp
857739 #define GL_ARB_depth_clamp
858740 #define GL_DEPTH_CLAMP 0x864F
864746 #endif
865747
866748 // GL_ARB_vertex_array_object
867 extern void (APIENTRY * qglBindVertexArrayARB)(GLuint array);
868 extern void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays);
869 extern void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
870 extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
749 #define QGL_ARB_vertex_array_object_PROCS \
750 GLE(void, BindVertexArray, GLuint array) \
751 GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
752 GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
753
871754 #ifndef GL_ARB_vertex_array_object
872755 #define GL_ARB_vertex_array_object
873756 #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5
874757 #endif
875758
876 #if defined(WIN32)
877 // WGL_ARB_create_context
878 #ifndef WGL_ARB_create_context
879 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
880 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
881 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
882 #define WGL_CONTEXT_FLAGS_ARB 0x2094
883 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
884 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
885 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
886 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
887 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
888 #define ERROR_INVALID_VERSION_ARB 0x2095
889 #define ERROR_INVALID_PROFILE_ARB 0x2096
890 #endif
891
892 extern HGLRC(APIENTRY * qwglCreateContextAttribsARB) (HDC hdC, HGLRC hShareContext, const int *attribList);
893 #endif
894
895 #if 0 //defined(__linux__)
896 // GLX_ARB_create_context
897 #ifndef GLX_ARB_create_context
898 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
899 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
900 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
901 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
902 #define GLX_CONTEXT_FLAGS_ARB 0x2094
903 #endif
904
905 extern GLXContext (APIENTRY * qglXCreateContextAttribsARB) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
906 #endif
907
908 #endif // USE_OPENGLES
759 // GL_EXT_direct_state_access
760 #define QGL_EXT_direct_state_access_PROCS \
761 GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
762 GLE(GLvoid, TextureParameterfEXT, GLuint texture, GLenum target, GLenum pname, GLfloat param) \
763 GLE(GLvoid, TextureParameteriEXT, GLuint texture, GLenum target, GLenum pname, GLint param) \
764 GLE(GLvoid, TextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
765 GLE(GLvoid, TextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
766 GLE(GLvoid, CopyTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) \
767 GLE(GLvoid, CompressedTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) \
768 GLE(GLvoid, CompressedTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) \
769 GLE(GLvoid, GenerateTextureMipmapEXT, GLuint texture, GLenum target) \
770 GLE(GLvoid, ProgramUniform1iEXT, GLuint program, GLint location, GLint v0) \
771 GLE(GLvoid, ProgramUniform1fEXT, GLuint program, GLint location, GLfloat v0) \
772 GLE(GLvoid, ProgramUniform2fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1) \
773 GLE(GLvoid, ProgramUniform3fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
774 GLE(GLvoid, ProgramUniform4fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
775 GLE(GLvoid, ProgramUniform1fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value) \
776 GLE(GLvoid, ProgramUniformMatrix4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
777 GLE(GLvoid, NamedRenderbufferStorageEXT, GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) \
778 GLE(GLvoid, NamedRenderbufferStorageMultisampleEXT, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
779 GLE(GLenum, CheckNamedFramebufferStatusEXT, GLuint framebuffer, GLenum target) \
780 GLE(GLvoid, NamedFramebufferTexture2DEXT, GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
781 GLE(GLvoid, NamedFramebufferRenderbufferEXT, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
782
783 #define GLE(ret, name, ...) typedef ret APIENTRY name##proc(__VA_ARGS__); extern name##proc * qgl##name;
784 QGL_1_2_PROCS;
785 QGL_1_3_PROCS;
786 QGL_1_4_PROCS;
787 QGL_1_5_PROCS;
788 QGL_2_0_PROCS;
789 QGL_EXT_framebuffer_object_PROCS;
790 QGL_EXT_framebuffer_blit_PROCS;
791 QGL_EXT_framebuffer_multisample_PROCS;
792 QGL_ARB_vertex_array_object_PROCS;
793 QGL_EXT_direct_state_access_PROCS;
794 #undef GLE
909795
910796 #endif // __QGL_H__
911
4343 //#define DBG_PROFILE_BONES
4444
4545 //-----------------------------------------------------------------------------
46 // Static Vars, ugly but easiest (and fastest) means of seperating RB_SurfaceAnim
46 // Static Vars, ugly but easiest (and fastest) means of separating RB_SurfaceAnim
4747 // and R_CalcBones
4848
4949 static float frontlerp, backlerp;
339339 ==================
340340 */
341341 void RB_TestFlare( flare_t *f ) {
342 qboolean visible;
343 float fade;
342 float depth;
343 qboolean visible;
344 float fade;
345 float screenZ;
344346
345347 backEnd.pc.c_flareTests++;
346348
349 // doing a readpixels is as good as doing a glFinish(), so
350 // don't bother with another sync
351 glState.finishCalled = qfalse;
352
353 // read back the z buffer contents
354 #ifdef USE_OPENGLES
355 screenZ = 0;
356 #else
357 qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
358
359 screenZ = backEnd.viewParms.projectionMatrix[14] /
360 ( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
361 #endif
362
347363 visible = f->cgvisible;
364
365 if ( -f->eyeZ - -screenZ > 24 )
366 visible = qfalse;
348367
349368 if ( visible ) {
350369 if ( !f->visible ) {
351370 f->visible = qtrue;
352371 f->fadeTime = backEnd.refdef.time - 1;
353372 }
354 fade = ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
373 fade = ( ( backEnd.refdef.time - f->fadeTime ) /1000.0f ) * r_flareFade->value;
355374 } else {
356375 if ( f->visible ) {
357376 f->visible = qfalse;
7979 #include "../qcommon/qcommon.h"
8080
8181 #ifdef BUILD_FREETYPE
82 #include <ft2build.h>
82 #ifdef USE_LOCAL_HEADERS
83 #include "../freetype-2.6.4/include/ft2build.h"
84 #else
85 #include <ft2build.h>
86 #endif
8387 #include FT_FREETYPE_H
8488 #include FT_ERRORS_H
8589 #include FT_SYSTEM_H
16581658 for ( i = 0; i < tr.numImages ; i++ ) {
16591659 qglDeleteTextures( 1, &tr.images[i]->texnum );
16601660 }
1661 memset( tr.images, 0, sizeof( tr.images ) );
1662
1663 memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
1661 Com_Memset( tr.images, 0, sizeof( tr.images ) );
1662
1663 tr.numImages = 0;
1664
1665 Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
16641666 if ( qglActiveTextureARB ) {
16651667 GL_SelectTexture( 1 );
16661668 qglBindTexture( GL_TEXTURE_2D, 0 );
10111011 */
10121012 void R_PrintLongString(const char *string) {
10131013 char buffer[1024];
1014 const char *p;
1015 int size = strlen(string);
1016
1017 p = string;
1018 while(size > 0)
1014 const char *p = string;
1015 int remainingLength = strlen(string);
1016
1017 while (remainingLength > 0)
10191018 {
1020 Q_strncpyz(buffer, p, sizeof (buffer) );
1019 // Take as much characters as possible from the string without splitting words between buffers
1020 // This avoids the client console splitting a word up when one half fits on the current line,
1021 // but the second half would have to be written on a new line
1022 int charsToTake = sizeof(buffer) - 1;
1023 if (remainingLength > charsToTake) {
1024 while (p[charsToTake - 1] > ' ' && p[charsToTake] > ' ') {
1025 charsToTake--;
1026 if (charsToTake == 0) {
1027 charsToTake = sizeof(buffer) - 1;
1028 break;
1029 }
1030 }
1031 } else if (remainingLength < charsToTake) {
1032 charsToTake = remainingLength;
1033 }
1034
1035 Q_strncpyz( buffer, p, charsToTake + 1 );
10211036 ri.Printf( PRINT_ALL, "%s", buffer );
1022 p += 1023;
1023 size -= 1023;
1037 remainingLength -= charsToTake;
1038 p += charsToTake;
10241039 }
10251040 }
10261041
11771192 r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH );
11781193 #ifdef USE_OPENGLES
11791194 r_mode = ri.Cvar_Get( "r_mode", "-2", CVAR_ARCHIVE | CVAR_LATCH );
1195 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
11801196 #else
11811197 r_mode = ri.Cvar_Get( "r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH );
1198 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "0", CVAR_ARCHIVE | CVAR_LATCH );
11821199 #endif
1183 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
11841200 r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE | CVAR_LATCH );
11851201 r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
11861202 r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
189189 byte *data;
190190 int lat, lng;
191191 vec3_t normal;
192
192 #if idppc
193 float d0, d1, d2, d3, d4, d5;
194 #endif
193195 factor = 1.0;
194196 data = gridData;
195197 for ( j = 0 ; j < 3 ; j++ ) {
211213 continue; // ignore samples in walls
212214 }
213215 totalFactor += factor;
214
216 #if idppc
217 d0 = data[0]; d1 = data[1]; d2 = data[2];
218 d3 = data[3]; d4 = data[4]; d5 = data[5];
219
220 ent->ambientLight[0] += factor * d0;
221 ent->ambientLight[1] += factor * d1;
222 ent->ambientLight[2] += factor * d2;
223
224 ent->directedLight[0] += factor * d3;
225 ent->directedLight[1] += factor * d4;
226 ent->directedLight[2] += factor * d5;
227 #else
215228 ent->ambientLight[0] += factor * data[0];
216229 ent->ambientLight[1] += factor * data[1];
217230 ent->ambientLight[2] += factor * data[2];
219232 ent->directedLight[0] += factor * data[3];
220233 ent->directedLight[1] += factor * data[4];
221234 ent->directedLight[2] += factor * data[5];
222
235 #endif
223236 lat = data[7];
224237 lng = data[6];
225238 lat *= ( FUNCTABLE_SIZE / 256 );
392405 LogLight( ent );
393406 }
394407
395 // save out the byte packet version
396 ( (byte *)&ent->ambientLightInt )[0] = ri.ftol( ent->ambientLight[0] );
397 ( (byte *)&ent->ambientLightInt )[1] = ri.ftol( ent->ambientLight[1] );
398 ( (byte *)&ent->ambientLightInt )[2] = ri.ftol( ent->ambientLight[2] );
399 ( (byte *)&ent->ambientLightInt )[3] = 0xff;
400
401408 // transform the direction to local space
402409 VectorNormalize( lightDir );
403410 ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
2424
2525 ===========================================================================
2626 */
27
2827
2928
3029 #ifndef TR_LOCAL_H
7069 qboolean lightingCalculated;
7170 vec3_t lightDir; // normalized direction towards light
7271 vec3_t ambientLight; // color normalized to 0-255
73 int ambientLightInt; // 32 bit rgba packed
7472 vec3_t directedLight;
7573 float brightness;
7674 } trRefEntity_t;
2828 // tr_shade.c
2929
3030 #include "tr_local.h"
31 #if idppc_altivec && !defined(MACOS_X)
31 #if idppc_altivec && !defined(__APPLE__)
3232 #include <altivec.h>
3333 #endif
3434
2828 // tr_shade_calc.c
2929
3030 #include "tr_local.h"
31 #if idppc_altivec && !defined(MACOS_X)
31 #if idppc_altivec && !defined(__APPLE__)
3232 #include <altivec.h>
3333 #endif
3434
11741174 int i;
11751175 float *v, *normal;
11761176 trRefEntity_t *ent;
1177 int ambientLightInt;
11781177 vec3_t lightDir;
11791178 int numVertexes;
11801179 vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
11911190 vector signed short jVecShort;
11921191 vector unsigned char jVecChar, normalPerm;
11931192 ent = backEnd.currentEntity;
1194 ambientLightInt = ent->ambientLightInt;
11951193 // A lot of this could be simplified if we made sure
11961194 // entities light info was 16-byte aligned.
11971195 jVecChar = vec_lvsl(0, ent->ambientLight);
12451243 float *v, *normal;
12461244 float incoming;
12471245 trRefEntity_t *ent;
1248 int ambientLightInt;
12491246 vec3_t ambientLight;
12501247 vec3_t lightDir;
12511248 vec3_t directedLight;
12521249 int numVertexes;
12531250 ent = backEnd.currentEntity;
1254 ambientLightInt = ent->ambientLightInt;
12551251 VectorCopy( ent->ambientLight, ambientLight );
12561252 VectorCopy( ent->directedLight, directedLight );
12571253 VectorCopy( ent->lightDir, lightDir );
12631259 for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
12641260 incoming = DotProduct (normal, lightDir);
12651261 if ( incoming <= 0 ) {
1266 *(int *)&colors[i*4] = ambientLightInt;
1267 continue;
1262 incoming = 0.0;
12681263 }
12691264 j = ri.ftol(ambientLight[0] + incoming * directedLight[0]);
12701265 if ( j > 255 ) {
3838 static texModInfo_t texMods[MAX_SHADER_STAGES][TR_MAX_TEXMODS];
3939
4040 #define FILE_HASH_SIZE 4096
41
4241 static shader_t* hashTable[FILE_HASH_SIZE];
43
44 // Ridah
45 // Table containing string indexes for each shader found in the scripts, referenced by their checksum
46 // values.
47 typedef struct shaderStringPointer_s
48 {
49 char *pStr;
50 struct shaderStringPointer_s *next;
51 } shaderStringPointer_t;
52 //
53 shaderStringPointer_t shaderChecksumLookup[FILE_HASH_SIZE];
54 // done.
5542
5643 /*
5744 ================
1001988 }
1002989 }
1003990
991 // allow crosshairs to be colorized for cg_crosshairHealth
992 if ( strstr( shader.name, "crosshair" ) && shader.lightmapIndex == LIGHTMAP_2D ) {
993 if ( stage->rgbGen == CGEN_IDENTITY || stage->rgbGen == CGEN_IDENTITY_LIGHTING ) {
994 stage->rgbGen = CGEN_VERTEX;
995 }
996 }
1004997
1005998 //
1006999 // implicitly assume that a GL_ONE GL_ZERO blend mask disables blending
24702463
24712464 if ( token[0] == '{' ) {
24722465 // skip the definition
2473 // SkipBracedSection_Depth( &p, 1 );
2474 SkipBracedSection( &p );
2466 SkipBracedSection( &p, 0 );
24752467 } else if ( !Q_stricmp( token, shadername ) ) {
24762468 return p;
24772469 } else {
29942986 char *p;
29952987 int numShaderFiles;
29962988 int i;
2997 char *oldp, *token, *textEnd;
2989 char *token, *textEnd;
2990 char shaderName[MAX_QPATH];
2991 int shaderLine;
29982992
29992993 long sum = 0, summand;
30002994 // scan for shader files
30233017
30243018 // Do a simple check on the shader structure in that file to make sure one bad shader file cannot fuck up all other shaders.
30253019 p = buffers[i];
3020 COM_BeginParseSession(filename);
30263021 while(1)
30273022 {
30283023 token = COM_ParseExt(&p, qtrue);
30293024
30303025 if(!*token)
30313026 break;
3032
3033 oldp = p;
3034
3027
3028 Q_strncpyz(shaderName, token, sizeof(shaderName));
3029 shaderLine = COM_GetCurrentParseLine();
3030
30353031 token = COM_ParseExt(&p, qtrue);
3036 if(token[0] != '{' && token[1] != '\0')
3032 if( !Q_stricmp( shaderName, token ) ) {
3033 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Invalid shader name \"%s\" on line %d.\n",
3034 filename, shaderName, shaderLine);
3035 break;
3036 }
3037
3038 if(token[0] != '{' || token[1] != '\0')
30373039 {
3038 ri.Printf(PRINT_WARNING, "WARNING: Bad shader file %s has incorrect syntax.\n", filename);
3040 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing opening brace",
3041 filename, shaderName, shaderLine);
3042 if (token[0])
3043 {
3044 ri.Printf(PRINT_WARNING, " (found \"%s\" on line %d)", token, COM_GetCurrentParseLine());
3045 }
3046 ri.Printf(PRINT_WARNING, "...Ignored\n");
30393047 ri.FS_FreeFile(buffers[i]);
30403048 buffers[i] = NULL;
30413049 break;
30423050 }
30433051
3044 SkipBracedSection(&oldp);
3045 p = oldp;
3052 if(!SkipBracedSection(&p, 1))
3053 {
3054 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing closing brace",
3055 filename, shaderName, shaderLine);
3056 if( !Q_stricmp( filename, "common.shader" ) ) { // HACK...Broken shader in pak0.pk3
3057 ri.Printf(PRINT_WARNING, "...Ignored\n");
3058 ri.FS_FreeFile(buffers[i]);
3059 buffers[i] = NULL;
3060 break;
3061 } else {
3062 ri.Printf(PRINT_WARNING, ".\n");
3063 }
3064 }
30463065 }
30473066
30483067 if (buffers[i])
10191019
10201020 qglPushMatrix();
10211021 GL_State( 0 );
1022 GL_Cull( CT_FRONT_SIDED );
10221023 qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
10231024
10241025 DrawSkyBox( tess.shader );
10391040
10401041 qglPushMatrix();
10411042 GL_State( 0 );
1043 GL_Cull( CT_FRONT_SIDED );
10421044 qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
10431045
10441046 DrawSkyBoxInner( tess.shader );
2727
2828 // tr_surf.c
2929 #include "tr_local.h"
30 #if idppc_altivec && !defined(MACOS_X)
30 #if idppc_altivec && !defined(__APPLE__)
3131 #include <altivec.h>
3232 #endif
3333
410410 R_RecursiveWorldNode
411411 ================
412412 */
413 static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits ) {
413 static void R_RecursiveWorldNode( mnode_t *node, unsigned int planeBits, unsigned int dlightBits ) {
414414
415415 do {
416 int newDlights[2];
416 unsigned int newDlights[2];
417417
418418 // if the node wasn't marked as potentially visible, exit
419419 if ( node->visframe != tr.visCount ) {
706706 ClearBounds( tr.viewParms.visBounds[0], tr.viewParms.visBounds[1] );
707707
708708 // perform frustum culling and add all the potentially visible surfaces
709 if ( tr.refdef.num_dlights > 32 ) {
710 tr.refdef.num_dlights = 32 ;
711 }
712 R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1 );
713 }
709 if ( tr.refdef.num_dlights > MAX_DLIGHTS ) {
710 tr.refdef.num_dlights = MAX_DLIGHTS ;
711 }
712 R_RecursiveWorldNode( tr.world->nodes, 15, ( 1ULL << tr.refdef.num_dlights ) - 1 );
713 }
3434
3535 static cvar_t *in_keyboardDebug = NULL;
3636
37 static SDL_GameController *gamepad = NULL;
3738 static SDL_Joystick *stick = NULL;
3839
3940 static qboolean mouseAvailable = qfalse;
246247 case SDLK_LCTRL:
247248 case SDLK_RCTRL: key = K_CTRL; break;
248249
249 #ifdef MACOS_X
250 #ifdef __APPLE__
250251 case SDLK_RGUI:
251252 case SDLK_LGUI: key = K_COMMAND; break;
252253 #else
409410
410411 struct
411412 {
412 qboolean buttons[16]; // !!! FIXME: these might be too many.
413 qboolean buttons[SDL_CONTROLLER_BUTTON_MAX + 1]; // +1 because old max was 16, current SDL_CONTROLLER_BUTTON_MAX is 15
413414 unsigned int oldaxes;
414415 int oldaaxes[MAX_JOYSTICK_AXIS];
415416 unsigned int oldhats;
427428 int total = 0;
428429 char buf[16384] = "";
429430
431 if (gamepad)
432 SDL_GameControllerClose(gamepad);
433
430434 if (stick != NULL)
431435 SDL_JoystickClose(stick);
432436
433437 stick = NULL;
438 gamepad = NULL;
434439 memset(&stick_state, '\0', sizeof (stick_state));
435440
441 // SDL 2.0.4 requires SDL_INIT_JOYSTICK to be initialized separately from
442 // SDL_INIT_GAMECONTROLLER for SDL_JoystickOpen() to work correctly,
443 // despite https://wiki.libsdl.org/SDL_Init (retrieved 2016-08-16)
444 // indicating SDL_INIT_JOYSTICK should be initialized automatically.
436445 if (!SDL_WasInit(SDL_INIT_JOYSTICK))
437446 {
438447 Com_DPrintf("Calling SDL_Init(SDL_INIT_JOYSTICK)...\n");
444453 Com_DPrintf("SDL_Init(SDL_INIT_JOYSTICK) passed.\n");
445454 }
446455
456 if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER))
457 {
458 Com_DPrintf("Calling SDL_Init(SDL_INIT_GAMECONTROLLER)...\n");
459 if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0)
460 {
461 Com_DPrintf("SDL_Init(SDL_INIT_GAMECONTROLLER) failed: %s\n", SDL_GetError());
462 return;
463 }
464 Com_DPrintf("SDL_Init(SDL_INIT_GAMECONTROLLER) passed.\n");
465 }
466
447467 total = SDL_NumJoysticks();
448468 Com_DPrintf("%d possible joysticks\n", total);
449469
458478
459479 if( !in_joystick->integer ) {
460480 Com_DPrintf( "Joystick is not active.\n" );
461 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
481 SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
462482 return;
463483 }
464484
471491 stick = SDL_JoystickOpen( in_joystickNo->integer );
472492
473493 if (stick == NULL) {
474 Com_DPrintf( "No joystick opened.\n" );
494 Com_DPrintf( "No joystick opened: %s\n", SDL_GetError() );
475495 return;
476496 }
497
498 if (SDL_IsGameController(in_joystickNo->integer))
499 gamepad = SDL_GameControllerOpen(in_joystickNo->integer);
477500
478501 Com_DPrintf( "Joystick %d opened\n", in_joystickNo->integer );
479502 Com_DPrintf( "Name: %s\n", SDL_JoystickNameForIndex(in_joystickNo->integer) );
482505 Com_DPrintf( "Buttons: %d\n", SDL_JoystickNumButtons(stick) );
483506 Com_DPrintf( "Balls: %d\n", SDL_JoystickNumBalls(stick) );
484507 Com_DPrintf( "Use Analog: %s\n", in_joystickUseAnalog->integer ? "Yes" : "No" );
508 Com_DPrintf( "Is gamepad: %s\n", gamepad ? "Yes" : "No" );
485509
486510 SDL_JoystickEventState(SDL_QUERY);
511 SDL_GameControllerEventState(SDL_QUERY);
487512 }
488513
489514 /*
493518 */
494519 static void IN_ShutdownJoystick( void )
495520 {
521 if ( !SDL_WasInit( SDL_INIT_GAMECONTROLLER ) )
522 return;
523
496524 if ( !SDL_WasInit( SDL_INIT_JOYSTICK ) )
497525 return;
498526
527 if (gamepad)
528 {
529 SDL_GameControllerClose(gamepad);
530 gamepad = NULL;
531 }
532
499533 if (stick)
500534 {
501535 SDL_JoystickClose(stick);
502536 stick = NULL;
503537 }
504538
539 SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
505540 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
506541 }
542
543
544 static qboolean KeyToAxisAndSign(int keynum, int *outAxis, int *outSign)
545 {
546 char *bind;
547
548 if (!keynum)
549 return qfalse;
550
551 bind = Key_GetBinding(keynum);
552
553 if (!bind || *bind != '+')
554 return qfalse;
555
556 *outSign = 0;
557
558 if (Q_stricmp(bind, "+forward") == 0)
559 {
560 *outAxis = j_forward_axis->integer;
561 *outSign = j_forward->value > 0.0f ? 1 : -1;
562 }
563 else if (Q_stricmp(bind, "+back") == 0)
564 {
565 *outAxis = j_forward_axis->integer;
566 *outSign = j_forward->value > 0.0f ? -1 : 1;
567 }
568 else if (Q_stricmp(bind, "+moveleft") == 0)
569 {
570 *outAxis = j_side_axis->integer;
571 *outSign = j_side->value > 0.0f ? -1 : 1;
572 }
573 else if (Q_stricmp(bind, "+moveright") == 0)
574 {
575 *outAxis = j_side_axis->integer;
576 *outSign = j_side->value > 0.0f ? 1 : -1;
577 }
578 else if (Q_stricmp(bind, "+lookup") == 0)
579 {
580 *outAxis = j_pitch_axis->integer;
581 *outSign = j_pitch->value > 0.0f ? -1 : 1;
582 }
583 else if (Q_stricmp(bind, "+lookdown") == 0)
584 {
585 *outAxis = j_pitch_axis->integer;
586 *outSign = j_pitch->value > 0.0f ? 1 : -1;
587 }
588 else if (Q_stricmp(bind, "+left") == 0)
589 {
590 *outAxis = j_yaw_axis->integer;
591 *outSign = j_yaw->value > 0.0f ? 1 : -1;
592 }
593 else if (Q_stricmp(bind, "+right") == 0)
594 {
595 *outAxis = j_yaw_axis->integer;
596 *outSign = j_yaw->value > 0.0f ? -1 : 1;
597 }
598 else if (Q_stricmp(bind, "+moveup") == 0)
599 {
600 *outAxis = j_up_axis->integer;
601 *outSign = j_up->value > 0.0f ? 1 : -1;
602 }
603 else if (Q_stricmp(bind, "+movedown") == 0)
604 {
605 *outAxis = j_up_axis->integer;
606 *outSign = j_up->value > 0.0f ? -1 : 1;
607 }
608
609 return *outSign != 0;
610 }
611
612 /*
613 ===============
614 IN_GamepadMove
615 ===============
616 */
617 static void IN_GamepadMove( void )
618 {
619 int i;
620 int translatedAxes[MAX_JOYSTICK_AXIS];
621 qboolean translatedAxesSet[MAX_JOYSTICK_AXIS];
622
623 SDL_GameControllerUpdate();
624
625 // check buttons
626 for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++)
627 {
628 qboolean pressed = SDL_GameControllerGetButton(gamepad, SDL_CONTROLLER_BUTTON_A + i);
629 if (pressed != stick_state.buttons[i])
630 {
631 Com_QueueEvent(0, SE_KEY, K_PAD0_A + i, pressed, 0, NULL);
632 stick_state.buttons[i] = pressed;
633 }
634 }
635
636 // must defer translated axes until all real axes are processed
637 // must be done this way to prevent a later mapped axis from zeroing out a previous one
638 if (in_joystickUseAnalog->integer)
639 {
640 for (i = 0; i < MAX_JOYSTICK_AXIS; i++)
641 {
642 translatedAxes[i] = 0;
643 translatedAxesSet[i] = qfalse;
644 }
645 }
646
647 // check axes
648 for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++)
649 {
650 int axis = SDL_GameControllerGetAxis(gamepad, SDL_CONTROLLER_AXIS_LEFTX + i);
651 int oldAxis = stick_state.oldaaxes[i];
652
653 // Smoothly ramp from dead zone to maximum value
654 float f = ((float)abs(axis) / 32767.0f - in_joystickThreshold->value) / (1.0f - in_joystickThreshold->value);
655
656 if (f < 0.0f)
657 f = 0.0f;
658
659 axis = (int)(32767 * ((axis < 0) ? -f : f));
660
661 if (axis != oldAxis)
662 {
663 const int negMap[SDL_CONTROLLER_AXIS_MAX] = { K_PAD0_LEFTSTICK_LEFT, K_PAD0_LEFTSTICK_UP, K_PAD0_RIGHTSTICK_LEFT, K_PAD0_RIGHTSTICK_UP, 0, 0 };
664 const int posMap[SDL_CONTROLLER_AXIS_MAX] = { K_PAD0_LEFTSTICK_RIGHT, K_PAD0_LEFTSTICK_DOWN, K_PAD0_RIGHTSTICK_RIGHT, K_PAD0_RIGHTSTICK_DOWN, K_PAD0_LEFTTRIGGER, K_PAD0_RIGHTTRIGGER };
665
666 qboolean posAnalog = qfalse, negAnalog = qfalse;
667 int negKey = negMap[i];
668 int posKey = posMap[i];
669
670 if (in_joystickUseAnalog->integer)
671 {
672 int posAxis = 0, posSign = 0, negAxis = 0, negSign = 0;
673
674 // get axes and axes signs for keys if available
675 posAnalog = KeyToAxisAndSign(posKey, &posAxis, &posSign);
676 negAnalog = KeyToAxisAndSign(negKey, &negAxis, &negSign);
677
678 // positive to negative/neutral -> keyup if axis hasn't yet been set
679 if (posAnalog && !translatedAxesSet[posAxis] && oldAxis > 0 && axis <= 0)
680 {
681 translatedAxes[posAxis] = 0;
682 translatedAxesSet[posAxis] = qtrue;
683 }
684
685 // negative to positive/neutral -> keyup if axis hasn't yet been set
686 if (negAnalog && !translatedAxesSet[negAxis] && oldAxis < 0 && axis >= 0)
687 {
688 translatedAxes[negAxis] = 0;
689 translatedAxesSet[negAxis] = qtrue;
690 }
691
692 // negative/neutral to positive -> keydown
693 if (posAnalog && axis > 0)
694 {
695 translatedAxes[posAxis] = axis * posSign;
696 translatedAxesSet[posAxis] = qtrue;
697 }
698
699 // positive/neutral to negative -> keydown
700 if (negAnalog && axis < 0)
701 {
702 translatedAxes[negAxis] = -axis * negSign;
703 translatedAxesSet[negAxis] = qtrue;
704 }
705 }
706
707 // keyups first so they get overridden by keydowns later
708
709 // positive to negative/neutral -> keyup
710 if (!posAnalog && posKey && oldAxis > 0 && axis <= 0)
711 Com_QueueEvent(0, SE_KEY, posKey, qfalse, 0, NULL);
712
713 // negative to positive/neutral -> keyup
714 if (!negAnalog && negKey && oldAxis < 0 && axis >= 0)
715 Com_QueueEvent(0, SE_KEY, negKey, qfalse, 0, NULL);
716
717 // negative/neutral to positive -> keydown
718 if (!posAnalog && posKey && oldAxis <= 0 && axis > 0)
719 Com_QueueEvent(0, SE_KEY, posKey, qtrue, 0, NULL);
720
721 // positive/neutral to negative -> keydown
722 if (!negAnalog && negKey && oldAxis >= 0 && axis < 0)
723 Com_QueueEvent(0, SE_KEY, negKey, qtrue, 0, NULL);
724
725 stick_state.oldaaxes[i] = axis;
726 }
727 }
728
729 // set translated axes
730 if (in_joystickUseAnalog->integer)
731 {
732 for (i = 0; i < MAX_JOYSTICK_AXIS; i++)
733 {
734 if (translatedAxesSet[i])
735 Com_QueueEvent(0, SE_JOYSTICK_AXIS, i, translatedAxes[i], 0, NULL);
736 }
737 }
738 }
739
507740
508741 /*
509742 ===============
516749 unsigned int hats = 0;
517750 int total = 0;
518751 int i = 0;
752
753 if (gamepad)
754 {
755 IN_GamepadMove();
756 return;
757 }
519758
520759 if (!stick)
521760 return;
7921031 Com_QueueEvent( 0, SE_KEY, K_CONSOLE, qtrue, 0, NULL );
7931032 Com_QueueEvent( 0, SE_KEY, K_CONSOLE, qfalse, 0, NULL );
7941033 }
1034 else if( utf32 == 0xDC ) // latin big letter u with diaeresis (U+00DC)
1035 {
1036 Com_QueueEvent( 0, SE_CHAR, 'U', 0, 0, NULL );
1037 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1038 }
1039 else if( utf32 == 0xFC ) // latin small letter u with diaeresis (U+00FC)
1040 {
1041 Com_QueueEvent( 0, SE_CHAR, 'u', 0, 0, NULL );
1042 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1043 }
1044 else if( utf32 == 0xD6 ) // latin big letter o with diaeresis (U+00D6)
1045 {
1046 Com_QueueEvent( 0, SE_CHAR, 'O', 0, 0, NULL );
1047 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1048 }
1049 else if( utf32 == 0xF6 ) // latin small letter o with diaeresis (U+00FC)
1050 {
1051 Com_QueueEvent( 0, SE_CHAR, 'o', 0, 0, NULL );
1052 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1053 }
1054 else if( utf32 == 0xC4 ) // latin big letter a with diaeresis (U+00C4)
1055 {
1056 Com_QueueEvent( 0, SE_CHAR, 'A', 0, 0, NULL );
1057 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1058 }
1059 else if( utf32 == 0xE4 ) // latin small letter a with diaeresis (U+00E4)
1060 {
1061 Com_QueueEvent( 0, SE_CHAR, 'a', 0, 0, NULL );
1062 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1063 }
7951064 else
7961065 Com_QueueEvent( 0, SE_CHAR, utf32, 0, 0, NULL );
7971066 }
798 }
799 }
1067 }
1068 }
8001069 break;
8011070
8021071 case SDL_MOUSEMOTION:
8391108 }
8401109 break;
8411110
1111 case SDL_CONTROLLERDEVICEADDED:
1112 case SDL_CONTROLLERDEVICEREMOVED:
1113 if (in_joystick->integer)
1114 IN_InitJoystick();
1115 break;
1116
8421117 case SDL_QUIT:
8431118 Cbuf_ExecuteText(EXEC_NOW, "quit Closed window\n");
8441119 break;
337337 extern cvar_t *sv_lanForceRate;
338338 extern cvar_t *sv_onlyVisibleClients;
339339
340 extern cvar_t *sv_forceNameUniq;
341
340342 extern cvar_t *sv_banFile;
341343
342344 extern serverBan_t serverBans[SERVER_MAXBANS];
398400 void SV_RemoveOperatorCommands( void );
399401
400402 void SV_MasterShutdown( void );
401
402 void SV_MasterGameCompleteStatus( void ); // NERVE - SMF
403403
404404 int SV_RateMsec(client_t *client);
405405
216216 }
217217 }
218218
219 // save the map name here cause on a map restart we reload the q3config.cfg
219 // save the map name here cause on a map restart we reload the wolfconfig_server.cfg
220220 // and thus nuke the arguments of the map command
221221 Q_strncpyz( mapname, map, sizeof( mapname ) );
222222
696696 }
697697
698698 #ifndef STANDALONE
699 #ifdef USE_AUTHORIZE_SERVER
699700 // these functions require the auth server which of course is not available anymore for stand-alone games.
700701
701702 /*
807808 Com_Printf( "%s was banned from coming back\n", cl->name );
808809 }
809810 }
811 #endif
810812 #endif
811813
812814 /*
15771579 SV_Shutdown( "killserver" );
15781580 }
15791581
1580 /*
1581 =================
1582 SV_GameCompleteStatus_f
1583
1584 NERVE - SMF
1585 =================
1586 */
1587 void SV_GameCompleteStatus_f( void ) {
1588 SV_MasterGameCompleteStatus();
1589 }
15901582
15911583 //===========================================================
15921584
16171609 Cmd_AddCommand( "heartbeat", SV_Heartbeat_f );
16181610 Cmd_AddCommand( "kick", SV_Kick_f );
16191611 #ifndef STANDALONE
1612 #ifdef USE_AUTHORIZE_SERVER
16201613 if(!com_standalone->integer)
16211614 {
16221615 Cmd_AddCommand ("banUser", SV_Ban_f);
16231616 Cmd_AddCommand ("banClient", SV_BanNum_f);
16241617 }
1618 #endif
16251619 #endif
16261620 Cmd_AddCommand ("kickbots", SV_KickBots_f);
16271621 Cmd_AddCommand ("kickall", SV_KickAll_f);
16351629 Cmd_AddCommand( "sectorlist", SV_SectorList_f );
16361630 Cmd_AddCommand( "map", SV_Map_f );
16371631 Cmd_SetCommandCompletionFunc( "map", SV_CompleteMapName );
1638 Cmd_AddCommand( "gameCompleteStatus", SV_GameCompleteStatus_f ); // NERVE - SMF
16391632 #ifndef PRE_RELEASE_DEMO
16401633 Cmd_AddCommand( "devmap", SV_Map_f );
16411634 Cmd_SetCommandCompletionFunc( "devmap", SV_CompleteMapName );
150150 challenge->time = svs.time;
151151
152152 #ifndef STANDALONE
153 #ifdef USE_AUTHORIZE_SERVER
153154 // Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
154155 // Drop also for addresses coming in on local LAN and for stand-alone games independent from id's assets.
155156 if(challenge->adr.type == NA_IP && !com_standalone->integer && !Sys_IsLANAddress(from))
203204 }
204205 }
205206 #endif
207 #endif
206208
207209 challenge->pingTime = svs.time;
208210 NET_OutOfBandPrint(NS_SERVER, challenge->adr, "challengeResponse %d %d %d %d",
211213
212214
213215 #ifndef STANDALONE
216 #ifdef USE_AUTHORIZE_SERVER
214217 /*
215218 ====================
216219 SV_AuthorizeIpPacket
284287 // clear the challenge record so it won't timeout and let them through
285288 Com_Memset( challengeptr, 0, sizeof(*challengeptr) );
286289 }
290 #endif
287291 #endif
288292
289293 /*
344348 intptr_t denied;
345349 int count;
346350 char *ip;
351 char *guid;
347352 #ifdef LEGACY_PROTOCOL
348353 qboolean compat = qfalse;
349354 #endif
358363 }
359364
360365 Q_strncpyz( userinfo, Cmd_Argv( 1 ), sizeof( userinfo ) );
366
367 // Check for GUID
368 guid = Info_ValueForKey( userinfo, "cl_guid" );
369
370 if ( !sv_allowAnonymous->integer && !Sys_IsLANAddress( from ) ) {
371 if ( !Q_stricmp( guid, "NO_GUID" ) ) {
372 NET_OutOfBandPrint(NS_SERVER, from, "print\nEmpty CD-Key or GUID not permitted on server.\n");
373 return;
374 }
375 }
361376
362377 // DHM - Nerve :: Update Server allows any protocol to connect
363378 #ifndef UPDATE_SERVER
14661481 void SV_UserinfoChanged( client_t *cl ) {
14671482 char *val;
14681483 char *ip;
1484 char *guid;
1485 char *name;
1486 char gname[MAX_QPATH];
14691487 int i;
14701488 int len;
14711489
14721490 // name for C code
1473 Q_strncpyz( cl->name, Info_ValueForKey( cl->userinfo, "name" ), sizeof( cl->name ) );
1491 name = Info_ValueForKey( cl->userinfo, "name" );
1492 guid = Info_ValueForKey( cl->userinfo, "cl_guid" );
1493
1494 if ( sv_forceNameUniq->integer == 1 ) {
1495 if ( !Q_stricmp( name, "" ) || !Q_stricmp( name, "WolfPlayer" ) || !Q_stricmp( name, "UnnamedPlayer" ) ) {
1496 Com_sprintf( gname, sizeof( gname ), "%s %s", name, guid + 24 );
1497 Info_SetValueForKey( cl->userinfo, "name", gname );
1498 }
1499 } else if ( sv_forceNameUniq->integer == 2 ) {
1500 Com_sprintf( gname, sizeof( gname ), "%s %s", name, guid + 24 );
1501 Info_SetValueForKey( cl->userinfo, "name", gname );
1502 }
1503
1504 Q_strncpyz( cl->name, name, sizeof( cl->name ) );
14741505
14751506 // rate command
14761507
20272058 // I don't like this hack though, it must have been working fine at some point, suspecting the fix is somewhere else
20282059 if ( serverId != sv.serverId && !*cl->downloadName && !strstr( cl->lastClientCommandString, "nextdl" ) ) {
20292060 if ( serverId >= sv.restartedServerId && serverId < sv.serverId ) { // TTimo - use a comparison here to catch multiple map_restart
2030 // they just haven't caught the map_restart yet
2031 Com_DPrintf( "%s : ignoring pre map_restart / outdated client message\n", cl->name );
2032 return;
2061 if ( strstr( cl->lastClientCommandString, "donedl" ) ) {
2062 SV_DoneDownload_f( cl );
2063 } else {
2064 // they just haven't caught the map_restart yet
2065 Com_DPrintf( "%s : ignoring pre map_restart / outdated client message\n", cl->name );
2066 return;
2067 }
20332068 }
20342069 // if we can tell that the client has dropped the last
20352070 // gamestate we sent them, resend it
441441 SV_ClearServer
442442 ================
443443 */
444 static cvar_t *sv_levelTimeReset;
445
446 static void SV_ClearServer( void ) {
444 static void SV_ClearServer(void) {
447445 int i;
448446
449447 for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
451449 Z_Free( sv.configstrings[i] );
452450 }
453451 }
454
455 if ( !sv_levelTimeReset->integer ) {
456 i = sv.time;
457 Com_Memset( &sv, 0, sizeof( sv ) );
458 sv.time = i;
459 } else {
460 Com_Memset( &sv, 0, sizeof( sv ) );
461 }
452 Com_Memset (&sv, 0, sizeof(sv));
462453 }
463454
464455 /*
912903 Cvar_Get ("sv_dlURL", "", CVAR_SERVERINFO | CVAR_ARCHIVE);
913904
914905 sv_master[0] = Cvar_Get("sv_master1", MASTER_SERVER_NAME, 0);
915 sv_master[1] = Cvar_Get("sv_master2", "master.ioquake3.org", 0);
906 sv_master[1] = Cvar_Get("sv_master2", "master.iortcw.org", 0);
916907 for(index = 2; index < MAX_MASTER_SERVERS; index++)
917908 sv_master[index] = Cvar_Get(va("sv_master%d", index + 1), "", CVAR_ARCHIVE);
918909
925916
926917 sv_banFile = Cvar_Get("sv_banFile", "serverbans.dat", CVAR_ARCHIVE);
927918
928 sv_levelTimeReset = Cvar_Get( "sv_levelTimeReset", "0", CVAR_ARCHIVE );
929
930919 sv_onlyVisibleClients = Cvar_Get( "sv_onlyVisibleClients", "0", 0 ); // DHM - Nerve
920
921 sv_forceNameUniq = Cvar_Get( "sv_forceNameUniq", "0", CVAR_ARCHIVE );
931922
932923 sv_showAverageBPS = Cvar_Get( "sv_showAverageBPS", "0", 0 ); // NERVE - SMF - net debugging
933924
7171 cvar_t *sv_allowAnonymous;
7272 cvar_t *sv_lanForceRate; // TTimo - dedicated 1 (LAN) server forces local client rates to 99999 (bug #491)
7373 cvar_t *sv_onlyVisibleClients; // DHM - Nerve
74
75 cvar_t *sv_forceNameUniq;
76
7477 cvar_t *sv_friendlyFire; // NERVE - SMF
7578 cvar_t *sv_maxlives; // NERVE - SMF
7679 cvar_t *sv_tourney; // NERVE - SMF
9396 cvar_t *awh_bbox_horz;
9497 cvar_t *awh_bbox_vert;
9598 #endif
96
97 void SVC_GameCompleteStatus( netadr_t from ); // NERVE - SMF
9899
99100 /*
100101 =============================================================================
237238 ================
238239 */
239240 #define HEARTBEAT_MSEC 300 * 1000
240
241241 void SV_MasterHeartbeat(const char *message)
242242 {
243243 static netadr_t adr[MAX_MASTER_SERVERS][2]; // [2] for v4 and v6 address for the same address string.
244 int i;
244 int i;
245245 int res;
246246 int netenabled;
247
248 netenabled = Cvar_VariableIntegerValue("net_enabled");
247 static qboolean firstRes = qtrue;
249248
250249 // DHM - Nerve :: Update Server doesn't send heartbeat
251250 #ifdef UPDATE_SERVER
252251 return;
253252 #endif
254253
254 netenabled = Cvar_VariableIntegerValue("net_enabled");
255
255256 // "dedicated 1" is for lan play, "dedicated 2" is for inet public play
256257 if (!com_dedicated || com_dedicated->integer != 2 || !(netenabled & (NET_ENABLEV4 | NET_ENABLEV6)))
257 return; // only dedicated servers send heartbeats
258 return; // only dedicated servers send heartbeats
258259
259260 // if not time yet, don't send anything
260 if ( svs.time < svs.nextHeartbeatTime )
261 if ( svs.time < svs.nextHeartbeatTime )
261262 return;
262263
263264 if ( !Q_stricmp( com_gamename->string, LEGACY_MASTER_GAMENAME ) )
266267 svs.nextHeartbeatTime = svs.time + HEARTBEAT_MSEC;
267268
268269 // send to group masters
269 for ( i = 0 ; i < MAX_MASTER_SERVERS ; i++ ) {
270 if ( !sv_master[i]->string[0] ) {
270 for (i = 0; i < MAX_MASTER_SERVERS; i++)
271 {
272 if(!sv_master[i]->string[0])
271273 continue;
272 }
273274
274275 // see if we haven't already resolved the name
275 // resolving usually causes hitches on win95, so only
276 // do it when needed
276 // if server did not resolve on first attempt, do not attempt another dns lookup
277 // if server did resolve on first attempt, attempt resolution on subsequent heartbeats
277278 if(sv_master[i]->modified || (adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD))
278279 {
279280 sv_master[i]->modified = qfalse;
280
281
281282 if(netenabled & NET_ENABLEV4)
282283 {
283 Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
284 res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);
285
286 if(res == 2)
287 {
288 // if no port was specified, use the default master port
289 adr[i][0].port = BigShort(PORT_MASTER);
284 if(firstRes || adr[i][0].type != NA_BAD) {
285 Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
286 res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);
287
288 if(res == 2)
289 {
290 // if no port was specified, use the default master port
291 adr[i][0].port = BigShort(PORT_MASTER);
292 }
293
294 if(res) {
295 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
296
297 if(adr[i][0].type != NA_BAD) {
298 Com_Printf ("Sending heartbeat to %s (IPv4)\n", sv_master[i]->string );
299 NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", message);
300 }
301 sv_master[i]->modified = qtrue;
302 } else {
303 Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
304 }
290305 }
291
292 if(res)
293 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
294 else
295 Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
296306 }
297307
298308 if(netenabled & NET_ENABLEV6)
299309 {
300 Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
301 res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);
302
303 if(res == 2)
304 {
305 // if no port was specified, use the default master port
306 adr[i][1].port = BigShort(PORT_MASTER);
310 if(firstRes || adr[i][1].type != NA_BAD) {
311 Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
312 res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);
313
314 if(res == 2)
315 {
316 // if no port was specified, use the default master port
317 adr[i][1].port = BigShort(PORT_MASTER);
318 }
319
320 if(res) {
321 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
322 if(adr[i][1].type != NA_BAD) {
323 Com_Printf ("Sending heartbeat to %s (IPv6)\n", sv_master[i]->string );
324 NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", message);
325 }
326 sv_master[i]->modified = qtrue;
327 } else {
328 Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
329 }
307330 }
308
309 if(res)
310 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
311 else
312 Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
313331 }
314332
315333 if(adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD)
316334 {
317 // if the address failed to resolve, clear it
335 // if the address failed to resolve in both ipv4 or ipv6, clear it
318336 // so we don't take repeated dns hits
319 Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string );
320 Cvar_Set( sv_master[i]->name, "" );
337 Com_Printf("Couldn't resolve address: %s\n", sv_master[i]->string);
338 Cvar_Set(sv_master[i]->name, "");
321339 sv_master[i]->modified = qfalse;
322340 continue;
323341 }
324342 }
325
326
327 Com_Printf( "Sending heartbeat to %s\n", sv_master[i]->string );
328 // this command should be changed if the server info / status format
329 // ever incompatably changes
330
331 if(adr[i][0].type != NA_BAD)
332 NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", message);
333 if(adr[i][1].type != NA_BAD)
334 NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", message);
335 }
336 }
337
338 /*
339 =================
340 SV_MasterGameCompleteStatus
341
342 NERVE - SMF - Sends gameCompleteStatus messages to all master servers
343 =================
344 */
345 void SV_MasterGameCompleteStatus() {
346 static netadr_t adr[MAX_MASTER_SERVERS][2]; // [2] for v4 and v6 address for the same address string.
347 int i;
348 int res;
349 int netenabled;
350
351 netenabled = Cvar_VariableIntegerValue("net_enabled");
352
353 // "dedicated 1" is for lan play, "dedicated 2" is for inet public play
354 if (!com_dedicated || com_dedicated->integer != 2 || !(netenabled & (NET_ENABLEV4 | NET_ENABLEV6)))
355 return; // only dedicated servers send master game status
356
357 // send to group masters
358 for ( i = 0 ; i < MAX_MASTER_SERVERS ; i++ ) {
359 if ( !sv_master[i]->string[0] ) {
360 continue;
361 }
362
363 // see if we haven't already resolved the name
364 // resolving usually causes hitches on win95, so only
365 // do it when needed
366 if(sv_master[i]->modified || (adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD))
367 {
368 sv_master[i]->modified = qfalse;
369
370 if(netenabled & NET_ENABLEV4)
371 {
372 Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
373 res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);
374
375 if(res == 2)
376 {
377 // if no port was specified, use the default master port
378 adr[i][0].port = BigShort(PORT_MASTER);
379 }
380
381 if(res)
382 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
383 else
384 Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
385 }
386
387 if(netenabled & NET_ENABLEV6)
388 {
389 Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
390 res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);
391
392 if(res == 2)
393 {
394 // if no port was specified, use the default master port
395 adr[i][1].port = BigShort(PORT_MASTER);
396 }
397
398 if(res)
399 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
400 else
401 Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
402 }
403
404 if(adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD)
405 {
406 // if the address failed to resolve, clear it
407 // so we don't take repeated dns hits
408 Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string );
409 Cvar_Set( sv_master[i]->name, "" );
410 sv_master[i]->modified = qfalse;
411 continue;
412 }
413 }
414
415 Com_Printf( "Sending gameCompleteStatus to %s\n", sv_master[i]->string );
416 // this command should be changed if the server info / status format
417 // ever incompatably changes
418
419 if(adr[i][0].type != NA_BAD)
420 SVC_GameCompleteStatus( adr[i][0] );
421 if(adr[i][1].type != NA_BAD)
422 SVC_GameCompleteStatus( adr[i][1] );
423 }
343 }
344
345 firstRes = qfalse;
424346 }
425347
426348 /*
436358 SV_MasterHeartbeat(FLATLINE_FOR_MASTER);
437359
438360 // send it again to minimize chance of drops
439 svs.nextHeartbeatTime = -9999;
440 SV_MasterHeartbeat(FLATLINE_FOR_MASTER);
361 // svs.nextHeartbeatTime = -9999;
362 // SV_MasterHeartbeat(FLATLINE_FOR_MASTER);
441363
442364 // when the master tries to poll the server, it won't respond, so
443365 // it will be removed from the list
685607 }
686608
687609 NET_OutOfBandPrint( NS_SERVER, from, "statusResponse\n%s\n%s", infostring, status );
688 }
689
690 /*
691 =================
692 SVC_GameCompleteStatus
693
694 NERVE - SMF - Send serverinfo cvars, etc to master servers when
695 game complete. Useful for tracking global player stats.
696 =================
697 */
698 void SVC_GameCompleteStatus( netadr_t from ) {
699 char player[1024];
700 char status[MAX_MSGLEN];
701 int i;
702 client_t *cl;
703 playerState_t *ps;
704 int statusLength;
705 int playerLength;
706 char infostring[MAX_INFO_STRING];
707
708 // ignore if we are in single player
709 if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
710 return;
711 }
712
713 // Prevent using getstatus as an amplifier
714 if ( SVC_RateLimitAddress( from, 10, 1000 ) ) {
715 Com_DPrintf( "SVC_Status: rate limit from %s exceeded, dropping request\n",
716 NET_AdrToString( from ) );
717 return;
718 }
719
720 // Allow getstatus to be DoSed relatively easily, but prevent
721 // excess outbound bandwidth usage when being flooded inbound
722 if ( SVC_RateLimit( &outboundLeakyBucket, 10, 100 ) ) {
723 Com_DPrintf( "SVC_Status: rate limit exceeded, dropping request\n" );
724 return;
725 }
726
727 // A maximum challenge length of 128 should be more than plenty.
728 if(strlen(Cmd_Argv(1)) > 128)
729 return;
730
731 strcpy( infostring, Cvar_InfoString( CVAR_SERVERINFO ) );
732
733 // echo back the parameter to status. so master servers can use it as a challenge
734 // to prevent timed spoofed reply packets that add ghost servers
735 Info_SetValueForKey( infostring, "challenge", Cmd_Argv( 1 ) );
736
737 status[0] = 0;
738 statusLength = 0;
739
740 for ( i = 0 ; i < sv_maxclients->integer ; i++ ) {
741 cl = &svs.clients[i];
742 if ( cl->state >= CS_CONNECTED ) {
743 ps = SV_GameClientNum( i );
744 Com_sprintf( player, sizeof( player ), "%i %i \"%s\"\n",
745 ps->persistant[PERS_SCORE], cl->ping, cl->name );
746 playerLength = strlen( player );
747 if ( statusLength + playerLength >= sizeof( status ) ) {
748 break; // can't hold any more
749 }
750 strcpy( status + statusLength, player );
751 statusLength += playerLength;
752 }
753 }
754
755 NET_OutOfBandPrint( NS_SERVER, from, "gameCompleteStatus\n%s\n%s", infostring, status );
756610 }
757611
758612 /*
1049903 } else if ( !Q_stricmp( c,"connect" ) ) {
1050904 SV_DirectConnect( from );
1051905 #ifndef STANDALONE
906 #ifdef USE_AUTHORIZE_SERVER
1052907 } else if ( !Q_stricmp( c,"ipAuthorize" ) ) {
1053908 SV_AuthorizeIpPacket( from );
909 #endif
1054910 #endif
1055911 } else if ( !Q_stricmp( c, "rcon" ) ) {
1056912 SVC_RemoteCommand( from, msg );
3535 #include <time.h>
3636 #include <ctype.h>
3737
38 #ifndef MACOS_X
38 #ifndef __APPLE__
3939 #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
4040 #endif
4141
5757 #define BASEGAME "main"
5858 #define CLIENT_WINDOW_TITLE "Return To Castle Wolfenstein"
5959 #define CLIENT_WINDOW_MIN_TITLE "iowolfmp"
60 #define HOMEPATH_NAME_UNIX ".iortcw"
60 #ifdef USE_XDG
61 #define HOMEPATH_NAME_UNIX "iortcw"
62 #else
63 #define HOMEPATH_NAME_UNIX ".wolf"
64 #endif
6165 #define HOMEPATH_NAME_WIN "RTCW"
6266 #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
6367 #define GAMENAME_FOR_MASTER "wolfmp"
4343 unsigned int CON_LogWrite( const char *in );
4444 unsigned int CON_LogRead( char *out, unsigned int outSize );
4545
46 #ifdef MACOS_X
46 #ifdef __APPLE__
4747 char *Sys_StripAppBundle( char *pwd );
4848 #endif
4949
166166 Sys_PIDFileName
167167 =================
168168 */
169 static char *Sys_PIDFileName( void )
169 static char *Sys_PIDFileName( const char *gamedir )
170170 {
171171 const char *homePath = Cvar_VariableString( "fs_homepath" );
172172
173173 if( *homePath != '\0' )
174 return va( "%s/%s", homePath, PID_FILENAME );
174 return va( "%s/%s/%s", homePath, gamedir, PID_FILENAME );
175175
176176 return NULL;
177177 }
178178
179179 /*
180180 =================
181 Sys_RemovePIDFile
182 =================
183 */
184 void Sys_RemovePIDFile( const char *gamedir )
185 {
186 char *pidFile = Sys_PIDFileName( gamedir );
187
188 if( pidFile != NULL )
189 remove( pidFile );
190 }
191
192 /*
193 =================
181194 Sys_WritePIDFile
182195
183196 Return qtrue if there is an existing stale PID file
184197 =================
185198 */
186 qboolean Sys_WritePIDFile( void )
187 {
188 char *pidFile = Sys_PIDFileName( );
199 static qboolean Sys_WritePIDFile( const char *gamedir )
200 {
201 char *pidFile = Sys_PIDFileName( gamedir );
189202 FILE *f;
190203 qboolean stale = qfalse;
191204
211224 stale = qtrue;
212225 }
213226
227 if( FS_CreatePath( pidFile ) ) {
228 return 0;
229 }
230
214231 if( ( f = fopen( pidFile, "w" ) ) != NULL )
215232 {
216233 fprintf( f, "%d", Sys_PID( ) );
224241
225242 /*
226243 =================
244 Sys_InitPIDFile
245 =================
246 */
247 void Sys_InitPIDFile( const char *gamedir ) {
248 if( Sys_WritePIDFile( gamedir ) ) {
249 #ifndef DEDICATED
250 char message[1024];
251 char modName[MAX_OSPATH];
252
253 FS_GetModDescription( gamedir, modName, sizeof ( modName ) );
254 Q_CleanStr( modName );
255
256 Com_sprintf( message, sizeof (message), "The last time %s ran, "
257 "it didn't exit properly. This may be due to inappropriate video "
258 "settings. Would you like to start with \"safe\" video settings?", modName );
259
260 if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) {
261 Cvar_Set( "com_abnormalExit", "1" );
262 }
263 #endif
264 }
265 }
266
267 /*
268 =================
227269 Sys_Exit
228270
229271 Single exit point (regular exit or in case of error)
237279 SDL_Quit( );
238280 #endif
239281
240 if( exitCode < 2 )
282 if( exitCode < 2 && com_fullyInitialized )
241283 {
242284 // Normal exit
243 char *pidFile = Sys_PIDFileName( );
244
245 if( pidFile != NULL )
246 remove( pidFile );
285 Sys_RemovePIDFile( FS_GetCurrentGameDir() );
247286 }
248287
249288 NET_Shutdown( );
273312 cpuFeatures_t features = 0;
274313
275314 #ifndef DEDICATED
276 if( SDL_HasRDTSC( ) ) features |= CF_RDTSC;
277 if( SDL_HasMMX( ) ) features |= CF_MMX;
278 if( SDL_HasSSE( ) ) features |= CF_SSE;
279 if( SDL_HasSSE2( ) ) features |= CF_SSE2;
315 if( SDL_HasRDTSC( ) ) features |= CF_RDTSC;
316 if( SDL_Has3DNow( ) ) features |= CF_3DNOW;
317 if( SDL_HasMMX( ) ) features |= CF_MMX;
318 if( SDL_HasSSE( ) ) features |= CF_SSE;
319 if( SDL_HasSSE2( ) ) features |= CF_SSE2;
320 if( SDL_HasAltiVec( ) ) features |= CF_ALTIVEC;
280321 #endif
281322
282323 return features;
550591 if( !strcmp( argv[1], "--version" ) ||
551592 !strcmp( argv[1], "-v" ) )
552593 {
553 const char* date = __DATE__;
594 const char* date = PRODUCT_DATE;
554595 #ifdef DEDICATED
555596 fprintf( stdout, Q3_VERSION " dedicated server (%s)\n", date );
556597 #else
562603 }
563604
564605 #ifndef DEFAULT_BASEDIR
565 # ifdef MACOS_X
606 # ifdef __APPLE__
566607 # define DEFAULT_BASEDIR Sys_StripAppBundle(Sys_BinaryPath())
567608 # else
568609 # define DEFAULT_BASEDIR Sys_BinaryPath()
643684 // Set the initial time base
644685 Sys_Milliseconds( );
645686
646 #ifdef MACOS_X
687 #ifdef __APPLE__
647688 // This is passed if we are launched by double-clicking
648689 if ( argc >= 2 && Q_strncmp ( argv[1], "-psn", 4 ) == 0 )
649690 argc = 1;
1919 ===========================================================================
2020 */
2121
22 #ifndef MACOS_X
22 #ifndef __APPLE__
2323 #error This file is for Mac OS X only. You probably should not compile it.
2424 #endif
2525
4242
4343 // Used to determine where to store user-specific files
4444 static char homePath[ MAX_OSPATH ] = { 0 };
45 #ifdef USE_XDG
46 static const char DEFAULT_XDG_DATA_HOME[] = {'.', 'l', 'o', 'c', 'a', 'l', PATH_SEP, 's', 'h', 'a', 'r', 'e', '\0'};
47 #endif
4548
4649 #ifndef STANDALONE
4750 // Used to store the Steam RTCW installation path
5558 */
5659 char *Sys_DefaultHomePath(void)
5760 {
58 char *p;
61 char *p1;
62 #ifdef USE_XDG
63 char *p2;
64 #endif
5965
6066 if( !*homePath && com_homepath != NULL )
6167 {
62 if( ( p = getenv( "HOME" ) ) != NULL )
68 #ifdef __APPLE__
69 if( ( p1 = getenv( "HOME" ) ) != NULL )
6370 {
64 Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP);
65 #ifdef MACOS_X
71 Com_sprintf(homePath, sizeof(homePath), "%s%c", p1, PATH_SEP);
72
6673 Q_strcat(homePath, sizeof(homePath),
6774 "Library/Application Support/");
6875
7077 Q_strcat(homePath, sizeof(homePath), com_homepath->string);
7178 else
7279 Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
80 }
7381 #else
82 #ifdef USE_XDG
83 if( ( p1 = getenv( "XDG_DATA_HOME" ) ) != NULL )
84 {
85 Com_sprintf(homePath, sizeof(homePath), "%s%c", p1, PATH_SEP);
86
87 }
88 else if( ( p2 = getenv( "HOME" ) ) != NULL)
89 {
90 Com_sprintf(homePath, sizeof(homePath), "%s%c%s%c", p2, PATH_SEP, DEFAULT_XDG_DATA_HOME, PATH_SEP);
91 }
92
93 if (p1 || p2)
94 {
7495 if(com_homepath->string[0])
7596 Q_strcat(homePath, sizeof(homePath), com_homepath->string);
7697 else
7798 Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
78 #endif
79 }
99 }
100 #else
101 if( ( p1 = getenv( "HOME" ) ) != NULL )
102 {
103 Com_sprintf(homePath, sizeof(homePath), "%s%c", p1, PATH_SEP);
104
105 if(com_homepath->string[0])
106 Q_strcat(homePath, sizeof(homePath), com_homepath->string);
107 else
108 Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
109 }
110 #endif // USE_XDG
111 #endif // __APPLE__
80112 }
81113
82114 return homePath;
96128
97129 if( ( p = getenv( "HOME" ) ) != NULL )
98130 {
99 #ifdef MACOS_X
131 #ifdef __APPLE__
100132 char *steamPathEnd = "/Library/Application Support/Steam/SteamApps/common/" STEAMPATH_NAME;
101133 #else
102134 char *steamPathEnd = "/.steam/steam/SteamApps/common/" STEAMPATH_NAME;
580612 close( f );
581613 }
582614
583 #ifndef MACOS_X
615 #ifndef __APPLE__
584616 static char execBuffer[ 1024 ];
585617 static char *execBufferPointer;
586618 static char *execArgv[ 16 ];
10381070 // build the command line
10391071 Com_sprintf( cmdline, MAX_CMD, "%s '%s' &", fn, url );
10401072
1041 Sys_StartProcess( cmdline, qfalse );
1073 if ( doexit ) {
1074 Sys_StartProcess( cmdline, qtrue );
1075 } else {
1076 Sys_StartProcess( cmdline, qfalse );
1077 }
10421078
10431079 }
10441080
476476 acc = (acc << 2) | (acc >> 30);
477477 acc &= 0xffffffffU;
478478 }
479 return abs(acc);
479 return acc;
480480 }
481481
482482
21172117 #else
21182118 UI_PlayerInfo_SetModel( &info2, model );
21192119 #endif // #ifdef MISSIONPACK
2120
21212120 UI_PlayerInfo_SetInfo( &info2, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MP40, qfalse );
2122
2121 #ifdef MISSIONPACK
2122 UI_RegisterClientModelname( &info2, model, headmodel, team );
2123 #else
21232124 UI_RegisterClientModelname( &info2, model );
2124
2125 #endif // #ifdef MISSIONPACK
21252126 updateOpponentModel = qfalse;
21262127 }
21272128
29352936 return vis;
29362937 }
29372938
2938 static qboolean UI_Handicap_HandleKey( int flags, float *special, int key ) {
2939 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
2939 static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) {
2940 int select = UI_SelectForKey(key);
2941 if (select != 0) {
29402942 int h;
2941 h = Com_Clamp( 5, 100, trap_Cvar_VariableValue( "handicap" ) );
2942 if ( key == K_MOUSE2 ) {
2943 h -= 5;
2944 } else {
2945 h += 5;
2946 }
2947 if ( h > 100 ) {
2943
2944 h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
2945 h += 5 * select;
2946
2947 if (h > 100) {
29482948 h = 5;
2949 } else if ( h < 5 ) {
2949 } else if (h < 5) {
29502950 h = 100;
29512951 }
2952 trap_Cvar_Set( "handicap", va( "%i", h ) );
2952
2953 trap_Cvar_SetValue( "handicap", h );
29532954 return qtrue;
29542955 }
29552956 return qfalse;
29562957 }
29572958
2958 static qboolean UI_Effects_HandleKey( int flags, float *special, int key ) {
2959 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
2960
2961 if ( key == K_MOUSE2 ) {
2962 uiInfo.effectsColor--;
2963 } else {
2964 uiInfo.effectsColor++;
2965 }
2966
2967 if ( uiInfo.effectsColor > 6 ) {
2959 static qboolean UI_Effects_HandleKey(int flags, float *special, int key) {
2960 int select = UI_SelectForKey(key);
2961 if (select != 0) {
2962 uiInfo.effectsColor += select;
2963
2964 if( uiInfo.effectsColor > 6 ) {
29682965 uiInfo.effectsColor = 0;
2969 } else if ( uiInfo.effectsColor < 0 ) {
2966 } else if (uiInfo.effectsColor < 0) {
29702967 uiInfo.effectsColor = 6;
29712968 }
29722969
29762973 return qfalse;
29772974 }
29782975
2979 static qboolean UI_ClanName_HandleKey( int flags, float *special, int key ) {
2980 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
2976 static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) {
2977 int select = UI_SelectForKey(key);
2978 if (select != 0) {
29812979 int i;
2982 i = UI_TeamIndexFromName( UI_Cvar_VariableString( "ui_teamName" ) );
2983 if ( uiInfo.teamList[i].cinematic >= 0 ) {
2984 trap_CIN_StopCinematic( uiInfo.teamList[i].cinematic );
2980
2981 i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
2982
2983 if (uiInfo.teamList[i].cinematic >= 0) {
2984 trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic);
29852985 uiInfo.teamList[i].cinematic = -1;
29862986 }
2987 if ( key == K_MOUSE2 ) {
2988 i--;
2989 } else {
2990 i++;
2991 }
2992 if ( i >= uiInfo.teamCount ) {
2987
2988 i += select;
2989
2990 if (i >= uiInfo.teamCount) {
29932991 i = 0;
2994 } else if ( i < 0 ) {
2992 } else if (i < 0) {
29952993 i = uiInfo.teamCount - 1;
29962994 }
2997 trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName );
2995
2996 trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName);
29982997 updateModel = qtrue;
29992998 return qtrue;
30002999 }
30013000 return qfalse;
30023001 }
30033002
3004 static qboolean UI_GameType_HandleKey( int flags, float *special, int key, qboolean resetMap ) {
3003 static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) {
30053004 //#ifdef MISSIONPACK
3006 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3007 int oldCount = UI_MapCountByGameType( qtrue );
3005 int select = UI_SelectForKey(key);
3006 if (select != 0) {
3007 int oldCount = UI_MapCountByGameType(qtrue);
30083008
30093009 // hard coded mess here
3010 if ( key == K_MOUSE2 ) {
3010 if (select < 0) {
30113011 ui_gameType.integer--;
3012 if ( ui_gameType.integer == 2 ) {
3012 if (ui_gameType.integer == 2) {
30133013 ui_gameType.integer = 1;
3014 } else if ( ui_gameType.integer < 2 ) {
3014 } else if (ui_gameType.integer < 2) {
30153015 ui_gameType.integer = uiInfo.numGameTypes - 1;
30163016 }
30173017 } else {
30183018 ui_gameType.integer++;
3019 if ( ui_gameType.integer >= uiInfo.numGameTypes ) {
3019 if (ui_gameType.integer >= uiInfo.numGameTypes) {
30203020 ui_gameType.integer = 1;
3021 } else if ( ui_gameType.integer == 2 ) {
3021 } else if (ui_gameType.integer == 2) {
30223022 ui_gameType.integer = 3;
30233023 }
30243024 }
3025
3026 if ( uiInfo.gameTypes[ui_gameType.integer].gtEnum == GT_TOURNAMENT ) {
3027 trap_Cvar_Set( "ui_Q3Model", "1" );
3025
3026 if (uiInfo.gameTypes[ui_gameType.integer].gtEnum < GT_TEAM) {
3027 trap_Cvar_SetValue( "ui_Q3Model", 1 );
30283028 } else {
3029 trap_Cvar_Set( "ui_Q3Model", "0" );
3030 }
3031
3032 trap_Cvar_Set( "ui_gameType", va( "%d", ui_gameType.integer ) );
3033 UI_SetCapFragLimits( qtrue );
3034 UI_LoadBestScores( uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum );
3035 if ( resetMap && oldCount != UI_MapCountByGameType( qtrue ) ) {
3036 trap_Cvar_Set( "ui_currentMap", "0" );
3037 Menu_SetFeederSelection( NULL, FEEDER_MAPS, 0, NULL );
3029 trap_Cvar_SetValue( "ui_Q3Model", 0 );
3030 }
3031
3032 trap_Cvar_SetValue("ui_gameType", ui_gameType.integer);
3033 UI_SetCapFragLimits(qtrue);
3034 UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
3035 if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) {
3036 trap_Cvar_SetValue( "ui_currentMap", 0);
3037 Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL);
30383038 }
30393039 return qtrue;
30403040 }
30423042 return qfalse;
30433043 }
30443044
3045 static qboolean UI_NetGameType_HandleKey( int flags, float *special, int key ) {
3045 static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) {
30463046 //#ifdef MISSIONPACK
3047 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3048
3049 if ( key == K_MOUSE2 ) {
3050 ui_netGameType.integer--;
3051 } else {
3052 ui_netGameType.integer++;
3053 }
3054
3055 if ( ui_netGameType.integer < 0 ) {
3047 int select = UI_SelectForKey(key);
3048 if (select != 0) {
3049 ui_netGameType.integer += select;
3050
3051 if (ui_netGameType.integer < 0) {
30563052 ui_netGameType.integer = uiInfo.numGameTypes - 1;
3057 } else if ( ui_netGameType.integer >= uiInfo.numGameTypes ) {
3053 } else if (ui_netGameType.integer >= uiInfo.numGameTypes) {
30583054 ui_netGameType.integer = 0;
30593055 }
30603056
3061 trap_Cvar_Set( "ui_netGameType", va( "%d", ui_netGameType.integer ) );
3062 trap_Cvar_Set( "ui_actualnetGameType", va( "%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) );
3063 trap_Cvar_Set( "ui_currentNetMap", "0" );
3064 UI_MapCountByGameType( qfalse );
3065 Menu_SetFeederSelection( NULL, FEEDER_ALLMAPS, 0, NULL );
3057 trap_Cvar_SetValue( "ui_netGameType", ui_netGameType.integer);
3058 trap_Cvar_SetValue( "ui_actualnetGameType", uiInfo.gameTypes[ui_netGameType.integer].gtEnum);
3059 trap_Cvar_SetValue( "ui_currentNetMap", 0);
3060 UI_MapCountByGameType(qfalse);
3061 Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL);
30663062 return qtrue;
30673063 }
30683064 //#endif // #ifdef MISSIONPACK
30693065 return qfalse;
30703066 }
30713067
3072 static qboolean UI_JoinGameType_HandleKey( int flags, float *special, int key ) {
3068 static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
30733069 //#ifdef MISSIONPACK
3074 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3075
3076 if ( key == K_MOUSE2 ) {
3077 ui_joinGameType.integer--;
3078 } else {
3079 ui_joinGameType.integer++;
3080 }
3081
3082 if ( ui_joinGameType.integer < 0 ) {
3070 int select = UI_SelectForKey(key);
3071 if (select != 0) {
3072 ui_joinGameType.integer += select;
3073
3074 if (ui_joinGameType.integer < 0) {
30833075 ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1;
3084 } else if ( ui_joinGameType.integer >= uiInfo.numJoinGameTypes ) {
3076 } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) {
30853077 ui_joinGameType.integer = 0;
30863078 }
30873079
3088 trap_Cvar_Set( "ui_joinGameType", va( "%d", ui_joinGameType.integer ) );
3089 UI_BuildServerDisplayList( qtrue );
3080 trap_Cvar_SetValue( "ui_joinGameType", ui_joinGameType.integer);
3081 UI_BuildServerDisplayList(qtrue);
30903082 return qtrue;
30913083 }
30923084 //#endif // #ifdef MISSIONPACK
30953087
30963088
30973089
3098 static qboolean UI_Skill_HandleKey( int flags, float *special, int key ) {
3099 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3090 static qboolean UI_Skill_HandleKey(int flags, float *special, int key) {
3091 int select = UI_SelectForKey(key);
3092 if (select != 0) {
31003093 int i = trap_Cvar_VariableValue( "g_spSkill" );
31013094
3102 if ( key == K_MOUSE2 ) {
3103 i--;
3104 } else {
3105 i++;
3106 }
3107
3108 if ( i < 1 ) {
3095 i += select;
3096
3097 if (i < 1) {
31093098 i = numSkillLevels;
3110 } else if ( i > numSkillLevels ) {
3099 } else if (i > numSkillLevels) {
31113100 i = 1;
31123101 }
31133102
3114 trap_Cvar_Set( "g_spSkill", va( "%i", i ) );
3103 trap_Cvar_SetValue("g_spSkill", i);
31153104 return qtrue;
31163105 }
31173106 return qfalse;
31183107 }
31193108
3120 static qboolean UI_TeamName_HandleKey( int flags, float *special, int key, qboolean blue ) {
3121 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3109 static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) {
3110 int select = UI_SelectForKey(key);
3111 if (select != 0) {
31223112 int i;
3123 i = UI_TeamIndexFromName( UI_Cvar_VariableString( ( blue ) ? "ui_blueTeam" : "ui_redTeam" ) );
3124
3125 if ( key == K_MOUSE2 ) {
3126 i--;
3127 } else {
3128 i++;
3129 }
3130
3131 if ( i >= uiInfo.teamCount ) {
3113
3114 i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
3115 i += select;
3116
3117 if (i >= uiInfo.teamCount) {
31323118 i = 0;
3133 } else if ( i < 0 ) {
3119 } else if (i < 0) {
31343120 i = uiInfo.teamCount - 1;
31353121 }
31363122
3137 trap_Cvar_Set( ( blue ) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName );
3138
3123 trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName);
31393124 return qtrue;
31403125 }
31413126 return qfalse;
31423127 }
31433128
3144 static qboolean UI_TeamMember_HandleKey( int flags, float *special, int key, qboolean blue, int num ) {
3145 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3129 static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) {
3130 int select = UI_SelectForKey(key);
3131 if (select != 0) {
31463132 // 0 - None
31473133 // 1 - Human
31483134 // 2..NumCharacters - Bot
3149 char *cvar = va( blue ? "ui_blueteam%i" : "ui_redteam%i", num );
3150 int value = trap_Cvar_VariableValue( cvar );
3151
3152 if ( key == K_MOUSE2 ) {
3153 value--;
3135 char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num);
3136 int value = trap_Cvar_VariableValue(cvar);
3137
3138 value += select;
3139
3140 if (ui_actualNetGameType.integer >= GT_TEAM) {
3141 if (value >= uiInfo.characterCount + 2) {
3142 value = 0;
3143 } else if (value < 0) {
3144 value = uiInfo.characterCount + 2 - 1;
3145 }
31543146 } else {
3155 value++;
3156 }
3157
3158 if ( ui_actualNetGameType.integer >= GT_TEAM ) {
3159 if ( value >= uiInfo.characterCount + 2 ) {
3147 if (value >= UI_GetNumBots() + 2) {
31603148 value = 0;
3161 } else if ( value < 0 ) {
3162 value = uiInfo.characterCount + 2 - 1;
3163 }
3164 } else {
3165 if ( value >= UI_GetNumBots() + 2 ) {
3166 value = 0;
3167 } else if ( value < 0 ) {
3149 } else if (value < 0) {
31683150 value = UI_GetNumBots() + 2 - 1;
31693151 }
31703152 }
31713153
3172 trap_Cvar_Set( cvar, va( "%i", value ) );
3154 trap_Cvar_SetValue(cvar, value);
31733155 return qtrue;
31743156 }
31753157 return qfalse;
31773159
31783160 static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
31793161 //#ifdef MISSIONPACK
3180 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
3181
3182 if (key == K_MOUSE2) {
3183 ui_netSource.integer--;
3184 } else {
3185 ui_netSource.integer++;
3186 }
3162 int select = UI_SelectForKey(key);
3163 if (select != 0) {
3164 ui_netSource.integer += select;
31873165
31883166 if(ui_netSource.integer >= UIAS_GLOBAL1 && ui_netSource.integer <= UIAS_GLOBAL5)
31893167 {
31953173 trap_Cvar_VariableStringBuffer(cvarname, masterstr, sizeof(masterstr));
31963174 if(*masterstr)
31973175 break;
3198
3199 if (key == K_MOUSE2) {
3200 ui_netSource.integer--;
3201 } else {
3202 ui_netSource.integer++;
3203 }
3176
3177 ui_netSource.integer += select;
32043178 }
32053179 }
32063180
32143188 if (!(ui_netSource.integer >= UIAS_GLOBAL1 && ui_netSource.integer <= UIAS_GLOBAL5)) {
32153189 UI_StartServerRefresh(qtrue);
32163190 }
3217 trap_Cvar_Set( "ui_netSource", va("%d", ui_netSource.integer));
3191 trap_Cvar_SetValue( "ui_netSource", ui_netSource.integer);
32183192 return qtrue;
32193193 }
32203194 //#endif // #ifdef MISSIONPACK
32213195 return qfalse;
32223196 }
32233197
3224 static qboolean UI_NetFilter_HandleKey( int flags, float *special, int key ) {
3198 static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) {
32253199 //#ifdef MISSIONPACK
3226 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3227
3228 if ( key == K_MOUSE2 ) {
3229 ui_serverFilterType.integer--;
3230 } else {
3231 ui_serverFilterType.integer++;
3232 }
3233
3234 if ( ui_serverFilterType.integer >= numServerFilters ) {
3200 int select = UI_SelectForKey(key);
3201 if (select != 0) {
3202 ui_serverFilterType.integer += select;
3203
3204 if (ui_serverFilterType.integer >= numServerFilters) {
32353205 ui_serverFilterType.integer = 0;
3236 } else if ( ui_serverFilterType.integer < 0 ) {
3206 } else if (ui_serverFilterType.integer < 0) {
32373207 ui_serverFilterType.integer = numServerFilters - 1;
32383208 }
3239 UI_BuildServerDisplayList( qtrue );
3209 UI_BuildServerDisplayList(qtrue);
32403210 return qtrue;
32413211 }
32423212 //#endif // #ifdef MISSIONPACK
32433213 return qfalse;
32443214 }
32453215
3246 static qboolean UI_OpponentName_HandleKey( int flags, float *special, int key ) {
3247 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3248 if ( key == K_MOUSE2 ) {
3216 static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) {
3217 int select = UI_SelectForKey(key);
3218 if (select != 0) {
3219 if (select < 0) {
32493220 UI_PriorOpponent();
32503221 } else {
32513222 UI_NextOpponent();
32553226 return qfalse;
32563227 }
32573228
3258 static qboolean UI_BotName_HandleKey( int flags, float *special, int key ) {
3259 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3260 int game = trap_Cvar_VariableValue( "g_gametype" );
3229 static qboolean UI_BotName_HandleKey(int flags, float *special, int key) {
3230 int select = UI_SelectForKey(key);
3231 if (select != 0) {
3232 int game = trap_Cvar_VariableValue("g_gametype");
32613233 int value = uiInfo.botIndex;
32623234
3263 if ( key == K_MOUSE2 ) {
3264 value--;
3235 value += select;
3236
3237 if (game >= GT_TEAM) {
3238 if (value >= uiInfo.characterCount + 2) {
3239 value = 0;
3240 } else if (value < 0) {
3241 value = uiInfo.characterCount + 2 - 1;
3242 }
32653243 } else {
3266 value++;
3267 }
3268
3269 if ( game >= GT_TEAM ) {
3270 if ( value >= uiInfo.characterCount + 2 ) {
3244 if (value >= UI_GetNumBots() + 2) {
32713245 value = 0;
3272 } else if ( value < 0 ) {
3273 value = uiInfo.characterCount + 2 - 1;
3274 }
3275 } else {
3276 if ( value >= UI_GetNumBots() + 2 ) {
3277 value = 0;
3278 } else if ( value < 0 ) {
3246 } else if (value < 0) {
32793247 value = UI_GetNumBots() + 2 - 1;
32803248 }
32813249 }
32853253 return qfalse;
32863254 }
32873255
3288 static qboolean UI_BotSkill_HandleKey( int flags, float *special, int key ) {
3289 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3290 if ( key == K_MOUSE2 ) {
3291 uiInfo.skillIndex--;
3292 } else {
3293 uiInfo.skillIndex++;
3294 }
3295 if ( uiInfo.skillIndex >= numSkillLevels ) {
3256 static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) {
3257 int select = UI_SelectForKey(key);
3258 if (select != 0) {
3259 uiInfo.skillIndex += select;
3260
3261 if (uiInfo.skillIndex >= numSkillLevels) {
32963262 uiInfo.skillIndex = 0;
3297 } else if ( uiInfo.skillIndex < 0 ) {
3298 uiInfo.skillIndex = numSkillLevels - 1;
3263 } else if (uiInfo.skillIndex < 0) {
3264 uiInfo.skillIndex = numSkillLevels-1;
32993265 }
33003266 return qtrue;
33013267 }
33023268 return qfalse;
33033269 }
33043270
3305 static qboolean UI_RedBlue_HandleKey( int flags, float *special, int key ) {
3306 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3271 static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) {
3272 int select = UI_SelectForKey(key);
3273 if (select != 0) {
33073274 uiInfo.redBlue ^= 1;
33083275 return qtrue;
33093276 }
33103277 return qfalse;
33113278 }
33123279
3313 static qboolean UI_Crosshair_HandleKey( int flags, float *special, int key ) {
3314 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3315 if ( key == K_MOUSE2 ) {
3316 uiInfo.currentCrosshair--;
3280 static qboolean UI_Crosshair_HandleKey(int flags, float *special, int key) {
3281 int select = UI_SelectForKey(key);
3282 if (select != 0) {
3283 uiInfo.currentCrosshair += select;
3284
3285 if (uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
3286 uiInfo.currentCrosshair = 0;
3287 } else if (uiInfo.currentCrosshair < 0) {
3288 uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
3289 }
3290 trap_Cvar_SetValue("cg_drawCrosshair", uiInfo.currentCrosshair);
3291 return qtrue;
3292 }
3293 return qfalse;
3294 }
3295
3296
3297
3298 static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) {
3299 int select = UI_SelectForKey(key);
3300 if (select != 0) {
3301 int selected;
3302
3303 UI_BuildPlayerList();
3304 if (!uiInfo.teamLeader) {
3305 return qfalse;
3306 }
3307 selected = trap_Cvar_VariableValue("cg_selectedPlayer");
3308
3309 selected += select;
3310
3311 if (selected > uiInfo.myTeamCount) {
3312 selected = 0;
3313 } else if (selected < 0) {
3314 selected = uiInfo.myTeamCount;
3315 }
3316
3317 if (selected == uiInfo.myTeamCount) {
3318 trap_Cvar_Set( "cg_selectedPlayerName", "Everyone");
33173319 } else {
3318 uiInfo.currentCrosshair++;
3319 }
3320
3321 if ( uiInfo.currentCrosshair >= NUM_CROSSHAIRS ) {
3322 uiInfo.currentCrosshair = 0;
3323 } else if ( uiInfo.currentCrosshair < 0 ) {
3324 uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
3325 }
3326 trap_Cvar_Set( "cg_drawCrosshair", va( "%d", uiInfo.currentCrosshair ) );
3327 return qtrue;
3328 }
3329 return qfalse;
3330 }
3331
3332
3333
3334 static qboolean UI_SelectedPlayer_HandleKey( int flags, float *special, int key ) {
3335 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3336 int selected;
3337
3338 UI_BuildPlayerList();
3339 if ( !uiInfo.teamLeader ) {
3340 return qfalse;
3341 }
3342 selected = trap_Cvar_VariableValue( "cg_selectedPlayer" );
3343
3344 if ( key == K_MOUSE2 ) {
3345 selected--;
3346 } else {
3347 selected++;
3348 }
3349
3350 if ( selected > uiInfo.myTeamCount ) {
3351 selected = 0;
3352 } else if ( selected < 0 ) {
3353 selected = uiInfo.myTeamCount;
3354 }
3355
3356 if ( selected == uiInfo.myTeamCount ) {
3357 trap_Cvar_Set( "cg_selectedPlayerName", "Everyone" );
3358 } else {
3359 trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected] );
3360 }
3361 trap_Cvar_Set( "cg_selectedPlayer", va( "%d", selected ) );
3320 trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]);
3321 }
3322 trap_Cvar_SetValue( "cg_selectedPlayer", selected);
33623323 }
33633324 return qfalse;
33643325 }
46414602 trap_Cmd_ExecuteText( EXEC_NOW, "exec language.cfg\n" ); // NERVE - SMF
46424603 trap_Cmd_ExecuteText( EXEC_NOW, "setRecommended\n" ); // NERVE - SMF
46434604 Controls_SetDefaults();
4605 #ifdef CINEMATICS_INTRO
46444606 trap_Cvar_Set( "com_introPlayed", "1" );
4607 #endif
46454608 trap_Cvar_Set( "com_recommendedSet", "1" ); // NERVE - SMF
46464609 trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
46474610 } else if ( Q_stricmp( name, "getCDKey" ) == 0 ) {
58675830 } else {
58685831 // add a line that shows the number of servers found
58695832 if ( !uiInfo.numFoundPlayerServers ) {
5870 Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1], sizeof( uiInfo.foundPlayerServerAddresses[0] ), "no servers found" );
5833 Com_sprintf( uiInfo.foundPlayerServerNames[0], sizeof( uiInfo.foundPlayerServerNames[0] ), "no servers found" );
58715834 } else {
5872 Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1], sizeof( uiInfo.foundPlayerServerAddresses[0] ),
5873 "%d server%s found with player %s", uiInfo.numFoundPlayerServers - 1,
5874 uiInfo.numFoundPlayerServers == 2 ? "" : "s", uiInfo.findPlayerName );
5835 Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof( uiInfo.foundPlayerServerNames[0] ),
5836 "%d server%s found with player %s", uiInfo.numFoundPlayerServers - 1,
5837 uiInfo.numFoundPlayerServers == 2 ? "" : "s", uiInfo.findPlayerName );
58755838 }
58765839 uiInfo.nextFindPlayerRefresh = 0;
58775840 // show the server status info for the selected server
14131413 continue;
14141414 }
14151415
1416 if ( pages & ( 1 << ( newpage - 1 ) ) ) {
1416 if ( pages & ( 1 << ( abs( newpage - 1 ) ) ) ) {
14171417 dec++;
14181418 // if(dec == inc)
14191419 // break;
14311431 newpage = newpage + NOTEBOOK_MAX_PAGES;
14321432 }
14331433
1434 if ( pages & ( 1 << ( newpage - 1 ) ) ) {
1434 if ( pages & ( 1 << ( abs( newpage - 1 ) ) ) ) {
14351435 break;
14361436 }
14371437 }
23132313 }
23142314
23152315 qboolean Item_YesNo_HandleKey( itemDef_t *item, int key ) {
2316 if ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) && item->window.flags & WINDOW_HASFOCUS && item->cvar ) {
2317 if ( key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3 ) {
2318 // ATVI Wolfenstein Misc #462
2319 // added the flag to toggle via action script only
2320 if ( !( item->cvarFlags & CVAR_NOTOGGLE ) ) {
2321 DC->setCVar( item->cvar, va( "%i", !DC->getCVarValue( item->cvar ) ) );
2322 }
2316 if (item->cvar) {
2317 qboolean action = qfalse;
2318 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
2319 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
2320 action = qtrue;
2321 }
2322 } else if (UI_SelectForKey(key) != 0) {
2323 action = qtrue;
2324 }
2325 // ATVI Wolfenstein Misc #462
2326 // added the flag to toggle via action script only
2327 if (action && !(item->cvarFlags & CVAR_NOTOGGLE)) {
2328 DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
23232329 return qtrue;
23242330 }
23252331 }
23892395 qboolean Item_Multi_HandleKey( itemDef_t *item, int key ) {
23902396 multiDef_t *multiPtr = (multiDef_t*)item->typeData;
23912397 if ( multiPtr ) {
2392 if ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) && item->window.flags & WINDOW_HASFOCUS && item->cvar ) {
2393 if ( key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3 ) {
2394 int current = Item_Multi_FindCvarByValue( item ) + 1;
2398 if (item->cvar) {
2399 int select = 0;
2400 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
2401 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
2402 select = (key == K_MOUSE2) ? -1 : 1;
2403 }
2404 } else {
2405 select = UI_SelectForKey(key);
2406 }
2407 if (select != 0) {
2408 int current = Item_Multi_FindCvarByValue(item) + select;
23952409 int max = Item_Multi_CountSettings( item );
2396 if ( current < 0 || current >= max ) {
2410 if ( current < 0 ) {
2411 current = max-1;
2412 } else if ( current >= max ) {
23972413 current = 0;
23982414 }
23992415 if ( multiPtr->strDef ) {
27192735 float x, value, width, work;
27202736
27212737 //DC->Print("slider handle key\n");
2722 if ( item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) ) {
2723 if ( key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3 ) {
2738 if (item->cvar) {
2739 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
27242740 editFieldDef_t *editDef = item->typeData;
2725 if ( editDef ) {
2741 if (editDef && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
27262742 rectDef_t testRect;
27272743 width = SLIDER_WIDTH;
27282744 if ( item->text ) {
27462762 // value = (((float)(DC->cursorx - x)/ SLIDER_WIDTH) * (editDef->maxVal - editDef->minVal));
27472763 value += editDef->minVal;
27482764 DC->setCVar( item->cvar, va( "%f", value ) );
2765 return qtrue;
2766 }
2767 }
2768 } else {
2769 int select = UI_SelectForKey(key);
2770 if (select != 0) {
2771 editFieldDef_t *editDef = item->typeData;
2772 if (editDef) {
2773 // 20 is number of steps
2774 value = DC->getCVarValue(item->cvar) + (((editDef->maxVal - editDef->minVal)/20) * select);
2775
2776 if (value < editDef->minVal)
2777 value = editDef->minVal;
2778 else if (value > editDef->maxVal)
2779 value = editDef->maxVal;
2780
2781 DC->setCVar(item->cvar, va("%f", value));
27492782 return qtrue;
27502783 }
27512784 }
29913024 return &rect;
29923025 }
29933026
3027 // menu item key horizontal action: -1 = previous value, 1 = next value, 0 = no change
3028 int UI_SelectForKey(int key)
3029 {
3030 switch (key) {
3031 case K_MOUSE1:
3032 case K_MOUSE3:
3033 case K_ENTER:
3034 case K_KP_ENTER:
3035 case K_RIGHTARROW:
3036 case K_KP_RIGHTARROW:
3037 case K_JOY1:
3038 case K_JOY2:
3039 case K_JOY3:
3040 case K_JOY4:
3041 return 1; // next
3042
3043 case K_MOUSE2:
3044 case K_LEFTARROW:
3045 case K_KP_LEFTARROW:
3046 return -1; // previous
3047 }
3048
3049 // no change
3050 return 0;
3051 }
3052
29943053 void Menu_HandleKey( menuDef_t *menu, int key, qboolean down ) {
29953054 int i;
29963055 itemDef_t *item = NULL;
31403199 case K_AUX14:
31413200 case K_AUX15:
31423201 case K_AUX16:
3143 break;
31443202 case K_KP_ENTER:
31453203 case K_ENTER:
31463204 case K_MOUSE3:
39393997 int id;
39403998 int i;
39413999
3942 if ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) && !g_waitingForKey ) {
3943 if ( down && ( key == K_MOUSE1 || key == K_ENTER ) ) {
4000 if (!g_waitingForKey)
4001 {
4002 if (down && ((key == K_MOUSE1 && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
4003 || key == K_ENTER || key == K_KP_ENTER || key == K_JOY1 || key == K_JOY2 || key == K_JOY3 || key == K_JOY4)) {
39444004 g_waitingForKey = qtrue;
39454005 g_bindItem = item;
39464006 }
39474007 return qtrue;
3948 } else
4008 }
4009 else
39494010 {
3950 if ( !g_waitingForKey || g_bindItem == NULL ) {
4011 if (g_bindItem == NULL) {
39514012 return qtrue;
39524013 }
39534014
461461 qboolean Menus_AnyFullScreenVisible( void );
462462 void Menus_Activate( menuDef_t *menu );
463463
464 int UI_SelectForKey(int key);
464465 displayContextDef_t *Display_GetContext( void );
465466 void *Display_CaptureItem( int x, int y );
466467 qboolean Display_MouseMove( void *p, int x, int y );
1313 #define _CRT_SECURE_NO_WARNINGS
1414 #endif
1515
16 #if defined(MACOS_X) || defined(IOAPI_NO_64)
16 #if defined(__APPLE__) || defined(IOAPI_NO_64)
1717 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
1818 #define FOPEN_FUNC(filename, mode) fopen(filename, mode)
1919 #define FTELLO_FUNC(stream) ftello(stream)
2020 #ifndef _ZLIBIOAPI64_H
2121 #define _ZLIBIOAPI64_H
2222
23 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(MACOS_X))
23 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
2424
2525 // Linux needs this to support file operation on files larger then 4+GB
2626 // But might need better if/def to select just the platforms that needs them.
5454 #define ftello64 ftell
5555 #define fseeko64 fseek
5656 #else
57 #ifdef __FreeBSD__
57 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
5858 #define fopen64 fopen
5959 #define ftello64 ftello
6060 #define fseeko64 fseeko
33
44 if [ "$ARCH" = "x86_64" ];
55 then
6 CMD_PREFIX="amd64-mingw32msvc x86_64-w64-mingw32"
6 CMD_PREFIX="x86_64-w64-mingw32 amd64-mingw32msvc"
77 else
8 CMD_PREFIX="i586-mingw32msvc i686-w64-mingw32"
8 CMD_PREFIX="i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32"
99 export ARCH=x86
1010 fi
1111
2424 done
2525 fi
2626
27 if [ "X$CXX" = "X" ]; then
28 for check in $CMD_PREFIX; do
29 full_check="${check}-g++"
30 which "$full_check" > /dev/null 2>&1
31 if [ "$?" = "0" ]; then
32 export CXX="$full_check"
33 fi
34 done
35 fi
36
2737 if [ "X$WINDRES" = "X" ]; then
2838 for check in $CMD_PREFIX; do
2939 full_check="${check}-windres"
3444 done
3545 fi
3646
37 if [ "X$WINDRES" = "X" -o "X$CC" = "X" ]; then
38 echo "Error: Must define or find WINDRES and CC"
47 if [ "X$WINDRES" = "X" -o "X$CC" = "X" -o "X$CXX" = "X" ]; then
48 echo "Error: Must define or find WINDRES, CC, and CXX"
3949 exit 1
4050 fi
4151
11
22 # Note: This works in Linux and cygwin
33
4 CMD_PREFIX="amd64-mingw32msvc x86_64-w64-mingw32";
4 CMD_PREFIX="x86_64-w64-mingw32 amd64-mingw32msvc";
55
66 if [ "X$CC" = "X" ]; then
77 for check in $CMD_PREFIX; do
99 which "$full_check" > /dev/null 2>&1
1010 if [ "$?" = "0" ]; then
1111 export CC="$full_check"
12 fi
13 done
14 fi
15
16 if [ "X$CXX" = "X" ]; then
17 for check in $CMD_PREFIX; do
18 full_check="${check}-g++"
19 which "$full_check" > /dev/null 2>&1
20 if [ "$?" = "0" ]; then
21 export CXX="$full_check"
1222 fi
1323 done
1424 fi
2333 done
2434 fi
2535
26 if [ "X$WINDRES" = "X" -o "X$CC" = "X" ]; then
27 echo "Error: Must define or find WINDRES and CC"
36 if [ "X$WINDRES" = "X" -o "X$CC" = "X" -o "X$CXX" = "X" ]; then
37 echo "Error: Must define or find WINDRES, CC, and CXX"
2838 exit 1
2939 fi
3040
0 # Rend2
1 <insert ascii art here>
2
3 Rend2 is an alternate renderer for iortcw. It aims to implement modern
4 features and technologies into the id tech 3 engine, but without sacrificing
5 compatibility with existing RTCW mods.
6
7
8 -------------------------------------------------------------------------------
9 FEATURES
10 -------------------------------------------------------------------------------
11
12 - Compatible with most vanilla RTCW mods.
13 - HDR Rendering, and support for HDR lightmaps
14 - Tone mapping and auto-exposure.
15 - Cascaded shadow maps.
16 - Multisample anti-aliasing.
17 - Texture upsampling.
18 - Advanced materials support.
19 - Advanced shading and specular methods.
20 - RGTC and BPTC texture compression support.
21 - Screen-space ambient occlusion.
22
23
24 -------------------------------------------------------------------------------
25 INSTALLATION
26 -------------------------------------------------------------------------------
27
28 For *nix:
29
30 1. This should be identical to installing iortcw. Check their README for more
31 details.
32
33
34 For Win32:
35
36 1. Have a RTCW install, fully patched.
37
38 2. Copy the following files into RTCW's install directory:
39
40 ioWolfMP.x86.exe
41 renderer_opengl1_x86.dll
42 renderer_rend2_x86.dll
43
44 These can be found in build/release-mingw32-x86 after compiling, or bug
45 someone to release binaries.
46
47
48 -------------------------------------------------------------------------------
49 RUNNING
50 -------------------------------------------------------------------------------
51
52 1. Start iowolfmp. (ioWolfMP.x86.exe on Win32)
53
54 2. Open the console (the default key is tilde ~) and type
55 `/cl_renderer rend2` and press enter
56 `/vid_restart` then press enter again.
57
58 3. Enjoy.
59
60
61 -------------------------------------------------------------------------------
62 CVARS
63 -------------------------------------------------------------------------------
64
65 Cvars for simple rendering features:
66
67 * `r_ext_compressed_textures` - Automatically compress textures.
68 0 - No texture compression. (default)
69 1 - DXT/RGTC texture compression if
70 supported.
71 2 - BPTC texture compression if supported.
72
73 * `r_ext_framebuffer_multisample` - Multisample Anti-aliasing.
74 0 - None. (default)
75 1-16 - Some.
76 17+ - Too much!
77
78 * `r_ssao` - Enable screen-space ambient occlusion.
79 Currently eats framerate and has some
80 visible artifacts.
81 0 - No. (default)
82 1 - Yes.
83
84 Cvars for HDR and tonemapping:
85
86 * `r_hdr` - Do scene rendering in a framebuffer with
87 high dynamic range. (Less banding, and
88 exposure changes look much better)
89 0 - No.
90 1 - Yes. (default)
91
92 * `r_cameraExposure` - Cheat. Alter brightness, in powers of two.
93 -2 - 4x as dark.
94 0 - Normal. (default)
95 0.5 - Sqrt(2)x as bright.
96 2 - 4x as bright.
97
98 * `r_postProcess` - Enable post-processing.
99 0 - No.
100 1 - Yes. (default)
101
102 * `r_toneMap` - Enable tone mapping. Requires
103 r_hdr and r_postProcess.
104 0 - No.
105 1 - Yes. (default)
106
107 * `r_forceToneMap` - Cheat. Override built-in and map tonemap settings and use cvars r_forceToneMapAvg, r_forceToneMapMin, and r_forceToneMapMax.
108 0 - No. (default)
109 1 - Yes.
110
111 * `r_forceToneMapAvg` - Cheat. Map average scene luminance to this
112 value, in powers of two. Requires
113 r_forceToneMap.
114 -2.0 - Dark.
115 -1.0 - Kinda dark. (default).
116 2.0 - Too bright.
117
118 * `r_forceToneMapMin` - Cheat. After mapping average, luminance
119 below this level is mapped to black.
120 Requires r_forceToneMap.
121 -5 - Not noticeable.
122 -3.25 - Normal. (default)
123 0.0 - Too dark.
124
125 * `r_forceToneMapMin` - Cheat. After mapping average, luminance
126 above this level is mapped to white.
127 Requires r_forceToneMap.
128 0.0 - Too bright.
129 1.0 - Normal. (default).
130 2.0 - Washed out.
131
132 * `r_autoExposure` - Do automatic exposure based on scene
133 brightness. Hardcoded to -2 to 2 on maps
134 that don't specify otherwise. Requires
135 r_hdr, r_postprocess, and r_toneMap.
136 0 - No.
137 1 - Yes. (default)
138
139 * `r_forceAutoExposure` - Cheat. Override built-in and map auto
140 exposure settings and use cvars
141 r_forceAutoExposureMin and
142 r_forceAutoExposureMax.
143 0 - No. (default)
144 1 - Yes.
145
146 * `r_forceAutoExposureMin` - Cheat. Set minimum exposure to this value,
147 in powers of two. Requires
148 r_forceAutoExpsure.
149 -3.0 - Dimmer.
150 -2.0 - Normal. (default)
151 -1.0 - Brighter.
152
153 * `r_forceAutoExposureMax` - Cheat. Set maximum exposure to this value,
154 in powers of two. Requires
155 r_forceAutoExpsure.
156 1.0 - Dimmer.
157 2.0 - Normal. (default)
158 3.0 - Brighter.
159
160 Cvars for advanced material usage:
161
162 * `r_normalMapping` - Enable normal maps for materials that
163 support it.
164 0 - No.
165 1 - Yes. (default)
166
167 * `r_specularMapping` - Enable specular maps for materials that
168 support it.
169 0 - No.
170 1 - Yes. (default)
171
172 * `r_deluxeMapping` - Enable deluxe mapping. (Map is compiled
173 with light directions.) Even if the map
174 doesn't have deluxe mapping compiled in,
175 an approximation based on the lightgrid
176 will be used.
177 0 - No.
178 1 - Yes. (default)
179
180 * `r_parallaxMapping` - Enable parallax mapping for materials that
181 support it.
182 0 - No. (default)
183 1 - Use parallax occlusion mapping.
184 2 - Use relief mapping. (slower)
185
186 * `r_baseSpecular` - Set the specular reflectance of materials
187 which don't include a specular map or
188 use the specularReflectance keyword.
189 0 - No.
190 0.04 - Realistic. (default)
191 1.0 - Ack.
192
193 * `r_baseGloss` - Set the glossiness of materials which don't
194 include a specular map or use the
195 specularExponent keyword.
196 0 - Rough.
197 0.3 - Default.
198 1.0 - Shiny.
199
200 * `r_baseNormalX` - Set the scale of the X values from normal
201 maps when the normalScale keyword is not
202 used.
203 -1 - Flip X.
204 0 - Ignore X.
205 1 - Normal X. (default)
206 2 - Double X.
207
208 * `r_baseNormalY` - Set the scale of the Y values from normal
209 maps when the normalScale keyword is not
210 used.
211 -1 - Flip Y.
212 0 - Ignore Y.
213 1 - Normal Y. (default)
214 2 - Double Y.
215
216 * `r_baseParallax` - Sets the scale of the parallax effect for
217 materials when the parallaxDepth keyword
218 is not used.
219 0 - No depth.
220 0.01 - Pretty smooth.
221 0.05 - Standard depth. (default)
222 0.1 - Looks broken.
223
224 * `r_pbr` - Enable physically based rendering.
225 Experimental, will not look correct without
226 assets meant for it.
227 0 - No. (default)
228 1 - Yes.
229
230 Cvars for image interpolation and generation:
231
232 * `r_imageUpsample` - Use interpolation to artifically increase
233 the resolution of all textures. Looks good
234 in certain circumstances.
235 0 - No. (default)
236 1 - 2x size.
237 2 - 4x size.
238 3 - 8x size, etc
239
240 * `r_imageUpsampleMaxSize` - Maximum texture size when upsampling
241 textures.
242 1024 - Default.
243 2048 - Really nice.
244 4096 - Really slow.
245 8192 - Crash.
246
247 * `r_imageUpsampleType` - Type of interpolation when upsampling
248 textures.
249 0 - None. (probably broken)
250 1 - Bad but fast (default,
251 FCBI without second derivatives)
252 2 - Okay but slow (normal FCBI)
253
254 * `r_genNormalMaps* - Naively generate normal maps for all
255 textures.
256 0 - Don't. (default)
257 1 - Do.
258
259 Cvars for the sunlight and cascaded shadow maps:
260
261 * `r_forceSun` - Cheat. Force sunlight and shadows, using sun position from sky material.
262 0 - Don't. (default)
263 1 - Do.
264 2 - Sunrise, sunset.
265
266 * `r_forceSunLightScale` - Cheat. Scale sun brightness by this factor
267 when r_forceSun 1.
268 1.0 - Default
269
270 * `r_forceSunAmbientScale` - Cheat. Scale sun ambient brightness by this factor when r_forceSun 1. 0.5 - Default
271
272 * `r_sunShadows` - Enable sunlight and cascaded shadow maps for
273 it on maps that support it.
274 0 - No.
275 1 - Yes. (default)
276
277 * `r_sunlightMode` - Specify the method used to add sunlight to
278 the scene.
279 0 - No.
280 1 - Multiply lit areas by light scale, and
281 shadowed areas by ambient scale.
282 (default)
283 2 - Add light. Looks better, but is slower
284 and doesn't integrate well with existing
285 maps.
286
287 * `r_shadowFilter` - Enable filtering shadows for a smoother
288 look.
289 0 - No.
290 1 - Some. (default)
291 2 - Much.
292
293 * `r_shadowMapSize` - Size of each cascaded shadow map.
294 256 - 256x256, ugly, probably shouldn't
295 go below this.
296 512 - 512x512, passable.
297 1024 - 1024x1024, good. (default)
298 2048 - 2048x2048, extreme.
299 4096 - 4096x4096, indistinguishable from
300 2048.
301
302 Cvars that you probably don't care about or shouldn't mess with:
303
304 * `r_mergeMultidraws` - Optimize number of calls to
305 glMultiDrawElements().
306 0 - Don't.
307 1 - Do some. (default)
308 2 - Do more than necessary (eats CPU).
309
310 * `r_mergeLeafSurfaces` - Merge surfaces that share common materials
311 and a common leaf. Speeds up rendering.
312 0 - Don't.
313 1 - Do. (default)
314
315 * `r_recalcMD3Normals` - Recalculate the normals when loading an MD3.
316 Fixes normal maps in some cases but looks
317 ugly in others.
318 0 - Don't. (default)
319 1 - Do.
320
321 * `r_depthPrepass` - Do a depth-only pass before rendering.
322 Speeds up rendering in cases where advanced
323 features are used. Required for
324 r_sunShadows.
325 0 - No.
326 1 - Yes. (default)
327
328 * `r_mergeLightmaps` - Merge the small (128x128) lightmaps into
329 2 or fewer giant (4096x4096) lightmaps.
330 Easy speedup.
331 0 - Don't.
332 1 - Do. (default)
333
334 * `r_shadowCascadeZNear` - Near plane for shadow cascade frustums.
335 4 - Default.
336
337 * `r_shadowCascadeZFar` - Far plane for shadow cascade frustums.
338 3072 - Default.
339
340 * `r_shadowCascadeZBias` - Z-bias for shadow cascade frustums.
341 -256 - Default.
342
343 Cvars that have broken bits:
344
345 * `r_dlightMode` - Change how dynamic lights look.
346 0 - Quake 3 style dlights, fake
347 brightening. (default)
348 1 - Actual lighting, no shadows.
349 2 - Light and shadows. (broken)
350
351 * `r_pshadowDist` - Virtual camera distance when creating shadowmaps for projected shadows. Deprecated.
352
353 * `cg_shadows` - Old shadow code. Deprecated.
354
355
356 -------------------------------------------------------------------------------
357 MATERIALS
358 -------------------------------------------------------------------------------
359
360 OpenGL2 supports .mtr files, which are basically the same as .shader files, and
361 are located in the same place, but override existing .shader files if they
362 exist. This is to allow maps and mods to use the new material features without
363 breaking the map when using the old renderer.
364
365 Here's an example of a material stored in one, showing off some new features:
366
367 textures/abandon/grass
368 {
369 qer_editorimage textures/abandon/grass.jpg
370 {
371 map textures/abandon/grass3_256_d.jpg
372 rgbgen identity
373 }
374 {
375 stage normalparallaxmap
376 map textures/abandon/grass3_1024_n.png
377 normalScale 1 1
378 parallaxDepth 0.05
379 }
380 {
381 stage specularmap
382 map textures/abandon/grass3_256_s.png
383 specularReflectance 0.12
384 specularExponent 16
385 }
386 {
387 map $lightmap
388 blendfunc GL_DST_COLOR GL_ZERO
389 }
390 }
391
392 The first thing to notice is that this is basically the same as old Quake 3
393 shader files. The next thing to notice are the new keywords. Here is what
394 they mean:
395
396 `stage <type>`
397 - State how this imagemap will be used by OpenGL2:
398 diffuseMap - Standard, same as no stage entry
399 normalMap - Image will be used as a normal map
400 normalParallaxMap - Image will be used as a normal map with
401 alpha treated as height for parallax mapping
402 specularMap - Image will be used as a specular map with
403 alpha treated as shininess.
404
405 `specularReflectance <value>`
406 - State how metallic this material is. Metals typically have a high
407 specular and a low diffuse, so this is typically high for them, and low
408 for other materials, such as plastic. For typical values for various
409 materials, see http://refractiveindex.info , pick a material, then scroll
410 down to the reflection calculator and look up its reflectance. Default
411 is 0.04, since most materials aren't metallic.
412
413 `specularExponent <value>`
414 - State how shiny this material is. Note that this is modulated by the
415 alpha channel of the specular map, so if it were set to 16, and the alpha
416 channel of the specular map was set to 0.5, then the shininess would be
417 set to 8. Default 256.
418
419 `normalScale <x> <y>`
420 - State the X and Y scales of the normal map. This is useful for increasing
421 or decreasing the "strength" of the normal map, or entering negative values
422 to flip the X and/or Y values. Default 1 1.
423
424 `parallaxDepth <value>`
425 - State the maximum depth of the parallax map. This is a fairly sensitive
426 value, and I recommend the default or lower. Default 0.05.
427
428 An important note is that normal and specular maps influence the diffuse map
429 declared before them, so materials like this are possible:
430
431 textures/terrain/grass
432 {
433 qer_editorimage textures/terrain/grass.jpg
434
435 {
436 map textures/terrain/rock.jpg
437 }
438 {
439 stage normalparallaxmap
440 map textures/terrain/rock_n.png
441 }
442 {
443 stage specularmap
444 map textures/terrain/rock_s.jpg
445 }
446 {
447 map textures/terrain/grass.jpg
448 blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
449 alphaGen vertex
450 }
451 {
452 stage normalparallaxmap
453 map textures/terrain/grass_n.png
454 }
455 {
456 stage specularmap
457 map textures/terrain/grass_s.png
458 specularReflectance 0.12
459 }
460 {
461 map $lightmap
462 blendfunc GL_DST_COLOR GL_ZERO
463 }
464 }
465
466 Though note due to the complexity of lighting, dynamic light (including
467 sunlight with cascaded shadow maps) currently only works 100% on materials like
468 this, where the second diffuse map doesn't have its own alpha, and only
469 uses vertex alpha. YMMV.
470
471 Another addition to materials is working normal/specular maps on vertex lit
472 surfaces. To enable this, make your material look like this:
473
474 textures/vehicles/car
475 {
476 qer_editorimage textures/vehicles/car.jpg
477
478 {
479 map textures/vehicles/car.jpg
480 rgbGen vertexLit
481 }
482 {
483 stage normalparallaxmap
484 map textures/vehicles/car_n.jpg
485 }
486 {
487 stage specularmap
488 map textures/vehicles/car_s.jpg
489 }
490 }
491
492 Note the new keyword, 'vertexLit' after rgbGen. This is analogous to
493 'rgbGen vertex', except a light direction will be determined from the lightgrid
494 and used with the normal and specular maps. 'exactVertexLit' exists as well,
495 and is the equivalent for 'exactVertex'.
496
497
498 -------------------------------------------------------------------------------
499 DYNAMIC SUNLIGHT AND CASCADED SHADOW MAPS
500 -------------------------------------------------------------------------------
501
502 This adds a new keyword to sky materials, q3gl2_sun. The syntax is:
503
504 q3gl2_sun <red> <green> <blue> <intensity> <degrees> <elevation> <ambientLightScale>
505
506 Note the first six parameters are the same as in q3map_sun or q3map_sunExt,
507 and the last two indicate scaling factors for the map brightness and an ambient
508 light of the same color as the sun.
509
510 There are currently two ways to use this in your own (and other people's) maps.
511
512 1. Create your map as normal, set r_sunlightMode to 1, and add a
513 'q3gl2_sun' line after your 'q3map_sun' line in your sky material, like
514 so:
515
516 textures/skies/bluesky
517 {
518 qer_editorimage textures/skies/bluesky.jpg
519
520 surfaceparm nomarks
521 surfaceparm noimpact
522 surfaceparm nolightmap
523 surfaceparm sky
524 q3map_sunExt 240 238 200 100 195 35 3 16
525 q3gl2_sun 240 238 200 50 195 35 0.2
526 q3map_skylight 50 16
527 q3map_lightimage $whiteimage
528
529 skyparms env/bluesky - -
530 }
531
532 The advantages with this method are that your map will continue to work
533 with the old renderer with the sunlight baked into the lightmap, and it
534 can be used with existing maps without recompilation. The downside is
535 artifacts like doubled shadows and uneven shadow edges.
536
537 2. Set r_sunlightMode to 2 and use 'q3gl2_sun' instead of 'q3map_sun' or
538 'q3map_sunExt', like so:
539
540 textures/skies/bluesky
541 {
542 qer_editorimage textures/skies/bluesky.jpg
543
544 surfaceparm nomarks
545 surfaceparm noimpact
546 surfaceparm nolightmap
547 surfaceparm sky
548 q3gl2_sun 240 238 200 50 195 35 0.2
549 q3map_skylight 50 16
550 q3map_lightimage $whiteimage
551
552 skyparms env/bluesky - -
553 }
554
555 The advantages with this method are that you don't get the artifacts that
556 characterize the other method, and your map compiles a lot faster without
557 the sunlight bouncing calculations. The downsides are that your map will
558 not display properly with the old renderer, and you lose the bounced light
559 that compiling the map with q3map_sun* in it would have.
560
561
562 -------------------------------------------------------------------------------
563 TONE MAPPING AND AUTO EXPOSURE
564 -------------------------------------------------------------------------------
565
566 This adds a new keyword to sky materials, q3gl2_tonemap. The syntax is:
567
568 q3gl2_tonemap <toneMapMin> <toneMapAvg> <toneMapMax> <autoExposureMin> <autoExposureMax>
569
570 Each of these settings corresponds to a matching cvar, so you can view and
571 adjust the effect before settling on fixed settings.
572
573
574 -------------------------------------------------------------------------------
575 THANKS
576 -------------------------------------------------------------------------------
577
578 I'd like to take this part of the readme to thank the numerous people who
579 contributed thoughts, ideas, and whole swaths of code to this project.
580
581 - Id Software, for creating Quake 3 and releasing its source code under a
582 GPL license, without which this project would not be possible.
583
584 - Zachary 'Zakk' Slater, Thilo Schulz, Tim Angus, and the rest of the
585 ioquake3 team and contributors, for improving massively upon the raw Quake
586 3 source, and accepting my and gimhael's modular renderer patch.
587
588 - Robert 'Tr3B' Beckebans and the other contributors to XReaL, for letting me
589 liberally copy code from you. :)
590
591 - Andrew 'Black Monk' Prosnik, Andrei 'Makro' Drexler, Tomi 'T.T.I.' Isoaho,
592 Richard 'JBravo' Allen, Walter 'Johnny Rocket' Somol, and the rest of the
593 Boomstick Studios, for contributing code, feature requests, and testing.
594
595 - Yoshiharu Gotanda, Tatsuya Shoji, and the rest of tri-Ace's R&D Department,
596 for creating the tri-Ace shading equations and posting their derivations in
597 simple English.
598
599 - Matthias 'gimhael' Bentrup, for random ideas and bits of code.
600
601 - Evan 'megatog615' Goers, for testing, ideas, and bugging me just enough
602 that I'd write documentation. :)
603
604 - The folks at #ioquake3, who don't seem to mind when I suddenly drop a
605 screenshot and insist on talking about it. :)
606
607 - And lots of various other random people, who posted on forums, blogs, and
608 Wikipedia, who helped in small but numerous ways.
609
610 If I missed you in this section, feel free to drop me a line and I'll add you.
611
612
613 -------------------------------------------------------------------------------
614 CONTACT
615 -------------------------------------------------------------------------------
616
617 My name is James Canete, and I wrote most of this readme. Also, a renderer.
618
619 If you wish to get in touch with me, try my GMail at use.less01 (you should be
620 able to solve this), or look for SmileTheory in #ioquake3 on irc.freenode.net.
+0
-634
MP/rend2-readme.txt less more
0 Rend2
1 <insert ascii art here>
2
3 Rend2 is an alternate renderer for iortcw. It aims to implement modern
4 features and technologies into the id tech 3 engine, but without sacrificing
5 compatibility with existing RTCW mods.
6
7
8 -------------------------------------------------------------------------------
9 FEATURES
10 -------------------------------------------------------------------------------
11
12 - Compatible with most vanilla RTCW mods.
13 - HDR Rendering, and support for HDR lightmaps
14 - Tone mapping and auto-exposure.
15 - Cascaded shadow maps.
16 - Multisample anti-aliasing.
17 - Texture upsampling.
18 - Advanced materials support.
19 - Advanced shading and specular methods.
20 - RGTC and BPTC texture compression support.
21 - Screen-space ambient occlusion.
22
23
24 -------------------------------------------------------------------------------
25 INSTALLATION
26 -------------------------------------------------------------------------------
27
28 For *nix:
29
30 1. This should be identical to installing iortcw. Check their README for more
31 details.
32
33
34 For Win32:
35
36 1. Have a RTCW install, fully patched.
37
38 2. Copy the following files into RTCW's install directory:
39
40 ioWolfMP.x86.exe
41 renderer_opengl1_x86.dll
42 renderer_rend2_x86.dll
43
44 These can be found in build/release-mingw32-x86 after compiling, or bug
45 someone to release binaries.
46
47
48 -------------------------------------------------------------------------------
49 RUNNING
50 -------------------------------------------------------------------------------
51
52 1. Start iowolfmp. (ioWolfMP.x86.exe on Win32)
53
54 2. Open the console (default key ~) and type '/cl_renderer rend2; vid_restart'
55
56 3. Enjoy.
57
58
59 -------------------------------------------------------------------------------
60 CVARS
61 -------------------------------------------------------------------------------
62
63 Cvars for simple rendering features:
64 r_ext_compressed_textures - Automatically compress textures.
65 0 - No texture compression. (default)
66 1 - DXT/RGTC texture compression if
67 supported.
68 2 - BPTC texture compression if supported.
69
70 r_ext_framebuffer_multisample - Multisample Anti-aliasing.
71 0 - None. (default)
72 1-16 - Some.
73 17+ - Too much!
74
75 r_ssao - Enable screen-space ambient occlusion.
76 Currently eats framerate and has some
77 visible artifacts.
78 0 - No. (default)
79 1 - Yes.
80
81 Cvars for HDR and tonemapping:
82 r_hdr - Do scene rendering in a framebuffer with
83 high dynamic range. (Less banding, and
84 exposure changes look much better)
85 0 - No.
86 1 - Yes. (default)
87
88 r_cameraExposure - Cheat. Alter brightness, in powers of two.
89 -2 - 4x as dark.
90 0 - Normal. (default)
91 0.5 - Sqrt(2)x as bright.
92 2 - 4x as bright.
93
94 r_postProcess - Enable post-processing.
95 0 - No.
96 1 - Yes. (default)
97
98 r_toneMap - Enable tone mapping. Requires
99 r_hdr and r_postProcess.
100 0 - No.
101 1 - Yes. (default)
102
103 r_forceToneMap - Cheat. Override built-in and map tonemap
104 settings and use cvars r_forceToneMapAvg,
105 r_forceToneMapMin, and r_forceToneMapMax.
106 0 - No. (default)
107 1 - Yes.
108
109 r_forceToneMapAvg - Cheat. Map average scene luminance to this
110 value, in powers of two. Requires
111 r_forceToneMap.
112 -2.0 - Dark.
113 -1.0 - Kinda dark. (default).
114 2.0 - Too bright.
115
116 r_forceToneMapMin - Cheat. After mapping average, luminance
117 below this level is mapped to black.
118 Requires r_forceToneMap.
119 -5 - Not noticeable.
120 -3.25 - Normal. (default)
121 0.0 - Too dark.
122
123 r_forceToneMapMin - Cheat. After mapping average, luminance
124 above this level is mapped to white.
125 Requires r_forceToneMap.
126 0.0 - Too bright.
127 1.0 - Normal. (default).
128 2.0 - Washed out.
129
130 r_autoExposure - Do automatic exposure based on scene
131 brightness. Hardcoded to -2 to 2 on maps
132 that don't specify otherwise. Requires
133 r_hdr, r_postprocess, and r_toneMap.
134 0 - No.
135 1 - Yes. (default)
136
137 r_forceAutoExposure - Cheat. Override built-in and map auto
138 exposure settings and use cvars
139 r_forceAutoExposureMin and
140 r_forceAutoExposureMax.
141 0 - No. (default)
142 1 - Yes.
143
144 r_forceAutoExposureMin - Cheat. Set minimum exposure to this value,
145 in powers of two. Requires
146 r_forceAutoExpsure.
147 -3.0 - Dimmer.
148 -2.0 - Normal. (default)
149 -1.0 - Brighter.
150
151 r_forceAutoExposureMax - Cheat. Set maximum exposure to this value,
152 in powers of two. Requires
153 r_forceAutoExpsure.
154 1.0 - Dimmer.
155 2.0 - Normal. (default)
156 3.0 - Brighter.
157
158 Cvars for advanced material usage:
159 r_normalMapping - Enable normal maps for materials that
160 support it.
161 0 - No.
162 1 - Yes. (default)
163
164 r_specularMapping - Enable specular maps for materials that
165 support it.
166 0 - No.
167 1 - Yes. (default)
168
169 r_deluxeMapping - Enable deluxe mapping. (Map is compiled
170 with light directions.) Even if the map
171 doesn't have deluxe mapping compiled in,
172 an approximation based on the lightgrid
173 will be used.
174 0 - No.
175 1 - Yes. (default)
176
177 r_parallaxMapping - Enable parallax mapping for materials that
178 support it.
179 0 - No. (default)
180 1 - Use parallax occlusion mapping.
181 2 - Use relief mapping. (slower)
182
183 r_baseSpecular - Set the specular reflectance of materials
184 which don't include a specular map or
185 use the specularReflectance keyword.
186 0 - No.
187 0.04 - Realistic. (default)
188 1.0 - Ack.
189
190 r_baseGloss - Set the glossiness of materials which don't
191 include a specular map or use the
192 specularExponent keyword.
193 0 - Rough.
194 0.3 - Default.
195 1.0 - Shiny.
196
197 r_baseNormalX - Set the scale of the X values from normal
198 maps when the normalScale keyword is not
199 used.
200 -1 - Flip X.
201 0 - Ignore X.
202 1 - Normal X. (default)
203 2 - Double X.
204
205 r_baseNormalY - Set the scale of the Y values from normal
206 maps when the normalScale keyword is not
207 used.
208 -1 - Flip Y.
209 0 - Ignore Y.
210 1 - Normal Y. (default)
211 2 - Double Y.
212
213 r_baseParallax - Sets the scale of the parallax effect for
214 materials when the parallaxDepth keyword
215 is not used.
216 0 - No depth.
217 0.01 - Pretty smooth.
218 0.05 - Standard depth. (default)
219 0.1 - Looks broken.
220
221 Cvars for image interpolation and generation:
222 r_imageUpsample - Use interpolation to artifically increase
223 the resolution of all textures. Looks good
224 in certain circumstances.
225 0 - No. (default)
226 1 - 2x size.
227 2 - 4x size.
228 3 - 8x size, etc
229
230 r_imageUpsampleMaxSize - Maximum texture size when upsampling
231 textures.
232 1024 - Default.
233 2048 - Really nice.
234 4096 - Really slow.
235 8192 - Crash.
236
237 r_imageUpsampleType - Type of interpolation when upsampling
238 textures.
239 0 - None. (probably broken)
240 1 - Bad but fast (default,
241 FCBI without second derivatives)
242 2 - Okay but slow (normal FCBI)
243
244 r_genNormalMaps - Naively generate normal maps for all
245 textures.
246 0 - Don't. (default)
247 1 - Do.
248
249 Cvars for the sunlight and cascaded shadow maps:
250 r_forceSun - Force sunlight and shadows, using sun
251 position from sky material.
252 0 - Don't. (default)
253 1 - Do.
254 2 - Sunrise, sunset.
255
256 r_forceSunMapLightScale - Cheat. Scale map brightness by this factor
257 when r_forceSun 1.
258 1.0 - Default
259
260 r_forceSunLightScale - Cheat. Scale sun brightness by this factor
261 when r_forceSun 1.
262 1.0 - Default
263
264 r_forceSunAmbientScale - Cheat. Scale sun ambient brightness by this
265 factor when r_forceSun 1.
266 0.5 - Default
267
268 r_sunShadows - Enable sunlight and cascaded shadow maps for
269 it on maps that support it.
270 0 - No.
271 1 - Yes. (default)
272
273 r_sunlightMode - Specify the method used to add sunlight to
274 the scene.
275 0 - No.
276 1 - Multiply lit areas by light scale, and
277 shadowed areas by ambient scale.
278 (default)
279 2 - Add light. Looks better, but is slower
280 and doesn't integrate well with existing
281 maps.
282
283 r_shadowFilter - Enable filtering shadows for a smoother
284 look.
285 0 - No.
286 1 - Some. (default)
287 2 - Much.
288
289 r_shadowMapSize - Size of each cascaded shadow map.
290 256 - 256x256, ugly, probably shouldn't
291 go below this.
292 512 - 512x512, passable.
293 1024 - 1024x1024, good. (default)
294 2048 - 2048x2048, extreme.
295 4096 - 4096x4096, indistinguishable from
296 2048.
297
298
299 Cvars that you probably don't care about or shouldn't mess with:
300 r_mergeMultidraws - Optimize number of calls to
301 glMultiDrawElements().
302 0 - Don't.
303 1 - Do some. (default)
304 2 - Do more than necessary (eats CPU).
305
306 r_mergeLeafSurfaces - Merge surfaces that share common materials
307 and a common leaf. Speeds up rendering.
308 0 - Don't.
309 1 - Do. (default)
310
311 r_recalcMD3Normals - Recalculate the normals when loading an MD3.
312 Fixes normal maps in some cases but looks
313 ugly in others.
314 0 - Don't. (default)
315 1 - Do.
316
317 r_depthPrepass - Do a depth-only pass before rendering.
318 Speeds up rendering in cases where advanced
319 features are used. Required for
320 r_sunShadows.
321 0 - No.
322 1 - Yes. (default)
323
324 r_mergeLightmaps - Merge the small (128x128) lightmaps into
325 2 or fewer giant (4096x4096) lightmaps.
326 Easy speedup.
327 0 - Don't.
328 1 - Do. (default)
329
330 r_shadowCascadeZNear - Near plane for shadow cascade frustums.
331 4 - Default.
332
333 r_shadowCascadeZFar - Far plane for shadow cascade frustums.
334 3072 - Default.
335
336 r_shadowCascadeZBias - Z-bias for shadow cascade frustums.
337 -256 - Default.
338
339 r_materialGamma - Gamma level for material textures.
340 (diffuse, specular)
341 1.0 - RTCW, fastest. (default)
342
343 r_lightGamma - Gamma level for light.
344 (lightmap, lightgrid, vertex lights)
345 1.0 - RTCW, fastest. (default)
346
347 r_framebufferGamma - Gamma level for framebuffers.
348 1.0 - RTCW, fastest. (default)
349
350 r_tonemapGamma - Gamma applied after tonemapping.
351 1.0 - RTCW, fastest. (default)
352
353
354 Cvars that have broken bits:
355 r_dlightMode - Change how dynamic lights look.
356 0 - RTCW style dlights, fake
357 brightening. (default)
358 1 - Actual lighting, no shadows.
359 2 - Light and shadows. (broken)
360
361 r_pshadowDist - Virtual camera distance when creating shadow
362 maps for projected shadows. Deprecated.
363
364 cg_shadows - Old shadow code. Deprecated.
365
366
367 -------------------------------------------------------------------------------
368 MATERIALS
369 -------------------------------------------------------------------------------
370
371 Rend2 supports .mtr files, which are basically the same as .shader files, and
372 are located in the same place, but override existing .shader files if they
373 exist. This is to allow maps and mods to use the new material features without
374 breaking the map when using the old renderer.
375
376 Here's an example of a material stored in one, showing off some new features:
377
378 textures/abandon/grass
379 {
380 qer_editorimage textures/abandon/grass.jpg
381 {
382 map textures/abandon/grass3_256_d.jpg
383 rgbgen identity
384 }
385 {
386 stage normalparallaxmap
387 map textures/abandon/grass3_1024_n.png
388 normalScale 1 1
389 parallaxDepth 0.05
390 }
391 {
392 stage specularmap
393 map textures/abandon/grass3_256_s.png
394 specularReflectance 0.12
395 specularExponent 16
396 }
397 {
398 map $lightmap
399 blendfunc GL_DST_COLOR GL_ZERO
400 }
401 }
402
403 The first thing to notice is that this is basically the same as old RTCW
404 shader files. The next thing to notice are the new keywords. Here is what
405 they mean:
406
407 stage <type>
408 - State how this imagemap will be used by Rend2:
409 diffuseMap - Standard, same as no stage entry
410 normalMap - Image will be used as a normal map
411 normalParallaxMap - Image will be used as a normal map with
412 alpha treated as height for parallax mapping
413 specularMap - Image will be used as a specular map with
414 alpha treated as shininess.
415
416 specularReflectance <value>
417 - State how metallic this material is. Metals typically have a high
418 specular and a low diffuse, so this is typically high for them, and low
419 for other materials, such as plastic. For typical values for various
420 materials, see http://refractiveindex.info , pick a material, then scroll
421 down to the reflection calculator and look up its reflectance. Default
422 is 0.04, since most materials aren't metallic.
423
424 specularExponent <value>
425 - State how shiny this material is. Note that this is modulated by the
426 alpha channel of the specular map, so if it were set to 16, and the alpha
427 channel of the specular map was set to 0.5, then the shininess would be
428 set to 8. Default 256.
429
430 normalScale <x> <y>
431 - State the X and Y scales of the normal map. This is useful for increasing
432 or decreasing the "strength" of the normal map, or entering negative values
433 to flip the X and/or Y values. Default 1 1.
434
435 parallaxDepth <value>
436 - State the maximum depth of the parallax map. This is a fairly sensitive
437 value, and I recommend the default or lower. Default 0.05.
438
439 An important note is that normal and specular maps influence the diffuse map
440 declared before them, so materials like this are possible:
441
442 textures/terrain/grass
443 {
444 qer_editorimage textures/terrain/grass.jpg
445
446 {
447 map textures/terrain/rock.jpg
448 }
449 {
450 stage normalparallaxmap
451 map textures/terrain/rock_n.png
452 }
453 {
454 stage specularmap
455 map textures/terrain/rock_s.jpg
456 }
457 {
458 map textures/terrain/grass.jpg
459 blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
460 alphaGen vertex
461 }
462 {
463 stage normalparallaxmap
464 map textures/terrain/grass_n.png
465 }
466 {
467 stage specularmap
468 map textures/terrain/grass_s.png
469 specularReflectance 0.12
470 }
471 {
472 map $lightmap
473 blendfunc GL_DST_COLOR GL_ZERO
474 }
475 }
476
477 Though note due to the complexity of lighting, dynamic light (including
478 sunlight with cascaded shadow maps) currently only works 100% on materials like
479 this, where the second diffuse map doesn't have its own alpha, and only
480 uses vertex alpha. YMMV.
481
482 Another addition to materials is working normal/specular maps on vertex lit
483 surfaces. To enable this, make your material look like this:
484
485 textures/vehicles/car
486 {
487 qer_editorimage textures/vehicles/car.jpg
488
489 {
490 map textures/vehicles/car.jpg
491 rgbGen vertexLit
492 }
493 {
494 stage normalparallaxmap
495 map textures/vehicles/car_n.jpg
496 }
497 {
498 stage specularmap
499 map textures/vehicles/car_s.jpg
500 }
501 }
502
503 Note the new keyword, 'vertexLit' after rgbGen. This is analogous to
504 'rgbGen vertex', except a light direction will be determined from the lightgrid
505 and used with the normal and specular maps. 'exactVertexLit' exists as well,
506 and is the equivalent for 'exactVertex'.
507
508
509 -------------------------------------------------------------------------------
510 DYNAMIC SUNLIGHT AND CASCADED SHADOW MAPS
511 -------------------------------------------------------------------------------
512
513 This adds a new keyword to sky materials, q3gl2_sun. The syntax is:
514
515 q3gl2_sun <red> <green> <blue> <intensity> <degrees> <elevation>
516 <mapLightScale> <ambientLightScale>
517
518 Note the first six parameters are the same as in q3map_sun or q3map_sunExt,
519 and the last two indicate scaling factors for the map brightness and an ambient
520 light of the same color as the sun.
521
522 There are currently two ways to use this in your own (and other people's) maps.
523
524 1. Create your map as normal, set r_sunlightMode to 1, and add a
525 'q3gl2_sun' line after your 'q3map_sun' line in your sky material, like
526 so:
527
528 textures/skies/bluesky
529 {
530 qer_editorimage textures/skies/bluesky.jpg
531
532 surfaceparm nomarks
533 surfaceparm noimpact
534 surfaceparm nolightmap
535 surfaceparm sky
536 q3map_sunExt 240 238 200 100 195 35 3 16
537 q3gl2_sun 240 238 200 50 195 35 1.0 0.2
538 q3map_skylight 50 16
539 q3map_lightimage $whiteimage
540
541 skyparms env/bluesky - -
542 }
543
544 The advantages with this method are that your map will continue to work
545 with the old renderer with the sunlight baked into the lightmap, and it
546 can be used with existing maps without recompilation. The downside is
547 artifacts like doubled shadows and uneven shadow edges.
548
549 2. Set r_sunlightMode to 2 and use 'q3gl2_sun' instead of 'q3map_sun' or
550 'q3map_sunExt', like so:
551
552 textures/skies/bluesky
553 {
554 qer_editorimage textures/skies/bluesky.jpg
555
556 surfaceparm nomarks
557 surfaceparm noimpact
558 surfaceparm nolightmap
559 surfaceparm sky
560 q3gl2_sun 240 238 200 50 195 35 0.5 0.2
561 q3map_skylight 50 16
562 q3map_lightimage $whiteimage
563
564 skyparms env/bluesky - -
565 }
566
567 The advantages with this method are that you don't get the artifacts that
568 characterize the other method, and your map compiles a lot faster without
569 the sunlight bouncing calculations. The downsides are that your map will
570 not display properly with the old renderer, and you lose the bounced light
571 that compiling the map with q3map_sun* in it would have.
572
573
574 -------------------------------------------------------------------------------
575 TONE MAPPING AND AUTO EXPOSURE
576 -------------------------------------------------------------------------------
577
578 This adds a new keyword to sky materials, q3gl2_tonemap. The syntax is:
579
580 q3gl2_tonemap <toneMapMin> <toneMapAvg> <toneMapMax <autoExposureMin>
581 <autoExposureMax>
582
583 Each of these settings corresponds to a matching cvar, so you can view and
584 adjust the effect before settling on fixed settings.
585
586
587 -------------------------------------------------------------------------------
588 THANKS
589 -------------------------------------------------------------------------------
590
591 I'd like to take this part of the readme to thank the numerous people who
592 contributed thoughts, ideas, and whole swaths of code to this project.
593
594 - Id Software, for creating RTCW and releasing its source code under a
595 GPL license, without which this project would not be possible.
596
597 - Zachary 'Zakk' Slater, Thilo Schulz, Tim Angus, and the rest of the
598 ioquake3 team and contributors, for improving massively upon the raw Quake
599 3 source, and accepting my and gimhael's modular renderer patch.
600
601 - Robert 'Tr3B' Beckebans and the other contributors to XReaL, for letting me
602 liberally copy code from you. :)
603
604 - Andrew 'Black Monk' Prosnik, Andrei 'Makro' Drexler, Tomi 'T.T.I.' Isoaho,
605 Richard 'JBravo' Allen, Walter 'Johnny Rocket' Somol, and the rest of the
606 Boomstick Studios, for contributing code, feature requests, and testing.
607
608 - Yoshiharu Gotanda, Tatsuya Shoji, and the rest of tri-Ace's R&D Department,
609 for creating the tri-Ace shading equations and posting their derivations in
610 simple English.
611
612 - Matthias 'gimhael' Bentrup, for random ideas and bits of code.
613
614 - Evan 'megatog615' Goers, for testing, ideas, and bugging me just enough
615 that I'd write documentation. :)
616
617 - The folks at #ioquake3, who don't seem to mind when I suddenly drop a
618 screenshot and insist on talking about it. :)
619
620 - And lots of various other random people, who posted on forums, blogs, and
621 Wikipedia, who helped in small but numerous ways.
622
623 If I missed you in this section, feel free to drop me a line and I'll add you.
624
625
626 -------------------------------------------------------------------------------
627 CONTACT
628 -------------------------------------------------------------------------------
629
630 My name is James Canete, and I wrote most of this readme. Also, a renderer.
631
632 If you wish to get in touch with me, try my GMail at use.less01 (you should be
633 able to solve this), or look for SmileTheory in #ioquake3 on irc.freenode.net.
6363 The following variables may be set, either on the command line or in
6464 Makefile.local:
6565
66 * CFLAGS - use this for custom CFLAGS
67 * V - set to show cc command line when building
68 * DEFAULT_BASEDIR - extra path to search for main and such
69 * BUILD_SERVER - build the 'iowolfded' server binary
70 * BUILD_CLIENT - build the 'iowolfmp' or 'iowolfsp' client binary
71 * BUILD_BASEGAME - build the 'main' binaries
72 * BUILD_GAME_SO - build the game shared libraries
73 * BUILD_GAME_QVM - build the game qvms
74 * BUILD_STANDALONE - build binaries suited for stand-alone games
75 * SERVERBIN - rename 'iowolfded' server binary
76 * CLIENTBIN - rename 'iowolfmp' or 'iowolfsp' client binary
77 * BASEGAME - rename 'main'
78 * BASEGAME_CFLAGS - custom CFLAGS for basegame
79 * USE_OPENAL - use OpenAL where available
80 * USE_OPENAL_DLOPEN - link with OpenAL at runtime
81 * USE_CURL - use libcurl for http/ftp download support
82 * USE_CURL_DLOPEN - link with libcurl at runtime
83 * USE_CODEC_VORBIS - enable Ogg Vorbis support
84 * USE_CODEC_OPUS - enable Ogg Opus support
85 * USE_MUMBLE - enable Mumble support
86 * USE_VOIP - enable built-in VoIP support
87 * USE_INTERNAL_LIBS - build internal libraries instead of dynamically linking against system libraries; this just sets the default for USE_INTERNAL_OPUS etc. and USE_LOCAL_HEADERS
88 * USE_FREETYPE - enable FreeType support for rendering fonts
89 * USE_INTERNAL_ZLIB - build and link against internal zlib
90 * USE_INTERNAL_JPEG - build and link against internal JPEG library
91 * USE_INTERNAL_OGG - build and link against internal ogg library
92 * USE_INTERNAL_OPUS - build and link against internal opus/opusfile libraries
93 * USE_LOCAL_HEADERS - use headers contained within this source tree instead of system ones
94 * DEBUG_CFLAGS - C compiler flags to use for building debug version
95 * COPYDIR - the target installation directory
96 * TEMPDIR - specify user defined directory for temp files
66 * CFLAGS - use this for custom CFLAGS
67 * V - set to show cc command line when building
68 * DEFAULT_BASEDIR - extra path to search for main and such
69 * BUILD_SERVER - build the 'iowolfded' server binary
70 * BUILD_CLIENT - build the 'iowolfmp' or 'iowolfsp' client binary
71 * BUILD_BASEGAME - build the 'main' binaries
72 * BUILD_GAME_SO - build the game shared libraries
73 * BUILD_GAME_QVM - build the game qvms
74 * BUILD_STANDALONE - build binaries suited for stand-alone games
75 * SERVERBIN - rename 'iowolfded' server binary
76 * CLIENTBIN - rename 'iowolfmp' or 'iowolfsp' client binary
77 * USE_RENDERER_DLOPEN - build and use the renderer in a library
78 * USE_YACC - use yacc to update code/tools/lcc/lburg/gram.c
79 * BASEGAME - rename 'main'
80 * BASEGAME_CFLAGS - custom CFLAGS for basegame
81 * USE_OPENAL - use OpenAL where available
82 * USE_OPENAL_DLOPEN - link with OpenAL at runtime
83 * USE_CURL - use libcurl for http/ftp download support
84 * USE_CURL_DLOPEN - link with libcurl at runtime
85 * USE_CODEC_VORBIS - enable Ogg Vorbis support
86 * USE_CODEC_OPUS - enable Ogg Opus support
87 * USE_MUMBLE - enable Mumble support
88 * USE_VOIP - enable built-in VoIP support
89 * USE_INTERNAL_LIBS - build internal libraries instead of dynamically linking against system libraries; this just sets the default for USE_INTERNAL_OPUS etc. and USE_LOCAL_HEADERS
90 * USE_FREETYPE - enable FreeType support for rendering fonts
91 * USE_INTERNAL_ZLIB - build and link against internal zlib
92 * USE_INTERNAL_JPEG - build and link against internal JPEG library
93 * USE_INTERNAL_OGG - build and link against internal ogg library
94 * USE_INTERNAL_OPUS - build and link against internal opus/opusfile libraries
95 * USE_LOCAL_HEADERS - use headers contained within this source tree instead of system ones
96 * DEBUG_CFLAGS - C compiler flags to use for building debug version
97 * COPYDIR - the target installation directory
98 * TEMPDIR - specify user defined directory for temp files
9799
98100 The defaults for these variables differ depending on the target platform.
99101
11 Makefile.local
22 *.swp
33 *tags
4 *~
45
56 # OS X
67 ####################
3435
3536 # Microsoft Visual Studio
3637 ####################
37 *.sdf
38 *.sdf
33 # GNU Make required
44 #
55
6 COMPILE_PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]'|sed -e 's/\//_/g')
7
8 COMPILE_ARCH=$(shell uname -m | sed -e s/i.86/i386/ | sed -e 's/^arm.*/arm/')
9
6 COMPILE_PLATFORM=$(shell uname | sed -e 's/_.*//' | tr '[:upper:]' '[:lower:]' | sed -e 's/\//_/g')
7 COMPILE_ARCH=$(shell uname -m | sed -e 's/i.86/x86/' | sed -e 's/^arm.*/arm/')
108 ARM_VER_CHECK=$(shell uname -m)
119
1210 ifeq ($(COMPILE_PLATFORM),sunos)
1311 # Solaris uname and GNU uname differ
14 COMPILE_ARCH=$(shell uname -p | sed -e s/i.86/i386/)
15 endif
16 ifeq ($(COMPILE_PLATFORM),darwin)
17 # Apple does some things a little differently...
18 COMPILE_ARCH=$(shell uname -p | sed -e s/i.86/i386/)
12 COMPILE_ARCH=$(shell uname -p | sed -e 's/i.86/x86/')
1913 endif
2014
2115 ifndef BUILD_STANDALONE
128122 export CROSS_COMPILING
129123
130124 ifndef VERSION
131 VERSION=1.42d
125 VERSION=1.5a
132126 endif
133127
134128 ifndef CLIENTBIN
255249 USE_RENDERER_DLOPEN=1
256250 endif
257251
252 ifndef USE_XDG
253 USE_XDG=0
254 endif
255
256 ifndef USE_YACC
257 USE_YACC=0
258 endif
259
258260 ifndef DEBUG_CFLAGS
259261 DEBUG_CFLAGS=-g -O0
260262 endif
269271
270272 ifndef RASPBERRY_PI
271273 RASPBERRY_PI=0
274 endif
275
276 ifndef USE_AUTHORIZE_SERVER
277 USE_AUTHORIZE_SERVER=0
272278 endif
273279
274280
291297 UIDIR=$(MOUNT_DIR)/ui
292298 JPDIR=$(MOUNT_DIR)/jpeg-8c
293299 OGGDIR=$(MOUNT_DIR)/libogg-1.3.2
294 VORBISDIR=$(MOUNT_DIR)/libvorbis-1.3.4
295 OPUSDIR=$(MOUNT_DIR)/opus-1.1
296 OPUSFILEDIR=$(MOUNT_DIR)/opusfile-0.6
300 VORBISDIR=$(MOUNT_DIR)/libvorbis-1.3.5
301 OPUSDIR=$(MOUNT_DIR)/opus-1.1.2
302 OPUSFILEDIR=$(MOUNT_DIR)/opusfile-0.7
297303 ZDIR=$(MOUNT_DIR)/zlib-1.2.8
298 FTDIR=$(MOUNT_DIR)/freetype-2.5.5
304 FTDIR=$(MOUNT_DIR)/freetype-2.6.4
299305 SPLDIR=$(MOUNT_DIR)/splines
300306 Q3ASMDIR=$(MOUNT_DIR)/tools/asm
301307 LBURGDIR=$(MOUNT_DIR)/tools/lcc/lburg
332338 endif
333339 endif
334340
335 # Add git version info
336 #USE_GIT=
337 #ifeq ($(wildcard ../.git),../.git)
338 # GIT_REV=$(shell git show -s --pretty=format:%h-%ad --date=short)
339 # ifneq ($(GIT_REV),)
340 # VERSION:=$(VERSION)_GIT_$(GIT_REV)
341 # USE_GIT=1
342 # endif
343 #endif
344
345341
346342 #############################################################################
347343 # SETUP AND BUILD -- LINUX
409405 ifeq ($(CROSS_COMPILING),1)
410406 ifeq ($(ARCH),x86)
411407 SDL_LIBS = $(LIBSDIR)/linux32/libSDL2main.a \
412 $(LIBSDIR)/linux32/libSDL2.so
408 $(LIBSDIR)/linux32/libSDL2-2.0.so.0.4.0
413409 endif
414410 ifeq ($(ARCH),x86_64)
415411 SDL_LIBS = $(LIBSDIR)/linux64/libSDL2main.a \
416 $(LIBSDIR)/linux64/libSDL2.so
412 $(LIBSDIR)/linux64/libSDL2-2.0.so.0.4.0
417413 endif
418414 endif
419415 endif
508504 $(error Architecture $(ARCH) is not supported when cross compiling)
509505 endif
510506 endif
511 else
512 TOOLS_CFLAGS += -DMACOS_X
513 endif
514
515 BASE_CFLAGS += -fno-strict-aliasing -DMACOS_X -fno-common -pipe
507 endif
508
509 BASE_CFLAGS += -fno-strict-aliasing -fno-common -pipe
516510
517511 ifeq ($(USE_OPENAL),1)
518512 ifneq ($(USE_OPENAL_DLOPEN),1)
585579
586580 # We need to figure out the correct gcc and windres
587581 ifeq ($(ARCH),x86_64)
588 MINGW_PREFIXES=amd64-mingw32msvc x86_64-w64-mingw32
582 MINGW_PREFIXES=x86_64-w64-mingw32 amd64-mingw32msvc
589583 endif
590584 ifeq ($(ARCH),x86)
591 MINGW_PREFIXES=i586-mingw32msvc i686-w64-mingw32 i686-pc-mingw32
585 MINGW_PREFIXES=i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32
592586 endif
593587
594588 ifndef CC
595 CC=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
596 $(call bin_path, $(MINGW_PREFIX)-gcc)))
589 CC=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
590 $(call bin_path, $(MINGW_PREFIX)-gcc))))
597591 endif
598592
599593 ifndef CXX
600 CXX=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
601 $(call bin_path, $(MINGW_PREFIX)-g++)))
594 CXX=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
595 $(call bin_path, $(MINGW_PREFIX)-g++))))
602596 endif
603597
604598 ifndef WINDRES
605 WINDRES=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
606 $(call bin_path, $(MINGW_PREFIX)-windres)))
599 WINDRES=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
600 $(call bin_path, $(MINGW_PREFIX)-windres))))
607601 endif
608602 else
609603 # Some MinGW installations define CC to cc, but don't actually provide cc,
613607 endif
614608
615609 ifndef CXX
616 CC=g++
610 CXX=g++
617611 endif
618612
619613 ifndef WINDRES
730724 else # ifdef MINGW
731725
732726 #############################################################################
733 # SETUP AND BUILD -- FREEBSD
734 #############################################################################
735
736 ifeq ($(PLATFORM),freebsd)
737
738 # flags
739 BASE_CFLAGS = $(shell env MACHINE_ARCH=$(ARCH) make -f /dev/null -VCFLAGS) \
740 -Wall -fno-strict-aliasing \
741 -DUSE_ICON -DMAP_ANONYMOUS=MAP_ANON
742 CLIENT_CFLAGS += $(SDL_CFLAGS)
743
744 OPTIMIZEVM = -O3
745 OPTIMIZE = $(OPTIMIZEVM) -ffast-math
746
747 SHLIBEXT=so
748 SHLIBCFLAGS=-fPIC
749 SHLIBLDFLAGS=-shared $(LDFLAGS)
750
751 THREAD_LIBS=-lpthread
752 # don't need -ldl (FreeBSD)
753 LIBS=-lm
754
755 CLIENT_LIBS =
756
757 CLIENT_LIBS += $(SDL_LIBS)
758 RENDERER_LIBS = $(SDL_LIBS) -lGL
759
760 # optional features/libraries
761 ifeq ($(USE_OPENAL),1)
762 ifeq ($(USE_OPENAL_DLOPEN),1)
763 CLIENT_LIBS += $(THREAD_LIBS) $(OPENAL_LIBS)
764 endif
765 endif
766
767 ifeq ($(USE_CURL),1)
768 CLIENT_CFLAGS += $(CURL_CFLAGS)
769 ifeq ($(USE_CURL_DLOPEN),1)
770 CLIENT_LIBS += $(CURL_LIBS)
771 endif
772 endif
773
774 else # ifeq freebsd
775
776 #############################################################################
777 # SETUP AND BUILD -- OPENBSD
778 #############################################################################
779
780 ifeq ($(PLATFORM),openbsd)
727 # SETUP AND BUILD -- *BSD (is dying)
728 #############################################################################
729
730 ifneq (,$(findstring "$(PLATFORM)", "freebsd" "openbsd" "netbsd"))
781731
782732 BASE_CFLAGS = -Wall -fno-strict-aliasing \
783733 -pipe -DUSE_ICON -DMAP_ANONYMOUS=MAP_ANON
789739 ifeq ($(ARCH),x86_64)
790740 OPTIMIZEVM = -O3
791741 OPTIMIZE = $(OPTIMIZEVM) -ffast-math
742 FILE_ARCH = amd64
792743 endif
793744 ifeq ($(ARCH),x86)
794745 OPTIMIZEVM = -O3 -march=i586
819770 USE_CURL_DLOPEN=0
820771 endif
821772
822 # no shm_open on OpenBSD
823 USE_MUMBLE=0
824
825773 SHLIBEXT=so
826774 SHLIBCFLAGS=-fPIC
827775 SHLIBLDFLAGS=-shared $(LDFLAGS)
845793 CLIENT_LIBS += $(CURL_LIBS)
846794 endif
847795 endif
848 else # ifeq openbsd
849
850 #############################################################################
851 # SETUP AND BUILD -- NETBSD
852 #############################################################################
853
854 ifeq ($(PLATFORM),netbsd)
855
856 LIBS=-lm
857 SHLIBEXT=so
858 SHLIBCFLAGS=-fPIC
859 SHLIBLDFLAGS=-shared $(LDFLAGS)
860 THREAD_LIBS=-lpthread
861
862 BASE_CFLAGS = -Wall -fno-strict-aliasing
863
864 BUILD_CLIENT = 0
865 else # ifeq netbsd
796 else # ifeq *BSD
866797
867798 #############################################################################
868799 # SETUP AND BUILD -- IRIX
954885 endif #Linux
955886 endif #darwin
956887 endif #MINGW
957 endif #FreeBSD
958 endif #OpenBSD
959 endif #NetBSD
888 endif #*BSD
960889 endif #IRIX
961890 endif #SunOS
962891
965894 endif
966895
967896 ifndef CXX
968 CC=g++
897 CXX=g++
969898 endif
970899
971900 ifndef RANLIB
10881017
10891018 ifeq ($(NEED_OPUS),1)
10901019 ifeq ($(USE_INTERNAL_OPUS),1)
1091 OPUS_CFLAGS = -DOPUS_BUILD -DHAVE_LRINTF -DFLOATING_POINT -DUSE_ALLOCA \
1020 OPUS_CFLAGS = -DOPUS_BUILD -DHAVE_LRINTF -DFLOAT_APPROX -DUSE_ALLOCA \
10921021 -I$(OPUSDIR)/include -I$(OPUSDIR)/celt -I$(OPUSDIR)/silk \
10931022 -I$(OPUSDIR)/silk/float -I$(OPUSFILEDIR)/include
10941023 else
11261055
11271056 ifeq ($(USE_RENDERER_DLOPEN),1)
11281057 CLIENT_CFLAGS += -DUSE_RENDERER_DLOPEN
1058 endif
1059
1060 ifeq ($(USE_XDG),1)
1061 CLIENT_CFLAGS += -DUSE_XDG
1062 SERVER_CFLAGS += -DUSE_XDG
11291063 endif
11301064
11311065 ifeq ($(USE_MUMBLE),1)
11841118 BASE_CFLAGS += -DSTANDALONE
11851119 endif
11861120
1121 ifeq ($(USE_AUTHORIZE_SERVER),1)
1122 BASE_CFLAGS += -DUSE_AUTHORIZE_SERVER
1123 endif
1124
11871125 ifeq ($(GENERATE_DEPENDENCIES),1)
11881126 DEPEND_CFLAGS = -MMD
11891127 else
11981136
11991137 ifeq ($(USE_BLOOM),1)
12001138 CLIENT_CFLAGS += -DUSE_BLOOM
1139 endif
1140
1141 # https://reproducible-builds.org/specs/source-date-epoch/
1142 ifdef SOURCE_DATE_EPOCH
1143 BASE_CFLAGS += -DPRODUCT_DATE=\\\"$(shell date --date="@$$SOURCE_DATE_EPOCH" "+%b %_d %Y" | sed -e 's/ /\\\ /'g)\\\"
12011144 endif
12021145
12031146 BASE_CFLAGS += -DPRODUCT_VERSION=\\\"$(VERSION)\\\"
14351378 TOOLS_CC = gcc
14361379 endif
14371380
1381 ifndef YACC
1382 YACC = yacc
1383 endif
1384
14381385 TOOLS_OPTIMIZE = -g -Wall -fno-strict-aliasing
14391386 TOOLS_CFLAGS += $(TOOLS_OPTIMIZE) \
14401387 -DTEMPDIR=\"$(TEMPDIR)\" -DSYSTEM=\"\" \
14471394 TOOLS_CFLAGS += -MMD
14481395 endif
14491396
1397 define DO_YACC
1398 $(echo_cmd) "YACC $<"
1399 $(Q)$(YACC) $<
1400 $(Q)mv -f y.tab.c $@
1401 endef
1402
14501403 define DO_TOOLS_CC
14511404 $(echo_cmd) "TOOLS_CC $<"
14521405 $(Q)$(TOOLS_CC) $(TOOLS_CFLAGS) -o $@ -c $<
14671420 LBURGOBJ= \
14681421 $(B)/tools/lburg/lburg.o \
14691422 $(B)/tools/lburg/gram.o
1423
1424 # override GNU Make built-in rule for converting gram.y to gram.c
1425 %.c: %.y
1426 ifeq ($(USE_YACC),1)
1427 $(DO_YACC)
1428 endif
14701429
14711430 $(B)/tools/lburg/%.o: $(LBURGDIR)/%.c
14721431 $(DO_TOOLS_CC)
17101669 $(B)/rend2/tr_bsp.o \
17111670 $(B)/rend2/tr_cmds.o \
17121671 $(B)/rend2/tr_curve.o \
1672 $(B)/rend2/tr_dsa.o \
17131673 $(B)/rend2/tr_extramath.o \
17141674 $(B)/rend2/tr_extensions.o \
17151675 $(B)/rend2/tr_fbo.o \
17221682 $(B)/rend2/tr_image_pcx.o \
17231683 $(B)/rend2/tr_image_png.o \
17241684 $(B)/rend2/tr_image_tga.o \
1685 $(B)/rend2/tr_image_dds.o \
17251686 $(B)/rend2/tr_init.o \
17261687 $(B)/rend2/tr_light.o \
17271688 $(B)/rend2/tr_main.o \
18881849 $(B)/renderer/ftbdf.o \
18891850 $(B)/renderer/ftbitmap.o \
18901851 $(B)/renderer/ftcid.o \
1852 $(B)/renderer/ftfntfmt.o \
18911853 $(B)/renderer/ftfstype.o \
18921854 $(B)/renderer/ftgasp.o \
18931855 $(B)/renderer/ftglyph.o \
19011863 $(B)/renderer/ftsynth.o \
19021864 $(B)/renderer/fttype1.o \
19031865 $(B)/renderer/ftwinfnt.o \
1904 $(B)/renderer/ftxf86.o \
19051866 $(B)/renderer/truetype.o \
19061867 $(B)/renderer/type1.o \
19071868 $(B)/renderer/cff.o \
21742135 ifneq ($(USE_RENDERER_DLOPEN),0)
21752136 $(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(LIBSDLMAIN)
21762137 $(echo_cmd) "LD $@"
2177 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
2138 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
21782139 -o $@ $(Q3OBJ) \
21792140 $(LIBSDLMAIN) $(CLIENT_LIBS) $(LIBS)
21802141
21902151 else
21912152 $(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(Q3ROBJ) $(JPGOBJ) $(FTOBJ) $(LIBSDLMAIN)
21922153 $(echo_cmd) "LD $@"
2193 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
2154 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
21942155 -o $@ $(Q3OBJ) $(Q3ROBJ) $(JPGOBJ) $(FTOBJ) \
21952156 $(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
21962157
21972158 $(B)/$(CLIENTBIN)_rend2$(FULLBINEXT): $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) $(FTOBJ) $(LIBSDLMAIN)
21982159 $(echo_cmd) "LD $@"
2199 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
2160 $(Q)$(CXX) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
22002161 -o $@ $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) $(FTOBJ) \
22012162 $(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
22022163 endif
23412302
23422303 $(B)/$(SERVERBIN)$(FULLBINEXT): $(Q3DOBJ)
23432304 $(echo_cmd) "LD $@"
2344 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(Q3DOBJ) $(LIBS)
2305 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) -o $@ $(Q3DOBJ) $(LIBS)
23452306
23462307
23472308
26962657 $(DO_DED_CC)
26972658
26982659 # Extra dependencies to ensure the git version is incorporated
2699 #ifeq ($(USE_GIT),1)
2700 # $(B)/client/cl_console.o : ../.git/index
2701 # $(B)/client/common.o : ../.git/index
2702 # $(B)/ded/common.o : ../.git/index
2703 #endif
2660 $(B)/client/cl_console.o : ../.git/index
2661 $(B)/client/common.o : ../.git/index
2662 $(B)/ded/common.o : ../.git/index
27042663
27052664
27062665 #############################################################################
151151 } //end else if
152152 else
153153 {
154 Log_Write( "portal using area %d is seperating more than two clusters\r\n", areanum );
154 Log_Write( "portal using area %d is separating more than two clusters\r\n", areanum );
155155 //remove the cluster portal flag contents
156156 ( *aasworld ).areasettings[areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL;
157157 return qfalse;
12901290 script = LoadScriptMemory( string, strlen( string ), "*extern" );
12911291 //create a new source
12921292 memset( &src, 0, sizeof( source_t ) );
1293 strncpy( src.filename, "*extern", _MAX_PATH );
1293 strncpy( src.filename, "*extern", sizeof( src.filename ) - 1 );
12941294 src.scriptstack = script;
12951295 #if DEFINEHASHING
12961296 src.definehash = GetClearedMemory( DEFINEHASHSIZE * sizeof( define_t * ) );
12151215 y = CG_DrawFPS( y );
12161216 }
12171217 if ( cg_drawTimer.integer ) {
1218 CG_DrawTimer( y );
1218 y = CG_DrawTimer( y );
12191219 }
12201220 // (SA) disabling drawattacker for the time being
12211221 if ( cg_oldWolfUI.integer ) {
12221222 if ( cg_drawAttacker.integer ) {
1223 y = CG_DrawAttacker( y );
1223 CG_DrawAttacker( y );
12241224 }
12251225 }
12261226 //----(SA) end
12481248 int v;
12491249 vec4_t color;
12501250
1251 s = CG_ConfigString( CS_SCORES1 );
12521251 s1 = cgs.scores1;
1253 s = CG_ConfigString( CS_SCORES2 );
12541252 s2 = cgs.scores2;
12551253
12561254 y -= BIGCHAR_HEIGHT + 8;
14811479 }
14821480
14831481 y = CG_DrawScores( y );
1484 y = CG_DrawPowerups( y );
1482 CG_DrawPowerups( y );
14851483 }
14861484
14871485 //===========================================================================================
21402138 }
21412139 }
21422140
2141 if ( cg_drawCrosshairReticle.integer ) {
2142 CG_FillRect( 80, 239, 480, 1, color ); // horiz
2143 CG_FillRect( 319, 0, 1, 480, color ); // vert
2144 }
2145
21432146 // hairs
21442147 CG_FillRect( 84, 239, 177, 2, color ); // left
21452148 CG_FillRect( 320, 242, 1, 58, color ); // center top
21462149 CG_FillRect( 319, 300, 2, 178, color ); // center bot
21472150 CG_FillRect( 380, 239, 177, 2, color ); // right
2151
21482152 } else if ( weap == WP_SNOOPERSCOPE ) {
21492153 // sides
21502154 if ( cg_fixedAspect.integer ) {
23352339 trap_R_DrawStretchPic( w, h, w, h, 1, 1, 0, 0, cgs.media.binocShaderSimpleQ ); // br
23362340 }
23372341 }
2342
2343 if ( cg_drawCrosshairBinoc.integer ) {
2344 CG_FillRect( 0, 239, 640, 1, color ); // horiz
2345 CG_FillRect( 320, 0, 1, 480, color ); // vert
2346 }
23382347
23392348
23402349 CG_FillRect( 146, 239, 348, 1, color );
23622371 float f;
23632372 float x, y;
23642373 int weapnum; // DHM - Nerve
2365 vec4_t hcolor = {1, 1, 1, 0};
2374 vec4_t hcolor = {1, 1, 1, 1};
23662375 qboolean friendInSights = qfalse;
23672376
23682377 if ( cg.renderingThirdPerson ) {
25442553 qhandle_t hShader;
25452554 float f;
25462555 int weapnum; // DHM - Nerve
2547 vec4_t hcolor = {1, 1, 1, 0};
2556 vec4_t hcolor = {1, 1, 1, 1};
25482557 qboolean friendInSights = qfalse;
25492558
25502559 trace_t trace;
27182727 ent.radius = w / 640 * xmax * trace.fraction * maxdist / zProj;
27192728 ent.customShader = hShader;
27202729
2721 // set color based on health
2722 if ( cg_crosshairHealth.integer ) {
2723 CG_ColorForHealth( hcolor );
2724 ent.shaderRGBA[0]=(byte)(hcolor[0]*255.f);
2725 ent.shaderRGBA[1]=(byte)(hcolor[1]*255.f);
2726 ent.shaderRGBA[2]=(byte)(hcolor[2]*255.f);
2727 ent.shaderRGBA[3]=(byte)(hcolor[3]*255.f);
2728 } else {
2729 ent.shaderRGBA[0]=255;
2730 ent.shaderRGBA[1]=255;
2731 ent.shaderRGBA[2]=255;
2732 ent.shaderRGBA[3]=255;
2733 }
2730 ent.shaderRGBA[0]=255;
2731 ent.shaderRGBA[1]=255;
2732 ent.shaderRGBA[2]=255;
2733 ent.shaderRGBA[3]=(byte)(hcolor[3]*255.f);
27342734
27352735 trap_R_AddRefEntityToScene(&ent);
27362736 }
32693269 if ( cg_fixedAspect.integer ) {
32703270 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
32713271 CG_FillRect( 0, 0, 640, 480, col );
3272 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
32723273 } else {
32733274 CG_FillRect( 0, 0, 640, 480, col ); // why do a bunch of these extend outside 640x480?
32743275 }
33283329 if ( cg_fixedAspect.integer ) {
33293330 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
33303331 CG_FillRect( -10, -10, 650, 490, color );
3332 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
33313333 } else {
33323334 CG_FillRect( -10, -10, 650, 490, color );
33333335 }
33493351 return;
33503352 }
33513353
3354 if (!cg_blood.integer) {
3355 return;
3356 }
3357
33523358 if ( cg.v_dmg_time > cg.time ) {
33533359 redFlash = fabs( cg.v_dmg_pitch * ( ( cg.v_dmg_time - cg.time ) / DAMAGE_TIME ) );
33543360
33633369 if ( cg_fixedAspect.integer ) {
33643370 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
33653371 CG_FillRect( -10, -10, 650, 490, col );
3372 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
33663373 } else {
33673374 CG_FillRect( -10, -10, 650, 490, col );
33683375 }
34203427 if ( cg_fixedAspect.integer ) {
34213428 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
34223429 CG_DrawPic( -10, -10, 650, 490, cgs.media.viewFlashFire[( cg.time / 50 ) % 16] );
3430 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
34233431 } else {
34243432 CG_DrawPic( -10, -10, 650, 490, cgs.media.viewFlashFire[( cg.time / 50 ) % 16] );
34253433 }
34633471 if ( cg_fixedAspect.integer ) {
34643472 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
34653473 CG_DrawPic( -10, -10, 650, 490, shader );
3474 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
34663475 } else {
34673476 CG_DrawPic( -10, -10, 650, 490, shader );
34683477 }
36843693 if ( cg_fixedAspect.integer ) {
36853694 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
36863695 CG_FillRect( 0, 0, 640, 480, col );
3696 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
36873697 } else {
36883698 CG_FillRect( 0, 0, 640, 480, col );
36893699 }
37223732 if ( cg_fixedAspect.integer ) {
37233733 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
37243734 CG_FillRect( 0, 0, 640, 480, cg.fadeColor1 );
3735 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
37253736 } else {
37263737 CG_FillRect( 0, 0, 640, 480, cg.fadeColor1 );
37273738 }
37383749 if ( cg_fixedAspect.integer ) {
37393750 CG_SetScreenPlacement(PLACE_STRETCH, PLACE_STRETCH);
37403751 CG_FillRect( 0, 0, 640, 480, color );
3752 CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER);
37413753 } else {
37423754 CG_FillRect( 0, 0, 640, 480, color );
37433755 }
13391339 vec4_t colorNorm; // normalized color vector
13401340 refEntity_t ent;
13411341 vec3_t angles;
1342 // float deadFrac = 0;
13431342
13441343 VectorCopy( realstart, start );
13451344
14521451
14531452
14541453 if ( cent->currentState.frame == 1 ) { // dead
1455 #if 0
1456 deadFrac = (float)( cg.time - cent->currentState.time2 ) / 5000.0f;
1457
1458 // no fade out, just off
1459 // if(deadFrac > 1)
14601454 return;
1461
1462 startAlpha *= ( 1.0f - deadFrac );
1463 endAlpha *= ( 1.0f - deadFrac );
1464 #endif
14651455 }
14661456
14671457
339339 int otime;
340340 int lastch, nextch;
341341
342 if ( !cent->dl_stylestring ) {
342 if ( cent->dl_stylestring[0] == '\0' ) {
343343 return;
344344 }
345345
374374 ====================
375375 */
376376 void CG_DrawInformation( void ) {
377 const char *s;
378 const char *info;
379 qhandle_t levelshot = 0; // TTimo: init
380377 static int callCount = 0;
381378 float percentDone;
382379
395392
396393 callCount++;
397394
398 info = CG_ConfigString( CS_SERVERINFO );
399
400395 trap_Cvar_VariableStringBuffer( "com_expectedhunkusage", hunkBuf, MAX_QPATH );
401396 expectedHunk = atoi( hunkBuf );
402397
403 s = Info_ValueForKey( info, "mapname" );
404
405398 //----(SA) just the briefing now
406
407 if ( s && s[0] != 0 ) { // there is often no 's'
408 levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) );
409 }
410
411 if ( !levelshot ) {
412 levelshot = trap_R_RegisterShaderNoMip( "levelshots/unknownmap.jpg" );
413 }
414399
415400 trap_R_SetColor( NULL );
416401
16321632 extern vmCvar_t cg_youGotMail; //----(SA) added
16331633 extern vmCvar_t cg_drawAmmoWarning;
16341634 extern vmCvar_t cg_drawCrosshair;
1635 extern vmCvar_t cg_drawCrosshairBinoc;
16351636 extern vmCvar_t cg_drawCrosshairNames;
16361637 extern vmCvar_t cg_drawCrosshairPickups;
1638 extern vmCvar_t cg_drawCrosshairReticle;
16371639 extern vmCvar_t cg_hudAlpha;
16381640 extern vmCvar_t cg_useWeapsForZoom;
16391641 extern vmCvar_t cg_weaponCycleDelay; //----(SA) added
115115 vmCvar_t cg_youGotMail; //----(SA) added
116116 vmCvar_t cg_drawAmmoWarning;
117117 vmCvar_t cg_drawCrosshair;
118 vmCvar_t cg_drawCrosshairBinoc;
118119 vmCvar_t cg_drawCrosshairNames;
119120 vmCvar_t cg_drawCrosshairPickups;
121 vmCvar_t cg_drawCrosshairReticle;
120122 vmCvar_t cg_hudAlpha;
121123 vmCvar_t cg_weaponCycleDelay; //----(SA) added
122124 vmCvar_t cg_cycleAllWeaps;
316318 { &cg_drawAmmoWarning, "cg_drawAmmoWarning", "1", CVAR_ARCHIVE },
317319 { &cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE },
318320 { &cg_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE },
321 { &cg_drawCrosshairBinoc, "cg_drawCrosshairBinoc", "0", CVAR_ARCHIVE },
319322 { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
320323 { &cg_drawCrosshairPickups, "cg_drawCrosshairPickups", "1", CVAR_ARCHIVE },
324 { &cg_drawCrosshairReticle, "cg_drawCrosshairReticle", "1", CVAR_ARCHIVE },
321325 { &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE },
322326 { &cg_hudAlpha, "cg_hudAlpha", "0.8", CVAR_ARCHIVE },
323327 { &cg_useWeapsForZoom, "cg_useWeapsForZoom", "1", CVAR_ARCHIVE },
648648 value = CG_Text_Width( num, font, scale, 0 );
649649 if ( type == 0 ) {
650650 // Moved this up a little so it's not on top of the weapon heat bar
651 CG_Text_Paint( rect->x + ( rect->w - value ) / 2, -15 + rect->y + rect->h, font, scale, color, num, 0, 0, textStyle );
651 CG_Text_Paint( -12 + rect->x + ( rect->w - value ) / 2, -15 + rect->y + rect->h, font, scale, color, num, 0, 0, textStyle );
652652 } else {
653 CG_Text_Paint( rect->x + ( rect->w - value ) / 2, rect->y + rect->h, font, scale, color, num, 0, 0, textStyle );
653 CG_Text_Paint( -12 + rect->x + ( rect->w - value ) / 2, rect->y + rect->h, font, scale, color, num, 0, 0, textStyle );
654654 }
655655
656656 // if(special) { // draw '0' for akimbo guns
30093009 fovOffset[2] = -0.2 * ( cg_fov.integer - 90 );
30103010 }
30113011
3012 memset( &hand, 0, sizeof( hand ) );
3013
30123014 if ( ps->weapon > WP_NONE ) {
30133015 // DHM - Nerve :: handle WP_CLASS_SPECIAL for different classes
30143016 if ( cgs.gametype == GT_WOLF && ps->weapon == WP_CLASS_SPECIAL ) {
30363038 }
30373039 // dhm - end
30383040
3039 memset( &hand, 0, sizeof( hand ) );
3040
30413041 // set up gun position
30423042 CG_CalculateWeaponPosition( hand.origin, angles );
30433043
30603060 CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp ); //----(SA) changed
30613061 }
30623062
3063 VectorCopy( hand.origin, hand.lightingOrigin );
30633064
30643065 hand.hModel = weapon->handsModel;
30653066 hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT; //----(SA)
14661466 RoQReset();
14671467 } else {
14681468 RoQShutdown();
1469 return FMV_EOF;
14691470 }
14701471 }
14711472
2727 #include "../qcommon/qcommon.h"
2828
2929 #ifdef USE_LOCAL_HEADERS
30 #include "../libcurl-7.35.0/curl/curl.h"
30 #include "../curl-7.46.0/include/curl/curl.h"
3131 #else
3232 #include <curl/curl.h>
3333 #endif
3636 #ifdef WIN32
3737 #define DEFAULT_CURL_LIB "libcurl-4.dll"
3838 #define ALTERNATE_CURL_LIB "libcurl-3.dll"
39 #elif defined(MACOS_X)
39 #elif defined(__APPLE__)
4040 #define DEFAULT_CURL_LIB "libcurl.dylib"
4141 #else
4242 #define DEFAULT_CURL_LIB "libcurl.so.4"
438438 void CL_JoystickMove( usercmd_t *cmd ) {
439439 float anglespeed;
440440
441 float yaw = j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
442 float right = j_side->value * cl.joystickAxis[j_side_axis->integer];
443 float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
444 float pitch = j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
445 float up = j_up->value * cl.joystickAxis[j_up_axis->integer];
446
441447 if ( !(kb[KB_SPEED].active ^ cl_run->integer )) {
442448 cmd->buttons |= BUTTON_WALKING;
443449 }
449455 }
450456
451457 if ( !kb[KB_STRAFE].active ) {
452 cl.viewangles[YAW] += anglespeed * j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
453 cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_side->value * cl.joystickAxis[j_side_axis->integer]) );
454 } else {
455 cl.viewangles[YAW] += anglespeed * j_side->value * cl.joystickAxis[j_side_axis->integer];
456 cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_yaw->value * cl.joystickAxis[j_yaw_axis->integer]) );
458 cl.viewangles[YAW] += anglespeed * yaw;
459 cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
460 } else {
461 cl.viewangles[YAW] += anglespeed * right;
462 cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
457463 }
458464 if ( kb[KB_MLOOK].active ) {
459 cl.viewangles[PITCH] += anglespeed * j_forward->value * cl.joystickAxis[j_forward_axis->integer];
460 cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_pitch->value * cl.joystickAxis[j_pitch_axis->integer]) );
461 } else {
462 cl.viewangles[PITCH] += anglespeed * j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
463 cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_forward->value * cl.joystickAxis[j_forward_axis->integer]) );
464 }
465
466 cmd->upmove = ClampChar( cmd->upmove + (int) (j_up->value * cl.joystickAxis[j_up_axis->integer]) );
465 cl.viewangles[PITCH] += anglespeed * forward;
466 cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
467 } else {
468 cl.viewangles[PITCH] += anglespeed * pitch;
469 cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
470 }
471
472 cmd->upmove = ClampChar( cmd->upmove + (int)up );
467473 }
468474
469475 /*
702708 }
703709
704710 frame_msec = com_frameTime - old_com_frameTime;
711
712 // if running over 1000fps, act as if each frame is 1ms
713 // prevents divisions by zero
714 if ( frame_msec < 1 ) {
715 frame_msec = 1;
716 }
705717
706718 // if running less than 5fps, truncate the extra time to prevent
707719 // unexpected moves after a hitch
297297 {"EURO", K_EURO},
298298 {"UNDO", K_UNDO},
299299
300 {"PAD0_A", K_PAD0_A },
301 {"PAD0_B", K_PAD0_B },
302 {"PAD0_X", K_PAD0_X },
303 {"PAD0_Y", K_PAD0_Y },
304 {"PAD0_BACK", K_PAD0_BACK },
305 {"PAD0_GUIDE", K_PAD0_GUIDE },
306 {"PAD0_START", K_PAD0_START },
307 {"PAD0_LEFTSTICK_CLICK", K_PAD0_LEFTSTICK_CLICK },
308 {"PAD0_RIGHTSTICK_CLICK", K_PAD0_RIGHTSTICK_CLICK },
309 {"PAD0_LEFTSHOULDER", K_PAD0_LEFTSHOULDER },
310 {"PAD0_RIGHTSHOULDER", K_PAD0_RIGHTSHOULDER },
311 {"PAD0_DPAD_UP", K_PAD0_DPAD_UP },
312 {"PAD0_DPAD_DOWN", K_PAD0_DPAD_DOWN },
313 {"PAD0_DPAD_LEFT", K_PAD0_DPAD_LEFT },
314 {"PAD0_DPAD_RIGHT", K_PAD0_DPAD_RIGHT },
315
316 {"PAD0_LEFTSTICK_LEFT", K_PAD0_LEFTSTICK_LEFT },
317 {"PAD0_LEFTSTICK_RIGHT", K_PAD0_LEFTSTICK_RIGHT },
318 {"PAD0_LEFTSTICK_UP", K_PAD0_LEFTSTICK_UP },
319 {"PAD0_LEFTSTICK_DOWN", K_PAD0_LEFTSTICK_DOWN },
320 {"PAD0_RIGHTSTICK_LEFT", K_PAD0_RIGHTSTICK_LEFT },
321 {"PAD0_RIGHTSTICK_RIGHT", K_PAD0_RIGHTSTICK_RIGHT },
322 {"PAD0_RIGHTSTICK_UP", K_PAD0_RIGHTSTICK_UP },
323 {"PAD0_RIGHTSTICK_DOWN", K_PAD0_RIGHTSTICK_DOWN },
324 {"PAD0_LEFTTRIGGER", K_PAD0_LEFTTRIGGER },
325 {"PAD0_RIGHTTRIGGER", K_PAD0_RIGHTTRIGGER },
326
300327 {NULL,0}
301328 };
302329
14401440 for (i = 0; i < MAX_CLIENTS; i++) {
14411441 opus_decoder_destroy(clc.opusDecoder[i]);
14421442 }
1443 clc.voipCodecInitialized = qfalse;
14431444 }
14441445 Cmd_RemoveCommand ("voip");
14451446 #endif
16131614 ===================
16141615 */
16151616 #ifndef STANDALONE
1617 #ifdef USE_AUTHORIZE_SERVER
16161618 void CL_RequestAuthorization( void ) {
16171619 char nums[64];
16181620 int i, j, l;
16561658
16571659 NET_OutOfBandPrint(NS_CLIENT, cls.authorizeServer, "getKeyAuthorize %i %s", fs->integer, nums );
16581660 }
1661 #endif
16591662 #endif
16601663
16611664 /*
23602363 case CA_CONNECTING:
23612364 // requesting a challenge .. IPv6 users always get in as authorize server supports no ipv6.
23622365 #ifndef STANDALONE
2366 #ifdef USE_AUTHORIZE_SERVER
23632367 if (!com_standalone->integer && clc.serverAddress.type == NA_IP && !Sys_IsLANAddress( clc.serverAddress ) )
23642368 CL_RequestAuthorization();
2369 #endif
23652370 #endif
23662371
23672372 // The challenge request shall be followed by a client challenge so no malicious server can hijack this connection.
37353740 j_yaw = Cvar_Get ("j_yaw", "-0.022", CVAR_ARCHIVE);
37363741 j_forward = Cvar_Get ("j_forward", "-0.25", CVAR_ARCHIVE);
37373742 j_side = Cvar_Get ("j_side", "0.25", CVAR_ARCHIVE);
3738 j_up = Cvar_Get ("j_up", "1", CVAR_ARCHIVE);
3743 j_up = Cvar_Get ("j_up", "0", CVAR_ARCHIVE);
37393744
37403745 j_pitch_axis = Cvar_Get ("j_pitch_axis", "3", CVAR_ARCHIVE);
3741 j_yaw_axis = Cvar_Get ("j_yaw_axis", "4", CVAR_ARCHIVE);
3746 j_yaw_axis = Cvar_Get ("j_yaw_axis", "2", CVAR_ARCHIVE);
37423747 j_forward_axis = Cvar_Get ("j_forward_axis", "1", CVAR_ARCHIVE);
37433748 j_side_axis = Cvar_Get ("j_side_axis", "0", CVAR_ARCHIVE);
3744 j_up_axis = Cvar_Get ("j_up_axis", "2", CVAR_ARCHIVE);
3749 j_up_axis = Cvar_Get ("j_up_axis", "4", CVAR_ARCHIVE);
37453750
37463751 Cvar_CheckRange(j_pitch_axis, 0, MAX_JOYSTICK_AXIS-1, qtrue);
37473752 Cvar_CheckRange(j_yaw_axis, 0, MAX_JOYSTICK_AXIS-1, qtrue);
4242
4343 #ifdef USE_VOIP
4444 #ifdef USE_LOCAL_HEADERS
45 #include "../opus-1.1/include/opus.h"
46 #include "../opusfile-0.6/include/opusfile.h"
45 #include "../opus-1.1.2/include/opus.h"
46 #include "../opusfile-0.7/include/opusfile.h"
4747 #else
4848 #include <opus/opus.h>
4949 #include <opus/opusfile.h>
265265 K_EURO,
266266 K_UNDO,
267267
268 // Gamepad controls
269 // Ordered to match SDL2 game controller buttons and axes
270 // Do not change this order without also changing IN_GamepadMove() in SDL_input.c
271 K_PAD0_A,
272 K_PAD0_B,
273 K_PAD0_X,
274 K_PAD0_Y,
275 K_PAD0_BACK,
276 K_PAD0_GUIDE,
277 K_PAD0_START,
278 K_PAD0_LEFTSTICK_CLICK,
279 K_PAD0_RIGHTSTICK_CLICK,
280 K_PAD0_LEFTSHOULDER,
281 K_PAD0_RIGHTSHOULDER,
282 K_PAD0_DPAD_UP,
283 K_PAD0_DPAD_DOWN,
284 K_PAD0_DPAD_LEFT,
285 K_PAD0_DPAD_RIGHT,
286
287 K_PAD0_LEFTSTICK_LEFT,
288 K_PAD0_LEFTSTICK_RIGHT,
289 K_PAD0_LEFTSTICK_UP,
290 K_PAD0_LEFTSTICK_DOWN,
291 K_PAD0_RIGHTSTICK_LEFT,
292 K_PAD0_RIGHTSTICK_RIGHT,
293 K_PAD0_RIGHTSTICK_UP,
294 K_PAD0_RIGHTSTICK_DOWN,
295 K_PAD0_LEFTTRIGGER,
296 K_PAD0_RIGHTTRIGGER,
297
268298 // Pseudo-key that brings the console down
269299 K_CONSOLE,
270300
3131 // includes for the OGG codec
3232 #include <errno.h>
3333 #define OV_EXCLUDE_STATIC_CALLBACKS
34 #include <vorbis/vorbisfile.h>
34 #ifdef USE_LOCAL_HEADERS
35 #include "../libvorbis-1.3.5/include/vorbis/vorbisfile.h"
36 #else
37 #include <vorbis/vorbisfile.h>
38 #endif
3539
3640 // The OGG codec can return the samples in a number of different formats,
3741 // we use the standard signed short format.
618618 int inplay, allowed;
619619 qboolean fullVolume;
620620
621 if ( !s_soundStarted || s_soundMuted || ( clc.state != CA_ACTIVE && clc.state != CA_DISCONNECTED ) ) {
621 if ( !s_soundStarted || s_soundMuted ) {
622622 return;
623623 }
624624
729729 continue;
730730 }
731731 }
732
733732 }
734733 }
735734
736735 // re-use channel if applicable
737736 for ( i = 0 ; i < MAX_CHANNELS ; i++ ) {
738 if ( s_channels[i].entnum == entityNum && s_channels[i].entchannel == entchannel ) {
737 if ( s_channels[i].entnum == entityNum && s_channels[i].entchannel == entchannel && entchannel != CHAN_AUTO ) {
739738 if ( !( s_channels[i].flags & SND_NOCUT ) && s_channels[i].thesfx == sfx ) {
740739 ch = &s_channels[i];
741740 break;
2222
2323 #include "client.h"
2424 #include "snd_local.h"
25 #if idppc_altivec && !defined(MACOS_X)
25 #if idppc_altivec && !defined(__APPLE__)
2626 #include <altivec.h>
2727 #endif
2828
584584 int flags; // flags from StartSoundEx
585585 } src_t;
586586
587 #ifdef MACOS_X
587 #ifdef __APPLE__
588588 #define MAX_SRC 128
589589 #else
590590 #define MAX_SRC 256
785785 }
786786
787787 memset(srcList, 0, sizeof(srcList));
788 memset( s_entityTalkAmplitude, 0, sizeof( s_entityTalkAmplitude ) );
788789
789790 alSourcesInitialised = qfalse;
790791 }
11111112 continue;
11121113 }
11131114
1114 // re-use channel if applicable
1115 if ( curSource->sfx == sfx && !cutDuplicateSound ) {
1116 cutDuplicateSound = qtrue;
1117 S_AL_SrcKill(i);
1118 if (empty == -1)
1119 empty = i;
1120 continue;
1121 }
1122
11231115 // RF, let client voice sounds be overwritten
11241116 if ( entnum < MAX_CLIENTS && curSource->channel != -1 && curSource->channel != CHAN_AUTO && curSource->channel != CHAN_WEAPON ) {
11251117 S_AL_SrcKill(i);
11451137 continue;
11461138 }
11471139 }
1140
1141 // re-use channel if applicable
1142 if ( curSource->channel != -1 && curSource->channel != CHAN_AUTO && curSource->sfx == sfx && !cutDuplicateSound ) {
1143 cutDuplicateSound = qtrue;
1144 S_AL_SrcKill(i);
1145 if (empty == -1)
1146 empty = i;
1147 continue;
1148 }
11481149 }
11491150 }
11501151
13231324 }
13241325
13251326 // Talk anims default to ZERO amplitude
1326 memset( s_entityTalkAmplitude, 0, sizeof( s_entityTalkAmplitude ) );
1327 if ( entchannel == CHAN_VOICE )
1328 memset( s_entityTalkAmplitude, 0, sizeof( s_entityTalkAmplitude ) );
13271329
13281330 if ( entnum < MAX_CLIENTS && entchannel == CHAN_VOICE )
13291331 {
23622364
23632365 #ifdef _WIN32
23642366 #define ALDRIVER_DEFAULT "OpenAL32.dll"
2365 #elif defined(MACOS_X)
2367 #elif defined(__APPLE__)
23662368 #define ALDRIVER_DEFAULT "libopenal.dylib"
23672369 #elif defined(__OpenBSD__)
23682370 #define ALDRIVER_DEFAULT "libopenal.so"
25872589 #ifdef USE_VOIP
25882590 if(capture_ext)
25892591 {
2590 #ifdef MACOS_X
2592 #ifdef __APPLE__
25912593 Com_Printf(" Input Device: %s\n", qalcGetString(alCaptureDevice, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
25922594 #else
25932595 Com_Printf(" Input Device: %s\n", qalcGetString(alCaptureDevice, ALC_CAPTURE_DEVICE_SPECIFIER));
26842686 {
26852687 #if defined( _WIN32 )
26862688 if( !Q_stricmp( s_alDriver->string, ALDRIVER_DEFAULT ) && !QAL_Init( "OpenAL64.dll" ) ) {
2687 #elif defined ( MACOS_X )
2689 #elif defined ( __APPLE__ )
26882690 if( !Q_stricmp( s_alDriver->string, ALDRIVER_DEFAULT ) && !QAL_Init( "/System/Library/Frameworks/OpenAL.framework/OpenAL" ) ) {
26892691 #else
26902692 if( !Q_stricmp( s_alDriver->string, ALDRIVER_DEFAULT ) || !QAL_Init( ALDRIVER_DEFAULT ) ) {
28122814 #endif
28132815 else
28142816 {
2815 #ifdef MACOS_X
2817 #ifdef __APPLE__
28162818 // !!! FIXME: Apple has a 1.1-compliant OpenAL, which includes
28172819 // !!! FIXME: capture support, but they don't list it in the
28182820 // !!! FIXME: extension string. We need to check the version string,
2929 void daub4(float b[], unsigned long n, int isign)
3030 {
3131 float wksp[4097] = { 0.0f };
32 float *a=b-1; // numerical recipies so a[1] = b[0]
32 #define a(x) b[(x)-1] // numerical recipies so a[1] = b[0]
3333
3434 unsigned long nh,nh1,i,j;
3535
3838 nh1=(nh=n >> 1)+1;
3939 if (isign >= 0) {
4040 for (i=1,j=1;j<=n-3;j+=2,i++) {
41 wksp[i] = C0*a[j]+C1*a[j+1]+C2*a[j+2]+C3*a[j+3];
42 wksp[i+nh] = C3*a[j]-C2*a[j+1]+C1*a[j+2]-C0*a[j+3];
43 }
44 wksp[i ] = C0*a[n-1]+C1*a[n]+C2*a[1]+C3*a[2];
45 wksp[i+nh] = C3*a[n-1]-C2*a[n]+C1*a[1]-C0*a[2];
41 wksp[i] = C0*a(j)+C1*a(j+1)+C2*a(j+2)+C3*a(j+3);
42 wksp[i+nh] = C3*a(j)-C2*a(j+1)+C1*a(j+2)-C0*a(j+3);
43 }
44 wksp[i ] = C0*a(n-1)+C1*a(n)+C2*a(1)+C3*a(2);
45 wksp[i+nh] = C3*a(n-1)-C2*a(n)+C1*a(1)-C0*a(2);
4646 } else {
47 wksp[1] = C2*a[nh]+C1*a[n]+C0*a[1]+C3*a[nh1];
48 wksp[2] = C3*a[nh]-C0*a[n]+C1*a[1]-C2*a[nh1];
47 wksp[1] = C2*a(nh)+C1*a(n)+C0*a(1)+C3*a(nh1);
48 wksp[2] = C3*a(nh)-C0*a(n)+C1*a(1)-C2*a(nh1);
4949 for (i=1,j=3;i<nh;i++) {
50 wksp[j++] = C2*a[i]+C1*a[i+nh]+C0*a[i+1]+C3*a[i+nh1];
51 wksp[j++] = C3*a[i]-C0*a[i+nh]+C1*a[i+1]-C2*a[i+nh1];
50 wksp[j++] = C2*a(i)+C1*a(i+nh)+C0*a(i+1)+C3*a(i+nh1);
51 wksp[j++] = C3*a(i)-C0*a(i+nh)+C1*a(i+1)-C2*a(i+nh1);
5252 }
5353 }
5454 for (i=1;i<=n;i++) {
55 a[i]=wksp[i];
56 }
55 a(i)=wksp[i];
56 }
57 #undef a
5758 }
5859
5960 void wt1(float a[], unsigned long n, int isign)
12081208 }
12091209 }
12101210
1211 // if we didnt just play a scripted sound, then play one of the default sounds
1211 // if we didn't just play a scripted sound, then play one of the default sounds
12121212 if ( cs->lastScriptSound < level.time ) {
12131213 G_AddEvent( ent, EV_GENERAL_SOUND, G_SoundIndex( aiDefaults[ent->aiCharacter].soundScripts[PAINSOUNDSCRIPT] ) );
12141214 }
10341034 cs->scriptPauseTime = 0;
10351035 return AIFunc_IdleStart( cs );
10361036 }
1037 // make sure we didnt change thinkfunc
1037 // make sure we didn't change thinkfunc
10381038 if ( cs->aifunc != AIFunc_InspectBulletImpact ) {
10391039 //G_Error( "scripting passed control out of AIFunc_InspectBulletImpact(), this is bad" );
10401040 return NULL;
17141714 AICast_PredictMovement( cs, 10, frameTime, &move, &ucmd, cs->followEntity );
17151715
17161716 if ( move.stopevent == PREDICTSTOP_HITENT ) { // success!
1717 // make sure we didnt spend a lot of time sliding along an obstacle
1717 // make sure we didn't spend a lot of time sliding along an obstacle
17181718 if ( ( move.frames * frameTime ) < ( 1.0 + ( goaldist / ( bs->cur_ps.speed * bs->cur_ps.runSpeedScale ) ) ) ) {
17191719 trap_EA_Move( cs->entityNum, dir, 400 );
17201720 vectoangles( dir, cs->ideal_viewangles );
14381438
14391439 }
14401440
1441 if ( !g_entities[cs->entityNum].client->ps.weapons ) {
1441 if ( !( g_entities[cs->entityNum].client->ps.weapons[0] ) && !( g_entities[cs->entityNum].client->ps.weapons[1] ) ) {
14421442 if ( cs->bs ) {
14431443 cs->weaponNum = WP_NONE;
14441444 } else {
11661166 //VectorCopy( thisHitVec, startHitVec );
11671167 VectorCopy( pm.ps->origin, lastOrg );
11681168 }
1169 // if we didnt reach the marker, then check for something that blocked us
1169 // if we didn't reach the marker, then check for something that blocked us
11701170 for ( i = 0; i < pm.numtouch; i++ ) {
11711171 if ( pm.touchents[i] == pm.ps->groundEntityNum ) {
11721172 continue;
12051205 // hack, if we are above ground, chances are it's because we only did one frame, and gravity isn't applied until
12061206 // after the frame, so try and drop us down some
12071207 if ( pm.ps->groundEntityNum == ENTITYNUM_NONE ) {
1208 VectorCopy( move->endpos, end );
1208 VectorCopy( pm.ps->origin, end );
12091209 end[2] -= 32;
1210 trap_Trace( &tr, move->endpos, pm.mins, pm.maxs, end, pm.ps->clientNum, pm.tracemask );
1210 trap_Trace( &tr, pm.ps->origin, pm.mins, pm.maxs, end, pm.ps->clientNum, pm.tracemask );
12111211 if ( !tr.startsolid && !tr.allsolid && tr.fraction < 1 ) {
12121212 VectorCopy( tr.endpos, pm.ps->origin );
12131213 pm.ps->groundEntityNum = tr.entityNum;
513513 bs->teammessage_time = 0;
514514 }
515515 //
516 if ( bs->lastkilledplayer == bs->teamgoal.entitynum ) {
516 if (bs->killedenemy_time > bs->teamgoal_time - TEAM_KILL_SOMEONE && bs->lastkilledplayer == bs->teamgoal.entitynum) {
517517 EasyClientName( bs->teamgoal.entitynum, buf, sizeof( buf ) );
518518 BotAI_BotInitialChat( bs, "kill_done", buf, NULL );
519519 trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
520 bs->lastkilledplayer = -1;
521520 bs->ltgtype = 0;
522521 }
523522 //
807807
808808 // read digits
809809 value = 0;
810 if ( string[0] != '.' ) {
810 if ( string[0] == '.' ) {
811 // read decimal point if followed by a digit
812 if ( string[1] >= '0' && string[1] <= '9' ) {
813 c = *string++;
814 }
815 } else {
811816 do {
812817 c = *string++;
813818 if ( c < '0' || c > '9' ) {
27432743 #ifdef GAMEDLL
27442744 if ( g_reloading.integer )
27452745 #endif
2746 gameReloading = qtrue;
2746 gameReloading = qtrue;
27472747 else {
27482748 gameReloading = qfalse;
27492749 }
28442844 }
28452845 return;
28462846 }
2847 } else
2848 {
2847 } else {
28492848 pm->ps->pm_flags &= ~PMF_USE_ITEM_HELD;
28502849 }
28512850
28642863 #ifdef GAMEDLL
28652864 if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
28662865 #endif
2867 if ( pm->ps->grenadeTimeLeft < 5000 ) {
2868 pm->ps->grenadeTimeLeft = 5000;
2866 if ( pm->ps->grenadeTimeLeft < 5000 ) {
2867 pm->ps->grenadeTimeLeft = 5000;
2868 }
28692869 }
2870 }
28712870 // jpw
28722871
2873 if ( pm->ps->grenadeTimeLeft > 8000 ) {
2874 PM_AddEvent( EV_FIRE_WEAPON );
2875 pm->ps->weaponTime = 1600;
2876 PM_WeaponUseAmmo( pm->ps->weapon, 1 ); //----(SA) take ammo
2877 return;
2878 }
2872 if ( pm->ps->grenadeTimeLeft > 8000 ) {
2873 PM_AddEvent( EV_FIRE_WEAPON );
2874 pm->ps->weaponTime = 1600;
2875 PM_WeaponUseAmmo( pm->ps->weapon, 1 ); //----(SA) take ammo
2876 return;
2877 }
28792878
28802879 // Com_Printf("Dynamite Timer: %d\n", pm->ps->grenadeTimeLeft);
2881 } else {
2882 pm->ps->grenadeTimeLeft -= pml.msec;
2880 } else {
2881 pm->ps->grenadeTimeLeft -= pml.msec;
28832882 // Com_Printf("Grenade Timer: %d\n", pm->ps->grenadeTimeLeft);
28842883
2885 if ( pm->ps->grenadeTimeLeft <= 0 ) { // give two frames advance notice so there's time to launch and detonate
2884 if ( pm->ps->grenadeTimeLeft <= 0 ) { // give two frames advance notice so there's time to launch and detonate
28862885 // pm->ps->grenadeTimeLeft = 100;
28872886 // PM_AddEvent( EV_FIRE_WEAPON );
2888 PM_WeaponUseAmmo( pm->ps->weapon, 1 ); //----(SA) take ammo
2887 PM_WeaponUseAmmo( pm->ps->weapon, 1 ); //----(SA) take ammo
28892888 // pm->ps->weaponTime = 1600;
28902889
2891 PM_AddEvent( EV_GRENADE_SUICIDE ); //----(SA) die, dumbass
2892
2890 PM_AddEvent( EV_GRENADE_SUICIDE ); //----(SA) die, dumbass
2891
2892 return;
2893 }
2894 }
2895
2896 if ( !( pm->cmd.buttons & BUTTON_ATTACK ) ) { //----(SA) modified
2897 if ( pm->ps->weaponDelay == ammoTable[pm->ps->weapon].fireDelayTime ) {
2898 // released fire button. Fire!!!
2899 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qtrue );
2900 }
2901 } else {
28932902 return;
28942903 }
28952904 }
2896
2897 if ( !( pm->cmd.buttons & BUTTON_ATTACK ) ) { //----(SA) modified
2898 if ( pm->ps->weaponDelay == ammoTable[pm->ps->weapon].fireDelayTime ) {
2899 // released fire button. Fire!!!
2900 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qtrue );
2901 }
2902 } else {
2903 return;
2904 }
2905 }
2906 }
2907
2908 if ( pm->ps->weaponDelay > 0 ) {
2909 pm->ps->weaponDelay -= pml.msec;
2910 if ( pm->ps->weaponDelay <= 0 ) {
2911 pm->ps->weaponDelay = 0;
2912 delayedFire = qtrue; // weapon delay has expired. Fire this frame
2913
2914 // double check the player is still holding the fire button down for these weapons
2915 // so you don't get a delayed "non-fire" (fire hit and released, then shot fires)
2916 switch ( pm->ps->weapon ) {
2917 case WP_VENOM:
2918 if ( pm->ps->weaponstate == WEAPON_FIRING ) {
2919 delayedFire = qfalse;
2920 }
2921 break;
2922 default:
2923 break;
2924 }
2925 }
2926 }
2927
2928
2929 if ( pm->ps->weaponstate == WEAPON_RELAXING ) {
2930 pm->ps->weaponstate = WEAPON_READY;
2931 return;
2932 }
2933
2934 // make weapon function
2935 if ( pm->ps->weaponTime > 0 ) {
2936 pm->ps->weaponTime -= pml.msec;
2937 if ( pm->ps->weaponTime < 0 ) {
2938 pm->ps->weaponTime = 0;
2939 }
2905 }
2906
2907 if ( pm->ps->weaponDelay > 0 ) {
2908 pm->ps->weaponDelay -= pml.msec;
2909 if ( pm->ps->weaponDelay <= 0 ) {
2910 pm->ps->weaponDelay = 0;
2911 delayedFire = qtrue; // weapon delay has expired. Fire this frame
2912
2913 // double check the player is still holding the fire button down for these weapons
2914 // so you don't get a delayed "non-fire" (fire hit and released, then shot fires)
2915 switch ( pm->ps->weapon ) {
2916 case WP_VENOM:
2917 if ( pm->ps->weaponstate == WEAPON_FIRING ) {
2918 delayedFire = qfalse;
2919 }
2920 break;
2921 default:
2922 break;
2923 }
2924 }
2925 }
2926
2927 if ( pm->ps->weaponstate == WEAPON_RELAXING ) {
2928 pm->ps->weaponstate = WEAPON_READY;
2929 return;
2930 }
2931
2932 // make weapon function
2933 if ( pm->ps->weaponTime > 0 ) {
2934 pm->ps->weaponTime -= pml.msec;
2935 if ( pm->ps->weaponTime < 0 ) {
2936 pm->ps->weaponTime = 0;
2937 }
29402938
29412939 //----(SA) removed for DM and id
29422940 /*
29762974 #ifdef GAMEDLL
29772975 if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
29782976 #endif
2979 if ( pm->ps->weapon == WP_LUGER ) {
2980 if ( pm->ps->releasedFire ) {
2981 if ( pm->ps->weaponTime <= 150 && ( pm->cmd.buttons & BUTTON_ATTACK ) ) {
2982 pm->ps->weaponTime = 0;
2983 }
2984 } else if ( !( pm->cmd.buttons & BUTTON_ATTACK ) && ( pm->ps->weaponTime >= 50 ) ) {
2985 pm->ps->releasedFire = qtrue;
2986 }
2987 } else if ( pm->ps->weapon == WP_COLT ) {
2988 if ( pm->ps->releasedFire ) {
2989 if ( pm->ps->weaponTime <= 150 && ( pm->cmd.buttons & BUTTON_ATTACK ) ) {
2990 pm->ps->weaponTime = 0;
2991 }
2992 } else if ( !( pm->cmd.buttons & BUTTON_ATTACK ) && ( pm->ps->weaponTime >= 100 ) ) {
2993 pm->ps->releasedFire = qtrue;
2994 }
2995 }
2996 }
2977 if ( pm->ps->weapon == WP_LUGER ) {
2978 if ( pm->ps->releasedFire ) {
2979 if ( pm->ps->weaponTime <= 150 && ( pm->cmd.buttons & BUTTON_ATTACK ) ) {
2980 pm->ps->weaponTime = 0;
2981 }
2982 } else if ( !( pm->cmd.buttons & BUTTON_ATTACK ) && ( pm->ps->weaponTime >= 50 ) ) {
2983 pm->ps->releasedFire = qtrue;
2984 }
2985 } else if ( pm->ps->weapon == WP_COLT ) {
2986 if ( pm->ps->releasedFire ) {
2987 if ( pm->ps->weaponTime <= 150 && ( pm->cmd.buttons & BUTTON_ATTACK ) ) {
2988 pm->ps->weaponTime = 0;
2989 }
2990 } else if ( !( pm->cmd.buttons & BUTTON_ATTACK ) && ( pm->ps->weaponTime >= 100 ) ) {
2991 pm->ps->releasedFire = qtrue;
2992 }
2993 }
2994 }
29972995 // jpw
29982996
29992997 }
30002998
3001
3002 // check for weapon change
3003 // can't change if weapon is firing, but can change
3004 // again if lowering or raising
3005
3006 // TTimo gcc: suggest parentheses around && within ||
3007 if ( pm->ps->weaponTime <= 0 || ( !weaponstateFiring && pm->ps->weaponDelay <= 0 ) ) {
3008 if ( pm->ps->weapon != pm->cmd.weapon ) {
3009 PM_BeginWeaponChange( pm->ps->weapon, pm->cmd.weapon, qfalse ); //----(SA) modified
3010 }
3011 }
3012
3013 // check for clip change
3014 PM_CheckForReload( pm->ps->weapon );
3015
3016 if ( pm->ps->weaponTime > 0 || pm->ps->weaponDelay > 0 ) {
3017 return;
3018 }
3019
3020 if ( pm->ps->weaponstate == WEAPON_RELOADING ) {
3021 PM_FinishWeaponReload();
3022 }
3023
3024 // change weapon if time
3025 if ( pm->ps->weaponstate == WEAPON_DROPPING || pm->ps->weaponstate == WEAPON_DROPPING_TORELOAD ) {
3026 PM_FinishWeaponChange();
3027 return;
3028 }
3029
3030 if ( pm->ps->weaponstate == WEAPON_RAISING ) {
3031 pm->ps->weaponstate = WEAPON_READY;
3032 PM_StartWeaponAnim( WEAP_IDLE1 );
3033 return;
3034 } else if ( pm->ps->weaponstate == WEAPON_RAISING_TORELOAD ) {
3035 pm->ps->weaponstate = WEAPON_READY; // need to switch to READY so the reload will work
3036 PM_BeginWeaponReload( pm->ps->weapon );
3037 return;
3038 }
3039
3040
3041 if ( pm->ps->weapon == WP_NONE ) { // this is possible since the player starts with nothing
3042 return;
3043 }
2999 // check for weapon change
3000 // can't change if weapon is firing, but can change
3001 // again if lowering or raising
3002
3003 // TTimo gcc: suggest parentheses around && within ||
3004 if ( pm->ps->weaponTime <= 0 || ( !weaponstateFiring && pm->ps->weaponDelay <= 0 ) ) {
3005 if ( pm->ps->weapon != pm->cmd.weapon ) {
3006 PM_BeginWeaponChange( pm->ps->weapon, pm->cmd.weapon, qfalse ); //----(SA) modified
3007 }
3008 }
3009
3010 // check for clip change
3011 PM_CheckForReload( pm->ps->weapon );
3012
3013 if ( pm->ps->weaponTime > 0 || pm->ps->weaponDelay > 0 ) {
3014 return;
3015 }
3016
3017 if ( pm->ps->weaponstate == WEAPON_RELOADING ) {
3018 PM_FinishWeaponReload();
3019 }
3020
3021 // change weapon if time
3022 if ( pm->ps->weaponstate == WEAPON_DROPPING || pm->ps->weaponstate == WEAPON_DROPPING_TORELOAD ) {
3023 PM_FinishWeaponChange();
3024 return;
3025 }
3026
3027 if ( pm->ps->weaponstate == WEAPON_RAISING ) {
3028 pm->ps->weaponstate = WEAPON_READY;
3029 PM_StartWeaponAnim( WEAP_IDLE1 );
3030 return;
3031 } else if ( pm->ps->weaponstate == WEAPON_RAISING_TORELOAD ) {
3032 pm->ps->weaponstate = WEAPON_READY; // need to switch to READY so the reload will work
3033 PM_BeginWeaponReload( pm->ps->weapon );
3034 return;
3035 }
3036
3037 if ( pm->ps->weapon == WP_NONE ) { // this is possible since the player starts with nothing
3038 return;
3039 }
30443040
30453041
30463042 // JPW NERVE -- in multiplayer, don't allow panzerfaust or dynamite to fire if charge bar isn't full
30473043 #ifdef GAMEDLL
3048 if ( g_gametype.integer == GT_WOLF ) {
3049 if ( pm->ps->weapon == WP_PANZERFAUST ) {
3050 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < g_soldierChargeTime.integer ) {
3051 return;
3052 }
3053 }
3054 if ( pm->ps->weapon == WP_DYNAMITE ) {
3055 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < g_engineerChargeTime.integer ) { // had to use multiplier because chargetime is used elsewhere as bomb diffuse time FIXME not really but NOTE changing bomb diffuse time will require changing this time as well (intended function: new charge ready when old one explodes, ie every 30 seconds or so)
3056
3057 return;
3058 }
3059 }
3060 }
3044 if ( g_gametype.integer == GT_WOLF ) {
3045 if ( pm->ps->weapon == WP_PANZERFAUST ) {
3046 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < g_soldierChargeTime.integer ) {
3047 return;
3048 }
3049 }
3050 if ( pm->ps->weapon == WP_DYNAMITE ) {
3051 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < g_engineerChargeTime.integer ) { // had to use multiplier because chargetime is used elsewhere as bomb diffuse time FIXME not really but NOTE changing bomb diffuse time will require changing this time as well (intended function: new charge ready when old one explodes, ie every 30 seconds or so)
3052
3053 return;
3054 }
3055 }
3056 }
30613057 #endif
30623058 #ifdef CGAMEDLL
3063 if ( cg_gameType.integer == GT_WOLF ) {
3064 if ( pm->ps->weapon == WP_PANZERFAUST ) {
3065 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < cg_soldierChargeTime.integer ) {
3066 return;
3067 }
3068 }
3069 if ( pm->ps->weapon == WP_DYNAMITE ) {
3070 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < cg_engineerChargeTime.integer ) {
3071 return;
3072 }
3073 }
3074 }
3059 if ( cg_gameType.integer == GT_WOLF ) {
3060 if ( pm->ps->weapon == WP_PANZERFAUST ) {
3061 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < cg_soldierChargeTime.integer ) {
3062 return;
3063 }
3064 }
3065 if ( pm->ps->weapon == WP_DYNAMITE ) {
3066 if ( pm->cmd.serverTime - pm->ps->classWeaponTime < cg_engineerChargeTime.integer ) {
3067 return;
3068 }
3069 }
3070 }
30753071 #endif
30763072 // jpw
30773073
3078 // check for fire
3079 if ( !( pm->cmd.buttons & ( BUTTON_ATTACK | WBUTTON_ATTACK2 ) ) && !delayedFire ) { // if not on fire button and there's not a delayed shot this frame...
3080 pm->ps->weaponTime = 0;
3081 pm->ps->weaponDelay = 0;
3082
3083 if ( weaponstateFiring ) { // you were just firing, time to relax
3084 PM_ContinueWeaponAnim( WEAP_IDLE1 );
3085 }
3086
3087 pm->ps->weaponstate = WEAPON_READY;
3088 return;
3089 }
3090
3091
3092 if ( gameReloading ) {
3093 return;
3094 }
3095
3096 // player is zooming - no fire
3097 if ( pm->ps->eFlags & EF_ZOOMING ) {
3098 return;
3099 }
3100
3101 // player is leaning - no fire
3102 if ( pm->ps->leanf != 0 && pm->ps->weapon != WP_GRENADE_LAUNCHER && pm->ps->weapon != WP_GRENADE_PINEAPPLE && pm->ps->weapon != WP_DYNAMITE ) {
3103 return;
3104 }
3105
3106 // player is underwater - no fire
3107 if ( pm->waterlevel == 3 ) {
3108 if ( pm->ps->weapon != WP_KNIFE &&
3109 pm->ps->weapon != WP_GRENADE_LAUNCHER &&
3110 pm->ps->weapon != WP_GRENADE_PINEAPPLE ) {
3111 PM_AddEvent( EV_NOFIRE_UNDERWATER ); // event for underwater 'click' for nofire
3112 pm->ps->weaponTime = 500;
3113 return;
3114 }
3115 }
3116
3117 // start the animation even if out of ammo
3118 switch ( pm->ps->weapon )
3119 {
3120 default:
3121 if ( !weaponstateFiring ) {
3122 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime; // delay so the weapon can get up into position before firing (and showing the flash)
3074 // check for fire
3075 if ( !( pm->cmd.buttons & ( BUTTON_ATTACK | WBUTTON_ATTACK2 ) ) && !delayedFire ) { // if not on fire button and there's not a delayed shot this frame...
3076 pm->ps->weaponTime = 0;
3077 pm->ps->weaponDelay = 0;
3078
3079 if ( weaponstateFiring ) { // you were just firing, time to relax
3080 PM_ContinueWeaponAnim( WEAP_IDLE1 );
3081 }
3082
3083 pm->ps->weaponstate = WEAPON_READY;
3084 return;
3085 }
3086
3087 if ( gameReloading ) {
3088 return;
3089 }
3090
3091 // player is zooming - no fire
3092 if ( pm->ps->eFlags & EF_ZOOMING ) {
3093 return;
3094 }
3095
3096 // player is leaning - no fire
3097 if ( pm->ps->leanf != 0 && pm->ps->weapon != WP_GRENADE_LAUNCHER && pm->ps->weapon != WP_GRENADE_PINEAPPLE && pm->ps->weapon != WP_DYNAMITE ) {
3098 return;
3099 }
3100
3101 // player is underwater - no fire
3102 if ( pm->waterlevel == 3 ) {
3103 if ( pm->ps->weapon != WP_KNIFE &&
3104 pm->ps->weapon != WP_GRENADE_LAUNCHER &&
3105 pm->ps->weapon != WP_GRENADE_PINEAPPLE ) {
3106 PM_AddEvent( EV_NOFIRE_UNDERWATER ); // event for underwater 'click' for nofire
3107 pm->ps->weaponTime = 500;
3108 return;
3109 }
3110 }
3111
3112 // start the animation even if out of ammo
3113 switch ( pm->ps->weapon ) {
3114 default:
3115 if ( !weaponstateFiring ) {
3116 // delay so the weapon can get up into position before firing (and showing the flash)
3117 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime;
3118 } else {
3119 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qtrue );
3120 }
3121 break;
3122 // machineguns should continue the anim, rather than start each fire
3123 case WP_MP40:
3124 case WP_THOMPSON:
3125 case WP_STEN:
3126 case WP_VENOM:
3127 case WP_FG42:
3128 case WP_FG42SCOPE:
3129 if ( !weaponstateFiring ) {
3130 if ( pm->ps->aiChar && pm->ps->weapon == WP_VENOM ) {
3131 // AI get fast spin-up
3132 pm->ps->weaponDelay = 150;
3133 } else {
3134 // delay so the weapon can get up into position before firing (and showing the flash)
3135 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime;
3136 }
3137 } else {
3138 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qtrue, qtrue );
3139 }
3140 break;
3141 case WP_PANZERFAUST:
3142 case WP_SILENCER:
3143 case WP_LUGER:
3144 case WP_COLT:
3145 case WP_AKIMBO: //----(SA) added
3146 case WP_SNIPERRIFLE:
3147 case WP_SNOOPERSCOPE:
3148 case WP_MAUSER:
3149 case WP_GARAND:
3150 if ( !weaponstateFiring ) {
3151 // NERVE's panzerfaust spinup
3152 // if (pm->ps->weapon == WP_PANZERFAUST)
3153 // PM_AddEvent( EV_SPINUP );
3154 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime;
3155 } else {
3156 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qtrue );
3157 }
3158 break;
3159 // melee
3160 case WP_KNIFE:
3161 if ( !delayedFire ) {
3162 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qfalse );
3163 }
3164 break;
3165 case WP_GAUNTLET:
3166 if ( !delayedFire ) {
3167 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qfalse );
3168 }
3169 break;
3170 // throw
3171 case WP_DYNAMITE:
3172 case WP_GRENADE_LAUNCHER:
3173 case WP_GRENADE_PINEAPPLE:
3174 if ( !delayedFire ) {
3175 if ( pm->ps->aiChar ) {
3176 // ai characters go into their regular animation setup
3177 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qtrue, qtrue );
3178 } else {
3179 // the player pulls the fuse and holds the hot potato
3180 if ( PM_WeaponAmmoAvailable( pm->ps->weapon ) ) {
3181 if ( pm->ps->weapon == WP_DYNAMITE ) {
3182 pm->ps->grenadeTimeLeft = 50;
3183 } else {
3184 // start at four seconds and count down
3185 pm->ps->grenadeTimeLeft = 4000;
3186 }
3187 PM_StartWeaponAnim( WEAP_ATTACK1 );
3188 }
3189 }
3190
3191 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime;
3192
3193 }
3194 break;
3195 }
3196
3197 pm->ps->weaponstate = WEAPON_FIRING;
3198
3199 // check for out of ammo
3200 ammoNeeded = ammoTable[pm->ps->weapon].uses;
3201
3202 if ( pm->ps->weapon ) {
3203 int ammoAvailable;
3204 qboolean reloadingW, playswitchsound = qtrue;
3205
3206 ammoAvailable = PM_WeaponAmmoAvailable( pm->ps->weapon );
3207
3208 if ( ammoNeeded > ammoAvailable ) {
3209
3210 // you have ammo for this, just not in the clip
3211 reloadingW = (qboolean)( ammoNeeded <= pm->ps->ammo[ BG_FindAmmoForWeapon( pm->ps->weapon )] );
3212
3213 if ( pm->ps->eFlags & EF_MELEE_ACTIVE ) {
3214 // not going to be allowed to reload if holding a chair
3215 reloadingW = qfalse;
3216 }
3217
3218 if ( pm->ps->weapon == WP_SNOOPERSCOPE ) {
3219 reloadingW = qfalse;
3220 }
3221
3222 switch ( pm->ps->weapon ) {
3223 // Ridah, only play if using a triggered weapon
3224 case WP_GAUNTLET:
3225 case WP_MONSTER_ATTACK1:
3226 case WP_DYNAMITE:
3227 case WP_GRENADE_LAUNCHER:
3228 case WP_GRENADE_PINEAPPLE:
3229 playswitchsound = qfalse;
3230 break;
3231 // some weapons not allowed to reload. must switch back to primary first
3232 case WP_SNOOPERSCOPE:
3233 case WP_SNIPERRIFLE:
3234 case WP_FG42SCOPE:
3235 reloadingW = qfalse;
3236 break;
3237 }
3238
3239 if ( playswitchsound ) {
3240 if ( reloadingW ) {
3241 PM_AddEvent( EV_EMPTYCLIP );
3242 } else {
3243 PM_AddEvent( EV_NOAMMO );
3244 }
3245 }
3246
3247 if ( reloadingW ) {
3248 PM_ContinueWeaponAnim( WEAP_RELOAD1 ); //----(SA)
3249 } else {
3250 PM_ContinueWeaponAnim( WEAP_IDLE1 );
3251 pm->ps->weaponTime += 500;
3252 }
3253
3254 return;
3255 }
3256 }
3257
3258 if ( pm->ps->weaponDelay > 0 ) {
3259 // if it hits here, the 'fire' has just been hit and the weapon dictated a delay.
3260 // animations have been started, weaponstate has been set, but no weapon events yet. (except possibly EV_NOAMMO)
3261 // checks for delayed weapons that have already been fired are return'ed above.
3262 return;
3263 }
3264
3265
3266 // take an ammo away if not infinite
3267 if ( PM_WeaponAmmoAvailable( pm->ps->weapon ) != -1 ) {
3268 // Rafael - check for being mounted on mg42
3269 if ( !( pm->ps->persistant[PERS_HWEAPON_USE] ) ) {
3270 PM_WeaponUseAmmo( pm->ps->weapon, ammoNeeded );
3271 }
3272 }
3273
3274
3275 // fire weapon
3276
3277 // add weapon heat
3278 if ( ammoTable[pm->ps->weapon].maxHeat ) {
3279 pm->ps->weapHeat[pm->ps->weapon] += ammoTable[pm->ps->weapon].nextShotTime;
3280 }
3281
3282 // first person weapon animations
3283
3284 // if this was the last round in the clip, play the 'lastshot' animation
3285 // this animation has the weapon in a "ready to reload" state
3286 if ( pm->ps->weapon == WP_AKIMBO ) {
3287 if ( akimboFire ) {
3288 weapattackanim = WEAP_ATTACK1; // attack1 is right hand
3289 } else {
3290 weapattackanim = WEAP_ATTACK2; // attack2 is left hand
3291 }
31233292 } else {
3124 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qtrue );
3125 }
3126 break;
3127 // machineguns should continue the anim, rather than start each fire
3128 case WP_MP40:
3129 case WP_THOMPSON:
3130 case WP_STEN:
3131 case WP_VENOM:
3132 case WP_FG42:
3133 case WP_FG42SCOPE:
3134 if ( !weaponstateFiring ) {
3135 if ( pm->ps->aiChar && pm->ps->weapon == WP_VENOM ) {
3136 // AI get fast spin-up
3137 pm->ps->weaponDelay = 150;
3293 if ( PM_WeaponClipEmpty( pm->ps->weapon ) ) {
3294 weapattackanim = WEAP_ATTACK_LASTSHOT;
31383295 } else {
3139 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime; // delay so the weapon can get up into position before firing (and showing the flash)
3296 weapattackanim = WEAP_ATTACK1;
3297 }
3298 }
3299
3300 switch ( pm->ps->weapon ) {
3301 case WP_MAUSER:
3302 case WP_GRENADE_LAUNCHER:
3303 case WP_GRENADE_PINEAPPLE:
3304 case WP_DYNAMITE:
3305 PM_StartWeaponAnim( weapattackanim );
3306 break;
3307 case WP_VENOM:
3308 case WP_MP40:
3309 case WP_THOMPSON:
3310 case WP_STEN:
3311 PM_ContinueWeaponAnim( weapattackanim );
3312 break;
3313
3314 default:
3315 // RF, testing
3316 // PM_ContinueWeaponAnim(weapattackanim);
3317 PM_StartWeaponAnim( weapattackanim );
3318 break;
3319 }
3320
3321
3322
3323 if ( pm->ps->weapon == WP_AKIMBO ) {
3324 if ( pm->ps->weapon == WP_AKIMBO && !akimboFire ) {
3325 PM_AddEvent( EV_FIRE_WEAPONB ); // really firing colt
3326 } else {
3327 PM_AddEvent( EV_FIRE_WEAPON );
31403328 }
31413329 } else {
3142 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qtrue, qtrue );
3143 }
3144 break;
3145 case WP_PANZERFAUST:
3146 case WP_SILENCER:
3147 case WP_LUGER:
3148 case WP_COLT:
3149 case WP_AKIMBO: //----(SA) added
3150 case WP_SNIPERRIFLE:
3151 case WP_SNOOPERSCOPE:
3152 case WP_MAUSER:
3153 case WP_GARAND:
3154 if ( !weaponstateFiring ) {
3155 // NERVE's panzerfaust spinup
3156 // if (pm->ps->weapon == WP_PANZERFAUST)
3157 // PM_AddEvent( EV_SPINUP );
3158 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime;
3159 } else {
3160 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qtrue );
3161 }
3162 break;
3163 // melee
3164 case WP_KNIFE:
3165 if ( !delayedFire ) {
3166 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qfalse );
3167 }
3168 break;
3169 case WP_GAUNTLET:
3170 if ( !delayedFire ) {
3171 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qfalse, qfalse );
3172 }
3173 break;
3174 // throw
3175 case WP_DYNAMITE:
3176 case WP_GRENADE_LAUNCHER:
3177 case WP_GRENADE_PINEAPPLE:
3178 if ( !delayedFire ) {
3179 if ( pm->ps->aiChar ) { // ai characters go into their regular animation setup
3180 BG_AnimScriptEvent( pm->ps, ANIM_ET_FIREWEAPON, qtrue, qtrue );
3181 } else { // the player pulls the fuse and holds the hot potato
3182 if ( PM_WeaponAmmoAvailable( pm->ps->weapon ) ) {
3183 if ( pm->ps->weapon == WP_DYNAMITE ) {
3184 pm->ps->grenadeTimeLeft = 50;
3185 } else {
3186 pm->ps->grenadeTimeLeft = 4000; // start at four seconds and count down
3187
3188 }
3189 PM_StartWeaponAnim( WEAP_ATTACK1 );
3190 }
3191 }
3192
3193 pm->ps->weaponDelay = ammoTable[pm->ps->weapon].fireDelayTime;
3194
3195 }
3196 break;
3197 }
3198
3199 pm->ps->weaponstate = WEAPON_FIRING;
3200
3201
3202
3203 // check for out of ammo
3204
3205 ammoNeeded = ammoTable[pm->ps->weapon].uses;
3206
3207 if ( pm->ps->weapon ) {
3208 int ammoAvailable;
3209 qboolean reloadingW, playswitchsound = qtrue;
3210
3211 ammoAvailable = PM_WeaponAmmoAvailable( pm->ps->weapon );
3212
3213 if ( ammoNeeded > ammoAvailable ) {
3214
3215 reloadingW = (qboolean)( ammoNeeded <= pm->ps->ammo[ BG_FindAmmoForWeapon( pm->ps->weapon )] ); // you have ammo for this, just not in the clip
3216
3217 if ( pm->ps->eFlags & EF_MELEE_ACTIVE ) { // not going to be allowed to reload if holding a chair
3218 reloadingW = qfalse;
3219 }
3220
3221 if ( pm->ps->weapon == WP_SNOOPERSCOPE ) {
3222 reloadingW = qfalse;
3223 }
3224
3225 switch ( pm->ps->weapon ) {
3226 // Ridah, only play if using a triggered weapon
3227 case WP_GAUNTLET:
3228 case WP_MONSTER_ATTACK1:
3229 case WP_DYNAMITE:
3230 case WP_GRENADE_LAUNCHER:
3231 case WP_GRENADE_PINEAPPLE:
3232 playswitchsound = qfalse;
3233 break;
3234
3235 // some weapons not allowed to reload. must switch back to primary first
3236 case WP_SNOOPERSCOPE:
3237 case WP_SNIPERRIFLE:
3238 case WP_FG42SCOPE:
3239 reloadingW = qfalse;
3240 break;
3241 }
3242
3243 if ( playswitchsound ) {
3244 if ( reloadingW ) {
3245 PM_AddEvent( EV_EMPTYCLIP );
3246 } else {
3247 PM_AddEvent( EV_NOAMMO );
3248 }
3249 }
3250
3251 if ( reloadingW ) {
3252 PM_ContinueWeaponAnim( WEAP_RELOAD1 ); //----(SA)
3330 if ( PM_WeaponClipEmpty( pm->ps->weapon ) ) {
3331 PM_AddEvent( EV_FIRE_WEAPON_LASTSHOT );
32533332 } else {
3254 PM_ContinueWeaponAnim( WEAP_IDLE1 );
3255 pm->ps->weaponTime += 500;
3256 }
3257
3258 return;
3259 }
3260 }
3261
3262 if ( pm->ps->weaponDelay > 0 ) {
3263 // if it hits here, the 'fire' has just been hit and the weapon dictated a delay.
3264 // animations have been started, weaponstate has been set, but no weapon events yet. (except possibly EV_NOAMMO)
3265 // checks for delayed weapons that have already been fired are return'ed above.
3266 return;
3267 }
3268
3269
3270 // take an ammo away if not infinite
3271 if ( PM_WeaponAmmoAvailable( pm->ps->weapon ) != -1 ) {
3272 // Rafael - check for being mounted on mg42
3273 if ( !( pm->ps->persistant[PERS_HWEAPON_USE] ) ) {
3274 PM_WeaponUseAmmo( pm->ps->weapon, ammoNeeded );
3275 }
3276 }
3277
3278
3279 // fire weapon
3280
3281 // add weapon heat
3282 if ( ammoTable[pm->ps->weapon].maxHeat ) {
3283 pm->ps->weapHeat[pm->ps->weapon] += ammoTable[pm->ps->weapon].nextShotTime;
3284 }
3285
3286 // first person weapon animations
3287
3288 // if this was the last round in the clip, play the 'lastshot' animation
3289 // this animation has the weapon in a "ready to reload" state
3290 if ( pm->ps->weapon == WP_AKIMBO ) {
3291 if ( akimboFire ) {
3292 weapattackanim = WEAP_ATTACK1; // attack1 is right hand
3293 } else {
3294 weapattackanim = WEAP_ATTACK2; // attack2 is left hand
3295 }
3296 } else {
3297 if ( PM_WeaponClipEmpty( pm->ps->weapon ) ) {
3298 weapattackanim = WEAP_ATTACK_LASTSHOT;
3299 } else {
3300 weapattackanim = WEAP_ATTACK1;
3301 }
3302 }
3303
3304 switch ( pm->ps->weapon ) {
3305 case WP_MAUSER:
3306 case WP_GRENADE_LAUNCHER:
3307 case WP_GRENADE_PINEAPPLE:
3308 case WP_DYNAMITE:
3309 PM_StartWeaponAnim( weapattackanim );
3310 break;
3311
3312 case WP_VENOM:
3313 case WP_MP40:
3314 case WP_THOMPSON:
3315 case WP_STEN:
3316 PM_ContinueWeaponAnim( weapattackanim );
3317 break;
3318
3319 default:
3320 // RF, testing
3321 // PM_ContinueWeaponAnim(weapattackanim);
3322 PM_StartWeaponAnim( weapattackanim );
3323 break;
3324 }
3325
3326
3327
3328 if ( pm->ps->weapon == WP_AKIMBO ) {
3329 if ( pm->ps->weapon == WP_AKIMBO && !akimboFire ) {
3330 PM_AddEvent( EV_FIRE_WEAPONB ); // really firing colt
3331 } else {
3332 PM_AddEvent( EV_FIRE_WEAPON );
3333 }
3334 } else {
3335 if ( PM_WeaponClipEmpty( pm->ps->weapon ) ) {
3336 PM_AddEvent( EV_FIRE_WEAPON_LASTSHOT );
3337 } else {
3338 PM_AddEvent( EV_FIRE_WEAPON );
3339 }
3340 }
3341
3342
3333 PM_AddEvent( EV_FIRE_WEAPON );
3334 }
3335 }
33433336 // RF
3344 pm->ps->releasedFire = qfalse;
3345 pm->ps->lastFireTime = pm->cmd.serverTime;
3346
3347
3348 aimSpreadScaleAdd = 0;
3349
3350 switch ( pm->ps->weapon ) {
3351 case WP_KNIFE:
3352 case WP_DYNAMITE:
3353 case WP_GRENADE_LAUNCHER:
3354 case WP_GRENADE_PINEAPPLE:
3355 case WP_FLAMETHROWER:
3356 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3357 break;
3358
3359 case WP_PANZERFAUST:
3360 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3361 aimSpreadScaleAdd = 30;
3362 break;
3363
3364 case WP_LUGER:
3365 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3366 aimSpreadScaleAdd = 35;
3367 break;
3368
3369 case WP_COLT:
3370 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3371 aimSpreadScaleAdd = 20;
3372 break;
3373
3337 pm->ps->releasedFire = qfalse;
3338 pm->ps->lastFireTime = pm->cmd.serverTime;
3339
3340
3341 aimSpreadScaleAdd = 0;
3342
3343 switch ( pm->ps->weapon ) {
3344 case WP_KNIFE:
3345 case WP_DYNAMITE:
3346 case WP_GRENADE_LAUNCHER:
3347 case WP_GRENADE_PINEAPPLE:
3348 case WP_FLAMETHROWER:
3349 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3350 break;
3351 case WP_PANZERFAUST:
3352 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3353 aimSpreadScaleAdd = 30;
3354 break;
3355 case WP_LUGER:
3356 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3357 aimSpreadScaleAdd = 35;
3358 break;
3359 case WP_COLT:
3360 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3361 aimSpreadScaleAdd = 20;
3362 break;
33743363 //----(SA) added
3375 case WP_AKIMBO:
3376 // if you're firing an akimbo colt, and your other gun is dry,
3377 // nextshot needs to take 2x time
3378
3379 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3380
3381 // (SA) (added check for last shot in both guns so there's no delay for the last shot)
3382 if ( !pm->ps->ammoclip[WP_AKIMBO] || !pm->ps->ammoclip[WP_COLT] ) {
3383 if ( ( !pm->ps->ammoclip[WP_AKIMBO] && !akimboFire ) || ( !pm->ps->ammoclip[WP_COLT] && akimboFire ) ) {
3384 addTime = 2 * ammoTable[pm->ps->weapon].nextShotTime;
3385 }
3386 }
3387
3388 aimSpreadScaleAdd = 20;
3389 break;
3364 case WP_AKIMBO:
3365 // if you're firing an akimbo colt, and your other gun is dry,
3366 // nextshot needs to take 2x time
3367 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3368
3369 // (SA) (added check for last shot in both guns so there's no delay for the last shot)
3370 if ( !pm->ps->ammoclip[WP_AKIMBO] || !pm->ps->ammoclip[WP_COLT] ) {
3371 if ( ( !pm->ps->ammoclip[WP_AKIMBO] && !akimboFire ) || ( !pm->ps->ammoclip[WP_COLT] && akimboFire ) ) {
3372 addTime = 2 * ammoTable[pm->ps->weapon].nextShotTime;
3373 }
3374 }
3375
3376 aimSpreadScaleAdd = 20;
3377 break;
33903378 //----(SA) end
3391
3392 case WP_MAUSER:
3393 case WP_GARAND:
3394 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3395 aimSpreadScaleAdd = 50;
3396 break;
3397
3398 case WP_SNIPERRIFLE: // (SA) not so much added per shot. these weapons mostly uses player movement to get out of whack
3399 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3379 case WP_MAUSER:
3380 case WP_GARAND:
3381 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3382 aimSpreadScaleAdd = 50;
3383 break;
3384 case WP_SNIPERRIFLE:
3385 // (SA) not so much added per shot. these weapons mostly uses player movement to get out of whack
3386 addTime = ammoTable[pm->ps->weapon].nextShotTime;
34003387 // JPW NERVE crippling the rifle a bit in multiplayer; it's way too strong so make it go completely out every time you fire
34013388 #ifdef CGAMEDLL
3402 if ( cg_gameType.integer != GT_SINGLE_PLAYER ) {
3389 if ( cg_gameType.integer != GT_SINGLE_PLAYER ) {
34033390 #endif
34043391 #ifdef GAMEDLL
3405 if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
3392 if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
34063393 #endif
34073394 // addTime *= 2; // pulled this and reduced rifle damage
3408 aimSpreadScaleAdd = 100;
3409 } else {
3395 aimSpreadScaleAdd = 100;
3396 } else {
34103397 // jpw
3411 aimSpreadScaleAdd = 20;
3412 }
3413 break;
3414 case WP_SNOOPERSCOPE:
3398 aimSpreadScaleAdd = 20;
3399 }
3400 break;
3401 case WP_SNOOPERSCOPE:
34153402 // JPW NERVE crippling the rifle a bit in multiplayer; it's way too strong so make it go completely out every time you fire
34163403 // snooper doesn't do one-shot body kills, so give it a little less bounce
3417 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3404 addTime = ammoTable[pm->ps->weapon].nextShotTime;
34183405 #ifdef CGAMEDLL
3419 if ( cg_gameType.integer != GT_SINGLE_PLAYER ) {
3406 if ( cg_gameType.integer != GT_SINGLE_PLAYER ) {
34203407 #endif
34213408 #ifdef GAMEDLL
3422 if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
3409 if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
34233410 #endif
3424 aimSpreadScaleAdd = 50;
3411 aimSpreadScaleAdd = 50;
34253412 // addTime *= 2;
3426 } else {
3413 } else {
34273414 // jpw
3428 aimSpreadScaleAdd = 10;
3429 }
3430 break;
3431
3432 case WP_FG42SCOPE:
3433 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3434 aimSpreadScaleAdd = 10;
3435 break;
3436
3437 case WP_FG42:
3438 case WP_MP40:
3439 case WP_THOMPSON:
3440 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3441 aimSpreadScaleAdd = 15 + rand() % 10; // (SA) new values for DM
3442 break;
3443
3444 case WP_STEN:
3445 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3446 aimSpreadScaleAdd = 15 + rand() % 10; // (SA) new values for DM
3447 break;
3448
3449 case WP_SILENCER:
3450 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3451 aimSpreadScaleAdd = 35;
3452 break;
3453
3454 case WP_VENOM:
3455 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3456 aimSpreadScaleAdd = 10;
3457 break;
3458
3415 aimSpreadScaleAdd = 10;
3416 }
3417 break;
3418 case WP_FG42SCOPE:
3419 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3420 aimSpreadScaleAdd = 10;
3421 break;
3422 case WP_FG42:
3423 case WP_MP40:
3424 case WP_THOMPSON:
3425 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3426 aimSpreadScaleAdd = 15 + rand() % 10; // (SA) new values for DM
3427 break;
3428 case WP_STEN:
3429 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3430 aimSpreadScaleAdd = 15 + rand() % 10; // (SA) new values for DM
3431 break;
3432 case WP_SILENCER:
3433 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3434 aimSpreadScaleAdd = 35;
3435 break;
3436 case WP_VENOM:
3437 addTime = ammoTable[pm->ps->weapon].nextShotTime;
3438 aimSpreadScaleAdd = 10;
3439 break;
34593440 // JPW NERVE
3460 case WP_CLASS_SPECIAL:
3461 // can't reliably get cvars for restart time in here, so set it small and check it in fireweapon routine
3462 addTime = 50;
3463 break;
3441 case WP_CLASS_SPECIAL:
3442 // can't reliably get cvars for restart time in here, so set it small and check it in fireweapon routine
3443 addTime = 50;
3444 break;
34643445 // jpw
3465 case WP_MONSTER_ATTACK1:
3466 addTime = 1000;
3467 break;
3468
3469 default:
3470 case WP_GAUNTLET:
3471 switch ( pm->ps->aiChar )
3472 {
3473 case AICHAR_LOPER: // delay 'til next attack
3474 addTime = 1000;
3475 break;
3476 default:
3477 addTime = 250;
3478 break;
3479 }
3480 break;
3481 }
3482
3483
3484 // check for overheat
3485
3486 // the weapon can overheat, and it's hot
3487 if ( ( pm->ps->aiChar != AICHAR_PROTOSOLDIER ) &&
3488 ( pm->ps->aiChar != AICHAR_SUPERSOLDIER ) &&
3489 ( ammoTable[pm->ps->weapon].maxHeat && pm->ps->weapHeat[pm->ps->weapon] ) ) {
3490 // it is overheating
3491 if ( pm->ps->weapHeat[pm->ps->weapon] >= ammoTable[pm->ps->weapon].maxHeat ) {
3492 pm->ps->weapHeat[pm->ps->weapon] = ammoTable[pm->ps->weapon].maxHeat; // cap heat to max
3493 PM_AddEvent( EV_WEAP_OVERHEAT );
3446 case WP_MONSTER_ATTACK1:
3447 addTime = 1000;
3448 break;
3449 default:
3450 case WP_GAUNTLET:
3451 switch ( pm->ps->aiChar ) {
3452 case AICHAR_LOPER: // delay 'til next attack
3453 addTime = 1000;
3454 break;
3455 default:
3456 addTime = 250;
3457 break;
3458 }
3459 break;
3460 }
3461
3462 // check for overheat
3463
3464 // the weapon can overheat, and it's hot
3465 if ( ( pm->ps->aiChar != AICHAR_PROTOSOLDIER ) &&
3466 ( pm->ps->aiChar != AICHAR_SUPERSOLDIER ) &&
3467 ( ammoTable[pm->ps->weapon].maxHeat && pm->ps->weapHeat[pm->ps->weapon] ) ) {
3468 // it is overheating
3469 if ( pm->ps->weapHeat[pm->ps->weapon] >= ammoTable[pm->ps->weapon].maxHeat ) {
3470 pm->ps->weapHeat[pm->ps->weapon] = ammoTable[pm->ps->weapon].maxHeat; // cap heat to max
3471 PM_AddEvent( EV_WEAP_OVERHEAT );
34943472 // PM_StartWeaponAnim(WEAP_IDLE1); // removed. client handles anim in overheat event
3495 addTime = 2000; // force "heat recovery minimum" to 2 sec right now
3496 }
3497 }
3498
3499 if ( pm->ps->powerups[PW_HASTE] ) {
3500 addTime /= 1.3;
3501 }
3502
3503 // add the recoil amount to the aimSpreadScale
3473 addTime = 2000; // force "heat recovery minimum" to 2 sec right now
3474 }
3475 }
3476
3477 if ( pm->ps->powerups[PW_HASTE] ) {
3478 addTime /= 1.3;
3479 }
3480
3481 // add the recoil amount to the aimSpreadScale
35043482 // pm->ps->aimSpreadScale += 3.0*aimSpreadScaleAdd;
3505 // if (pm->ps->aimSpreadScale > 255) pm->ps->aimSpreadScale = 255;
3506 pm->ps->aimSpreadScaleFloat += 3.0 * aimSpreadScaleAdd;
3507 if ( pm->ps->aimSpreadScaleFloat > 255 ) {
3508 pm->ps->aimSpreadScaleFloat = 255;
3509 }
3510 pm->ps->aimSpreadScale = (int)( pm->ps->aimSpreadScaleFloat );
3511
3512 pm->ps->weaponTime += addTime;
3513
3514 PM_SwitchIfEmpty();
3483 // if (pm->ps->aimSpreadScale > 255)
3484 // pm->ps->aimSpreadScale = 255;
3485 pm->ps->aimSpreadScaleFloat += 3.0 * aimSpreadScaleAdd;
3486 if ( pm->ps->aimSpreadScaleFloat > 255 ) {
3487 pm->ps->aimSpreadScaleFloat = 255;
3488 }
3489 pm->ps->aimSpreadScale = (int)( pm->ps->aimSpreadScaleFloat );
3490
3491 pm->ps->weaponTime += addTime;
3492
3493 PM_SwitchIfEmpty();
35153494 }
35163495
35173496
6868 extern void Parse2DMatrix ( char * * buf_p , int y , int x , float * m ) ;
6969 extern void Parse1DMatrix ( char * * buf_p , int x , float * m ) ;
7070 extern void SkipRestOfLine ( char * * data ) ;
71 extern void SkipBracedSection ( char * * program ) ;
71 extern qboolean SkipBracedSection ( char * * program , int depth ) ;
7272 extern void COM_MatchToken ( char * * buf_p , char * match ) ;
7373 extern char * COM_ParseExt ( char * * data_p , qboolean allowLineBreaks ) ;
7474 extern int COM_Compress ( char * data_p ) ;
147147
148148 // noset vars
149149 { NULL, "gamename", GAMEVERSION, CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
150 { NULL, "gamedate", __DATE__, CVAR_ROM, 0, qfalse },
150 { NULL, "gamedate", PRODUCT_DATE, CVAR_ROM, 0, qfalse },
151151 { &g_restarted, "g_restarted", "0", CVAR_ROM, 0, qfalse },
152152
153153 // latched vars
11761176 if ( trap_Cvar_VariableIntegerValue( "g_gametype" ) != GT_SINGLE_PLAYER ) {
11771177 G_Printf( "------- Game Initialization -------\n" );
11781178 G_Printf( "gamename: %s\n", GAMEVERSION );
1179 G_Printf( "gamedate: %s\n", __DATE__ );
1179 G_Printf( "gamedate: %s\n", PRODUCT_DATE );
11801180 }
11811181
11821182 srand( randomSeed );
363363 break;
364364 }
365365 }
366 // didnt work, so set the position back
366 // didn't work, so set the position back
367367 VectorCopy( org, check->s.pos.trBase );
368368 if ( check->client ) {
369369 VectorCopy( org, check->client->ps.origin );
178178
179179 attacker->client->pers.teamState.carrierdefense++;
180180 team = attacker->client->sess.sessionTeam;
181 PrintMsg( NULL, "%s" S_COLOR_WHITE " defends %s's flag carrier against an agressive enemy\n",
181 PrintMsg( NULL, "%s" S_COLOR_WHITE " defends %s's flag carrier against an aggressive enemy\n",
182182 attacker->client->pers.netname, TeamName( team ) );
183183 return;
184184 }
286286 }
287287
288288 if ( !num_choices ) {
289 G_Printf( "GetNextTrack didnt find a track\n" );
289 G_Printf( "GetNextTrack didn't find a track\n" );
290290 return;
291291 }
292292
3434 void GLimp_EndFrame( void ) {
3535 }
3636
37 int GLimp_Init( void )
38 {
37 void GLimp_Init( void ) {
3938 }
4039
4140 void GLimp_Shutdown( void ) {
4443 void GLimp_EnableLogging( qboolean enable ) {
4544 }
4645
47 void GLimp_LogComment( char *comment ) {
46 void GLimp_LogComment( char *comment ) {
4847 }
4948
50 qboolean QGL_Init( const char *dllname ) {
49 qboolean QGL_Init( const char *dllname ) {
5150 return qtrue;
5251 }
5352
5453 void QGL_Shutdown( void ) {
5554 }
55
56 void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] ) {
57 }
58
59 void GLimp_Minimize( void ) {
60 }
10551055 }
10561056
10571057 //
1058 // find the point distances to the seperating plane
1058 // find the point distances to the separating plane
10591059 // and the offset for the size of the box
10601060 //
10611061 node = cm.nodes + num;
8181 cvar_t *com_version;
8282 cvar_t *com_blood;
8383 cvar_t *com_buildScript; // for automated data building scripts
84 #ifdef CINEMATICS_INTRO
8485 cvar_t *com_introPlayed;
86 #endif
8587 cvar_t *cl_paused;
8688 cvar_t *sv_paused;
8789 cvar_t *cl_packetdelay;
128130 qboolean com_errorEntered = qfalse;
129131 qboolean com_fullyInitialized = qfalse;
130132 qboolean com_gameRestarting = qfalse;
133 qboolean com_gameClientRestarting = qfalse;
131134
132135 char com_errorMessage[MAXPRINTMSG];
133136
275278 static int lastErrorTime;
276279 static int errorCount;
277280 int currentTime;
281 qboolean restartClient;
278282
279283 if(com_errorEntered)
280284 Sys_Error("recursive error after: %s", com_errorMessage);
312316 Cvar_Set( "com_errorMessage", com_errorMessage );
313317 }
314318
319 restartClient = com_gameClientRestarting && !( com_cl_running && com_cl_running->integer );
320
321 com_gameRestarting = qfalse;
322 com_gameClientRestarting = qfalse;
323
315324 if (code == ERR_DISCONNECT || code == ERR_SERVERDISCONNECT) {
316325 VM_Forced_Unload_Start();
317326 SV_Shutdown( "Server disconnected" );
327 if ( restartClient ) {
328 CL_Init();
329 }
318330 CL_Disconnect( qtrue );
319331 CL_FlushMemory();
320332 VM_Forced_Unload_Done();
325337 } else if ( code == ERR_ENDGAME ) { //----(SA) added
326338 VM_Forced_Unload_Start();
327339 SV_Shutdown( "endgame" );
340 if ( restartClient ) {
341 CL_Init();
342 }
328343 if ( com_cl_running && com_cl_running->integer ) {
329344 CL_Disconnect( qtrue );
330345 CL_FlushMemory();
342357 Com_Printf( "********************\nERROR: %s\n********************\n", com_errorMessage );
343358 VM_Forced_Unload_Start();
344359 SV_Shutdown (va("Server crashed: %s", com_errorMessage));
360 if ( restartClient ) {
361 CL_Init();
362 }
345363 CL_Disconnect( qtrue );
346364 CL_FlushMemory();
347365 VM_Forced_Unload_Done();
351369 } else if ( code == ERR_NEED_CD ) {
352370 VM_Forced_Unload_Start();
353371 SV_Shutdown( "Server didn't have CD" );
372 if ( restartClient ) {
373 CL_Init();
374 }
354375 if ( com_cl_running && com_cl_running->integer ) {
355376 CL_Disconnect( qtrue );
356377 CL_FlushMemory();
439460 com_numConsoleLines = 1;
440461
441462 while ( *commandLine ) {
442 // look for a + seperating character
463 // look for a + separating character
443464 // if commandLine came from a file, we might have real line seperators
444465 if ( *commandLine == '+' || *commandLine == '\n' ) {
445466 if ( com_numConsoleLines == MAX_CONSOLE_LINES ) {
19091930
19101931 if(!Com_SafeMode())
19111932 {
1912 // skip the q3config.cfg and autoexec.cfg if "safe" is on the command line
1933 // skip the wolfconfig.cfg and autoexec.cfg if "safe" is on the command line
19131934 Cbuf_ExecuteText(EXEC_NOW, "exec " Q3CONFIG_CFG "\n");
19141935 Cbuf_Execute();
19151936 Cbuf_ExecuteText(EXEC_NOW, "exec autoexec.cfg\n");
19301951 // make sure no recursion can be triggered
19311952 if(!com_gameRestarting && com_fullyInitialized)
19321953 {
1933 int clWasRunning;
1934
19351954 com_gameRestarting = qtrue;
1936 clWasRunning = com_cl_running->integer;
1937
1955 com_gameClientRestarting = com_cl_running->integer;
1956
19381957 // Kill server if we have one
19391958 if(com_sv_running->integer)
19401959 SV_Shutdown("Game directory changed");
19411960
1942 if(clWasRunning)
1961 if(com_gameClientRestarting)
19431962 {
19441963 if(disconnect)
19451964 CL_Disconnect(qfalse);
19611980 NET_Restart_f();
19621981 }
19631982
1964 if(clWasRunning)
1983 if(com_gameClientRestarting)
19651984 {
19661985 CL_Init();
19671986 CL_StartHunkUsers(qfalse);
19681987 }
19691988
19701989 com_gameRestarting = qfalse;
1990 com_gameClientRestarting = qfalse;
19711991 }
19721992 }
19731993
21032123
21042124 FS_Printf( f, "\n// generated by RTCW, do not modify\r\n" );
21052125 FS_Printf( f, "// Do not give this file to ANYONE.\r\n" );
2106 #ifdef MACOS_X // TTimo
2126 #ifdef __APPLE__ // TTimo
21072127 FS_Printf( f, "// Aspyr will NOT ask you to send this file to them.\r\n" );
21082128 #else
21092129 FS_Printf( f, "// id Software and Activision will NOT ask you to send this file to them.\r\n" );
22512271 char *s;
22522272 int qport;
22532273
2254 Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, __DATE__ );
2274 Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, PRODUCT_DATE );
22552275
22562276 if ( setjmp( abortframe ) ) {
22572277 Sys_Error( "Error during initialization" );
23672387 com_busyWait = Cvar_Get("com_busyWait", "0", CVAR_ARCHIVE);
23682388 Cvar_Get("com_errorMessage", "", CVAR_ROM | CVAR_NORESTART);
23692389
2390 #ifdef CINEMATICS_INTRO
23702391 com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE );
2392 #endif
23712393 com_recommendedSet = Cvar_Get( "com_recommendedSet", "0", CVAR_ARCHIVE );
23722394
23732395 Cvar_Get( "savegame_loading", "0", CVAR_ROM );
23742396
2375 s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
2397 s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, PRODUCT_DATE );
23762398 com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
23772399 com_gamename = Cvar_Get("com_gamename", GAMENAME_FOR_MASTER, CVAR_SERVERINFO | CVAR_INIT);
23782400 com_protocol = Cvar_Get("com_protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO | CVAR_INIT);
23902412
23912413 Sys_Init();
23922414
2393 if( Sys_WritePIDFile( ) ) {
2394 #ifndef DEDICATED
2395 const char *message = "The last time " CLIENT_WINDOW_TITLE " ran, "
2396 "it didn't exit properly. This may be due to inappropriate video "
2397 "settings. Would you like to start with \"safe\" video settings?";
2398
2399 if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) {
2400 Cvar_Set( "com_abnormalExit", "1" );
2401 }
2402 #endif
2403 }
2415 Sys_InitPIDFile( FS_GetCurrentGameDir() );
24042416
24052417 // Pick a random port value
24062418 Com_RandomBytes( (byte*)&qport, sizeof(int) );
24362448 }
24372449
24382450 if ( !com_dedicated->integer ) {
2439 //Cbuf_AddText ("cinematic gmlogo.RoQ\n");
2451 #ifdef CINEMATICS_LOGO
2452 //Cbuf_AddText ("cinematic " CINEMATICS_LOGO "\n");
2453 #endif
2454 #ifdef CINEMATICS_INTRO
24402455 if ( !com_introPlayed->integer ) {
24412456 //Cvar_Set( com_introPlayed->name, "1" ); //----(SA) force this to get played every time (but leave cvar for override)
2442 Cbuf_AddText( "cinematic wolfintro.RoQ 3\n" );
2443 //Cvar_Set( "nextmap", "cinematic wolfintro.RoQ" );
2444 }
2457 Cbuf_AddText( "cinematic " CINEMATICS_INTRO " 3\n" );
2458 //Cvar_Set( "nextmap", "cinematic " CINEMATICS_INTRO );
2459 }
2460 #endif
24452461 }
24462462
24472463 com_fullyInitialized = qtrue;
273273 static cvar_t *fs_debug;
274274 static cvar_t *fs_homepath;
275275
276 #ifdef MACOS_X
276 #ifdef __APPLE__
277277 // Also search the .app bundle for .pk3 files
278278 static cvar_t *fs_apppath;
279279 #endif
333333
334334 // last valid game folder used
335335 char lastValidBase[MAX_OSPATH];
336 char lastValidComBaseGame[MAX_OSPATH];
337 char lastValidFsBaseGame[MAX_OSPATH];
336338 char lastValidGame[MAX_OSPATH];
337339
338340 #ifdef FS_MISSING
27492751
27502752 /*
27512753 ================
2754 FS_GetModDescription
2755 ================
2756 */
2757 void FS_GetModDescription( const char *modDir, char *description, int descriptionLen ) {
2758 fileHandle_t descHandle;
2759 char descPath[MAX_QPATH];
2760 int nDescLen;
2761 FILE *file;
2762
2763 Com_sprintf( descPath, sizeof ( descPath ), "%s/description.txt", modDir );
2764 nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
2765
2766 if ( nDescLen > 0 && descHandle ) {
2767 file = FS_FileForHandle(descHandle);
2768 Com_Memset( description, 0, descriptionLen );
2769 nDescLen = fread(description, 1, descriptionLen, file);
2770 if (nDescLen >= 0) {
2771 description[nDescLen] = '\0';
2772 }
2773 FS_FCloseFile(descHandle);
2774 } else {
2775 Q_strncpyz( description, modDir, descriptionLen );
2776 }
2777 }
2778
2779 /*
2780 ================
27522781 FS_GetModList
27532782
27542783 Returns a list of mod directory names
27612790 char **pFiles = NULL;
27622791 char **pPaks = NULL;
27632792 char *name, *path;
2764 char descPath[MAX_OSPATH];
2765 fileHandle_t descHandle;
2793 char description[MAX_OSPATH];
27662794
27672795 int dummy;
27682796 char **pFiles0 = NULL;
28462874 nLen = strlen(name) + 1;
28472875 // nLen is the length of the mod path
28482876 // we need to see if there is a description available
2849 descPath[0] = '\0';
2850 strcpy(descPath, name);
2851 strcat(descPath, "/description.txt");
2852 nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
2853 if ( nDescLen > 0 && descHandle) {
2854 FILE *file;
2855 file = FS_FileForHandle(descHandle);
2856 Com_Memset( descPath, 0, sizeof( descPath ) );
2857 nDescLen = fread(descPath, 1, 48, file);
2858 if (nDescLen >= 0) {
2859 descPath[nDescLen] = '\0';
2860 }
2861 FS_FCloseFile(descHandle);
2862 } else {
2863 strcpy(descPath, name);
2864 }
2865 nDescLen = strlen(descPath) + 1;
2877 FS_GetModDescription( name, description, sizeof( description ) );
2878 nDescLen = strlen(description) + 1;
28662879
28672880 if (nTotal + nLen + 1 + nDescLen + 1 < bufsize) {
28682881 strcpy(listbuf, name);
28692882 listbuf += nLen;
2870 strcpy(listbuf, descPath);
2883 strcpy(listbuf, description);
28712884 listbuf += nDescLen;
28722885 nTotal += nLen + nDescLen;
28732886 nMods++;
32713284 if ( !FS_FilenameCompare( pak, va( "%s/mp_pak%d",base,i ) ) ) {
32723285 break;
32733286 }
3274 if ( !FS_FilenameCompare( pak, va( "%s/sp_pak%d",base,i ) ) ) {
3287 if ( !FS_FilenameCompare( pak, va( "%s/sp_pak%d",base,i + 1) ) ) {
32753288 break;
32763289 }
32773290 // jpw
35493562 }
35503563 // fs_homepath is somewhat particular to *nix systems, only add if relevant
35513564
3552 #ifdef MACOS_X
3565 #ifdef __APPLE__
35533566 fs_apppath = Cvar_Get ("fs_apppath", Sys_DefaultAppPath(), CVAR_INIT|CVAR_PROTECTED );
35543567 // Make MacOSX also include the base path included with the .app bundle
35553568 if (fs_apppath->string[0])
42304243 }
42314244
42324245 Q_strncpyz( lastValidBase, fs_basepath->string, sizeof( lastValidBase ) );
4246 Q_strncpyz( lastValidComBaseGame, com_basegame->string, sizeof( lastValidComBaseGame ) );
4247 Q_strncpyz( lastValidFsBaseGame, fs_basegame->string, sizeof( lastValidFsBaseGame ) );
42334248 Q_strncpyz( lastValidGame, fs_gamedirvar->string, sizeof( lastValidGame ) );
42344249 }
42354250
42404255 ================
42414256 */
42424257 void FS_Restart( int checksumFeed ) {
4258 const char *lastGameDir;
42434259
42444260 // free anything we currently have loaded
42454261 FS_Shutdown( qfalse );
42664282 if ( lastValidBase[0] ) {
42674283 FS_PureServerSetLoadedPaks( "", "" );
42684284 Cvar_Set( "fs_basepath", lastValidBase );
4269 Cvar_Set("fs_game", lastValidGame);
4285 Cvar_Set( "com_basegame", lastValidComBaseGame );
4286 Cvar_Set( "fs_basegame", lastValidFsBaseGame );
4287 Cvar_Set( "fs_game", lastValidGame );
42704288 lastValidBase[0] = '\0';
4289 lastValidComBaseGame[0] = '\0';
4290 lastValidFsBaseGame[0] = '\0';
42714291 lastValidGame[0] = '\0';
42724292 FS_Restart( checksumFeed );
42734293 Com_Error( ERR_DROP, "Invalid game folder" );
42764296 Com_Error( ERR_FATAL, "Couldn't load default.cfg" );
42774297 }
42784298
4279 if ( Q_stricmp( fs_gamedirvar->string, lastValidGame ) ) {
4299 lastGameDir = ( lastValidGame[0] ) ? lastValidGame : lastValidComBaseGame;
4300
4301 if ( Q_stricmp( FS_GetCurrentGameDir(), lastGameDir ) ) {
4302 Sys_RemovePIDFile( lastGameDir );
4303 Sys_InitPIDFile( FS_GetCurrentGameDir() );
4304
42804305 // skip the wolfconfig.cfg if "safe" is on the command line
42814306 if ( !Com_SafeMode() ) {
42824307 Cbuf_AddText ("exec " Q3CONFIG_CFG "\n");
42844309 }
42854310
42864311 Q_strncpyz( lastValidBase, fs_basepath->string, sizeof( lastValidBase ) );
4312 Q_strncpyz( lastValidComBaseGame, com_basegame->string, sizeof( lastValidComBaseGame ) );
4313 Q_strncpyz( lastValidFsBaseGame, fs_basegame->string, sizeof( lastValidFsBaseGame ) );
42874314 Q_strncpyz( lastValidGame, fs_gamedirvar->string, sizeof( lastValidGame ) );
42884315
42894316 }
0 /*
1 ===========================================================================
2 Copyright (C) 2016 James Canete
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 ===========================================================================
18 */
19
20 #ifndef JSON_H
21 #define JSON_H
22
23 enum
24 {
25 JSONTYPE_STRING, // string
26 JSONTYPE_OBJECT, // object
27 JSONTYPE_ARRAY, // array
28 JSONTYPE_VALUE, // number, true, false, or null
29 JSONTYPE_ERROR // out of data
30 };
31
32 // --------------------------------------------------------------------------
33 // Array Functions
34 // --------------------------------------------------------------------------
35
36 // Get pointer to first value in array
37 // When given pointer to an array, returns pointer to the first
38 // returns NULL if array is empty or not an array.
39 const char *JSON_ArrayGetFirstValue(const char *json, const char *jsonEnd);
40
41 // Get pointer to next value in array
42 // When given pointer to a value, returns pointer to the next value
43 // returns NULL when no next value.
44 const char *JSON_ArrayGetNextValue(const char *json, const char *jsonEnd);
45
46 // Get pointers to values in an array
47 // returns 0 if not an array, array is empty, or out of data
48 // returns number of values in the array and copies into index if successful
49 unsigned int JSON_ArrayGetIndex(const char *json, const char *jsonEnd, const char **indexes, unsigned int numIndexes);
50
51 // Get pointer to indexed value from array
52 // returns NULL if not an array, no index, or out of data
53 const char *JSON_ArrayGetValue(const char *json, const char *jsonEnd, unsigned int index);
54
55 // --------------------------------------------------------------------------
56 // Object Functions
57 // --------------------------------------------------------------------------
58
59 // Get pointer to named value from object
60 // returns NULL if not an object, name not found, or out of data
61 const char *JSON_ObjectGetNamedValue(const char *json, const char *jsonEnd, const char *name);
62
63 // --------------------------------------------------------------------------
64 // Value Functions
65 // --------------------------------------------------------------------------
66
67 // Get type of value
68 // returns JSONTYPE_ERROR if out of data
69 unsigned int JSON_ValueGetType(const char *json, const char *jsonEnd);
70
71 // Get value as string
72 // returns 0 if out of data
73 // returns length and copies into string if successful, including terminating nul.
74 // string values are stripped of enclosing quotes but not escaped
75 unsigned int JSON_ValueGetString(const char *json, const char *jsonEnd, char *outString, unsigned int stringLen);
76
77 // Get value as appropriate type
78 // returns 0 if value is false, value is null, or out of data
79 // returns 1 if value is true
80 // returns value otherwise
81 double JSON_ValueGetDouble(const char *json, const char *jsonEnd);
82 float JSON_ValueGetFloat(const char *json, const char *jsonEnd);
83 int JSON_ValueGetInt(const char *json, const char *jsonEnd);
84
85 #endif
86
87 #ifdef JSON_IMPLEMENTATION
88 #include <stdio.h>
89
90 // --------------------------------------------------------------------------
91 // Internal Functions
92 // --------------------------------------------------------------------------
93
94 static const char *JSON_SkipSeparators(const char *json, const char *jsonEnd);
95 static const char *JSON_SkipString(const char *json, const char *jsonEnd);
96 static const char *JSON_SkipStruct(const char *json, const char *jsonEnd);
97 static const char *JSON_SkipValue(const char *json, const char *jsonEnd);
98 static const char *JSON_SkipValueAndSeparators(const char *json, const char *jsonEnd);
99
100 #define IS_SEPARATOR(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r' || (x) == ',' || (x) == ':')
101 #define IS_STRUCT_OPEN(x) ((x) == '{' || (x) == '[')
102 #define IS_STRUCT_CLOSE(x) ((x) == '}' || (x) == ']')
103
104 static const char *JSON_SkipSeparators(const char *json, const char *jsonEnd)
105 {
106 while (json < jsonEnd && IS_SEPARATOR(*json))
107 json++;
108
109 return json;
110 }
111
112 static const char *JSON_SkipString(const char *json, const char *jsonEnd)
113 {
114 for (json++; json < jsonEnd && *json != '"'; json++)
115 if (*json == '\\')
116 json++;
117
118 return (json + 1 > jsonEnd) ? jsonEnd : json + 1;
119 }
120
121 static const char *JSON_SkipStruct(const char *json, const char *jsonEnd)
122 {
123 json = JSON_SkipSeparators(json + 1, jsonEnd);
124 while (json < jsonEnd && !IS_STRUCT_CLOSE(*json))
125 json = JSON_SkipValueAndSeparators(json, jsonEnd);
126
127 return (json + 1 > jsonEnd) ? jsonEnd : json + 1;
128 }
129
130 static const char *JSON_SkipValue(const char *json, const char *jsonEnd)
131 {
132 if (json >= jsonEnd)
133 return jsonEnd;
134 else if (*json == '"')
135 json = JSON_SkipString(json, jsonEnd);
136 else if (IS_STRUCT_OPEN(*json))
137 json = JSON_SkipStruct(json, jsonEnd);
138 else
139 {
140 while (json < jsonEnd && !IS_SEPARATOR(*json) && !IS_STRUCT_CLOSE(*json))
141 json++;
142 }
143
144 return json;
145 }
146
147 static const char *JSON_SkipValueAndSeparators(const char *json, const char *jsonEnd)
148 {
149 json = JSON_SkipValue(json, jsonEnd);
150 return JSON_SkipSeparators(json, jsonEnd);
151 }
152
153 // returns 0 if value requires more parsing, 1 if no more data/false/null, 2 if true
154 static unsigned int JSON_NoParse(const char *json, const char *jsonEnd)
155 {
156 if (!json || json >= jsonEnd || *json == 'f' || *json == 'n')
157 return 1;
158
159 if (*json == 't')
160 return 2;
161
162 return 0;
163 }
164
165 // --------------------------------------------------------------------------
166 // Array Functions
167 // --------------------------------------------------------------------------
168
169 const char *JSON_ArrayGetFirstValue(const char *json, const char *jsonEnd)
170 {
171 if (!json || json >= jsonEnd || !IS_STRUCT_OPEN(*json))
172 return NULL;
173
174 json = JSON_SkipSeparators(json + 1, jsonEnd);
175
176 return (json >= jsonEnd || IS_STRUCT_CLOSE(*json)) ? NULL : json;
177 }
178
179 const char *JSON_ArrayGetNextValue(const char *json, const char *jsonEnd)
180 {
181 if (!json || json >= jsonEnd || IS_STRUCT_CLOSE(*json))
182 return NULL;
183
184 json = JSON_SkipValueAndSeparators(json, jsonEnd);
185
186 return (json >= jsonEnd || IS_STRUCT_CLOSE(*json)) ? NULL : json;
187 }
188
189 unsigned int JSON_ArrayGetIndex(const char *json, const char *jsonEnd, const char **indexes, unsigned int numIndexes)
190 {
191 unsigned int length = 0;
192
193 for (json = JSON_ArrayGetFirstValue(json, jsonEnd); json; json = JSON_ArrayGetNextValue(json, jsonEnd))
194 {
195 if (indexes && numIndexes)
196 {
197 *indexes++ = json;
198 numIndexes--;
199 }
200 length++;
201 }
202
203 return length;
204 }
205
206 const char *JSON_ArrayGetValue(const char *json, const char *jsonEnd, unsigned int index)
207 {
208 for (json = JSON_ArrayGetFirstValue(json, jsonEnd); json && index; json = JSON_ArrayGetNextValue(json, jsonEnd))
209 index--;
210
211 return json;
212 }
213
214 // --------------------------------------------------------------------------
215 // Object Functions
216 // --------------------------------------------------------------------------
217
218 const char *JSON_ObjectGetNamedValue(const char *json, const char *jsonEnd, const char *name)
219 {
220 unsigned int nameLen = strlen(name);
221
222 for (json = JSON_ArrayGetFirstValue(json, jsonEnd); json; json = JSON_ArrayGetNextValue(json, jsonEnd))
223 {
224 if (*json == '"')
225 {
226 const char *thisNameStart, *thisNameEnd;
227
228 thisNameStart = json + 1;
229 json = JSON_SkipString(json, jsonEnd);
230 thisNameEnd = json - 1;
231 json = JSON_SkipSeparators(json, jsonEnd);
232
233 if ((unsigned int)(thisNameEnd - thisNameStart) == nameLen)
234 if (strncmp(thisNameStart, name, nameLen) == 0)
235 return json;
236 }
237 }
238
239 return NULL;
240 }
241
242 // --------------------------------------------------------------------------
243 // Value Functions
244 // --------------------------------------------------------------------------
245
246 unsigned int JSON_ValueGetType(const char *json, const char *jsonEnd)
247 {
248 if (!json || json >= jsonEnd)
249 return JSONTYPE_ERROR;
250 else if (*json == '"')
251 return JSONTYPE_STRING;
252 else if (*json == '{')
253 return JSONTYPE_OBJECT;
254 else if (*json == '[')
255 return JSONTYPE_ARRAY;
256
257 return JSONTYPE_VALUE;
258 }
259
260 unsigned int JSON_ValueGetString(const char *json, const char *jsonEnd, char *outString, unsigned int stringLen)
261 {
262 const char *stringEnd, *stringStart;
263
264 if (!json)
265 {
266 *outString = '\0';
267 return 0;
268 }
269
270 stringStart = json;
271 stringEnd = JSON_SkipValue(stringStart, jsonEnd);
272 if (stringEnd >= jsonEnd)
273 {
274 *outString = '\0';
275 return 0;
276 }
277
278 // skip enclosing quotes if they exist
279 if (*stringStart == '"')
280 stringStart++;
281
282 if (*(stringEnd - 1) == '"')
283 stringEnd--;
284
285 stringLen--;
286 if (stringLen > stringEnd - stringStart)
287 stringLen = stringEnd - stringStart;
288
289 json = stringStart;
290 while (stringLen--)
291 *outString++ = *json++;
292 *outString = '\0';
293
294 return stringEnd - stringStart;
295 }
296
297 double JSON_ValueGetDouble(const char *json, const char *jsonEnd)
298 {
299 char cValue[256];
300 double dValue = 0.0;
301 unsigned int np = JSON_NoParse(json, jsonEnd);
302
303 if (np)
304 return (double)(np - 1);
305
306 if (!JSON_ValueGetString(json, jsonEnd, cValue, 256))
307 return 0.0;
308
309 sscanf(cValue, "%lf", &dValue);
310
311 return dValue;
312 }
313
314 float JSON_ValueGetFloat(const char *json, const char *jsonEnd)
315 {
316 char cValue[256];
317 float fValue = 0.0f;
318 unsigned int np = JSON_NoParse(json, jsonEnd);
319
320 if (np)
321 return (float)(np - 1);
322
323 if (!JSON_ValueGetString(json, jsonEnd, cValue, 256))
324 return 0.0f;
325
326 sscanf(cValue, "%f", &fValue);
327
328 return fValue;
329 }
330
331 int JSON_ValueGetInt(const char *json, const char *jsonEnd)
332 {
333 char cValue[256];
334 int iValue = 0;
335 unsigned int np = JSON_NoParse(json, jsonEnd);
336
337 if (np)
338 return np - 1;
339
340 if (!JSON_ValueGetString(json, jsonEnd, cValue, 256))
341 return 0;
342
343 sscanf(cValue, "%d", &iValue);
344
345 return iValue;
346 }
347
348 #undef IS_SEPARATOR
349 #undef IS_STRUCT_OPEN
350 #undef IS_STRUCT_CLOSE
351
352 #endif
104104 =============================================================================
105105 */
106106
107 int overflows;
108
109107 // negative bit values include signs
110108 void MSG_WriteBits( msg_t *msg, int value, int bits ) {
111109 int i;
112 // FILE* fp;
113110
114111 oldsize += bits;
115112
123120 Com_Error( ERR_DROP, "MSG_WriteBits: bad bits %i", bits );
124121 }
125122
126 // check for overflows
127 if ( bits != 32 ) {
128 if ( bits > 0 ) {
129 if ( value > ( ( 1 << bits ) - 1 ) || value < 0 ) {
130 overflows++;
131 }
132 } else {
133 int r;
134
135 r = 1 << ( bits - 1 );
136
137 if ( value > r - 1 || value < -r ) {
138 overflows++;
139 }
140 }
141 }
142123 if ( bits < 0 ) {
143124 bits = -bits;
144125 }
161142 Com_Error( ERR_DROP, "can't read %d bits", bits );
162143 }
163144 } else {
164 // fp = fopen("c:\\netchan.bin", "a");
165145 value &= ( 0xffffffff >> ( 32 - bits ) );
166146 if ( bits & 7 ) {
167147 int nbits;
174154 }
175155 if ( bits ) {
176156 for ( i = 0; i < bits; i += 8 ) {
177 // fwrite(bp, 1, 1, fp);
178157 Huff_offsetTransmit( &msgHuff.compressor, ( value & 0xff ), msg->data, &msg->bit );
179158 value = ( value >> 8 );
180159 }
181160 }
182161 msg->cursize = ( msg->bit >> 3 ) + 1;
183 // fclose(fp);
184162 }
185163 }
186164
4545 #define idppc 1
4646 #if defined(__VEC__)
4747 #define idppc_altivec 1
48 #ifdef MACOS_X // Apple's GCC does this differently than the FSF.
48 #ifdef __APPLE__ // Apple's GCC does this differently than the FSF.
4949 #define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
5050 (vector unsigned char) (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
5151 #else
138138
139139 //============================================================== MAC OS X ===
140140
141 #if defined(MACOS_X) || defined(__APPLE_CC__)
142
143 // make sure this is defined, just for sanity's sake...
144 #ifndef MACOS_X
145 #define MACOS_X
146 #endif
141 #if defined(__APPLE__) || defined(__APPLE_CC__)
147142
148143 #define OS_STRING "macosx"
149144 #define ID_INLINE inline
643643 =================
644644 SkipBracedSection
645645
646 The next token should be an open brace.
646 The next token should be an open brace or set depth to 1 if already parsed it.
647647 Skips until a matching close brace is found.
648648 Internal brace depths are properly skipped.
649649 =================
650650 */
651 void SkipBracedSection( char **program ) {
652 char *token;
653 int depth;
654
655 depth = 0;
651 qboolean SkipBracedSection (char **program, int depth) {
652 char *token;
653
656654 do {
657655 token = COM_ParseExt( program, qtrue );
658 if ( token[1] == 0 ) {
659 if ( token[0] == '{' ) {
656 if( token[1] == 0 ) {
657 if( token[0] == '{' ) {
660658 depth++;
661 } else if ( token[0] == '}' ) {
659 }
660 else if( token[0] == '}' ) {
662661 depth--;
663662 }
664663 }
665 } while ( depth && *program );
664 } while( depth && *program );
665
666 return ( depth == 0 );
666667 }
667668
668669 /*
5050 // #define STEAMPATH_APPID ""
5151 #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
5252 #define GAMENAME_FOR_MASTER "foobar" // must NOT contain whitespace
53 #define CINEMATICS_LOGO "foologo.roq"
54 #define CINEMATICS_INTRO "foointro.roq"
5355 // #define LEGACY_PROTOCOL // You probably don't need this for your standalone game
5456 #else
5557 #define PRODUCT_NAME "iortcw"
5658 #define BASEGAME "main"
5759 #define CLIENT_WINDOW_TITLE "Return To Castle Wolfenstein"
5860 #define CLIENT_WINDOW_MIN_TITLE "iowolfsp"
61 #ifdef USE_XDG
62 #define HOMEPATH_NAME_UNIX "iortcw"
63 #else
5964 #define HOMEPATH_NAME_UNIX ".wolf"
65 #endif
6066 #define HOMEPATH_NAME_WIN "RTCW"
6167 #define STEAMPATH_NAME "Return To Castle Wolfenstein"
6268 #define STEAMPATH_APPID "9010"
6369 #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
6470 #define GAMENAME_FOR_MASTER "wolfsp"
71 #define CINEMATICS_LOGO "gmlogo.RoQ" // non-existent
72 #define CINEMATICS_INTRO "wolfintro.RoQ" // SP only
6573 #define LEGACY_PROTOCOL
6674 #endif
6775
7583 #define LEGACY_HEARTBEAT_FOR_MASTER "Wolfenstein-1"
7684
7785 #ifndef PRODUCT_VERSION
78 #define PRODUCT_VERSION "1.42d"
86 #define PRODUCT_VERSION "1.5a"
87 #endif
88
89 #ifndef PRODUCT_DATE
90 # define PRODUCT_DATE __DATE__
7991 #endif
8092
8193 #define Q3_VERSION PRODUCT_NAME " " PRODUCT_VERSION
847859
848860 void COM_MatchToken( char**buf_p, char *match );
849861
850 void SkipBracedSection( char **program );
862 qboolean SkipBracedSection( char **program, int depth );
851863 void SkipRestOfLine( char **data );
852864
853865 void Parse1DMatrix( char **buf_p, int x, float *m );
293293 #endif
294294
295295 #ifndef STANDALONE
296 #ifdef USE_AUTHORIZE_SERVER
296297 #ifndef AUTHORIZE_SERVER_NAME
297298 #define AUTHORIZE_SERVER_NAME "authorize.gmistudios.com"
298299 #endif
299300 #ifndef PORT_AUTHORIZE
300301 #define PORT_AUTHORIZE 27952
301302 #endif
303 #endif
302304 #endif
303305
304306 #define PORT_MASTER 27950
629631 #define FS_CGAME_REF 0x04
630632 // #define FS_QAGAME_REF 0x08
631633 // number of id paks that will never be autodownloaded from baseq3
632 #define NUM_ID_PAKS 1
634 #define NUM_ID_PAKS 6
633635 #define NUM_SP_PAKS 4
634636
635637 #define MAX_FILE_HANDLES 64
671673
672674 int FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
673675 int FS_GetModList( char *listbuf, int bufsize );
676
677 void FS_GetModDescription( const char *modDir, char *description, int descriptionLen );
674678
675679 fileHandle_t FS_FOpenFileWrite( const char *qpath );
676680 fileHandle_t FS_FOpenFileAppend( const char *filename );
11491153 char *Sys_SteamPath(void);
11501154 #endif
11511155
1152 #ifdef MACOS_X
1156 #ifdef __APPLE__
11531157 char *Sys_DefaultAppPath(void);
11541158 #endif
11551159
11851189
11861190 dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title );
11871191
1188 qboolean Sys_WritePIDFile( void );
1192 void Sys_RemovePIDFile( const char *gamedir );
1193 void Sys_InitPIDFile( const char *gamedir );
11891194
11901195 void Sys_StartProcess( char *cmdline, qboolean doexit ); // NERVE - SMF
11911196 // TTimo
1313
1414 #ifdef FIRST_PASS
1515
16 #if defined(r_framebufferGamma)
17 minAvgMax = pow(minAvgMax, vec3(r_framebufferGamma));
16 #if defined(USE_PBR)
17 minAvgMax *= minAvgMax;
1818 #endif
1919
2020 float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001);
00 uniform sampler2D u_ScreenImageMap;
11 uniform sampler2D u_ScreenDepthMap;
22
3 uniform vec4 u_ViewInfo; // zfar / znear, zfar
3 uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
44 varying vec2 var_ScreenTex;
55
6 //float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06);
67 //float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033);
78 float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044);
89 //float gauss[3] = float[3](0.60, 0.19, 0.0066);
9 #define GAUSS_SIZE 4
10 #define BLUR_SIZE 4
11
12 #if !defined(USE_DEPTH)
13 //#define USE_GAUSS
14 #endif
1015
1116 float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
1217 {
13 float sampleZDivW = texture2D(depthMap, tex).r;
14 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
18 float sampleZDivW = texture2D(depthMap, tex).r;
19 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
1520 }
1621
17 vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar)
22 vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale)
1823 {
19 float scale = 1.0 / 256.0;
24
25 #if defined(USE_DEPTH)
26 float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear);
27 vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
28 scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0);
29 #endif
2030
2131 #if defined(USE_HORIZONTAL_BLUR)
22 vec2 direction = vec2(1.0, 0.0) * scale;
32 vec2 direction = vec2(scale.x * 2.0, 0.0);
33 vec2 nudge = vec2(0.0, scale.y * 0.5);
2334 #else // if defined(USE_VERTICAL_BLUR)
24 vec2 direction = vec2(0.0, 1.0) * scale;
35 vec2 direction = vec2(0.0, scale.y * 2.0);
36 vec2 nudge = vec2(-scale.x * 0.5, 0.0);
2537 #endif
26
27 float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
28 vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
29
38
39 #if defined(USE_GAUSS)
3040 vec4 result = texture2D(imageMap, tex) * gauss[0];
3141 float total = gauss[0];
42 #else
43 vec4 result = texture2D(imageMap, tex);
44 float total = 1.0;
45 #endif
3246
47 float zLimit = 5.0 / zFar;
3348 int i, j;
3449 for (i = 0; i < 2; i++)
3550 {
36 for (j = 1; j < GAUSS_SIZE; j++)
51 for (j = 1; j < BLUR_SIZE; j++)
3752 {
38 vec2 offset = direction * j;
39 float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
40 float depthExpected = depthCenter + dot(centerSlope, offset);
41 if(abs(depthSample - depthExpected) < 5.0)
42 {
43 result += texture2D(imageMap, tex + offset) * gauss[j];
44 total += gauss[j];
45 }
53 vec2 offset = direction * (float(j) - 0.25) + nudge;
54 #if defined(USE_DEPTH)
55 float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
56 float depthExpected = depthCenter + dot(slope, offset);
57 float useSample = float(abs(depthSample - depthExpected) < zLimit);
58 #else
59 float useSample = 1.0;
60 #endif
61 #if defined(USE_GAUSS)
62 result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
63 total += gauss[j] * useSample;
64 #else
65 result += texture2D(imageMap, tex + offset) * useSample;
66 total += useSample;
67 #endif
68 nudge = -nudge;
4669 }
47
70
4871 direction = -direction;
49 }
50
72 nudge = -nudge;
73 }
74
5175 return result / total;
5276 }
5377
5478 void main()
55 {
56 gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
79 {
80 gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw);
5781 }
00 attribute vec4 attr_Position;
11 attribute vec4 attr_TexCoord0;
2
3 uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
24
35 varying vec2 var_ScreenTex;
46
57 void main()
68 {
79 gl_Position = attr_Position;
8 var_ScreenTex = attr_TexCoord0.xy;
10 vec2 wh = vec2(1.0) / u_ViewInfo.zw - vec2(1.0);
11 var_ScreenTex = (floor(attr_TexCoord0.xy * wh) + vec2(0.5)) * u_ViewInfo.zw;
12
913 //vec2 screenCoords = gl_Position.xy / gl_Position.w;
1014 //var_ScreenTex = screenCoords * 0.5 + 0.5;
1115 }
2828 uniform vec4 u_EnableTextures;
2929 #endif
3030
31 #if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
32 uniform vec3 u_DirectedLight;
33 uniform vec3 u_AmbientLight;
34 #endif
35
3631 #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
3732 uniform vec3 u_PrimaryLightColor;
3833 uniform vec3 u_PrimaryLightAmbient;
5247 varying vec4 var_TexCoords;
5348
5449 varying vec4 var_Color;
55
5650 #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
57 #if defined(USE_VERT_TANGENT_SPACE)
51 varying vec4 var_ColorAmbient;
52 #endif
53
54 #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
5855 varying vec4 var_Normal;
5956 varying vec4 var_Tangent;
6057 varying vec4 var_Bitangent;
61 #else
62 varying vec3 var_Normal;
63 varying vec3 var_ViewDir;
64 #endif
6558 #endif
6659
6760 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
149142 }
150143 #endif
151144
152 vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float roughness)
145 vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
153146 {
154147 #if defined(USE_BURLEY)
155148 // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
170163 return vec3(v) + specular;
171164 }
172165
173 vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float roughness)
166 vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness)
174167 {
175168 // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
176169 float rr = roughness*roughness;
197190 return attenuation;
198191 }
199192
200 // from http://www.thetenthplanet.de/archives/1180
201 mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv )
202 {
203 // get edge vectors of the pixel triangle
204 vec3 dp1 = dFdx( p );
205 vec3 dp2 = dFdy( p );
206 vec2 duv1 = dFdx( uv );
207 vec2 duv2 = dFdy( uv );
208
209 // solve the linear system
210 vec3 dp2perp = cross( dp2, N );
211 vec3 dp1perp = cross( N, dp1 );
212 vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
213 vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
214
215 // construct a scale-invariant frame
216 float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
217 return mat3( T * invmax, B * invmax, N );
218 }
219193
220194 void main()
221195 {
222 vec3 viewDir, lightColor, ambientColor;
196 vec3 viewDir, lightColor, ambientColor, reflectance;
223197 vec3 L, N, E, H;
224198 float NL, NH, NE, EH, attenuation;
225199
226200 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
227 #if defined(USE_VERT_TANGENT_SPACE)
228201 mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);
229202 viewDir = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w);
230 #else
231 mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy);
232 viewDir = var_ViewDir;
233 #endif
234
235203 E = normalize(viewDir);
236
237 L = var_LightDir.xyz;
238 #if defined(USE_DELUXEMAP)
239 L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
240 #endif
241 float sqrLightDist = dot(L, L);
242 #endif
204 #endif
205
206 lightColor = var_Color.rgb;
243207
244208 #if defined(USE_LIGHTMAP)
245209 vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw);
246210 #if defined(RGBM_LIGHTMAP)
247211 lightmapColor.rgb *= lightmapColor.a;
248212 #endif
213 #if defined(USE_PBR) && !defined(USE_FAST_LIGHT)
214 lightmapColor.rgb *= lightmapColor.rgb;
215 #endif
216 lightColor *= lightmapColor.rgb;
249217 #endif
250218
251219 vec2 texCoords = var_TexCoords.xy;
261229 vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
262230
263231 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
264 #if defined(USE_LIGHTMAP)
265 lightColor = lightmapColor.rgb * var_Color.rgb;
266 ambientColor = vec3(0.0);
232 L = var_LightDir.xyz;
233 #if defined(USE_DELUXEMAP)
234 L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
235 #endif
236 float sqrLightDist = dot(L, L);
237 L /= sqrt(sqrLightDist);
238
239 #if defined(USE_LIGHT_VECTOR)
240 attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
241 #else
267242 attenuation = 1.0;
268 #elif defined(USE_LIGHT_VECTOR)
269 lightColor = u_DirectedLight * var_Color.rgb;
270 ambientColor = u_AmbientLight * var_Color.rgb;
271 attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
272 #elif defined(USE_LIGHT_VERTEX)
273 lightColor = var_Color.rgb;
274 ambientColor = vec3(0.0);
275 attenuation = 1.0;
276 #endif
277
278 #if defined(r_lightGamma)
279 lightColor = pow(lightColor, vec3(r_lightGamma));
280 ambientColor = pow(ambientColor, vec3(r_lightGamma));
281243 #endif
282244
283245 #if defined(USE_NORMALMAP)
294256 #endif
295257
296258 N = normalize(N);
297 L /= sqrt(sqrLightDist);
298259
299260 #if defined(USE_SHADOWMAP)
300261 vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
301262 float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
302263
303264 // surfaces not facing the light are always shadowed
304 shadowValue *= float(dot(var_Normal.xyz, var_PrimaryLightDir.xyz) > 0.0);
265 shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0);
305266
306267 #if defined(SHADOWMAP_MODULATE)
307268 lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
308269 #endif
309270 #endif
310271
311 #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
272 #if !defined(USE_LIGHT_VECTOR)
312273 ambientColor = lightColor;
313274 float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
275
276 // reserve 25% ambient to avoid black areas on normalmaps
277 lightColor *= 0.75;
314278
315279 // Scale the incoming light to compensate for the baked-in light angle
316280 // attenuation.
318282
319283 // Recover any unused light as ambient, in case attenuation is over 4x or
320284 // light is below the surface
321 ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0);
322 #endif
323
324 vec3 reflectance;
285 ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0));
286 #else
287 ambientColor = var_ColorAmbient.rgb;
288 #endif
325289
326290 NL = clamp(dot(N, L), 0.0, 1.0);
327291 NE = clamp(dot(N, E), 0.0, 1.0);
331295 #else
332296 vec4 specular = vec4(1.0);
333297 #endif
334
335298 specular *= u_SpecularScale;
336299
337 #if defined(r_materialGamma)
338 diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma));
339 #if !defined(SPECULAR_IS_METALLIC)
340 specular.rgb = pow(specular.rgb, vec3(r_materialGamma));
341 #endif
342 #endif
343
300 #if defined(USE_PBR)
301 diffuse.rgb *= diffuse.rgb;
302 #endif
303
304 #if defined(USE_PBR)
305 // diffuse rgb is base color
306 // specular red is gloss
307 // specular green is metallicness
308 float gloss = specular.r;
309 float metal = specular.g;
310 specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal);
311 diffuse.rgb *= 1.0 - metal;
312 #else
313 // diffuse rgb is diffuse
314 // specular rgb is specular reflectance at normal incidence
315 // specular alpha is gloss
344316 float gloss = specular.a;
345 #if defined(GLOSS_IS_ROUGHNESS)
346 float roughness = gloss;
347 #else
348 float roughness = exp2(-3.0 * gloss);
349 #endif
350
351 #if defined(SPECULAR_IS_METALLIC)
352 // diffuse is actually base color, and green of specular is metallicness
353 float metallic = specular.g;
354
355 specular.rgb = metallic * diffuse.rgb + vec3(0.04 - 0.04 * metallic);
356 diffuse.rgb *= 1.0 - metallic;
357 #else
317
358318 // adjust diffuse by specular reflectance, to maintain energy conservation
359319 diffuse.rgb *= vec3(1.0) - specular.rgb;
360320 #endif
361321
362 reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness);
322 #if defined(GLOSS_IS_GLOSS)
323 float roughness = exp2(-3.0 * gloss);
324 #elif defined(GLOSS_IS_SMOOTHNESS)
325 float roughness = 1.0 - gloss;
326 #elif defined(GLOSS_IS_ROUGHNESS)
327 float roughness = gloss;
328 #elif defined(GLOSS_IS_SHININESS)
329 float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25);
330 #endif
331
332 reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness);
363333
364334 gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
365 gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb);
335 gl_FragColor.rgb += ambientColor * diffuse.rgb;
366336
367337 #if defined(USE_CUBEMAP)
368338 reflectance = EnvironmentBRDF(roughness, NE, specular.rgb);
373343 // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
374344 vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
375345
376 #if defined(GLOSS_IS_ROUGHNESS)
377 vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w;
378 #else
379 vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w;
380 #endif
381
382 // normalize cubemap based on lowest mip (~diffuse)
346 vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w;
347
348 // normalize cubemap based on last roughness mip (~diffuse)
383349 // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
384 //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, 6.0).rgb, 0.5 / 255.0);
350 //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, ROUGHNESS_MIPS).rgb, 0.5 / 255.0);
385351 //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721));
386352
387 #if defined(r_framebufferGamma)
388 cubeLightColor = pow(cubeLightColor, vec3(r_framebufferGamma));
353 #if defined(USE_PBR)
354 cubeLightColor *= cubeLightColor;
389355 #endif
390356
391357 // multiply cubemap values by lighting
406372 //L2 /= sqrt(sqrLightDist);
407373
408374 NL2 = clamp(dot(N, L2), 0.0, 1.0);
409
410375 H2 = normalize(L2 + E);
411376 EH2 = clamp(dot(E, H2), 0.0, 1.0);
412377 NH2 = clamp(dot(N, H2), 0.0, 1.0);
413378
414 reflectance = CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness);
379 reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness);
415380
416381 // bit of a hack, with modulated shadowmaps, ignore diffuse
417382 #if !defined(SHADOWMAP_MODULATE)
418 reflectance += CalcDiffuse(diffuse.rgb, EH2, NH2, roughness);
383 reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness);
419384 #endif
420385
421386 lightColor = u_PrimaryLightColor;
422
423 #if defined(r_lightGamma)
424 lightColor = pow(lightColor, vec3(r_lightGamma));
425 #endif
426387
427388 #if defined(USE_SHADOWMAP)
428389 lightColor *= shadowValue;
433394
434395 gl_FragColor.rgb += lightColor * reflectance * NL2;
435396 #endif
397
398 #if defined(USE_PBR)
399 gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
400 #endif
401
436402 #else
437 lightColor = var_Color.rgb;
438
439 #if defined(USE_LIGHTMAP)
440 lightColor *= lightmapColor.rgb;
441 #endif
442
443 #if defined(r_lightGamma)
444 lightColor = pow(lightColor, vec3(r_lightGamma));
445 #endif
446
447 #if defined(r_materialGamma)
448 diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma));
449 #endif
450403
451404 gl_FragColor.rgb = diffuse.rgb * lightColor;
452405
453406 #endif
454407
455 #if defined(r_framebufferGamma)
456 gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / r_framebufferGamma));
457 #endif
458
459408 gl_FragColor.a = diffuse.a * var_Color.a;
460409 }
55
66 attribute vec3 attr_Position;
77 attribute vec3 attr_Normal;
8 #if defined(USE_VERT_TANGENT_SPACE)
98 attribute vec4 attr_Tangent;
10 #endif
119
1210 #if defined(USE_VERTEX_ANIMATION)
1311 attribute vec3 attr_Position2;
1412 attribute vec3 attr_Normal2;
15 #if defined(USE_VERT_TANGENT_SPACE)
1613 attribute vec4 attr_Tangent2;
17 #endif
1814 #endif
1915
2016 #if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
5652 #if defined(USE_LIGHT_VECTOR)
5753 uniform vec4 u_LightOrigin;
5854 uniform float u_LightRadius;
59 #if defined(USE_FAST_LIGHT)
6055 uniform vec3 u_DirectedLight;
6156 uniform vec3 u_AmbientLight;
62 #endif
6357 #endif
6458
6559 #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
7064 varying vec4 var_TexCoords;
7165
7266 varying vec4 var_Color;
73
74 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
75 #if defined(USE_VERT_TANGENT_SPACE)
67 #if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
68 varying vec4 var_ColorAmbient;
69 #endif
70
71 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
7672 varying vec4 var_Normal;
7773 varying vec4 var_Tangent;
7874 varying vec4 var_Bitangent;
79 #else
80 varying vec3 var_Normal;
81 varying vec3 var_ViewDir;
82 #endif
8375 #endif
8476
8577 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
155147 #if defined(USE_VERTEX_ANIMATION)
156148 vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
157149 vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
158 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
150 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
159151 vec3 tangent = mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp);
160152 #endif
161153 #else
162154 vec3 position = attr_Position;
163155 vec3 normal = attr_Normal;
164 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
156 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
165157 vec3 tangent = attr_Tangent.xyz;
166158 #endif
167159 #endif
183175 #if defined(USE_MODELMATRIX)
184176 position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
185177 normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;
186 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
178 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
187179 tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;
188180 #endif
189181 #endif
190182
191 #if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
183 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
192184 vec3 bitangent = cross(normal, tangent) * attr_Tangent.w;
193185 #endif
194186
207199
208200 var_Color = u_VertColor * attr_Color + u_BaseColor;
209201
210 #if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)
202 #if defined(USE_LIGHT_VECTOR)
203 #if defined(USE_FAST_LIGHT)
211204 float sqrLightDist = dot(L, L);
205 float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
212206 float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
213 float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
214207
215208 var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight;
209 #else
210 var_ColorAmbient.rgb = u_AmbientLight * var_Color.rgb;
211 var_Color.rgb *= u_DirectedLight;
212 #if defined(USE_PBR)
213 var_ColorAmbient.rgb *= var_ColorAmbient.rgb;
214 #endif
215 #endif
216 #endif
217
218 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) && defined(USE_PBR)
219 var_Color.rgb *= var_Color.rgb;
216220 #endif
217221
218222 #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
233237
234238 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
235239 vec3 viewDir = u_ViewOrigin - position;
236 #if defined(USE_VERT_TANGENT_SPACE)
237240 // store view direction in tangent space to save on varyings
238241 var_Normal = vec4(normal, viewDir.x);
239242 var_Tangent = vec4(tangent, viewDir.y);
240243 var_Bitangent = vec4(bitangent, viewDir.z);
241 #else
242 var_Normal = normal;
243 var_ViewDir = viewDir;
244 #endif
245 #endif
246 }
244 #endif
245 }
00 uniform sampler2D u_ScreenDepthMap;
11
2 uniform vec4 u_ViewInfo; // zfar / znear, zfar
2 uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
33
44 varying vec2 var_ScreenTex;
55
1010 vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
1111 vec2(0.7320465, 0.6317794)
1212 );
13 #define NUM_SAMPLES 3
1314
1415 // Input: It uses texture coords as the random number seed.
1516 // Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
3839
3940 float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
4041 {
41 float sampleZDivW = texture2D(depthMap, tex).r;
42 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
42 float sampleZDivW = texture2D(depthMap, tex).r;
43 return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
4344 }
4445
45 float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar)
46 float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale)
4647 {
4748 float result = 0;
4849
49 float sampleZ = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
50 float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
51 float scaleZ = zFarDivZNear * sampleZ;
5052
51 vec2 expectedSlope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
52
53 if (length(expectedSlope) > 5000.0)
53 vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
54
55 if (length(slope) * zFar > 5000.0)
5456 return 1.0;
55
56 vec2 offsetScale = vec2(3.0 / sampleZ);
57
57
58 vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
59
5860 mat2 rmat = randomRotation(tex);
59
61
62 float invZFar = 1.0 / zFar;
63 float zLimit = 20.0 * invZFar;
6064 int i;
61 for (i = 0; i < 3; i++)
65 for (i = 0; i < NUM_SAMPLES; i++)
6266 {
6367 vec2 offset = rmat * poissonDisc[i] * offsetScale;
64 float sampleZ2 = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
68 float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ;
6569
66 if (abs(sampleZ - sampleZ2) > 20.0)
67 result += 1.0;
68 else
69 {
70 float expectedZ = sampleZ + dot(expectedSlope, offset);
71 result += step(expectedZ - 1.0, sampleZ2);
72 }
70 bool s1 = abs(sampleDiff) > zLimit;
71 bool s2 = sampleDiff + invZFar > dot(slope, offset);
72 result += float(s1 || s2);
7373 }
74
75 result *= 0.33333;
76
74
75 result *= 1.0 / float(NUM_SAMPLES);
76
7777 return result;
7878 }
7979
8080 void main()
8181 {
82 float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
83
82 float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz);
83
8484 gl_FragColor = vec4(vec3(result), 1.0);
8585 }
2727 {
2828 vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color;
2929
30 #if defined(r_framebufferGamma)
31 color.rgb = pow(color.rgb, vec3(r_framebufferGamma));
30 #if defined(USE_PBR)
31 color.rgb *= color.rgb;
3232 #endif
3333
3434 vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb;
4545
4646 color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0);
4747
48 #if defined(r_tonemapGamma)
49 color.rgb = pow(color.rgb, vec3(1.0 / r_tonemapGamma));
48 #if defined(USE_PBR)
49 color.rgb = sqrt(color.rgb);
5050 #endif
51
52 // add a bit of dither to reduce banding
53 color.rgb += vec3(1.0/510.0 * mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) - 1.0/1020.0);
5154
5255 gl_FragColor = color;
5356 }
00 /*
11 ===========================================================================
2 Copyright (C) 1999-2005 Id Software, Inc.
3
4 This file is part of Quake III Arena source code.
5
6 Quake III Arena source code is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 Quake III Arena source code is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
2
3 Return to Castle Wolfenstein single player GPL Source Code
4 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
5
6 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”).
7
8 RTCW SP Source Code is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 RTCW SP Source Code is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
1315 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1416 GNU General Public License for more details.
1517
1618 You should have received a copy of the GNU General Public License
17 along with Quake III Arena source code; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 along with RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
20
21 In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below.
22
23 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
24
1925 ===========================================================================
2026 */
27
2128 /*
2229 ** QGL.H
2330 */
3138 # include <SDL_opengl.h>
3239 #endif
3340
34 extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
35 extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
36 extern void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
37
38 extern void ( APIENTRY * qglLockArraysEXT )( GLint, GLint );
39 extern void ( APIENTRY * qglUnlockArraysEXT )( void );
41 extern void (APIENTRYP qglActiveTextureARB) (GLenum texture);
42 extern void (APIENTRYP qglClientActiveTextureARB) (GLenum texture);
43 extern void (APIENTRYP qglMultiTexCoord2fARB) (GLenum target, GLfloat s, GLfloat t);
44
45 extern void (APIENTRYP qglLockArraysEXT) (GLint first, GLsizei count);
46 extern void (APIENTRYP qglUnlockArraysEXT) (void);
4047
4148 //===========================================================================
4249
5966 // GL_ATI_pn_triangles
6067 #ifndef GL_ATI_pn_triangles
6168 #define GL_ATI_pn_triangles 1
62 #ifndef MACOS_X //DAJ BUGFIX changed the numbers
69 #ifndef __APPLE__ //DAJ BUGFIX changed the numbers
6370 #define GL_PN_TRIANGLES_ATI 0x6090
6471 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x6091
6572 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x6092
8087 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
8188 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
8289 #endif
83 typedef void ( APIENTRY * PFNGLPNTRIANGLESIATIPROC )( GLenum pname, GLint param );
84 typedef void ( APIENTRY * PFNGLPNTRIANGLESFATIPROC )( GLenum pname, GLfloat param );
90 typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC)(GLenum pname, GLint param);
91 typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param);
8592 #endif
8693
8794 //----(SA) added
88 extern void ( APIENTRY * qglPNTrianglesiATI )( GLenum pname, GLint param );
89 extern void ( APIENTRY * qglPNTrianglesfATI )( GLenum pname, GLfloat param );
95 extern void (APIENTRYP qglPNTrianglesiATI)(GLenum pname, GLint param);
96 extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
9097 //----(SA) end
9198
9299 // for NV fog distance
452459 #define qglVertexPointer glVertexPointer
453460 #define qglViewport glViewport
454461
455 // GL_EXT_draw_range_elements
456 extern void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
457
458 // GL_EXT_multi_draw_arrays
459 extern void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
460 extern void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
461
462 // rend2
463
464 // GL_ARB_shading_language_100
465 #ifndef GL_ARB_shading_language_100
466 #define GL_ARB_shading_language_100
467 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
468 #endif
469
470 // GL_ARB_vertex_program
471 extern void (APIENTRY * qglVertexAttrib4fARB) (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
472 extern void (APIENTRY * qglVertexAttrib4fvARB) (GLuint, const GLfloat *);
473 extern void (APIENTRY * qglVertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized,
474 GLsizei stride, const GLvoid * pointer);
475 extern void (APIENTRY * qglEnableVertexAttribArrayARB) (GLuint index);
476 extern void (APIENTRY * qglDisableVertexAttribArrayARB) (GLuint index);
477
478 // GL_ARB_vertex_buffer_object
479 extern void (APIENTRY * qglBindBufferARB) (GLenum target, GLuint buffer);
480 extern void (APIENTRY * qglDeleteBuffersARB) (GLsizei n, const GLuint * buffers);
481 extern void (APIENTRY * qglGenBuffersARB) (GLsizei n, GLuint * buffers);
482 extern GLboolean(APIENTRY * qglIsBufferARB) (GLuint buffer);
483 extern void (APIENTRY * qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
484 extern void (APIENTRY * qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
485 extern void (APIENTRY * qglGetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data);
486 extern void (APIENTRY * qglGetBufferParameterivARB) (GLenum target, GLenum pname, GLint * params);
487 extern void (APIENTRY * qglGetBufferPointervARB) (GLenum target, GLenum pname, GLvoid * *params);
488
489 // GL_ARB_shader_objects
490 extern void (APIENTRY * qglDeleteObjectARB) (GLhandleARB obj);
491 extern GLhandleARB(APIENTRY * qglGetHandleARB) (GLenum pname);
492 extern void (APIENTRY * qglDetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj);
493 extern GLhandleARB(APIENTRY * qglCreateShaderObjectARB) (GLenum shaderType);
494 extern void (APIENTRY * qglShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB * *string,
495 const GLint * length);
496 extern void (APIENTRY * qglCompileShaderARB) (GLhandleARB shaderObj);
497 extern GLhandleARB(APIENTRY * qglCreateProgramObjectARB) (void);
498 extern void (APIENTRY * qglAttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj);
499 extern void (APIENTRY * qglLinkProgramARB) (GLhandleARB programObj);
500 extern void (APIENTRY * qglUseProgramObjectARB) (GLhandleARB programObj);
501 extern void (APIENTRY * qglValidateProgramARB) (GLhandleARB programObj);
502 extern void (APIENTRY * qglUniform1fARB) (GLint location, GLfloat v0);
503 extern void (APIENTRY * qglUniform2fARB) (GLint location, GLfloat v0, GLfloat v1);
504 extern void (APIENTRY * qglUniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
505 extern void (APIENTRY * qglUniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
506 extern void (APIENTRY * qglUniform1iARB) (GLint location, GLint v0);
507 extern void (APIENTRY * qglUniform2iARB) (GLint location, GLint v0, GLint v1);
508 extern void (APIENTRY * qglUniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2);
509 extern void (APIENTRY * qglUniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
510 extern void (APIENTRY * qglUniform1fvARB) (GLint location, GLsizei count, const GLfloat * value);
511 extern void (APIENTRY * qglUniform2fvARB) (GLint location, GLsizei count, const GLfloat * value);
512 extern void (APIENTRY * qglUniform3fvARB) (GLint location, GLsizei count, const GLfloat * value);
513 extern void (APIENTRY * qglUniform4fvARB) (GLint location, GLsizei count, const GLfloat * value);
514 extern void (APIENTRY * qglUniform2ivARB) (GLint location, GLsizei count, const GLint * value);
515 extern void (APIENTRY * qglUniform3ivARB) (GLint location, GLsizei count, const GLint * value);
516 extern void (APIENTRY * qglUniform4ivARB) (GLint location, GLsizei count, const GLint * value);
517 extern void (APIENTRY * qglUniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
518 extern void (APIENTRY * qglUniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
519 extern void (APIENTRY * qglUniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
520 extern void (APIENTRY * qglGetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat * params);
521 extern void (APIENTRY * qglGetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint * params);
522 extern void (APIENTRY * qglGetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog);
523 extern void (APIENTRY * qglGetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count,
524 GLhandleARB * obj);
525 extern GLint(APIENTRY * qglGetUniformLocationARB) (GLhandleARB programObj, const GLcharARB * name);
526 extern void (APIENTRY * qglGetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxIndex, GLsizei * length,
527 GLint * size, GLenum * type, GLcharARB * name);
528 extern void (APIENTRY * qglGetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat * params);
529 extern void (APIENTRY * qglGetUniformivARB) (GLhandleARB programObj, GLint location, GLint * params);
530 extern void (APIENTRY * qglGetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source);
531
532 // GL_ARB_vertex_shader
533 extern void (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB * name);
534 extern void (APIENTRY * qglGetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length,
535 GLint * size, GLenum * type, GLcharARB * name);
536 extern GLint(APIENTRY * qglGetAttribLocationARB) (GLhandleARB programObj, const GLcharARB * name);
537
538 // GL_ARB_texture_compression
539 extern void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
540 GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
541 extern void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
542 GLint border, GLsizei imageSize, const GLvoid *data);
543 extern void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
544 GLsizei imageSize, const GLvoid *data);
545 extern void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
546 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
547 extern void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
548 GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
549 extern void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
550 GLsizei imageSize, const GLvoid *data);
551 extern void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
552 GLvoid *img);
462 // GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
463
464 // OpenGL 1.2, was GL_EXT_draw_range_elements
465 #define QGL_1_2_PROCS \
466 GLE(void, DrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) \
467
468 // OpenGL 1.3, was GL_ARB_texture_compression
469 #define QGL_1_3_PROCS \
470 GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
471 GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
472
473 // OpenGL 1.4, was GL_EXT_multi_draw_arrays
474 #define QGL_1_4_PROCS \
475 GLE(void, MultiDrawElements, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) \
476
477 // OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
478 #define QGL_1_5_PROCS \
479 GLE(void, GenQueries, GLsizei n, GLuint *ids) \
480 GLE(void, DeleteQueries, GLsizei n, const GLuint *ids) \
481 GLE(void, BeginQuery, GLenum target, GLuint id) \
482 GLE(void, EndQuery, GLenum target) \
483 GLE(void, GetQueryObjectiv, GLuint id, GLenum pname, GLint *params) \
484 GLE(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params) \
485 GLE(void, BindBuffer, GLenum target, GLuint buffer) \
486 GLE(void, DeleteBuffers, GLsizei n, const GLuint *buffers) \
487 GLE(void, GenBuffers, GLsizei n, GLuint *buffers) \
488 GLE(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) \
489 GLE(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) \
490
491 // OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
492 #define QGL_2_0_PROCS \
493 GLE(void, AttachShader, GLuint program, GLuint shader) \
494 GLE(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) \
495 GLE(void, CompileShader, GLuint shader) \
496 GLE(GLuint, CreateProgram, void) \
497 GLE(GLuint, CreateShader, GLenum type) \
498 GLE(void, DeleteProgram, GLuint program) \
499 GLE(void, DeleteShader, GLuint shader) \
500 GLE(void, DetachShader, GLuint program, GLuint shader) \
501 GLE(void, DisableVertexAttribArray, GLuint index) \
502 GLE(void, EnableVertexAttribArray, GLuint index) \
503 GLE(void, GetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) \
504 GLE(void, GetProgramiv, GLuint program, GLenum pname, GLint *params) \
505 GLE(void, GetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
506 GLE(void, GetShaderiv, GLuint shader, GLenum pname, GLint *params) \
507 GLE(void, GetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
508 GLE(void, GetShaderSource, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) \
509 GLE(GLint, GetUniformLocation, GLuint program, const GLchar *name) \
510 GLE(void, LinkProgram, GLuint program) \
511 GLE(void, ShaderSource, GLuint shader, GLsizei count, const GLchar* *string, const GLint *length) \
512 GLE(void, UseProgram, GLuint program) \
513 GLE(void, Uniform1f, GLint location, GLfloat v0) \
514 GLE(void, Uniform2f, GLint location, GLfloat v0, GLfloat v1) \
515 GLE(void, Uniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
516 GLE(void, Uniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
517 GLE(void, Uniform1i, GLint location, GLint v0) \
518 GLE(void, Uniform1fv, GLint location, GLsizei count, const GLfloat *value) \
519 GLE(void, UniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
520 GLE(void, ValidateProgram, GLuint program) \
521 GLE(void, VertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) \
553522
554523 // GL_NVX_gpu_memory_info
555524 #ifndef GL_NVX_gpu_memory_info
600569 #endif
601570
602571 // GL_EXT_framebuffer_object
603 extern GLboolean (APIENTRY * qglIsRenderbufferEXT)(GLuint renderbuffer);
604 extern void (APIENTRY * qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
605 extern void (APIENTRY * qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
606 extern void (APIENTRY * qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
607 extern void (APIENTRY * qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
608 extern void (APIENTRY * qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
609 extern GLboolean (APIENTRY * qglIsFramebufferEXT)(GLuint framebuffer);
610 extern void (APIENTRY * qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
611 extern void (APIENTRY * qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
612 extern void (APIENTRY * qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
613 extern GLenum (APIENTRY * qglCheckFramebufferStatusEXT)(GLenum target);
614 extern void (APIENTRY * qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
615 GLint level);
616 extern void (APIENTRY * qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
617 GLint level);
618 extern void (APIENTRY * qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
619 GLint level, GLint zoffset);
620 extern void (APIENTRY * qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget,
621 GLuint renderbuffer);
622 extern void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
623 extern void (APIENTRY * qglGenerateMipmapEXT)(GLenum target);
572 #define QGL_EXT_framebuffer_object_PROCS \
573 GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
574 GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
575 GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
576 GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
577 GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
578 GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
579 GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
580 GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
581 GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
582 GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
583 GLE(void, GenerateMipmapEXT, GLenum target) \
624584
625585 #ifndef GL_EXT_framebuffer_object
626586 #define GL_EXT_framebuffer_object
677637 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
678638 #endif
679639
680 // GL_EXT_packed_depth_stencil
681 #ifndef GL_EXT_packed_depth_stencil
682 #define GL_EXT_packed_depth_stencil
683 #define GL_DEPTH_STENCIL_EXT 0x84F9
684 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA
685 #define GL_DEPTH24_STENCIL8_EXT 0x88F0
686 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
687 #endif
688
689 // GL_ARB_occlusion_query
690 extern void (APIENTRY * qglGenQueriesARB)(GLsizei n, GLuint *ids);
691 extern void (APIENTRY * qglDeleteQueriesARB)(GLsizei n, const GLuint *ids);
692 extern GLboolean (APIENTRY * qglIsQueryARB)(GLuint id);
693 extern void (APIENTRY * qglBeginQueryARB)(GLenum target, GLuint id);
694 extern void (APIENTRY * qglEndQueryARB)(GLenum target);
695 extern void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
696 extern void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
697 extern void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
698
699 #ifndef GL_ARB_occlusion_query
700 #define GL_ARB_occlusion_query
701 #define GL_SAMPLES_PASSED_ARB 0x8914
702 #define GL_QUERY_COUNTER_BITS_ARB 0x8864
703 #define GL_CURRENT_QUERY_ARB 0x8865
704 #define GL_QUERY_RESULT_ARB 0x8866
705 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
706 #endif
707
708640 // GL_EXT_framebuffer_blit
709 extern void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
710 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
711 GLbitfield mask, GLenum filter);
641 #define QGL_EXT_framebuffer_blit_PROCS \
642 GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
712643
713644 #ifndef GL_EXT_framebuffer_blit
714645 #define GL_EXT_framebuffer_blit
719650 #endif
720651
721652 // GL_EXT_framebuffer_multisample
722 extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
723 GLenum internalformat, GLsizei width, GLsizei height);
653 #define QGL_EXT_framebuffer_multisample_PROCS \
654 GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
724655
725656 #ifndef GL_EXT_framebuffer_multisample
726657 #define GL_EXT_framebuffer_multisample
727658 #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
728659 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
729660 #define GL_MAX_SAMPLES_EXT 0x8D57
730 #endif
731
732 #ifndef GL_EXT_texture_sRGB
733 #define GL_EXT_texture_sRGB
734 #define GL_SRGB_EXT 0x8C40
735 #define GL_SRGB8_EXT 0x8C41
736 #define GL_SRGB_ALPHA_EXT 0x8C42
737 #define GL_SRGB8_ALPHA8_EXT 0x8C43
738 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44
739 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
740 #define GL_SLUMINANCE_EXT 0x8C46
741 #define GL_SLUMINANCE8_EXT 0x8C47
742 #define GL_COMPRESSED_SRGB_EXT 0x8C48
743 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
744 #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
745 #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
746 #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
747 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
748 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
749 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
750 #endif
751
752 #ifndef GL_EXT_framebuffer_sRGB
753 #define GL_EXT_framebuffer_sRGB
754 #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
755661 #endif
756662
757663 #ifndef GL_ARB_texture_compression_rgtc
770676 #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
771677 #endif
772678
773 // GL_ARB_draw_buffers
774 extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
775 #ifndef GL_ARB_draw_buffers
776 #define GL_ARB_draw_buffers
777 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824
778 #define GL_DRAW_BUFFER0_ARB 0x8825
779 #define GL_DRAW_BUFFER1_ARB 0x8826
780 #define GL_DRAW_BUFFER2_ARB 0x8827
781 #define GL_DRAW_BUFFER3_ARB 0x8828
782 #define GL_DRAW_BUFFER4_ARB 0x8829
783 #define GL_DRAW_BUFFER5_ARB 0x882A
784 #define GL_DRAW_BUFFER6_ARB 0x882B
785 #define GL_DRAW_BUFFER7_ARB 0x882C
786 #define GL_DRAW_BUFFER8_ARB 0x882D
787 #define GL_DRAW_BUFFER9_ARB 0x882E
788 #define GL_DRAW_BUFFER10_ARB 0x882F
789 #define GL_DRAW_BUFFER11_ARB 0x8830
790 #define GL_DRAW_BUFFER12_ARB 0x8831
791 #define GL_DRAW_BUFFER13_ARB 0x8832
792 #define GL_DRAW_BUFFER14_ARB 0x8833
793 #define GL_DRAW_BUFFER15_ARB 0x8834
794 #endif
795
796679 #ifndef GL_ARB_depth_clamp
797680 #define GL_ARB_depth_clamp
798681 #define GL_DEPTH_CLAMP 0x864F
804687 #endif
805688
806689 // GL_ARB_vertex_array_object
807 extern void (APIENTRY * qglBindVertexArrayARB)(GLuint array);
808 extern void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays);
809 extern void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
810 extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
690 #define QGL_ARB_vertex_array_object_PROCS \
691 GLE(void, BindVertexArray, GLuint array) \
692 GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
693 GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
694
811695 #ifndef GL_ARB_vertex_array_object
812696 #define GL_ARB_vertex_array_object
813697 #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5
814698 #endif
815699
816 #if defined(WIN32)
817 // WGL_ARB_create_context
818 #ifndef WGL_ARB_create_context
819 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
820 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
821 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
822 #define WGL_CONTEXT_FLAGS_ARB 0x2094
823 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
824 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
825 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
826 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
827 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
828 #define ERROR_INVALID_VERSION_ARB 0x2095
829 #define ERROR_INVALID_PROFILE_ARB 0x2096
830 #endif
831
832 extern HGLRC(APIENTRY * qwglCreateContextAttribsARB) (HDC hdC, HGLRC hShareContext, const int *attribList);
833 #endif
834
835 #if 0 //defined(__linux__)
836 // GLX_ARB_create_context
837 #ifndef GLX_ARB_create_context
838 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
839 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
840 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
841 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
842 #define GLX_CONTEXT_FLAGS_ARB 0x2094
843 #endif
844
845 extern GLXContext (APIENTRY * qglXCreateContextAttribsARB) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
846 #endif
700 // GL_EXT_direct_state_access
701 #define QGL_EXT_direct_state_access_PROCS \
702 GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
703 GLE(GLvoid, TextureParameterfEXT, GLuint texture, GLenum target, GLenum pname, GLfloat param) \
704 GLE(GLvoid, TextureParameteriEXT, GLuint texture, GLenum target, GLenum pname, GLint param) \
705 GLE(GLvoid, TextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
706 GLE(GLvoid, TextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
707 GLE(GLvoid, CopyTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) \
708 GLE(GLvoid, CompressedTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) \
709 GLE(GLvoid, CompressedTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) \
710 GLE(GLvoid, GenerateTextureMipmapEXT, GLuint texture, GLenum target) \
711 GLE(GLvoid, ProgramUniform1iEXT, GLuint program, GLint location, GLint v0) \
712 GLE(GLvoid, ProgramUniform1fEXT, GLuint program, GLint location, GLfloat v0) \
713 GLE(GLvoid, ProgramUniform2fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1) \
714 GLE(GLvoid, ProgramUniform3fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
715 GLE(GLvoid, ProgramUniform4fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
716 GLE(GLvoid, ProgramUniform1fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value) \
717 GLE(GLvoid, ProgramUniformMatrix4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
718 GLE(GLvoid, NamedRenderbufferStorageEXT, GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) \
719 GLE(GLvoid, NamedRenderbufferStorageMultisampleEXT, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
720 GLE(GLenum, CheckNamedFramebufferStatusEXT, GLuint framebuffer, GLenum target) \
721 GLE(GLvoid, NamedFramebufferTexture2DEXT, GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
722 GLE(GLvoid, NamedFramebufferRenderbufferEXT, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
723
724 #define GLE(ret, name, ...) typedef ret APIENTRY name##proc(__VA_ARGS__); extern name##proc * qgl##name;
725 QGL_1_2_PROCS;
726 QGL_1_3_PROCS;
727 QGL_1_4_PROCS;
728 QGL_1_5_PROCS;
729 QGL_2_0_PROCS;
730 QGL_EXT_framebuffer_object_PROCS;
731 QGL_EXT_framebuffer_blit_PROCS;
732 QGL_EXT_framebuffer_multisample_PROCS;
733 QGL_ARB_vertex_array_object_PROCS;
734 QGL_EXT_direct_state_access_PROCS;
735 #undef GLE
847736
848737 #endif // __QGL_H__
4343 //#define DBG_PROFILE_BONES
4444
4545 //-----------------------------------------------------------------------------
46 // Static Vars, ugly but easiest (and fastest) means of seperating RB_SurfaceAnim
46 // Static Vars, ugly but easiest (and fastest) means of separating RB_SurfaceAnim
4747 // and R_CalcBones
4848
4949 static float frontlerp, backlerp;
6767 static float *pf;
6868 static vec3_t angles, tangles, torsoParentOffset, torsoAxis[3], tmpAxis[3];
6969 static float *tempVert;
70 static uint32_t *tempNormal;
70 static int16_t *tempNormal;
7171 static vec3_t vec, v2, dir;
7272 static float diff, a1, a2;
7373 static int render_count;
11771177 numVerts = surface->numVerts;
11781178 v = ( mdsVertex_t * )( (byte *)surface + surface->ofsVerts );
11791179 tempVert = ( float * )( tess.xyz + baseVertex );
1180 tempNormal = ( uint32_t * )( tess.normal + baseVertex );
1181 for ( j = 0; j < render_count; j++, tempVert += 4, tempNormal++ ) {
1180 tempNormal = ( int16_t * )( tess.normal + baseVertex );
1181 for ( j = 0; j < render_count; j++, tempVert += 4, tempNormal += 4 ) {
11821182 mdsWeight_t *w;
11831183 vec3_t newNormal;
11841184
11891189 bone = &bones[w->boneIndex];
11901190 LocalAddScaledMatrixTransformVectorTranslate( w->offset, w->boneWeight, bone->matrix, bone->translation, tempVert );
11911191 }
1192
11921193 LocalMatrixTransformVector( v->normal, bones[v->weights[0].boneIndex].matrix, newNormal );
11931194
1194 R_VaoPackNormal((byte *)tempNormal, newNormal);
1195 R_VaoPackNormal(tempNormal, newNormal);
11951196
11961197 tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
11971198 tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
12081209 for ( i = 0; i < surface->numBoneReferences; i++, boneRefs++ ) {
12091210 bonePtr = &bones[*boneRefs];
12101211
1211 GL_Bind( tr.whiteImage );
1212 GL_BindToTMU(tr.whiteImage, TB_COLORMAP);
12121213 qglLineWidth( 1 );
12131214 qglBegin( GL_LINES );
12141215 for ( j = 0; j < 3; j++ ) {
12401241
12411242 // show mesh edges
12421243 tempVert = ( float * )( tess.xyz + baseVertex );
1243 tempNormal = ( uint32_t * )( tess.normal + baseVertex );
1244
1245 GL_Bind( tr.whiteImage );
1244 tempNormal = ( int16_t * )( tess.normal + baseVertex );
1245
1246 GL_BindToTMU(tr.whiteImage, TB_COLORMAP);
12461247 qglLineWidth( 1 );
12471248 qglBegin( GL_LINES );
12481249 qglColor3f( .0,.0,.8 );
17411742 tess.xyz[baseVertex + j][1] = tempVert[1];
17421743 tess.xyz[baseVertex + j][2] = tempVert[2];
17431744
1744 R_VaoPackNormal((byte *)&tess.normal[baseVertex + j], tempNormal);
1745 R_VaoPackNormal(tess.normal[baseVertex + j], tempNormal);
17451746
17461747 tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
17471748 tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
2626 */
2727
2828 #include "tr_local.h"
29 #include "tr_fbo.h"
30 #include "tr_dsa.h"
2931
3032 backEndData_t *backEndData;
3133 backEndState_t backEnd;
4042 0, 0, 0, 1
4143 };
4244
43
44 /*
45 ** GL_Bind
46 */
47 void GL_Bind( image_t *image ) {
48 int texnum;
49
50 if ( !image ) {
51 ri.Printf( PRINT_WARNING, "GL_Bind: NULL image\n" );
52 texnum = tr.defaultImage->texnum;
53 } else {
54 texnum = image->texnum;
55 }
56
57 if ( r_nobind->integer && tr.dlightImage ) { // performance evaluation option
58 texnum = tr.dlightImage->texnum;
59 }
60
61 if ( glState.currenttextures[glState.currenttmu] != texnum ) {
62 if ( image ) {
63 image->frameUsed = tr.frameCount;
64 }
65 glState.currenttextures[glState.currenttmu] = texnum;
66 if (image && image->flags & IMGFLAG_CUBEMAP)
67 qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
68 else
69 qglBindTexture( GL_TEXTURE_2D, texnum );
70 }
71 }
72
73
74 /*
75 ** GL_SelectTexture
76 */
77 void GL_SelectTexture( int unit ) {
78 if ( glState.currenttmu == unit ) {
79 return;
80 }
81
82 if (!(unit >= 0 && unit <= 31))
83 ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit );
84
85 if (!qglActiveTextureARB)
86 ri.Error( ERR_DROP, "GL_SelectTexture: multitexture disabled" );
87
88 qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
89
90 glState.currenttmu = unit;
91 }
92
93
9445 /*
9546 ** GL_BindToTMU
9647 */
9748 void GL_BindToTMU( image_t *image, int tmu )
9849 {
99 int texnum;
100 int oldtmu = glState.currenttmu;
101
102 if (!image)
103 texnum = 0;
50 GLuint texture = (tmu == TB_COLORMAP) ? tr.defaultImage->texnum : 0;
51 GLenum target = GL_TEXTURE_2D;
52
53 if (image)
54 {
55 if (image->flags & IMGFLAG_CUBEMAP)
56 target = GL_TEXTURE_CUBE_MAP;
57
58 image->frameUsed = tr.frameCount;
59 texture = image->texnum;
60 }
10461 else
105 texnum = image->texnum;
106
107 if ( glState.currenttextures[tmu] != texnum ) {
108 GL_SelectTexture( tmu );
109 if (image)
110 image->frameUsed = tr.frameCount;
111 glState.currenttextures[tmu] = texnum;
112
113 if (image && (image->flags & IMGFLAG_CUBEMAP))
114 qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
115 else
116 qglBindTexture( GL_TEXTURE_2D, texnum );
117 GL_SelectTexture( oldtmu );
118 }
62 {
63 ri.Printf(PRINT_WARNING, "GL_BindToTMU: NULL image\n");
64 }
65
66 GL_BindMultiTexture(GL_TEXTURE0_ARB + tmu, target, texture);
11967 }
12068
12169 /*
14492 }
14593
14694 glState.faceCulling = cullType;
147 }
148
149 /*
150 ** GL_TexEnv
151 */
152 void GL_TexEnv( int env ) {
153 if ( env == glState.texEnv[glState.currenttmu] ) {
154 return;
155 }
156
157 glState.texEnv[glState.currenttmu] = env;
158
159
160 switch ( env )
161 {
162 case GL_MODULATE:
163 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
164 break;
165 case GL_REPLACE:
166 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
167 break;
168 case GL_DECAL:
169 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
170 break;
171 case GL_ADD:
172 qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
173 break;
174 default:
175 ri.Error( ERR_DROP, "GL_TexEnv: invalid env '%d' passed", env );
176 break;
177 }
17895 }
17996
18097 /*
456373
457374 if (glRefConfig.framebufferObject)
458375 {
376 FBO_t *fbo = backEnd.viewParms.targetFbo;
377
459378 // FIXME: HUGE HACK: render to the screen fbo if we've already postprocessed the frame and aren't drawing more world
460379 // drawing more world check is in case of double renders, such as skyportals
461 if (backEnd.viewParms.targetFbo == NULL)
462 {
463 if (!tr.renderFbo || (backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL)))
464 {
465 FBO_Bind(NULL);
466 }
467 else
468 {
469 FBO_Bind(tr.renderFbo);
470 }
471 }
472 else
473 {
474 FBO_Bind(backEnd.viewParms.targetFbo);
475
476 // FIXME: hack for cubemap testing
477 if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
478 {
479 cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
480 //qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, backEnd.viewParms.targetFbo->colorImage[0]->texnum, 0);
481 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, cubemap->image->texnum, 0);
482 }
483 }
380 if (fbo == NULL && !(backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL)))
381 fbo = tr.renderFbo;
382
383 if (tr.renderCubeFbo && fbo == tr.renderCubeFbo)
384 {
385 cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
386 FBO_AttachImage(fbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, backEnd.viewParms.targetFboLayer);
387 }
388 FBO_Bind(fbo);
484389 }
485390
486391 //
693598
694599 void RB_ZombieFXProcessNewHits( trZombieFleshHitverts_t *fleshHitVerts, int oldNumVerts, int numSurfVerts ) {
695600 float *xyzTrav;
696 uint32_t *normTrav;
601 int16_t *normTrav;
697602 vec3_t hitPos, hitDir, v, testDir;
698603 float bestHitDist, thisDist;
699604 qboolean foundHit;
721626 foundHit = qfalse;
722627
723628 // for each vertex
724 for ( j = 0, bestHitDist = -1, xyzTrav = tess.xyz[oldNumVerts], normTrav = &tess.normal[oldNumVerts];
629 for ( j = 0, bestHitDist = -1, xyzTrav = tess.xyz[oldNumVerts], normTrav = tess.normal[oldNumVerts];
725630 j < numSurfVerts;
726 j++, xyzTrav += 4, normTrav++ ) {
631 j++, xyzTrav += 4, normTrav += 4 ) {
727632 vec3_t fNormTrav;
728633
729634 // if this vert has been hit enough times already
731636 continue;
732637 }
733638
734 R_VaoUnpackNormal(fNormTrav, *normTrav);
639 R_VaoUnpackNormal(fNormTrav, normTrav);
735640
736641 // if this normal faces the wrong way, reject it
737642 if ( DotProduct( fNormTrav, hitDir ) > 0 ) {
797702 }
798703
799704 void RB_ZombieFXShowFleshHits( trZombieFleshHitverts_t *fleshHitVerts, int oldNumVerts, int numSurfVerts ) {
800 byte *vertColors;
705 uint16_t *vertColors;
801706 unsigned short *vertHits;
802707 int i;
803708
804 vertColors = (byte *)tess.vertexColors[oldNumVerts];
709 vertColors = tess.color[oldNumVerts];
805710 vertHits = fleshHitVerts->vertHits;
806711
807712 // for each hit entry, adjust that verts alpha component
808713 for ( i = 0; i < fleshHitVerts->numHits; i++, vertHits++ ) {
809 if ( vertColors[( *vertHits ) * 4 + 3] < ZOMBIEFX_PERHIT_TAKEALPHA ) {
714 if ( vertColors[( *vertHits ) * 4 + 3] < ZOMBIEFX_PERHIT_TAKEALPHA * 257 ) {
810715 vertColors[( *vertHits ) * 4 + 3] = 0;
811716 } else {
812 vertColors[( *vertHits ) * 4 + 3] -= ZOMBIEFX_PERHIT_TAKEALPHA;
717 vertColors[( *vertHits ) * 4 + 3] -= ZOMBIEFX_PERHIT_TAKEALPHA * 257;
813718 }
814719 }
815720 }
816721
817722 void RB_ZombieFXDecompose( int oldNumVerts, int numSurfVerts, float deltaTimeScale ) {
818 byte *vertColors;
723 uint16_t *vertColors;
819724 float *xyz;
820 uint32_t *norm;
725 int16_t *norm;
821726 vec3_t fNorm;
822727 int i;
823728 float alpha;
824729
825 vertColors = (byte *)tess.vertexColors[oldNumVerts];
730 vertColors = tess.color[oldNumVerts];
826731 xyz = tess.xyz[oldNumVerts];
827 norm = &tess.normal[oldNumVerts];
828
829 for ( i = 0; i < numSurfVerts; i++, vertColors += 4, xyz += 4, norm++ ) {
830 alpha = 255.0 * ( (float)( 1 + i % 3 ) / 3.0 ) * deltaTimeScale * 2;
831 if ( alpha > 255.0 ) {
832 alpha = 255.0;
732 norm = tess.normal[oldNumVerts];
733
734 for ( i = 0; i < numSurfVerts; i++, vertColors += 4, xyz += 4, norm += 4 ) {
735 alpha = 65535.0 * ( (float)( 1 + i % 3 ) / 3.0 ) * deltaTimeScale * 2;
736 if ( alpha > 65535.0 ) {
737 alpha = 65535.0;
833738 }
834739 if ( (float)vertColors[3] - alpha < 0 ) {
835740 vertColors[3] = 0;
837742 vertColors[3] -= (byte)alpha;
838743 }
839744
840 R_VaoUnpackNormal(fNorm, *norm);
745 R_VaoUnpackNormal(fNorm, norm);
841746
842747 // skin shrinks with age
843748 VectorMA( xyz, -2.0 * deltaTimeScale, fNorm, xyz );
845750 }
846751
847752 void RB_ZombieFXFullAlpha( int oldNumVerts, int numSurfVerts ) {
848 byte *vertColors;
753 uint16_t *vertColors;
849754 int i;
850755
851 vertColors = (byte *)tess.vertexColors[oldNumVerts];
756 vertColors = tess.color[oldNumVerts];
852757
853758 for ( i = 0; i < numSurfVerts; i++, vertColors += 4 ) {
854 vertColors[3] = 255;
759 vertColors[3] = 65535;
855760 }
856761 }
857762
865770
866771 if ( *drawSurf->surface == SF_MDV ) {
867772 surfName = ( (mdvSurface_t *)drawSurf->surface )->name;
868 } else if ( *drawSurf->surface == SF_MDC ) {
869 surfName = ( (mdcSurface_t *)drawSurf->surface )->name;
870773 } else {
871774 Com_Printf( "RB_ZombieFX: unknown surface type\n" );
872775 return;
11631066 R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
11641067
11651068 if (inQuery) {
1166 qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
1069 qglEndQuery(GL_SAMPLES_PASSED);
11671070 }
11681071
11691072 if (glRefConfig.framebufferObject)
12321135 // set time for 2D shaders
12331136 backEnd.refdef.time = ri.Milliseconds();
12341137 backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f;
1235
1236 // reset color scaling
1237 backEnd.refdef.colorScale = 1.0f;
12381138 }
12391139
12401140
12801180 }
12811181
12821182 RE_UploadCinematic (w, h, cols, rows, data, client, dirty);
1183 GL_BindToTMU(tr.scratchImage[client], TB_COLORMAP);
12831184
12841185 if ( r_speeds->integer ) {
12851186 end = ri.Milliseconds();
12891190 // FIXME: HUGE hack
12901191 if (glRefConfig.framebufferObject)
12911192 {
1292 if (!tr.renderFbo || backEnd.framePostProcessed)
1293 {
1294 FBO_Bind(NULL);
1295 }
1296 else
1297 {
1298 FBO_Bind(tr.renderFbo);
1299 }
1193 FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo);
13001194 }
13011195
13021196 RB_SetGL2D();
13211215
13221216
13231217 void RE_UploadCinematic( int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty ) {
1324
1325 GL_Bind( tr.scratchImage[client] );
1218 GLuint texture;
1219
1220 if (!tr.scratchImage[client])
1221 {
1222 ri.Printf(PRINT_WARNING, "RE_UploadCinematic: scratch images not initialized\n");
1223 return;
1224 }
1225
1226 texture = tr.scratchImage[client]->texnum;
13261227
13271228 // if the scratchImage isn't in the format we want, specify it as a new texture
13281229 if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
13291230 tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
13301231 tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
1331 qglTexImage2D( GL_TEXTURE_2D, 0, 3, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
1332 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
1333 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1334 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1335 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
1232 qglTextureImage2DEXT(texture, GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
1233 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1234 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1235 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1236 qglTextureParameterfEXT(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
13361237 } else {
13371238 if ( dirty ) {
13381239 // otherwise, just subimage upload it so that drivers can tell we are going to be changing
13391240 // it and don't try and do a texture compression
1340 qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
1241 qglTextureSubImage2DEXT(texture, GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data);
13411242 }
13421243 }
13431244 }
13761277
13771278 // FIXME: HUGE hack
13781279 if (glRefConfig.framebufferObject)
1379 {
1380 if (!tr.renderFbo || backEnd.framePostProcessed)
1381 {
1382 FBO_Bind(NULL);
1383 }
1384 else
1385 {
1386 FBO_Bind(tr.renderFbo);
1387 }
1388 }
1280 FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo);
13891281
13901282 RB_SetGL2D();
13911283
14131305 tess.indexes[ numIndexes + 5 ] = numVerts + 1;
14141306
14151307 {
1416 vec4_t color;
1417
1418 VectorScale4(backEnd.color2D, 1.0f / 255.0f, color);
1419
1420 VectorCopy4(color, tess.vertexColors[ numVerts ]);
1421 VectorCopy4(color, tess.vertexColors[ numVerts + 1]);
1422 VectorCopy4(color, tess.vertexColors[ numVerts + 2]);
1423 VectorCopy4(color, tess.vertexColors[ numVerts + 3 ]);
1308 uint16_t color[4];
1309
1310 VectorScale4(backEnd.color2D, 257, color);
1311
1312 VectorCopy4(color, tess.color[ numVerts ]);
1313 VectorCopy4(color, tess.color[ numVerts + 1]);
1314 VectorCopy4(color, tess.color[ numVerts + 2]);
1315 VectorCopy4(color, tess.color[ numVerts + 3 ]);
14241316 }
14251317
14261318 tess.xyz[ numVerts ][0] = cmd->x;
15041396 tess.indexes[ numIndexes + 4 ] = numVerts + 0;
15051397 tess.indexes[ numIndexes + 5 ] = numVerts + 1;
15061398
1507 // *(int *)tess.vertexColors[ numVerts ] =
1508 // *(int *)tess.vertexColors[ numVerts + 1 ] =
1509 // *(int *)tess.vertexColors[ numVerts + 2 ] =
1510 // *(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)backEnd.color2D;
1511
1512 *(int *)tess.vertexColors[ numVerts ] =
1513 *(int *)tess.vertexColors[ numVerts + 1 ] = *(int *)backEnd.color2D;
1514
1515 *(int *)tess.vertexColors[ numVerts + 2 ] =
1516 *(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)cmd->gradientColor;
1399 {
1400 uint16_t color[4];
1401
1402 VectorScale4(backEnd.color2D, 257, color);
1403
1404 VectorCopy4(color, tess.color[ numVerts ]);
1405 VectorCopy4(color, tess.color[ numVerts + 1]);
1406
1407 VectorScale4(cmd->gradientColor, 257, color);
1408
1409 VectorCopy4(color, tess.color[ numVerts + 2]);
1410 VectorCopy4(color, tess.color[ numVerts + 3 ]);
1411 }
15171412
15181413 tess.xyz[ numVerts ][0] = cmd->x;
15191414 tess.xyz[ numVerts ][1] = cmd->y;
15771472 if (glRefConfig.framebufferObject && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW)))
15781473 {
15791474 FBO_t *oldFbo = glState.currentFBO;
1475 vec4_t viewInfo;
1476
1477 VectorSet4(viewInfo, backEnd.viewParms.zFar / r_znear->value, backEnd.viewParms.zFar, 0.0, 0.0);
15801478
15811479 backEnd.depthFill = qtrue;
15821480 qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
15891487 // If we're using multisampling, resolve the depth first
15901488 FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
15911489 }
1592 else if (tr.renderFbo == NULL)
1490 else if (tr.renderFbo == NULL && tr.renderDepthImage)
15931491 {
15941492 // If we're rendering directly to the screen, copy the depth to a texture
1595 GL_BindToTMU(tr.renderDepthImage, 0);
1596 qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
1597 }
1598
1599 if (r_ssao->integer)
1493 qglCopyTextureImage2DEXT(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
1494 }
1495
1496 if (tr.hdrDepthFbo)
16001497 {
16011498 // need the depth in a texture we can do GL_LINEAR sampling on, so copy it to an HDR image
1602 FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
1499 vec4_t srcTexCoords;
1500
1501 VectorSet4(srcTexCoords, 0.0f, 0.0f, 1.0f, 1.0f);
1502
1503 FBO_BlitFromTexture(tr.renderDepthImage, srcTexCoords, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
16031504 }
16041505
16051506 if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT)
16641565
16651566 GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
16661567 {
1667 vec4_t viewInfo;
16681568 vec3_t viewVector;
16691569
16701570 float zmax = backEnd.viewParms.zFar;
16711571 float ymax = zmax * tan(backEnd.viewParms.fovY * M_PI / 360.0f);
16721572 float xmax = zmax * tan(backEnd.viewParms.fovX * M_PI / 360.0f);
1673
1674 float zmin = r_znear->value;
16751573
16761574 VectorScale(backEnd.refdef.viewaxis[0], zmax, viewVector);
16771575 GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWFORWARD, viewVector);
16801578 VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector);
16811579 GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWUP, viewVector);
16821580
1683 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1684
16851581 GLSL_SetUniformVec4(&tr.shadowmaskShader, UNIFORM_VIEWINFO, viewInfo);
16861582 }
16871583
16881584
16891585 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
1586
1587 if (r_shadowBlur->integer)
1588 {
1589 viewInfo[2] = 1.0f / (float)(tr.screenScratchFbo->width);
1590 viewInfo[3] = 1.0f / (float)(tr.screenScratchFbo->height);
1591
1592 FBO_Bind(tr.screenScratchFbo);
1593
1594 GLSL_BindProgram(&tr.depthBlurShader[0]);
1595
1596 GL_BindToTMU(tr.screenShadowImage, TB_COLORMAP);
1597 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
1598
1599 GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
1600
1601 RB_InstantQuad2(quadVerts, texCoords);
1602
1603 FBO_Bind(tr.screenShadowFbo);
1604
1605 GLSL_BindProgram(&tr.depthBlurShader[1]);
1606
1607 GL_BindToTMU(tr.screenScratchImage, TB_COLORMAP);
1608 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
1609
1610 GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
1611
1612 RB_InstantQuad2(quadVerts, texCoords);
1613 }
16901614 }
16911615
16921616 if (r_ssao->integer)
16931617 {
16941618 vec4_t quadVerts[4];
16951619 vec2_t texCoords[4];
1620
1621 viewInfo[2] = 1.0f / ((float)(tr.quarterImage[0]->width) * tan(backEnd.viewParms.fovX * M_PI / 360.0f) * 2.0f);
1622 viewInfo[3] = 1.0f / ((float)(tr.quarterImage[0]->height) * tan(backEnd.viewParms.fovY * M_PI / 360.0f) * 2.0f);
1623 viewInfo[3] *= (float)backEnd.viewParms.viewportHeight / (float)backEnd.viewParms.viewportWidth;
16961624
16971625 FBO_Bind(tr.quarterFbo[0]);
16981626
17151643
17161644 GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP);
17171645
1718 {
1719 vec4_t viewInfo;
1720
1721 float zmax = backEnd.viewParms.zFar;
1722 float zmin = r_znear->value;
1723
1724 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1725
1726 GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
1727 }
1646 GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
17281647
17291648 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
17301649
1650
1651 viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width);
1652 viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height);
17311653
17321654 FBO_Bind(tr.quarterFbo[1]);
17331655
17391661 GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
17401662 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
17411663
1742 {
1743 vec4_t viewInfo;
1744
1745 float zmax = backEnd.viewParms.zFar;
1746 float zmin = r_znear->value;
1747
1748 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1749
1750 GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
1751 }
1664 GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
17521665
17531666 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
17541667
17631676 GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
17641677 GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
17651678
1766 {
1767 vec4_t viewInfo;
1768
1769 float zmax = backEnd.viewParms.zFar;
1770 float zmin = r_znear->value;
1771
1772 VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
1773
1774 GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
1775 }
1679 GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
17761680
17771681
17781682 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
17971701 RB_DrawSun(0.2, tr.sunShader);
17981702 }
17991703
1800 if (r_drawSunRays->integer)
1704 if (glRefConfig.framebufferObject && r_drawSunRays->integer)
18011705 {
18021706 FBO_t *oldFbo = glState.currentFBO;
18031707 FBO_Bind(tr.sunRaysFbo);
18081712 if (glRefConfig.occlusionQuery)
18091713 {
18101714 tr.sunFlareQueryActive[tr.sunFlareQueryIndex] = qtrue;
1811 qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, tr.sunFlareQuery[tr.sunFlareQueryIndex]);
1715 qglBeginQuery(GL_SAMPLES_PASSED, tr.sunFlareQuery[tr.sunFlareQueryIndex]);
18121716 }
18131717
18141718 RB_DrawSun(0.3, tr.sunFlareShader);
18151719
18161720 if (glRefConfig.occlusionQuery)
18171721 {
1818 qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
1722 qglEndQuery(GL_SAMPLES_PASSED);
18191723 }
18201724
18211725 FBO_Bind(oldFbo);
18331737 cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
18341738
18351739 FBO_Bind(NULL);
1836 GL_SelectTexture(TB_CUBEMAP);
1837 GL_BindToTMU(cubemap->image, TB_CUBEMAP);
1838 qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
1839 GL_SelectTexture(0);
1740 if (cubemap && cubemap->image)
1741 qglGenerateTextureMipmapEXT(cubemap->image->texnum, GL_TEXTURE_CUBE_MAP);
18401742 }
18411743
18421744 return (const void *)( cmd + 1 );
19151817 {
19161818 vec4_t quadVerts[4];
19171819
1918 GL_Bind(image);
1820 GL_BindToTMU(image, TB_COLORMAP);
19191821
19201822 VectorSet4(quadVerts[0], x, y, 0, 1);
19211823 VectorSet4(quadVerts[1], x + w, y, 0, 1);
20901992
20911993 if (cmd->map != -1)
20921994 {
2093 GL_SelectTexture(0);
20941995 if (cmd->cubeSide != -1)
20951996 {
20961997 if (tr.shadowCubemaps[cmd->map])
20971998 {
2098 GL_Bind(tr.shadowCubemaps[cmd->map]);
2099 qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
1999 qglCopyTextureImage2DEXT(tr.shadowCubemaps[cmd->map]->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
21002000 }
21012001 }
21022002 else
21032003 {
21042004 if (tr.pshadowMaps[cmd->map])
21052005 {
2106 GL_Bind(tr.pshadowMaps[cmd->map]);
2107 qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
2006 qglCopyTextureImage2DEXT(tr.pshadowMaps[cmd->map]->texnum, GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - (backEnd.refdef.y + PSHADOW_MAP_SIZE), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
21082007 }
21092008 }
21102009 }
21632062 srcBox[2] = backEnd.viewParms.viewportWidth * tr.screenSsaoImage->width / (float)glConfig.vidWidth;
21642063 srcBox[3] = backEnd.viewParms.viewportHeight * tr.screenSsaoImage->height / (float)glConfig.vidHeight;
21652064
2166 //FBO_BlitFromTexture(tr.screenSsaoImage, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
2167 srcBox[1] = tr.screenSsaoImage->height - srcBox[1];
2168 srcBox[3] = -srcBox[3];
2169
21702065 FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
21712066 }
21722067
21772072
21782073 if (srcFbo)
21792074 {
2180 if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer) && qglActiveTextureARB)
2075 if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer))
21812076 {
21822077 autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer;
21832078 RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure);
22062101 RB_BokehBlur(NULL, srcBox, NULL, dstBox, backEnd.refdef.blurFactor);
22072102 else
22082103 RB_GaussianBlur(backEnd.refdef.blurFactor);
2104
2105 #if 0
2106 if (0)
2107 {
2108 vec4_t quadVerts[4];
2109 vec2_t texCoords[4];
2110 ivec4_t iQtrBox;
2111 vec4_t box;
2112 vec4_t viewInfo;
2113 static float scale = 5.0f;
2114
2115 scale -= 0.005f;
2116 if (scale < 0.01f)
2117 scale = 5.0f;
2118
2119 FBO_FastBlit(NULL, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
2120
2121 iQtrBox[0] = backEnd.viewParms.viewportX * tr.quarterImage[0]->width / (float)glConfig.vidWidth;
2122 iQtrBox[1] = backEnd.viewParms.viewportY * tr.quarterImage[0]->height / (float)glConfig.vidHeight;
2123 iQtrBox[2] = backEnd.viewParms.viewportWidth * tr.quarterImage[0]->width / (float)glConfig.vidWidth;
2124 iQtrBox[3] = backEnd.viewParms.viewportHeight * tr.quarterImage[0]->height / (float)glConfig.vidHeight;
2125
2126 qglViewport(iQtrBox[0], iQtrBox[1], iQtrBox[2], iQtrBox[3]);
2127 qglScissor(iQtrBox[0], iQtrBox[1], iQtrBox[2], iQtrBox[3]);
2128
2129 VectorSet4(box, 0.0f, 0.0f, 1.0f, 1.0f);
2130
2131 texCoords[0][0] = box[0]; texCoords[0][1] = box[3];
2132 texCoords[1][0] = box[2]; texCoords[1][1] = box[3];
2133 texCoords[2][0] = box[2]; texCoords[2][1] = box[1];
2134 texCoords[3][0] = box[0]; texCoords[3][1] = box[1];
2135
2136 VectorSet4(box, -1.0f, -1.0f, 1.0f, 1.0f);
2137
2138 VectorSet4(quadVerts[0], box[0], box[3], 0, 1);
2139 VectorSet4(quadVerts[1], box[2], box[3], 0, 1);
2140 VectorSet4(quadVerts[2], box[2], box[1], 0, 1);
2141 VectorSet4(quadVerts[3], box[0], box[1], 0, 1);
2142
2143 GL_State(GLS_DEPTHTEST_DISABLE);
2144
2145
2146 VectorSet4(viewInfo, backEnd.viewParms.zFar / r_znear->value, backEnd.viewParms.zFar, 0.0, 0.0);
2147
2148 viewInfo[2] = scale / (float)(tr.quarterImage[0]->width);
2149 viewInfo[3] = scale / (float)(tr.quarterImage[0]->height);
2150
2151 FBO_Bind(tr.quarterFbo[1]);
2152 GLSL_BindProgram(&tr.depthBlurShader[2]);
2153 GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
2154 GLSL_SetUniformVec4(&tr.depthBlurShader[2], UNIFORM_VIEWINFO, viewInfo);
2155 RB_InstantQuad2(quadVerts, texCoords);
2156
2157 FBO_Bind(tr.quarterFbo[0]);
2158 GLSL_BindProgram(&tr.depthBlurShader[3]);
2159 GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
2160 GLSL_SetUniformVec4(&tr.depthBlurShader[3], UNIFORM_VIEWINFO, viewInfo);
2161 RB_InstantQuad2(quadVerts, texCoords);
2162
2163 SetViewportAndScissor();
2164
2165 FBO_FastBlit(tr.quarterFbo[1], NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
2166 FBO_Bind(NULL);
2167 }
2168 #endif
22092169
22102170 if (0 && r_sunlightMode->integer)
22112171 {
22562216 return (const void *)(cmd + 1);
22572217 }
22582218
2219 // FIXME: put this function declaration elsewhere
2220 void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth);
2221
2222 /*
2223 =============
2224 RB_ExportCubemaps
2225
2226 =============
2227 */
2228 const void *RB_ExportCubemaps(const void *data)
2229 {
2230 const exportCubemapsCommand_t *cmd = data;
2231
2232 // finish any 2D drawing if needed
2233 if (tess.numIndexes)
2234 RB_EndSurface();
2235
2236 if (!glRefConfig.framebufferObject || !tr.world || tr.numCubemaps == 0)
2237 {
2238 // do nothing
2239 ri.Printf(PRINT_ALL, "Nothing to export!\n");
2240 return (const void *)(cmd + 1);
2241 }
2242
2243 if (cmd)
2244 {
2245 FBO_t *oldFbo = glState.currentFBO;
2246 int sideSize = r_cubemapSize->integer * r_cubemapSize->integer * 4;
2247 byte *cubemapPixels = ri.Z_Malloc(sideSize * 6);
2248 int i, j;
2249
2250 FBO_Bind(tr.renderCubeFbo);
2251
2252 for (i = 0; i < tr.numCubemaps; i++)
2253 {
2254 char filename[MAX_QPATH];
2255 cubemap_t *cubemap = &tr.cubemaps[i];
2256 byte *p = cubemapPixels;
2257
2258 for (j = 0; j < 6; j++)
2259 {
2260 FBO_AttachImage(tr.renderCubeFbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, j);
2261 qglReadPixels(0, 0, r_cubemapSize->integer, r_cubemapSize->integer, GL_RGBA, GL_UNSIGNED_BYTE, p);
2262 p += sideSize;
2263 }
2264
2265 if (cubemap->name[0])
2266 {
2267 COM_StripExtension(cubemap->name, filename, MAX_QPATH);
2268 Q_strcat(filename, MAX_QPATH, ".dds");
2269 }
2270 else
2271 {
2272 Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i);
2273 }
2274
2275 R_SaveDDS(filename, cubemapPixels, r_cubemapSize->integer, r_cubemapSize->integer, 6);
2276 ri.Printf(PRINT_ALL, "Saved cubemap %d as %s\n", i, filename);
2277 }
2278
2279 FBO_Bind(oldFbo);
2280
2281 ri.Free(cubemapPixels);
2282 }
2283
2284 return (const void *)(cmd + 1);
2285 }
22592286
22602287 /*
22612288 ====================
23072334 case RC_POSTPROCESS:
23082335 data = RB_PostProcess(data);
23092336 break;
2337 case RC_EXPORT_CUBEMAPS:
2338 data = RB_ExportCubemaps(data);
2339 break;
23102340 case RC_END_OF_LIST:
23112341 default:
23122342 // finish any 2D drawing if needed
2828 // tr_map.c
2929
3030 #include "tr_local.h"
31
32 #define JSON_IMPLEMENTATION
33 #include "../qcommon/json.h"
34 #undef JSON_IMPLEMENTATION
3135
3236 /*
3337
106110 int shift, r, g, b;
107111
108112 // shift the color data based on overbright range
109 #if defined(USE_OVERBRIGHT)
110113 shift = r_mapOverBrightBits->integer - tr.overbrightBits;
111 #else
112 shift = 0;
113 #endif
114114
115115 // shift the data based on overbright range
116116 r = in[0] << shift;
140140
141141 ===============
142142 */
143 static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale )
143 static void R_ColorShiftLightingFloats(float in[4], float out[4])
144144 {
145145 float r, g, b;
146146
147 #if defined(USE_OVERBRIGHT)
148 scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits);
149 #endif
147 float scale = (1 << (r_mapOverBrightBits->integer - tr.overbrightBits)) / 255.0f;
150148
151149 r = in[0] * scale;
152150 g = in[1] * scale;
193191 }
194192
195193
196 void ColorToRGBA16F(const vec3_t color, unsigned short rgba16f[4])
194 void ColorToRGB16(const vec3_t color, uint16_t rgb16[3])
197195 {
198 rgba16f[0] = FloatToHalf(color[0]);
199 rgba16f[1] = FloatToHalf(color[1]);
200 rgba16f[2] = FloatToHalf(color[2]);
201 rgba16f[3] = FloatToHalf(1.0f);
196 rgb16[0] = color[0] * 65535.0f + 0.5f;
197 rgb16[1] = color[1] * 65535.0f + 0.5f;
198 rgb16[2] = color[2] * 65535.0f + 0.5f;
202199 }
203200
204201 /*
208205 ===============
209206 */
210207 #define DEFAULT_LIGHTMAP_SIZE 128
211 #define MAX_LIGHTMAP_PAGES 2
212208 static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
209 imgFlags_t imgFlags = IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE;
213210 byte *buf, *buf_p;
214211 dsurface_t *surf;
215212 int len;
216213 byte *image;
217214 int i, j, numLightmaps, textureInternalFormat = 0;
215 int numLightmapsPerPage = 16;
218216 float maxIntensity = 0;
219217 double sumIntensity = 0;
220218
254252 if (tr.worldDeluxeMapping)
255253 numLightmaps >>= 1;
256254
257 if(numLightmaps == 1)
258 {
259 //FIXME: HACK: maps with only one lightmap turn up fullbright for some reason.
260 //this avoids this, but isn't the correct solution.
261 numLightmaps++;
262 }
263 else if (r_mergeLightmaps->integer && numLightmaps >= 1024 )
264 {
265 // FIXME: fat light maps don't support more than 1024 light maps
266 ri.Printf(PRINT_WARNING, "WARNING: number of lightmaps > 1024\n");
267 numLightmaps = 1024;
268 }
269
270 // use fat lightmaps of an appropriate size
255 // Use fat lightmaps of an appropriate size.
271256 if (r_mergeLightmaps->integer)
272257 {
273 tr.fatLightmapSize = 512;
274 tr.fatLightmapStep = tr.fatLightmapSize / tr.lightmapSize;
275
276 // at most MAX_LIGHTMAP_PAGES
277 while (tr.fatLightmapStep * tr.fatLightmapStep * MAX_LIGHTMAP_PAGES < numLightmaps && tr.fatLightmapSize != glConfig.maxTextureSize )
278 {
279 tr.fatLightmapSize <<= 1;
280 tr.fatLightmapStep = tr.fatLightmapSize / tr.lightmapSize;
281 }
282
283 tr.numLightmaps = numLightmaps / (tr.fatLightmapStep * tr.fatLightmapStep);
284
285 if (numLightmaps % (tr.fatLightmapStep * tr.fatLightmapStep) != 0)
286 tr.numLightmaps++;
258 int maxLightmapsPerAxis = glConfig.maxTextureSize / tr.lightmapSize;
259 int lightmapCols = 4, lightmapRows = 4;
260
261 // Increase width at first, then height.
262 while (lightmapCols * lightmapRows < numLightmaps && lightmapCols != maxLightmapsPerAxis)
263 lightmapCols <<= 1;
264
265 while (lightmapCols * lightmapRows < numLightmaps && lightmapRows != maxLightmapsPerAxis)
266 lightmapRows <<= 1;
267
268 tr.fatLightmapCols = lightmapCols;
269 tr.fatLightmapRows = lightmapRows;
270 numLightmapsPerPage = lightmapCols * lightmapRows;
271
272 tr.numLightmaps = (numLightmaps + (numLightmapsPerPage - 1)) / numLightmapsPerPage;
287273 }
288274 else
289275 {
292278
293279 tr.lightmaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
294280 if (tr.worldDeluxeMapping)
295 {
296281 tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
297 }
298
299 if (glRefConfig.floatLightmap)
300 textureInternalFormat = GL_RGBA16F_ARB;
301 else
302 textureInternalFormat = GL_RGBA8;
282
283 textureInternalFormat = GL_RGBA8;
284 if (r_hdr->integer)
285 {
286 // Check for the first hdr lightmap, if it exists, use GL_RGBA16 for textures.
287 char filename[MAX_QPATH];
288
289 Com_sprintf(filename, sizeof(filename), "maps/%s/lm_0000.hdr", s_worldData.baseName);
290 if (ri.FS_FileExists(filename))
291 textureInternalFormat = GL_RGBA16;
292 }
303293
304294 if (r_mergeLightmaps->integer)
305295 {
296 int width = tr.fatLightmapCols * tr.lightmapSize;
297 int height = tr.fatLightmapRows * tr.lightmapSize;
298
306299 for (i = 0; i < tr.numLightmaps; i++)
307300 {
308 tr.lightmaps[i] = R_CreateImage(va("_fatlightmap%d", i), NULL, tr.fatLightmapSize, tr.fatLightmapSize, IMGTYPE_COLORALPHA, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, textureInternalFormat );
301 tr.lightmaps[i] = R_CreateImage(va("_fatlightmap%d", i), NULL, width, height, IMGTYPE_COLORALPHA, imgFlags, textureInternalFormat);
309302
310303 if (tr.worldDeluxeMapping)
311 {
312 tr.deluxemaps[i] = R_CreateImage(va("_fatdeluxemap%d", i), NULL, tr.fatLightmapSize, tr.fatLightmapSize, IMGTYPE_DELUXE, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, 0 );
313 }
304 tr.deluxemaps[i] = R_CreateImage(va("_fatdeluxemap%d", i), NULL, width, height, IMGTYPE_DELUXE, imgFlags, 0);
314305 }
315306 }
316307
321312 // expand the 24 bit on-disk to 32 bit
322313 if (r_mergeLightmaps->integer)
323314 {
324 int lightmaponpage = i % (tr.fatLightmapStep * tr.fatLightmapStep);
325 xoff = (lightmaponpage % tr.fatLightmapStep) * tr.lightmapSize;
326 yoff = (lightmaponpage / tr.fatLightmapStep) * tr.lightmapSize;
327
328 lightmapnum /= (tr.fatLightmapStep * tr.fatLightmapStep);
315 int lightmaponpage = i % numLightmapsPerPage;
316 xoff = (lightmaponpage % tr.fatLightmapCols) * tr.lightmapSize;
317 yoff = (lightmaponpage / tr.fatLightmapCols) * tr.lightmapSize;
318
319 lightmapnum /= numLightmapsPerPage;
329320 }
330321
331322 // if (tr.worldLightmapping)
335326 int size = 0;
336327
337328 // look for hdr lightmaps
338 if (r_hdr->integer)
329 if (textureInternalFormat == GL_RGBA16)
339330 {
340331 Com_sprintf( filename, sizeof( filename ), "maps/%s/lm_%04d.hdr", s_worldData.baseName, i * (tr.worldDeluxeMapping ? 2 : 1) );
341332 //ri.Printf(PRINT_ALL, "looking for %s\n", filename);
345336
346337 if (hdrLightmap)
347338 {
348 byte *p = hdrLightmap;
339 byte *p = hdrLightmap, *end = hdrLightmap + size;
349340 //ri.Printf(PRINT_ALL, "found!\n");
350341
351342 /* FIXME: don't just skip over this header and actually parse it */
352 while (size && !(*p == '\n' && *(p+1) == '\n'))
353 {
354 size--;
343 while (p < end && !(*p == '\n' && *(p+1) == '\n'))
355344 p++;
356 }
357
358 if (!size)
359 ri.Error(ERR_DROP, "Bad header for %s!", filename);
360
361 size -= 2;
345
362346 p += 2;
363347
364 while (size && !(*p == '\n'))
365 {
366 size--;
348 while (p < end && !(*p == '\n'))
367349 p++;
368 }
369
370 size--;
350
371351 p++;
372352
373 buf_p = (byte *)p;
353 if (p >= end)
354 ri.Error(ERR_DROP, "Bad header for %s!", filename);
355
356 buf_p = p;
374357
375358 #if 0 // HDRFILE_RGBE
376 if (size != tr.lightmapSize * tr.lightmapSize * 4)
359 if ((int)(end - hdrLightmap) != tr.lightmapSize * tr.lightmapSize * 4)
377360 ri.Error(ERR_DROP, "Bad size for %s (%i)!", filename, size);
378361 #else // HDRFILE_FLOAT
379 if (size != tr.lightmapSize * tr.lightmapSize * 12)
362 if ((int)(end - hdrLightmap) != tr.lightmapSize * tr.lightmapSize * 12)
380363 ri.Error(ERR_DROP, "Bad size for %s (%i)!", filename, size);
381364 #endif
382365 }
383366 else
384367 {
385 if (tr.worldDeluxeMapping)
386 buf_p = buf + (i * 2) * tr.lightmapSize * tr.lightmapSize * 3;
387 else
388 buf_p = buf + i * tr.lightmapSize * tr.lightmapSize * 3;
368 int imgOffset = tr.worldDeluxeMapping ? i * 2 : i;
369 buf_p = buf + imgOffset * tr.lightmapSize * tr.lightmapSize * 3;
389370 }
390371
391372 for ( j = 0 ; j < tr.lightmapSize * tr.lightmapSize; j++ )
408389 #endif
409390 color[3] = 1.0f;
410391
411 R_ColorShiftLightingFloats(color, color, 1.0f/255.0f);
412
413 if (glRefConfig.floatLightmap)
414 ColorToRGBA16F(color, (unsigned short *)(&image[j*8]));
415 else
416 ColorToRGBM(color, &image[j*4]);
392 R_ColorShiftLightingFloats(color, color);
393
394 ColorToRGB16(color, (uint16_t *)(&image[j * 8]));
395 ((uint16_t *)(&image[j * 8]))[3] = 65535;
417396 }
418 else if (glRefConfig.floatLightmap)
397 else if (textureInternalFormat == GL_RGBA16)
419398 {
420399 vec4_t color;
421400
435414 }
436415 color[3] = 1.0f;
437416
438 R_ColorShiftLightingFloats(color, color, 1.0f/255.0f);
439
440 ColorToRGBA16F(color, (unsigned short *)(&image[j*8]));
417 R_ColorShiftLightingFloats(color, color);
418
419 ColorToRGB16(color, (uint16_t *)(&image[j * 8]));
420 ((uint16_t *)(&image[j * 8]))[3] = 65535;
441421 }
442422 else
443423 {
478458 }
479459
480460 if (r_mergeLightmaps->integer)
481 R_UpdateSubImage(tr.lightmaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize);
461 R_UpdateSubImage(tr.lightmaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize, textureInternalFormat);
482462 else
483 tr.lightmaps[i] = R_CreateImage(va("*lightmap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_COLORALPHA, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, textureInternalFormat );
463 tr.lightmaps[i] = R_CreateImage(va("*lightmap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_COLORALPHA, imgFlags, textureInternalFormat );
484464
485465 if (hdrLightmap)
486466 ri.FS_FreeFile(hdrLightmap);
507487 }
508488
509489 if (r_mergeLightmaps->integer)
510 {
511 R_UpdateSubImage(tr.deluxemaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize );
512 }
490 R_UpdateSubImage(tr.deluxemaps[lightmapnum], image, xoff, yoff, tr.lightmapSize, tr.lightmapSize, GL_RGBA8 );
513491 else
514 {
515 tr.deluxemaps[i] = R_CreateImage(va("*deluxemap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_DELUXE, IMGFLAG_NOLIGHTSCALE | IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, 0 );
516 }
492 tr.deluxemaps[i] = R_CreateImage(va("*deluxemap%d", i), image, tr.lightmapSize, tr.lightmapSize, IMGTYPE_DELUXE, imgFlags, 0 );
517493 }
518494 }
519495
532508 if (tr.worldDeluxeMapping)
533509 lightmapnum >>= 1;
534510
535 if(tr.fatLightmapSize > 0)
536 {
537 int x;
538
539 lightmapnum %= (tr.fatLightmapStep * tr.fatLightmapStep);
540
541 x = lightmapnum % tr.fatLightmapStep;
542
543 return (input / ((float)tr.fatLightmapStep)) + ((1.0 / ((float)tr.fatLightmapStep)) * (float)x);
511 if (tr.fatLightmapCols > 0)
512 {
513 lightmapnum %= (tr.fatLightmapCols * tr.fatLightmapRows);
514 return (input + (lightmapnum % tr.fatLightmapCols)) / (float)(tr.fatLightmapCols);
544515 }
545516
546517 return input;
554525 if (tr.worldDeluxeMapping)
555526 lightmapnum >>= 1;
556527
557 if(tr.fatLightmapSize > 0)
558 {
559 int y;
560
561 lightmapnum %= (tr.fatLightmapStep * tr.fatLightmapStep);
562
563 y = lightmapnum / tr.fatLightmapStep;
564
565 return (input / ((float)tr.fatLightmapStep)) + ((1.0 / ((float)tr.fatLightmapStep)) * (float)y);
528 if (tr.fatLightmapCols > 0)
529 {
530 lightmapnum %= (tr.fatLightmapCols * tr.fatLightmapRows);
531 return (input + (lightmapnum / tr.fatLightmapCols)) / (float)(tr.fatLightmapRows);
566532 }
567533
568534 return input;
577543 if (tr.worldDeluxeMapping)
578544 lightmapnum >>= 1;
579545
580 if (tr.fatLightmapSize > 0)
581 {
582 return lightmapnum / (tr.fatLightmapStep * tr.fatLightmapStep);
583 }
546 if (tr.fatLightmapCols > 0)
547 return lightmapnum / (tr.fatLightmapCols * tr.fatLightmapRows);
584548
585549 return lightmapnum;
586550 }
705669
706670 return (void *)retval;
707671 }
672
673 void LoadDrawVertToSrfVert(srfVert_t *s, drawVert_t *d, int realLightmapNum, float hdrVertColors[3], vec3_t *bounds)
674 {
675 vec4_t v;
676
677 s->xyz[0] = LittleFloat(d->xyz[0]);
678 s->xyz[1] = LittleFloat(d->xyz[1]);
679 s->xyz[2] = LittleFloat(d->xyz[2]);
680
681 if (bounds)
682 AddPointToBounds(s->xyz, bounds[0], bounds[1]);
683
684 s->st[0] = LittleFloat(d->st[0]);
685 s->st[1] = LittleFloat(d->st[1]);
686
687 if (realLightmapNum >= 0)
688 {
689 s->lightmap[0] = FatPackU(LittleFloat(d->lightmap[0]), realLightmapNum);
690 s->lightmap[1] = FatPackV(LittleFloat(d->lightmap[1]), realLightmapNum);
691 }
692 else
693 {
694 s->lightmap[0] = LittleFloat(d->lightmap[0]);
695 s->lightmap[1] = LittleFloat(d->lightmap[1]);
696 }
697
698 v[0] = LittleFloat(d->normal[0]);
699 v[1] = LittleFloat(d->normal[1]);
700 v[2] = LittleFloat(d->normal[2]);
701
702 R_VaoPackNormal(s->normal, v);
703
704 if (hdrVertColors)
705 {
706 v[0] = hdrVertColors[0];
707 v[1] = hdrVertColors[1];
708 v[2] = hdrVertColors[2];
709 }
710 else
711 {
712 //hack: convert LDR vertex colors to HDR
713 if (r_hdr->integer)
714 {
715 v[0] = MAX(d->color[0], 0.499f);
716 v[1] = MAX(d->color[1], 0.499f);
717 v[2] = MAX(d->color[2], 0.499f);
718 }
719 else
720 {
721 v[0] = d->color[0];
722 v[1] = d->color[1];
723 v[2] = d->color[2];
724 }
725
726 }
727 v[3] = d->color[3] / 255.0f;
728
729 R_ColorShiftLightingFloats(v, v);
730 R_VaoPackColor(s->color, v);
731 }
732
708733
709734 /*
710735 ===============
753778 ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
754779 verts += LittleLong(ds->firstVert);
755780 for(i = 0; i < numVerts; i++)
756 {
757 vec4_t color;
758
759 for(j = 0; j < 3; j++)
760 {
761 cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]);
762 cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]);
763 }
764 AddPointToBounds(cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
765 for(j = 0; j < 2; j++)
766 {
767 cv->verts[i].st[j] = LittleFloat(verts[i].st[j]);
768 //cv->verts[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]);
769 }
770 cv->verts[i].lightmap[0] = FatPackU(LittleFloat(verts[i].lightmap[0]), realLightmapNum);
771 cv->verts[i].lightmap[1] = FatPackV(LittleFloat(verts[i].lightmap[1]), realLightmapNum);
772
773 if (hdrVertColors)
774 {
775 color[0] = hdrVertColors[(ds->firstVert + i) * 3 ];
776 color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1];
777 color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2];
778 }
779 else
780 {
781 //hack: convert LDR vertex colors to HDR
782 if (r_hdr->integer)
783 {
784 color[0] = MAX(verts[i].color[0], 0.499f);
785 color[1] = MAX(verts[i].color[1], 0.499f);
786 color[2] = MAX(verts[i].color[2], 0.499f);
787 }
788 else
789 {
790 color[0] = verts[i].color[0];
791 color[1] = verts[i].color[1];
792 color[2] = verts[i].color[2];
793 }
794
795 }
796 color[3] = verts[i].color[3] / 255.0f;
797
798 R_ColorShiftLightingFloats( color, cv->verts[i].vertexColors, 1.0f / 255.0f );
799 }
781 LoadDrawVertToSrfVert(&cv->verts[i], &verts[i], realLightmapNum, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, surf->cullinfo.bounds);
800782
801783 // copy triangles
802784 badTriangles = 0;
837819
838820 surf->data = (surfaceType_t *)cv;
839821
840 #ifdef USE_VERT_TANGENT_SPACE
841822 // Calculate tangent spaces
842823 {
843824 srfVert_t *dv[3];
851832 R_CalcTangentVectors(dv);
852833 }
853834 }
854 #endif
855835 }
856836
857837
861841 ===============
862842 */
863843 static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf ) {
864 srfBspSurface_t *grid;
865 int i, j;
844 srfBspSurface_t *grid = (srfBspSurface_t *)surf->data;
845 int i;
866846 int width, height, numPoints;
867847 srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE];
868848 vec3_t bounds[2];
897877 verts += LittleLong( ds->firstVert );
898878 numPoints = width * height;
899879 for(i = 0; i < numPoints; i++)
900 {
901 vec4_t color;
902
903 for(j = 0; j < 3; j++)
904 {
905 points[i].xyz[j] = LittleFloat(verts[i].xyz[j]);
906 points[i].normal[j] = LittleFloat(verts[i].normal[j]);
907 }
908
909 for(j = 0; j < 2; j++)
910 {
911 points[i].st[j] = LittleFloat(verts[i].st[j]);
912 //points[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]);
913 }
914 points[i].lightmap[0] = FatPackU(LittleFloat(verts[i].lightmap[0]), realLightmapNum);
915 points[i].lightmap[1] = FatPackV(LittleFloat(verts[i].lightmap[1]), realLightmapNum);
916
917 if (hdrVertColors)
918 {
919 color[0] = hdrVertColors[(ds->firstVert + i) * 3 ];
920 color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1];
921 color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2];
922 }
923 else
924 {
925 //hack: convert LDR vertex colors to HDR
926 if (r_hdr->integer)
927 {
928 color[0] = MAX(verts[i].color[0], 0.499f);
929 color[1] = MAX(verts[i].color[1], 0.499f);
930 color[2] = MAX(verts[i].color[2], 0.499f);
931 }
932 else
933 {
934 color[0] = verts[i].color[0];
935 color[1] = verts[i].color[1];
936 color[2] = verts[i].color[2];
937 }
938 }
939 color[3] = verts[i].color[3] / 255.0f;
940
941 R_ColorShiftLightingFloats( color, points[i].vertexColors, 1.0f / 255.0f );
942 }
880 LoadDrawVertToSrfVert(&points[i], &verts[i], realLightmapNum, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, NULL);
943881
944882 // pre-tesseleate
945 grid = R_SubdividePatchToGrid( width, height, points );
946 surf->data = (surfaceType_t *)grid;
883 R_SubdividePatchToGrid( grid, width, height, points );
947884
948885 // copy the level of detail origin, which is the center
949886 // of the group of all curves that must subdivide the same
956893 VectorScale( bounds[1], 0.5f, grid->lodOrigin );
957894 VectorSubtract( bounds[0], grid->lodOrigin, tmpVec );
958895 grid->lodRadius = VectorLength( tmpVec );
896
897 surf->cullinfo.type = CULLINFO_BOX | CULLINFO_SPHERE;
898 VectorCopy(grid->cullBounds[0], surf->cullinfo.bounds[0]);
899 VectorCopy(grid->cullBounds[1], surf->cullinfo.bounds[1]);
900 VectorCopy(grid->cullOrigin, surf->cullinfo.localOrigin);
901 surf->cullinfo.radius = grid->cullRadius;
959902 }
960903
961904 /*
998941 ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
999942 verts += LittleLong(ds->firstVert);
1000943 for(i = 0; i < numVerts; i++)
1001 {
1002 vec4_t color;
1003
1004 for(j = 0; j < 3; j++)
1005 {
1006 cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]);
1007 cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]);
1008 }
1009 AddPointToBounds( cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1] );
1010
1011 for(j = 0; j < 2; j++)
1012 {
1013 cv->verts[i].st[j] = LittleFloat(verts[i].st[j]);
1014 cv->verts[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]);
1015 }
1016
1017 if (hdrVertColors)
1018 {
1019 color[0] = hdrVertColors[(ds->firstVert + i) * 3 ];
1020 color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1];
1021 color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2];
1022 }
1023 else
1024 {
1025 //hack: convert LDR vertex colors to HDR
1026 if (r_hdr->integer)
1027 {
1028 color[0] = MAX(verts[i].color[0], 0.499f);
1029 color[1] = MAX(verts[i].color[1], 0.499f);
1030 color[2] = MAX(verts[i].color[2], 0.499f);
1031 }
1032 else
1033 {
1034 color[0] = verts[i].color[0];
1035 color[1] = verts[i].color[1];
1036 color[2] = verts[i].color[2];
1037 }
1038 }
1039 color[3] = verts[i].color[3] / 255.0f;
1040
1041 R_ColorShiftLightingFloats( color, cv->verts[i].vertexColors, 1.0f / 255.0f );
1042 }
944 LoadDrawVertToSrfVert(&cv->verts[i], &verts[i], -1, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, surf->cullinfo.bounds);
1043945
1044946 // copy triangles
1045947 badTriangles = 0;
1069971 cv->numIndexes -= badTriangles * 3;
1070972 }
1071973
1072 #ifdef USE_VERT_TANGENT_SPACE
1073974 // Calculate tangent spaces
1074975 {
1075976 srfVert_t *dv[3];
1083984 R_CalcTangentVectors(dv);
1084985 }
1085986 }
1086 #endif
1087987 }
1088988
1089989 /*
11151015 flare->color[i] = LittleFloat( ds->lightmapVecs[0][i] );
11161016 flare->normal[i] = LittleFloat( ds->lightmapVecs[2][i] );
11171017 }
1018
1019 surf->cullinfo.type = CULLINFO_NONE;
11181020 }
11191021
11201022
14411343 if ( m ) {
14421344 row = grid2->height - 1;
14431345 } else { row = 0;}
1444 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1445 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1346 R_GridInsertColumn( grid2, l + 1, row,
1347 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
14461348 grid2->lodStitched = qfalse;
14471349 s_worldData.surfaces[grid2num].data = (void *) grid2;
14481350 return qtrue;
14971399 if ( m ) {
14981400 column = grid2->width - 1;
14991401 } else { column = 0;}
1500 grid2 = R_GridInsertRow( grid2, l + 1, column,
1501 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1402 R_GridInsertRow( grid2, l + 1, column,
1403 grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k + 1] );
15021404 grid2->lodStitched = qfalse;
15031405 s_worldData.surfaces[grid2num].data = (void *) grid2;
15041406 return qtrue;
15641466 if ( m ) {
15651467 row = grid2->height - 1;
15661468 } else { row = 0;}
1567 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1568 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1469 R_GridInsertColumn( grid2, l + 1, row,
1470 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
15691471 grid2->lodStitched = qfalse;
15701472 s_worldData.surfaces[grid2num].data = (void *) grid2;
15711473 return qtrue;
16201522 if ( m ) {
16211523 column = grid2->width - 1;
16221524 } else { column = 0;}
1623 grid2 = R_GridInsertRow( grid2, l + 1, column,
1624 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1525 R_GridInsertRow( grid2, l + 1, column,
1526 grid1->verts[grid1->width * ( k + 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
16251527 grid2->lodStitched = qfalse;
16261528 s_worldData.surfaces[grid2num].data = (void *) grid2;
16271529 return qtrue;
16881590 if ( m ) {
16891591 row = grid2->height - 1;
16901592 } else { row = 0;}
1691 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1692 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1593 R_GridInsertColumn( grid2, l + 1, row,
1594 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
16931595 grid2->lodStitched = qfalse;
16941596 s_worldData.surfaces[grid2num].data = (void *) grid2;
16951597 return qtrue;
17441646 if ( m ) {
17451647 column = grid2->width - 1;
17461648 } else { column = 0;}
1747 grid2 = R_GridInsertRow( grid2, l + 1, column,
1748 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
1649 R_GridInsertRow( grid2, l + 1, column,
1650 grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k + 1] );
17491651 if ( !grid2 ) {
17501652 break;
17511653 }
18141716 if ( m ) {
18151717 row = grid2->height - 1;
18161718 } else { row = 0;}
1817 grid2 = R_GridInsertColumn( grid2, l + 1, row,
1818 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1719 R_GridInsertColumn( grid2, l + 1, row,
1720 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
18191721 grid2->lodStitched = qfalse;
18201722 s_worldData.surfaces[grid2num].data = (void *) grid2;
18211723 return qtrue;
18701772 if ( m ) {
18711773 column = grid2->width - 1;
18721774 } else { column = 0;}
1873 grid2 = R_GridInsertRow( grid2, l + 1, column,
1874 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
1775 R_GridInsertRow( grid2, l + 1, column,
1776 grid1->verts[grid1->width * ( k - 1 ) + offset1].xyz, grid1->heightLodError[k + 1] );
18751777 grid2->lodStitched = qfalse;
18761778 s_worldData.surfaces[grid2num].data = (void *) grid2;
18771779 return qtrue;
19721874 ===============
19731875 */
19741876 void R_MovePatchSurfacesToHunk( void ) {
1975 int i, size;
1976 srfBspSurface_t *grid, *hunkgrid;
1877 int i;
1878 srfBspSurface_t *grid;
19771879
19781880 for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
1881 void *copyFrom;
19791882 //
19801883 grid = (srfBspSurface_t *) s_worldData.surfaces[i].data;
19811884 // if this surface is not a grid
19831886 continue;
19841887 }
19851888 //
1986 size = sizeof(*grid);
1987 hunkgrid = ri.Hunk_Alloc(size, h_low);
1988 Com_Memcpy( hunkgrid, grid, size );
1989
1990 hunkgrid->widthLodError = ri.Hunk_Alloc( grid->width * 4, h_low );
1991 Com_Memcpy( hunkgrid->widthLodError, grid->widthLodError, grid->width * 4 );
1992
1993 hunkgrid->heightLodError = ri.Hunk_Alloc( grid->height * 4, h_low );
1994 Com_Memcpy( hunkgrid->heightLodError, grid->heightLodError, grid->height * 4 );
1995
1996 hunkgrid->numIndexes = grid->numIndexes;
1997 hunkgrid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low);
1998 Com_Memcpy(hunkgrid->indexes, grid->indexes, grid->numIndexes * sizeof(glIndex_t));
1999
2000 hunkgrid->numVerts = grid->numVerts;
2001 hunkgrid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low);
2002 Com_Memcpy(hunkgrid->verts, grid->verts, grid->numVerts * sizeof(srfVert_t));
2003
2004 R_FreeSurfaceGridMesh( grid );
2005
2006 s_worldData.surfaces[i].data = (void *) hunkgrid;
1889 copyFrom = grid->widthLodError;
1890 grid->widthLodError = ri.Hunk_Alloc( grid->width * 4, h_low );
1891 Com_Memcpy(grid->widthLodError, copyFrom, grid->width * 4);
1892 ri.Free(copyFrom);
1893
1894 copyFrom = grid->heightLodError;
1895 grid->heightLodError = ri.Hunk_Alloc(grid->height * 4, h_low);
1896 Com_Memcpy(grid->heightLodError, copyFrom, grid->height * 4);
1897 ri.Free(copyFrom);
1898
1899 copyFrom = grid->indexes;
1900 grid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low);
1901 Com_Memcpy(grid->indexes, copyFrom, grid->numIndexes * sizeof(glIndex_t));
1902 ri.Free(copyFrom);
1903
1904 copyFrom = grid->verts;
1905 grid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low);
1906 Com_Memcpy(grid->verts, copyFrom, grid->numVerts * sizeof(srfVert_t));
1907 ri.Free(copyFrom);
20071908 }
20081909 }
20091910
20551956 static void CopyVert(const srfVert_t * in, srfVert_t * out)
20561957 {
20571958 VectorCopy(in->xyz, out->xyz);
2058 #ifdef USE_VERT_TANGENT_SPACE
20591959 VectorCopy4(in->tangent, out->tangent);
2060 #endif
2061 VectorCopy(in->normal, out->normal);
2062 VectorCopy(in->lightdir, out->lightdir);
1960 VectorCopy4(in->normal, out->normal);
1961 VectorCopy4(in->lightdir, out->lightdir);
20631962
20641963 VectorCopy2(in->st, out->st);
20651964 VectorCopy2(in->lightmap, out->lightmap);
20661965
2067 VectorCopy4(in->vertexColors, out->vertexColors);
1966 VectorCopy4(in->color, out->color);
20681967 }
20691968
20701969
23362235 // -1 represents 0, -2 represents 1, and so on
23372236 s_worldData.viewSurfaces = ri.Hunk_Alloc(sizeof(*s_worldData.viewSurfaces) * s_worldData.nummarksurfaces, h_low);
23382237
2339 // copy view surfaces into mark surfaces
2340 for (i = 0; i < s_worldData.nummarksurfaces; i++)
2341 {
2342 s_worldData.viewSurfaces[i] = s_worldData.marksurfaces[i];
2343 }
2344
23452238 // actually merge surfaces
23462239 mergedSurf = s_worldData.mergedSurfaces;
23472240 for(firstSurf = lastSurf = surfacesSorted; firstSurf < surfacesSorted + numSortedSurfaces; firstSurf = lastSurf)
24022295 mergedSurf->cubemapIndex = (*firstSurf)->cubemapIndex;
24032296 mergedSurf->shader = (*firstSurf)->shader;
24042297
2405 // redirect view surfaces to this surf
2298 // change surfacesViewCount[] from leaf index to viewSurface index - 1 so we can redirect later
2299 // subtracting 2 (viewSurface index - 1) to avoid collision with -1 (no leaf)
24062300 for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
2407 s_worldData.surfacesViewCount[*currSurf - s_worldData.surfaces] = -2;
2408
2409 for (k = 0; k < s_worldData.nummarksurfaces; k++)
2410 {
2411 if (s_worldData.surfacesViewCount[s_worldData.marksurfaces[k]] == -2)
2412 s_worldData.viewSurfaces[k] = -((int)(mergedSurf - s_worldData.mergedSurfaces) + 1);
2413 }
2414
2415 for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
2416 s_worldData.surfacesViewCount[*currSurf - s_worldData.surfaces] = -1;
2301 s_worldData.surfacesViewCount[*currSurf - s_worldData.surfaces] = -((int)(mergedSurf - s_worldData.mergedSurfaces)) - 2;
24172302
24182303 mergedSurf++;
24192304 }
24202305
2421 ri.Printf(PRINT_ALL, "Processed %d mergeable surfaces into %d merged, %d unmerged\n",
2306 // direct viewSurfaces to merged and unmerged surfaces
2307 for (i = 0; i < s_worldData.nummarksurfaces; i++)
2308 {
2309 int viewSurfaceIndex = s_worldData.surfacesViewCount[s_worldData.marksurfaces[i]] + 1;
2310 s_worldData.viewSurfaces[i] = (viewSurfaceIndex < 0) ? viewSurfaceIndex : s_worldData.marksurfaces[i];
2311 }
2312
2313 ri.Printf(PRINT_ALL, "Processed %d mergeable surfaces into %d merged, %d unmerged\n",
24222314 numSortedSurfaces, numMergedSurfaces, numUnmergedSurfaces);
24232315 }
24242316
25062398 for ( i = 0 ; i < count ; i++, in++, out++ ) {
25072399 switch ( LittleLong( in->surfaceType ) ) {
25082400 case MST_PATCH:
2509 // FIXME: do this
2401 out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
25102402 break;
25112403 case MST_TRIANGLE_SOUP:
25122404 out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
25282420 switch ( LittleLong( in->surfaceType ) ) {
25292421 case MST_PATCH:
25302422 ParseMesh ( in, dv, hdrVertColors, out );
2531 {
2532 srfBspSurface_t *surface = (srfBspSurface_t *)out->data;
2533
2534 out->cullinfo.type = CULLINFO_BOX | CULLINFO_SPHERE;
2535 VectorCopy(surface->cullBounds[0], out->cullinfo.bounds[0]);
2536 VectorCopy(surface->cullBounds[1], out->cullinfo.bounds[1]);
2537 VectorCopy(surface->cullOrigin, out->cullinfo.localOrigin);
2538 out->cullinfo.radius = surface->cullRadius;
2539 }
25402423 numMeshes++;
25412424 break;
25422425 case MST_TRIANGLE_SOUP:
25492432 break;
25502433 case MST_FLARE:
25512434 ParseFlare( in, dv, out, indexes );
2552 {
2553 out->cullinfo.type = CULLINFO_NONE;
2554 }
25552435 numFlares++;
25562436 break;
25572437 default:
29062786
29072787 out->parms = shader->fogParms;
29082788
2909 out->colorInt = ColorBytes4( shader->fogParms.color[0] * tr.identityLight,
2910 shader->fogParms.color[1] * tr.identityLight,
2911 shader->fogParms.color[2] * tr.identityLight, 1.0 );
2789 out->colorInt = ColorBytes4 ( shader->fogParms.color[0],
2790 shader->fogParms.color[1],
2791 shader->fogParms.color[2], 1.0 );
29122792
29132793 d = shader->fogParms.depthForOpaque < 1 ? 1 : shader->fogParms.depthForOpaque;
29142794 out->tcScale = 1.0f / ( d * 8 );
30982978
30992979 if (hdrLightGrid)
31002980 {
3101 #if defined(USE_OVERBRIGHT)
3102 float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits);
3103 #else
3104 float lightScale = 1.0f;
3105 #endif
3106
31072981 //ri.Printf(PRINT_ALL, "found!\n");
31082982
31092983 if (size != sizeof(float) * 6 * numGridPoints)
3110 {
31112984 ri.Error(ERR_DROP, "Bad size for %s (%i, expected %i)!", filename, size, (int)(sizeof(float)) * 6 * numGridPoints);
3112 }
3113
3114 w->hdrLightGrid = ri.Hunk_Alloc(size, h_low);
2985
2986 w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints, h_low);
31152987
31162988 for (i = 0; i < numGridPoints ; i++)
31172989 {
3118 w->hdrLightGrid[i * 6 ] = hdrLightGrid[i * 6 ] * lightScale;
3119 w->hdrLightGrid[i * 6 + 1] = hdrLightGrid[i * 6 + 1] * lightScale;
3120 w->hdrLightGrid[i * 6 + 2] = hdrLightGrid[i * 6 + 2] * lightScale;
3121 w->hdrLightGrid[i * 6 + 3] = hdrLightGrid[i * 6 + 3] * lightScale;
3122 w->hdrLightGrid[i * 6 + 4] = hdrLightGrid[i * 6 + 4] * lightScale;
3123 w->hdrLightGrid[i * 6 + 5] = hdrLightGrid[i * 6 + 5] * lightScale;
2990 vec4_t c;
2991
2992 c[0] = hdrLightGrid[i * 6];
2993 c[1] = hdrLightGrid[i * 6 + 1];
2994 c[2] = hdrLightGrid[i * 6 + 2];
2995 c[3] = 1.0f;
2996
2997 R_ColorShiftLightingFloats(c, c);
2998 ColorToRGB16(c, &w->lightGrid16[i * 6]);
2999
3000 c[0] = hdrLightGrid[i * 6 + 3];
3001 c[1] = hdrLightGrid[i * 6 + 4];
3002 c[2] = hdrLightGrid[i * 6 + 5];
3003 c[3] = 1.0f;
3004
3005 R_ColorShiftLightingFloats(c, c);
3006 ColorToRGB16(c, &w->lightGrid16[i * 6 + 3]);
3007 }
3008 }
3009 else if (0)
3010 {
3011 // promote 8-bit lightgrid to 16-bit
3012 w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints, h_low);
3013
3014 for (i = 0; i < numGridPoints; i++)
3015 {
3016 w->lightGrid16[i * 6] = w->lightGridData[i * 8] * 257;
3017 w->lightGrid16[i * 6 + 1] = w->lightGridData[i * 8 + 1] * 257;
3018 w->lightGrid16[i * 6 + 2] = w->lightGridData[i * 8 + 2] * 257;
3019 w->lightGrid16[i * 6 + 3] = w->lightGridData[i * 8 + 3] * 257;
3020 w->lightGrid16[i * 6 + 4] = w->lightGridData[i * 8 + 4] * 257;
3021 w->lightGrid16[i * 6 + 5] = w->lightGridData[i * 8 + 5] * 257;
31243022 }
31253023 }
31263024
33093207 return qtrue;
33103208 }
33113209
3210 void R_LoadEnvironmentJson(const char *baseName)
3211 {
3212 char filename[MAX_QPATH];
3213
3214 union {
3215 char *c;
3216 void *v;
3217 } buffer;
3218 char *bufferEnd;
3219
3220 const char *cubemapArrayJson;
3221 int filelen, i;
3222
3223 Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/env.json", baseName);
3224
3225 filelen = ri.FS_ReadFile(filename, &buffer.v);
3226 if (!buffer.c)
3227 return;
3228 bufferEnd = buffer.c + filelen;
3229
3230 if (JSON_ValueGetType(buffer.c, bufferEnd) != JSONTYPE_OBJECT)
3231 {
3232 ri.Printf(PRINT_ALL, "Bad %s: does not start with a object\n", filename);
3233 ri.FS_FreeFile(buffer.v);
3234 return;
3235 }
3236
3237 cubemapArrayJson = JSON_ObjectGetNamedValue(buffer.c, bufferEnd, "Cubemaps");
3238 if (!cubemapArrayJson)
3239 {
3240 ri.Printf(PRINT_ALL, "Bad %s: no Cubemaps\n", filename);
3241 ri.FS_FreeFile(buffer.v);
3242 return;
3243 }
3244
3245 if (JSON_ValueGetType(cubemapArrayJson, bufferEnd) != JSONTYPE_ARRAY)
3246 {
3247 ri.Printf(PRINT_ALL, "Bad %s: Cubemaps not an array\n", filename);
3248 ri.FS_FreeFile(buffer.v);
3249 return;
3250 }
3251
3252 tr.numCubemaps = JSON_ArrayGetIndex(cubemapArrayJson, bufferEnd, NULL, 0);
3253 tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low);
3254 memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps));
3255
3256 for (i = 0; i < tr.numCubemaps; i++)
3257 {
3258 cubemap_t *cubemap = &tr.cubemaps[i];
3259 const char *cubemapJson, *keyValueJson, *indexes[3];
3260 int j;
3261
3262 cubemapJson = JSON_ArrayGetValue(cubemapArrayJson, bufferEnd, i);
3263
3264 keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Name");
3265 if (!JSON_ValueGetString(keyValueJson, bufferEnd, cubemap->name, MAX_QPATH))
3266 cubemap->name[0] = '\0';
3267
3268 keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Position");
3269 JSON_ArrayGetIndex(keyValueJson, bufferEnd, indexes, 3);
3270 for (j = 0; j < 3; j++)
3271 cubemap->origin[j] = JSON_ValueGetFloat(indexes[j], bufferEnd);
3272
3273 cubemap->parallaxRadius = 1000.0f;
3274 keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Radius");
3275 if (keyValueJson)
3276 cubemap->parallaxRadius = JSON_ValueGetFloat(keyValueJson, bufferEnd);
3277 }
3278
3279 ri.FS_FreeFile(buffer.v);
3280 }
3281
33123282 void R_LoadCubemapEntities(char *cubemapEntityName)
33133283 {
33143284 char spawnVarChars[2048];
33403310 while(R_ParseSpawnVars(spawnVarChars, sizeof(spawnVarChars), &numSpawnVars, spawnVars))
33413311 {
33423312 int i;
3313 char name[MAX_QPATH];
33433314 qboolean isCubemap = qfalse;
33443315 qboolean originSet = qfalse;
33453316 vec3_t origin;
33463317 float parallaxRadius = 1000.0f;
33473318
3319 name[0] = '\0';
33483320 for (i = 0; i < numSpawnVars; i++)
33493321 {
33503322 if (!Q_stricmp(spawnVars[i][0], "classname") && !Q_stricmp(spawnVars[i][1], cubemapEntityName))
33513323 isCubemap = qtrue;
3324
3325 if (!Q_stricmp(spawnVars[i][0], "name"))
3326 Q_strncpyz(name, spawnVars[i][1], MAX_QPATH);
33523327
33533328 if (!Q_stricmp(spawnVars[i][0], "origin"))
33543329 {
33633338
33643339 if (isCubemap && originSet)
33653340 {
3366 //ri.Printf(PRINT_ALL, "cubemap at %f %f %f\n", origin[0], origin[1], origin[2]);
3367 VectorCopy(origin, tr.cubemaps[numCubemaps].origin);
3368 tr.cubemaps[numCubemaps].parallaxRadius = parallaxRadius;
3341 cubemap_t *cubemap = &tr.cubemaps[numCubemaps];
3342 Q_strncpyz(cubemap->name, name, MAX_QPATH);
3343 VectorCopy(origin, cubemap->origin);
3344 cubemap->parallaxRadius = parallaxRadius;
33693345 numCubemaps++;
33703346 }
33713347 }
34053381 }
34063382
34073383
3408 void R_RenderAllCubemaps(void)
3384 void R_LoadCubemaps(void)
3385 {
3386 int i;
3387 imgFlags_t flags = IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP;
3388
3389 for (i = 0; i < tr.numCubemaps; i++)
3390 {
3391 char filename[MAX_QPATH];
3392 cubemap_t *cubemap = &tr.cubemaps[i];
3393
3394 Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i);
3395
3396 cubemap->image = R_FindImageFile(filename, IMGTYPE_COLORALPHA, flags);
3397 }
3398 }
3399
3400
3401 void R_RenderMissingCubemaps(void)
34093402 {
34103403 int i, j;
3411
3412 for (i = 0; i < tr.numCubemaps; i++)
3413 {
3414 tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8);
3415 }
3404 imgFlags_t flags = IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP;
34163405
34173406 ri.Printf(PRINT_ALL, "Total cubemaps: %d\n", tr.numCubemaps );
34183407
34193408 for (i = 0; i < tr.numCubemaps; i++)
34203409 {
3421 for (j = 0; j < 6; j++)
3422 {
3423 RE_ClearScene();
3424 R_RenderCubemapSide(i, j, qfalse);
3425 R_IssuePendingRenderCommands();
3426 R_InitNextFrame();
3410 if (!tr.cubemaps[i].image)
3411 {
3412 tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, flags, GL_RGBA8);
3413
3414 for (j = 0; j < 6; j++)
3415 {
3416 RE_ClearScene();
3417 R_RenderCubemapSide(i, j, qfalse);
3418 R_IssuePendingRenderCommands();
3419 R_InitNextFrame();
3420 }
34273421 }
34283422 }
34293423 }
34443438 case SF_GRID:
34453439 case SF_TRIANGLES:
34463440 for(i = 0; i < bspSurf->numVerts; i++)
3447 R_LightDirForPoint( bspSurf->verts[i].xyz, bspSurf->verts[i].lightdir, bspSurf->verts[i].normal, &s_worldData );
3441 {
3442 vec3_t lightDir;
3443 vec3_t normal;
3444
3445 R_VaoUnpackNormal(normal, bspSurf->verts[i].normal);
3446 R_LightDirForPoint( bspSurf->verts[i].xyz, lightDir, normal, &s_worldData );
3447 R_VaoPackNormal(bspSurf->verts[i].lightdir, lightDir);
3448 }
34483449
34493450 break;
34503451
34773478 }
34783479
34793480 // set default map light scale
3480 tr.mapLightScale = 1.0f;
34813481 tr.sunShadowScale = 0.5f;
34823482
34833483 // set default sun direction to be used if it isn't
37663766 // load cubemaps
37673767 if (r_cubeMapping->integer)
37683768 {
3769 R_LoadCubemapEntities("misc_cubemap");
3769 // Try loading an env.json file first
3770 R_LoadEnvironmentJson(s_worldData.baseName);
3771
3772 if (!tr.numCubemaps)
3773 {
3774 R_LoadCubemapEntities("misc_cubemap");
3775 }
3776
37703777 if (!tr.numCubemaps)
37713778 {
37723779 // use ai markers as cubemaps
38003807 // make sure the VAO glState entry is safe
38013808 R_BindNullVao();
38023809
3803 // Render all cubemaps
3804 if (r_cubeMapping->integer && tr.numCubemaps)
3805 {
3806 R_RenderAllCubemaps();
3810 // Render or load all cubemaps
3811 if (r_cubeMapping->integer && tr.numCubemaps && glRefConfig.framebufferObject)
3812 {
3813 R_LoadCubemaps();
3814 R_RenderMissingCubemaps();
38073815 }
38083816
38093817 ri.FS_FreeFile( buffer.v );
6060 out->lightmap[0] = 0.5f * ( a->lightmap[0] + b->lightmap[0] );
6161 out->lightmap[1] = 0.5f * ( a->lightmap[1] + b->lightmap[1] );
6262
63 out->vertexColors[0] = 0.5f * (a->vertexColors[0] + b->vertexColors[0]);
64 out->vertexColors[1] = 0.5f * (a->vertexColors[1] + b->vertexColors[1]);
65 out->vertexColors[2] = 0.5f * (a->vertexColors[2] + b->vertexColors[2]);
66 out->vertexColors[3] = 0.5f * (a->vertexColors[3] + b->vertexColors[3]);
63 out->color[0] = ((int)a->color[0] + (int)b->color[0]) >> 1;
64 out->color[1] = ((int)a->color[1] + (int)b->color[1]) >> 1;
65 out->color[2] = ((int)a->color[2] + (int)b->color[2]) >> 1;
66 out->color[3] = ((int)a->color[3] + (int)b->color[3]) >> 1;
6767 }
6868
6969 /*
213213 //if ( count == 0 ) {
214214 //printf("bad normal\n");
215215 //}
216 VectorNormalize2( sum, dv->normal );
217 }
218 }
219 }
220
221 #ifdef USE_VERT_TANGENT_SPACE
216 {
217 vec3_t fNormal;
218 VectorNormalize2(sum, fNormal);
219 R_VaoPackNormal(dv->normal, fNormal);
220 }
221 }
222 }
223 }
224
222225 static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numIndexes,
223226 glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
224227 {
257260 }
258261 }
259262 }
260 #endif
261
262
263 static int MakeMeshIndexes(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
264 glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
263
264
265 static int MakeMeshIndexes(int width, int height, glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
265266 {
266267 int i, j;
267268 int numIndexes;
268269 int w, h;
269 srfVert_t *dv;
270 static srfVert_t ctrl2[MAX_GRID_SIZE * MAX_GRID_SIZE];
271270
272271 h = height - 1;
273272 w = width - 1;
294293 }
295294 }
296295
297 // FIXME: use more elegant way
298 for(i = 0; i < width; i++)
299 {
300 for(j = 0; j < height; j++)
301 {
302 dv = &ctrl2[j * width + i];
303 *dv = ctrl[j][i];
304 }
305 }
306
307296 return numIndexes;
308297 }
309298
381370 R_CreateSurfaceGridMesh
382371 =================
383372 */
384 srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height,
373 void R_CreateSurfaceGridMesh(srfBspSurface_t *grid, int width, int height,
385374 srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], float errorTable[2][MAX_GRID_SIZE],
386375 int numIndexes, glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]) {
387 int i, j, size;
376 int i, j;
388377 srfVert_t *vert;
389378 vec3_t tmpVec;
390 srfBspSurface_t *grid;
391379
392380 // copy the results out to a grid
393 size = (width * height - 1) * sizeof( srfVert_t ) + sizeof( *grid );
381 Com_Memset(grid, 0, sizeof(*grid));
394382
395383 #ifdef PATCH_STITCHING
396 grid = malloc( size );
397 Com_Memset( grid, 0, size );
398
399384 grid->widthLodError = malloc( width * 4 );
400385 memcpy( grid->widthLodError, errorTable[0], width * 4 );
401386
409394 grid->numVerts = (width * height);
410395 grid->verts = ri.Z_Malloc(grid->numVerts * sizeof(srfVert_t));
411396 #else
412 grid = ri.Hunk_Alloc( size, h_low );
413 memset( grid, 0, size );
414
415397 grid->widthLodError = ri.Hunk_Alloc( width * 4, h_low );
416398 memcpy( grid->widthLodError, errorTable[0], width * 4 );
417399
447429 VectorCopy( grid->cullOrigin, grid->lodOrigin );
448430 grid->lodRadius = grid->cullRadius;
449431 //
450 return grid;
451 }
452
453 /*
454 =================
455 R_FreeSurfaceGridMesh
456 =================
457 */
458 void R_FreeSurfaceGridMesh( srfBspSurface_t *grid ) {
432 }
433
434 /*
435 =================
436 R_FreeSurfaceGridMeshData
437 =================
438 */
439 static void R_FreeSurfaceGridMeshData( srfBspSurface_t *grid ) {
459440 ri.Free( grid->widthLodError );
460441 ri.Free( grid->heightLodError );
461442 ri.Free( grid->indexes );
462443 ri.Free( grid->verts );
463 ri.Free( grid );
464444 }
465445
466446 /*
468448 R_SubdividePatchToGrid
469449 =================
470450 */
471 srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
451 void R_SubdividePatchToGrid( srfBspSurface_t *grid, int width, int height,
472452 srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
473453 int i, j, k, l;
474454 srfVert_t_cleared( prev );
634614 #endif
635615
636616 // calculate indexes
637 numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
617 numIndexes = MakeMeshIndexes(width, height, indexes);
638618
639619 // calculate normals
640620 MakeMeshNormals( width, height, ctrl );
641 #ifdef USE_VERT_TANGENT_SPACE
642621 MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes);
643 #endif
644
645 return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
622
623 R_CreateSurfaceGridMesh(grid, width, height, ctrl, errorTable, numIndexes, indexes);
646624 }
647625
648626 /*
650628 R_GridInsertColumn
651629 ===============
652630 */
653 srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror ) {
631 void R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror ) {
654632 int i, j;
655633 int width, height, oldwidth;
656634 srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
663641 oldwidth = 0;
664642 width = grid->width + 1;
665643 if ( width > MAX_GRID_SIZE ) {
666 return NULL;
644 return;
667645 }
668646 height = grid->height;
669647 for ( i = 0; i < width; i++ ) {
691669 //PutPointsOnCurve( ctrl, width, height );
692670
693671 // calculate indexes
694 numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
672 numIndexes = MakeMeshIndexes(width, height, indexes);
695673
696674 // calculate normals
697675 MakeMeshNormals( width, height, ctrl );
676 MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes);
698677
699678 VectorCopy( grid->lodOrigin, lodOrigin );
700679 lodRadius = grid->lodRadius;
701680 // free the old grid
702 R_FreeSurfaceGridMesh( grid );
681 R_FreeSurfaceGridMeshData(grid);
703682 // create a new grid
704 grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
683 R_CreateSurfaceGridMesh(grid, width, height, ctrl, errorTable, numIndexes, indexes);
705684 grid->lodRadius = lodRadius;
706685 VectorCopy( lodOrigin, grid->lodOrigin );
707 return grid;
708686 }
709687
710688 /*
712690 R_GridInsertRow
713691 ===============
714692 */
715 srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror ) {
693 void R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror ) {
716694 int i, j;
717695 int width, height, oldheight;
718696 srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
726704 width = grid->width;
727705 height = grid->height + 1;
728706 if ( height > MAX_GRID_SIZE ) {
729 return NULL;
707 return;
730708 }
731709 for ( i = 0; i < height; i++ ) {
732710 if ( i == row ) {
753731 //PutPointsOnCurve( ctrl, width, height );
754732
755733 // calculate indexes
756 numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
734 numIndexes = MakeMeshIndexes(width, height, indexes);
757735
758736 // calculate normals
759737 MakeMeshNormals( width, height, ctrl );
738 MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes);
760739
761740 VectorCopy( grid->lodOrigin, lodOrigin );
762741 lodRadius = grid->lodRadius;
763742 // free the old grid
764 R_FreeSurfaceGridMesh( grid );
743 R_FreeSurfaceGridMeshData(grid);
765744 // create a new grid
766 grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
745 R_CreateSurfaceGridMesh(grid, width, height, ctrl, errorTable, numIndexes, indexes);
767746 grid->lodRadius = lodRadius;
768747 VectorCopy( lodOrigin, grid->lodOrigin );
769 return grid;
770 }
771
748 }
749
0 /*
1 ===========================================================================
2 Copyright (C) 2016 James Canete
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 ===========================================================================
18 */
19
20 #include "tr_local.h"
21
22 #include "tr_dsa.h"
23
24 static struct
25 {
26 GLuint textures[NUM_TEXTURE_BUNDLES];
27 GLenum texunit;
28
29 GLuint program;
30
31 GLuint drawFramebuffer;
32 GLuint readFramebuffer;
33 GLuint renderbuffer;
34 }
35 glDsaState;
36
37 void GL_BindNullTextures()
38 {
39 int i;
40
41 if (glRefConfig.directStateAccess)
42 {
43 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
44 {
45 qglBindMultiTextureEXT(GL_TEXTURE0_ARB + i, GL_TEXTURE_2D, 0);
46 glDsaState.textures[i] = 0;
47 }
48 }
49 else
50 {
51 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
52 {
53 qglActiveTextureARB(GL_TEXTURE0_ARB + i);
54 qglBindTexture(GL_TEXTURE_2D, 0);
55 glDsaState.textures[i] = 0;
56 }
57
58 qglActiveTextureARB(GL_TEXTURE0_ARB);
59 glDsaState.texunit = GL_TEXTURE0_ARB;
60 }
61 }
62
63 int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture)
64 {
65 GLuint tmu = texunit - GL_TEXTURE0_ARB;
66
67 if (glDsaState.textures[tmu] == texture)
68 return 0;
69
70 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
71 target = GL_TEXTURE_CUBE_MAP;
72
73 qglBindMultiTextureEXT(texunit, target, texture);
74 glDsaState.textures[tmu] = texture;
75 return 1;
76 }
77
78 GLvoid APIENTRY GLDSA_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture)
79 {
80 if (glDsaState.texunit != texunit)
81 {
82 qglActiveTextureARB(texunit);
83 glDsaState.texunit = texunit;
84 }
85
86 qglBindTexture(target, texture);
87 }
88
89 GLvoid APIENTRY GLDSA_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param)
90 {
91 GL_BindMultiTexture(glDsaState.texunit, target, texture);
92 qglTexParameterf(target, pname, param);
93 }
94
95 GLvoid APIENTRY GLDSA_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param)
96 {
97 GL_BindMultiTexture(glDsaState.texunit, target, texture);
98 qglTexParameteri(target, pname, param);
99 }
100
101 GLvoid APIENTRY GLDSA_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat,
102 GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
103 {
104 GL_BindMultiTexture(glDsaState.texunit, target, texture);
105 qglTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
106 }
107
108 GLvoid APIENTRY GLDSA_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
109 GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
110 {
111 GL_BindMultiTexture(glDsaState.texunit, target, texture);
112 qglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
113 }
114
115 GLvoid APIENTRY GLDSA_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
116 GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
117 {
118 GL_BindMultiTexture(glDsaState.texunit, target, texture);
119 qglCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
120 }
121
122 GLvoid APIENTRY GLDSA_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
123 GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
124 {
125 GL_BindMultiTexture(glDsaState.texunit, target, texture);
126 qglCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
127 }
128
129 GLvoid APIENTRY GLDSA_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
130 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
131 GLsizei imageSize, const GLvoid *data)
132 {
133 GL_BindMultiTexture(glDsaState.texunit, target, texture);
134 qglCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
135 }
136
137 GLvoid APIENTRY GLDSA_GenerateTextureMipmapEXT(GLuint texture, GLenum target)
138 {
139 GL_BindMultiTexture(glDsaState.texunit, target, texture);
140 qglGenerateMipmapEXT(target);
141 }
142
143 void GL_BindNullProgram()
144 {
145 qglUseProgram(0);
146 glDsaState.program = 0;
147 }
148
149 int GL_UseProgram(GLuint program)
150 {
151 if (glDsaState.program == program)
152 return 0;
153
154 qglUseProgram(program);
155 glDsaState.program = program;
156 return 1;
157 }
158
159 GLvoid APIENTRY GLDSA_ProgramUniform1iEXT(GLuint program, GLint location, GLint v0)
160 {
161 GL_UseProgram(program);
162 qglUniform1i(location, v0);
163 }
164
165 GLvoid APIENTRY GLDSA_ProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0)
166 {
167 GL_UseProgram(program);
168 qglUniform1f(location, v0);
169 }
170
171 GLvoid APIENTRY GLDSA_ProgramUniform2fEXT(GLuint program, GLint location,
172 GLfloat v0, GLfloat v1)
173 {
174 GL_UseProgram(program);
175 qglUniform2f(location, v0, v1);
176 }
177
178 GLvoid APIENTRY GLDSA_ProgramUniform3fEXT(GLuint program, GLint location,
179 GLfloat v0, GLfloat v1, GLfloat v2)
180 {
181 GL_UseProgram(program);
182 qglUniform3f(location, v0, v1, v2);
183 }
184
185 GLvoid APIENTRY GLDSA_ProgramUniform4fEXT(GLuint program, GLint location,
186 GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
187 {
188 GL_UseProgram(program);
189 qglUniform4f(location, v0, v1, v2, v3);
190 }
191
192 GLvoid APIENTRY GLDSA_ProgramUniform1fvEXT(GLuint program, GLint location,
193 GLsizei count, const GLfloat *value)
194 {
195 GL_UseProgram(program);
196 qglUniform1fv(location, count, value);
197 }
198
199 GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fvEXT(GLuint program, GLint location,
200 GLsizei count, GLboolean transpose,
201 const GLfloat *value)
202 {
203 GL_UseProgram(program);
204 qglUniformMatrix4fv(location, count, transpose, value);
205 }
206
207 void GL_BindNullFramebuffers()
208 {
209 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
210 glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0;
211 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
212 glDsaState.renderbuffer = 0;
213 }
214
215 void GL_BindFramebuffer(GLenum target, GLuint framebuffer)
216 {
217 switch (target)
218 {
219 case GL_FRAMEBUFFER_EXT:
220 if (framebuffer != glDsaState.drawFramebuffer || framebuffer != glDsaState.readFramebuffer)
221 {
222 qglBindFramebufferEXT(target, framebuffer);
223 glDsaState.drawFramebuffer = glDsaState.readFramebuffer = framebuffer;
224 }
225 break;
226
227 case GL_DRAW_FRAMEBUFFER_EXT:
228 if (framebuffer != glDsaState.drawFramebuffer)
229 {
230 qglBindFramebufferEXT(target, framebuffer);
231 glDsaState.drawFramebuffer = framebuffer;
232 }
233 break;
234
235 case GL_READ_FRAMEBUFFER_EXT:
236 if (framebuffer != glDsaState.readFramebuffer)
237 {
238 qglBindFramebufferEXT(target, framebuffer);
239 glDsaState.readFramebuffer = framebuffer;
240 }
241 break;
242 }
243 }
244
245 void GL_BindRenderbuffer(GLuint renderbuffer)
246 {
247 if (renderbuffer != glDsaState.renderbuffer)
248 {
249 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer);
250 glDsaState.renderbuffer = renderbuffer;
251 }
252 }
253
254 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageEXT(GLuint renderbuffer,
255 GLenum internalformat, GLsizei width, GLsizei height)
256 {
257 GL_BindRenderbuffer(renderbuffer);
258 qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalformat, width, height);
259 }
260
261 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer,
262 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
263 {
264 GL_BindRenderbuffer(renderbuffer);
265 qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internalformat, width, height);
266 }
267
268 GLenum APIENTRY GLDSA_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)
269 {
270 GL_BindFramebuffer(target, framebuffer);
271 return qglCheckFramebufferStatusEXT(target);
272 }
273
274 GLvoid APIENTRY GLDSA_NamedFramebufferTexture2DEXT(GLuint framebuffer,
275 GLenum attachment, GLenum textarget, GLuint texture, GLint level)
276 {
277 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
278 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, textarget, texture, level);
279 }
280
281 GLvoid APIENTRY GLDSA_NamedFramebufferRenderbufferEXT(GLuint framebuffer,
282 GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
283 {
284 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
285 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, renderbuffertarget, renderbuffer);
286 }
0 /*
1 ===========================================================================
2 Copyright (C) 2016 James Canete
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 ===========================================================================
18 */
19
20 #ifndef __TR_DSA_H__
21 #define __TR_DSA_H__
22
23 #include "qgl.h"
24
25 void GL_BindNullTextures(void);
26 int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture);
27
28 GLvoid APIENTRY GLDSA_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture);
29 GLvoid APIENTRY GLDSA_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param);
30 GLvoid APIENTRY GLDSA_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param);
31 GLvoid APIENTRY GLDSA_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat,
32 GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
33 GLvoid APIENTRY GLDSA_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
34 GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
35 GLvoid APIENTRY GLDSA_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
36 GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
37 GLvoid APIENTRY GLDSA_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat,
38 GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
39 GLvoid APIENTRY GLDSA_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
40 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format,
41 GLsizei imageSize, const GLvoid *data);
42
43 GLvoid APIENTRY GLDSA_GenerateTextureMipmapEXT(GLuint texture, GLenum target);
44
45 void GL_BindNullProgram(void);
46 int GL_UseProgram(GLuint program);
47
48 GLvoid APIENTRY GLDSA_ProgramUniform1iEXT(GLuint program, GLint location, GLint v0);
49 GLvoid APIENTRY GLDSA_ProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0);
50 GLvoid APIENTRY GLDSA_ProgramUniform2fEXT(GLuint program, GLint location,
51 GLfloat v0, GLfloat v1);
52 GLvoid APIENTRY GLDSA_ProgramUniform3fEXT(GLuint program, GLint location,
53 GLfloat v0, GLfloat v1, GLfloat v2);
54 GLvoid APIENTRY GLDSA_ProgramUniform4fEXT(GLuint program, GLint location,
55 GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
56 GLvoid APIENTRY GLDSA_ProgramUniform1fvEXT(GLuint program, GLint location,
57 GLsizei count, const GLfloat *value);
58 GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fvEXT(GLuint program, GLint location,
59 GLsizei count, GLboolean transpose,
60 const GLfloat *value);
61
62 void GL_BindNullFramebuffers(void);
63 void GL_BindFramebuffer(GLenum target, GLuint framebuffer);
64 void GL_BindRenderbuffer(GLuint renderbuffer);
65
66 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageEXT(GLuint renderbuffer,
67 GLenum internalformat, GLsizei width, GLsizei height);
68
69 GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer,
70 GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
71
72 GLenum APIENTRY GLDSA_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target);
73 GLvoid APIENTRY GLDSA_NamedFramebufferTexture2DEXT(GLuint framebuffer,
74 GLenum attachment, GLenum textarget, GLuint texture, GLint level);
75 GLvoid APIENTRY GLDSA_NamedFramebufferRenderbufferEXT(GLuint framebuffer,
76 GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
77
78
79 #endif
2727 #endif
2828
2929 #include "tr_local.h"
30
31 // GL_EXT_draw_range_elements
32 void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
33
34 // GL_EXT_multi_draw_arrays
35 void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
36 void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
37
38 // GL_ARB_vertex_shader
39 void (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB * name);
40 void (APIENTRY * qglGetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length,
41 GLint * size, GLenum * type, GLcharARB * name);
42 GLint(APIENTRY * qglGetAttribLocationARB) (GLhandleARB programObj, const GLcharARB * name);
43
44 // GL_ARB_vertex_program
45 void (APIENTRY * qglVertexAttrib4fARB) (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
46 void (APIENTRY * qglVertexAttrib4fvARB) (GLuint, const GLfloat *);
47 void (APIENTRY * qglVertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized,
48 GLsizei stride, const GLvoid * pointer);
49 void (APIENTRY * qglEnableVertexAttribArrayARB) (GLuint index);
50 void (APIENTRY * qglDisableVertexAttribArrayARB) (GLuint index);
51
52 // GL_ARB_vertex_buffer_object
53 void (APIENTRY * qglBindBufferARB) (GLenum target, GLuint buffer);
54 void (APIENTRY * qglDeleteBuffersARB) (GLsizei n, const GLuint * buffers);
55 void (APIENTRY * qglGenBuffersARB) (GLsizei n, GLuint * buffers);
56
57 GLboolean(APIENTRY * qglIsBufferARB) (GLuint buffer);
58 void (APIENTRY * qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
59 void (APIENTRY * qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
60 void (APIENTRY * qglGetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data);
61
62 void (APIENTRY * qglGetBufferParameterivARB) (GLenum target, GLenum pname, GLint * params);
63 void (APIENTRY * qglGetBufferPointervARB) (GLenum target, GLenum pname, GLvoid * *params);
64
65 // GL_ARB_shader_objects
66 void (APIENTRY * qglDeleteObjectARB) (GLhandleARB obj);
67
68 GLhandleARB(APIENTRY * qglGetHandleARB) (GLenum pname);
69 void (APIENTRY * qglDetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj);
70
71 GLhandleARB(APIENTRY * qglCreateShaderObjectARB) (GLenum shaderType);
72 void (APIENTRY * qglShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB * *string,
73 const GLint * length);
74 void (APIENTRY * qglCompileShaderARB) (GLhandleARB shaderObj);
75
76 GLhandleARB(APIENTRY * qglCreateProgramObjectARB) (void);
77 void (APIENTRY * qglAttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj);
78 void (APIENTRY * qglLinkProgramARB) (GLhandleARB programObj);
79 void (APIENTRY * qglUseProgramObjectARB) (GLhandleARB programObj);
80 void (APIENTRY * qglValidateProgramARB) (GLhandleARB programObj);
81 void (APIENTRY * qglUniform1fARB) (GLint location, GLfloat v0);
82 void (APIENTRY * qglUniform2fARB) (GLint location, GLfloat v0, GLfloat v1);
83 void (APIENTRY * qglUniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
84 void (APIENTRY * qglUniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
85 void (APIENTRY * qglUniform1iARB) (GLint location, GLint v0);
86 void (APIENTRY * qglUniform2iARB) (GLint location, GLint v0, GLint v1);
87 void (APIENTRY * qglUniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2);
88 void (APIENTRY * qglUniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
89 void (APIENTRY * qglUniform1fvARB) (GLint location, GLsizei count, const GLfloat * value);
90 void (APIENTRY * qglUniform2fvARB) (GLint location, GLsizei count, const GLfloat * value);
91 void (APIENTRY * qglUniform3fvARB) (GLint location, GLsizei count, const GLfloat * value);
92 void (APIENTRY * qglUniform4fvARB) (GLint location, GLsizei count, const GLfloat * value);
93 void (APIENTRY * qglUniform2ivARB) (GLint location, GLsizei count, const GLint * value);
94 void (APIENTRY * qglUniform3ivARB) (GLint location, GLsizei count, const GLint * value);
95 void (APIENTRY * qglUniform4ivARB) (GLint location, GLsizei count, const GLint * value);
96 void (APIENTRY * qglUniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
97 void (APIENTRY * qglUniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
98 void (APIENTRY * qglUniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
99 void (APIENTRY * qglGetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat * params);
100 void (APIENTRY * qglGetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint * params);
101 void (APIENTRY * qglGetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog);
102 void (APIENTRY * qglGetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count,
103 GLhandleARB * obj);
104 GLint(APIENTRY * qglGetUniformLocationARB) (GLhandleARB programObj, const GLcharARB * name);
105 void (APIENTRY * qglGetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxIndex, GLsizei * length,
106 GLint * size, GLenum * type, GLcharARB * name);
107 void (APIENTRY * qglGetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat * params);
108 void (APIENTRY * qglGetUniformivARB) (GLhandleARB programObj, GLint location, GLint * params);
109 void (APIENTRY * qglGetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source);
110
111 // GL_ARB_texture_compression
112 void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
113 GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
114 void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
115 GLint border, GLsizei imageSize, const GLvoid *data);
116 void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
117 GLsizei imageSize, const GLvoid *data);
118 void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
119 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
120 void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
121 GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
122 void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
123 GLsizei imageSize, const GLvoid *data);
124 void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
125 GLvoid *img);
126
127 // GL_EXT_framebuffer_object
128 GLboolean (APIENTRY * qglIsRenderbufferEXT)(GLuint renderbuffer);
129 void (APIENTRY * qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
130 void (APIENTRY * qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
131 void (APIENTRY * qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
132
133 void (APIENTRY * qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
134
135 void (APIENTRY * qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
136
137 GLboolean (APIENTRY * qglIsFramebufferEXT)(GLuint framebuffer);
138 void (APIENTRY * qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
139 void (APIENTRY * qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
140 void (APIENTRY * qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
141
142 GLenum (APIENTRY * qglCheckFramebufferStatusEXT)(GLenum target);
143
144 void (APIENTRY * qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
145 GLint level);
146 void (APIENTRY * qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
147 GLint level);
148 void (APIENTRY * qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
149 GLint level, GLint zoffset);
150
151 void (APIENTRY * qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget,
152 GLuint renderbuffer);
153
154 void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
155
156 void (APIENTRY * qglGenerateMipmapEXT)(GLenum target);
157
158 // GL_ARB_occlusion_query
159 void (APIENTRY * qglGenQueriesARB)(GLsizei n, GLuint *ids);
160 void (APIENTRY * qglDeleteQueriesARB)(GLsizei n, const GLuint *ids);
161 GLboolean (APIENTRY * qglIsQueryARB)(GLuint id);
162 void (APIENTRY * qglBeginQueryARB)(GLenum target, GLuint id);
163 void (APIENTRY * qglEndQueryARB)(GLenum target);
164 void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
165 void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
166 void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
167
168 // GL_EXT_framebuffer_blit
169 void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
170 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
171 GLbitfield mask, GLenum filter);
172
173 // GL_EXT_framebuffer_multisample
174 void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
175 GLenum internalformat, GLsizei width, GLsizei height);
176
177 // GL_ARB_draw_buffers
178 void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
179
180 // GL_ARB_vertex_array_object
181 void (APIENTRY * qglBindVertexArrayARB)(GLuint array);
182 void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays);
183 void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
184 GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
30 #include "tr_dsa.h"
31
32 #define GLE(ret, name, ...) name##proc * qgl##name;
33 QGL_1_2_PROCS;
34 QGL_1_3_PROCS;
35 QGL_1_4_PROCS;
36 QGL_1_5_PROCS;
37 QGL_2_0_PROCS;
38 QGL_EXT_framebuffer_object_PROCS;
39 QGL_EXT_framebuffer_blit_PROCS;
40 QGL_EXT_framebuffer_multisample_PROCS;
41 QGL_ARB_vertex_array_object_PROCS;
42 QGL_EXT_direct_state_access_PROCS;
43 #undef GLE
18544
18645 static qboolean GLimp_HaveExtension(const char *ext)
18746 {
19756 char *extension;
19857 const char* result[3] = { "...ignoring %s\n", "...using %s\n", "...%s not found\n" };
19958
200 // GL_EXT_draw_range_elements
201 extension = "GL_EXT_draw_range_elements";
202 glRefConfig.drawRangeElements = qfalse;
203 qglMultiDrawArraysEXT = NULL;
204 qglMultiDrawElementsEXT = NULL;
205 if( GLimp_HaveExtension( extension ) )
206 {
207 qglDrawRangeElementsEXT = (void *) SDL_GL_GetProcAddress("glDrawRangeElementsEXT");
208
209 if ( r_ext_draw_range_elements->integer)
210 glRefConfig.drawRangeElements = qtrue;
211
212 ri.Printf(PRINT_ALL, result[glRefConfig.drawRangeElements], extension);
213 }
214 else
215 {
216 ri.Printf(PRINT_ALL, result[2], extension);
217 }
218
219 // GL_EXT_multi_draw_arrays
220 extension = "GL_EXT_multi_draw_arrays";
221 glRefConfig.multiDrawArrays = qfalse;
222 qglMultiDrawArraysEXT = NULL;
223 qglMultiDrawElementsEXT = NULL;
224 if( GLimp_HaveExtension( extension ) )
225 {
226 qglMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC) SDL_GL_GetProcAddress("glMultiDrawArraysEXT");
227 qglMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC) SDL_GL_GetProcAddress("glMultiDrawElementsEXT");
228
229 if ( r_ext_multi_draw_arrays->integer )
230 glRefConfig.multiDrawArrays = qtrue;
231
232 ri.Printf(PRINT_ALL, result[glRefConfig.multiDrawArrays], extension);
233 }
234 else
235 {
236 ri.Printf(PRINT_ALL, result[2], extension);
237 }
238
239 // GL_ARB_vertex_program
240 //glRefConfig.vertexProgram = qfalse;
241 extension = "GL_ARB_vertex_program";
242 qglVertexAttrib4fARB = NULL;
243 qglVertexAttrib4fvARB = NULL;
244 qglVertexAttribPointerARB = NULL;
245 qglEnableVertexAttribArrayARB = NULL;
246 qglDisableVertexAttribArrayARB = NULL;
247 if( GLimp_HaveExtension( extension ) )
248 {
249 qglVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) SDL_GL_GetProcAddress("glVertexAttrib4fARB");
250 qglVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) SDL_GL_GetProcAddress("glVertexAttrib4fvARB");
251 qglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) SDL_GL_GetProcAddress("glVertexAttribPointerARB");
252 qglEnableVertexAttribArrayARB =
253 (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) SDL_GL_GetProcAddress("glEnableVertexAttribArrayARB");
254 qglDisableVertexAttribArrayARB =
255 (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) SDL_GL_GetProcAddress("glDisableVertexAttribArrayARB");
59 // Check OpenGL version
60 sscanf(glConfig.version_string, "%d.%d", &glRefConfig.openglMajorVersion, &glRefConfig.openglMinorVersion);
61 if (glRefConfig.openglMajorVersion < 2)
62 ri.Error(ERR_FATAL, "OpenGL 2.0 required!");
63 ri.Printf(PRINT_ALL, "...using OpenGL %s\n", glConfig.version_string);
64
65 // set DSA fallbacks
66 #define GLE(ret, name, ...) qgl##name = GLDSA_##name;
67 QGL_EXT_direct_state_access_PROCS;
68 #undef GLE
69
70 // GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
71 #define GLE(ret, name, ...) qgl##name = (name##proc *) SDL_GL_GetProcAddress("gl" #name);
72
73 // OpenGL 1.2, was GL_EXT_draw_range_elements
74 QGL_1_2_PROCS;
75 glRefConfig.drawRangeElements = !!r_ext_draw_range_elements->integer;
76 ri.Printf(PRINT_ALL, result[glRefConfig.drawRangeElements], "glDrawRangeElements()");
77
78 // OpenGL 1.3, was GL_ARB_texture_compression
79 QGL_1_3_PROCS;
80
81 // OpenGL 1.4, was GL_EXT_multi_draw_arrays
82 QGL_1_4_PROCS;
83 glRefConfig.multiDrawArrays = !!r_ext_multi_draw_arrays->integer;
84 ri.Printf(PRINT_ALL, result[glRefConfig.multiDrawArrays], "glMultiDrawElements()");
85
86 // OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
87 QGL_1_5_PROCS;
88 glRefConfig.occlusionQuery = qtrue;
89
90 // OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
91 QGL_2_0_PROCS;
92
93 // Determine GLSL version
94 if (1)
95 {
96 char version[256];
97
98 Q_strncpyz(version, (char *)qglGetString(GL_SHADING_LANGUAGE_VERSION), sizeof(version));
99
100 sscanf(version, "%d.%d", &glRefConfig.glslMajorVersion, &glRefConfig.glslMinorVersion);
101
102 ri.Printf(PRINT_ALL, "...using GLSL version %s\n", version);
103 }
104
105 glRefConfig.memInfo = MI_NONE;
106
107 // GL_NVX_gpu_memory_info
108 extension = "GL_NVX_gpu_memory_info";
109 if( GLimp_HaveExtension( extension ) )
110 {
111 glRefConfig.memInfo = MI_NVX;
256112
257113 ri.Printf(PRINT_ALL, result[1], extension);
258 //glRefConfig.vertexProgram = qtrue;
259 }
260 else
261 {
262 ri.Error(ERR_FATAL, result[2], extension);
263 }
264
265 // GL_ARB_vertex_buffer_object
266 //glRefConfig.vertexBufferObject = qfalse;
267 extension = "GL_ARB_vertex_buffer_object";
268 qglBindBufferARB = NULL;
269 qglDeleteBuffersARB = NULL;
270 qglGenBuffersARB = NULL;
271 qglIsBufferARB = NULL;
272 qglBufferDataARB = NULL;
273 qglBufferSubDataARB = NULL;
274 qglGetBufferSubDataARB = NULL;
275 qglGetBufferParameterivARB = NULL;
276 qglGetBufferPointervARB = NULL;
277 if( GLimp_HaveExtension( extension ) )
278 {
279 qglBindBufferARB = (PFNGLBINDBUFFERARBPROC) SDL_GL_GetProcAddress("glBindBufferARB");
280 qglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB");
281 qglGenBuffersARB = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress("glGenBuffersARB");
282 qglIsBufferARB = (PFNGLISBUFFERARBPROC) SDL_GL_GetProcAddress("glIsBufferARB");
283 qglBufferDataARB = (PFNGLBUFFERDATAARBPROC) SDL_GL_GetProcAddress("glBufferDataARB");
284 qglBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC) SDL_GL_GetProcAddress("glBufferSubDataARB");
285 qglGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC) SDL_GL_GetProcAddress("glGetBufferSubDataARB");
286 qglGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetBufferParameterivARB");
287 qglGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC) SDL_GL_GetProcAddress("glGetBufferPointervARB");
288 ri.Printf(PRINT_ALL, result[1], extension);
289 //glRefConfig.vertexBufferObject = qtrue;
290 }
291 else
292 {
293 ri.Error(ERR_FATAL, result[2], extension);
294 }
295
296 // GL_ARB_shader_objects
297 extension = "GL_ARB_shader_objects";
298 //glRefConfig.shaderObjects = qfalse;
299 qglDeleteObjectARB = NULL;
300 qglGetHandleARB = NULL;
301 qglDetachObjectARB = NULL;
302 qglCreateShaderObjectARB = NULL;
303 qglShaderSourceARB = NULL;
304 qglCompileShaderARB = NULL;
305 qglCreateProgramObjectARB = NULL;
306 qglAttachObjectARB = NULL;
307 qglLinkProgramARB = NULL;
308 qglUseProgramObjectARB = NULL;
309 qglValidateProgramARB = NULL;
310 qglUniform1fARB = NULL;
311 qglUniform2fARB = NULL;
312 qglUniform3fARB = NULL;
313 qglUniform4fARB = NULL;
314 qglUniform1iARB = NULL;
315 qglUniform2iARB = NULL;
316 qglUniform3iARB = NULL;
317 qglUniform4iARB = NULL;
318 qglUniform1fvARB = NULL;
319 qglUniform2fvARB = NULL;
320 qglUniform3fvARB = NULL;
321 qglUniform4fvARB = NULL;
322 qglUniform2ivARB = NULL;
323 qglUniform3ivARB = NULL;
324 qglUniform4ivARB = NULL;
325 qglUniformMatrix2fvARB = NULL;
326 qglUniformMatrix3fvARB = NULL;
327 qglUniformMatrix4fvARB = NULL;
328 qglGetObjectParameterfvARB = NULL;
329 qglGetObjectParameterivARB = NULL;
330 qglGetInfoLogARB = NULL;
331 qglGetAttachedObjectsARB = NULL;
332 qglGetUniformLocationARB = NULL;
333 qglGetActiveUniformARB = NULL;
334 qglGetUniformfvARB = NULL;
335 qglGetUniformivARB = NULL;
336 qglGetShaderSourceARB = NULL;
337 if( GLimp_HaveExtension( extension ) )
338 {
339 qglDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB");
340 qglGetHandleARB = (PFNGLGETHANDLEARBPROC) SDL_GL_GetProcAddress("glGetHandleARB");
341 qglDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) SDL_GL_GetProcAddress("glDetachObjectARB");
342 qglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB");
343 qglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB");
344 qglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB");
345 qglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB");
346 qglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB");
347 qglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB");
348 qglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB");
349 qglValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) SDL_GL_GetProcAddress("glValidateProgramARB");
350 qglUniform1fARB = (PFNGLUNIFORM1FARBPROC) SDL_GL_GetProcAddress("glUniform1fARB");
351 qglUniform2fARB = (PFNGLUNIFORM2FARBPROC) SDL_GL_GetProcAddress("glUniform2fARB");
352 qglUniform3fARB = (PFNGLUNIFORM3FARBPROC) SDL_GL_GetProcAddress("glUniform3fARB");
353 qglUniform4fARB = (PFNGLUNIFORM4FARBPROC) SDL_GL_GetProcAddress("glUniform4fARB");
354 qglUniform1iARB = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB");
355 qglUniform2iARB = (PFNGLUNIFORM2IARBPROC) SDL_GL_GetProcAddress("glUniform2iARB");
356 qglUniform3iARB = (PFNGLUNIFORM3IARBPROC) SDL_GL_GetProcAddress("glUniform3iARB");
357 qglUniform4iARB = (PFNGLUNIFORM4IARBPROC) SDL_GL_GetProcAddress("glUniform4iARB");
358 qglUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) SDL_GL_GetProcAddress("glUniform1fvARB");
359 qglUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) SDL_GL_GetProcAddress("glUniform2fvARB");
360 qglUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) SDL_GL_GetProcAddress("glUniform3fvARB");
361 qglUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) SDL_GL_GetProcAddress("glUniform4fvARB");
362 qglUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) SDL_GL_GetProcAddress("glUniform2ivARB");
363 qglUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) SDL_GL_GetProcAddress("glUniform3ivARB");
364 qglUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) SDL_GL_GetProcAddress("glUniform4ivARB");
365 qglUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) SDL_GL_GetProcAddress("glUniformMatrix2fvARB");
366 qglUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) SDL_GL_GetProcAddress("glUniformMatrix3fvARB");
367 qglUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) SDL_GL_GetProcAddress("glUniformMatrix4fvARB");
368 qglGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterfvARB");
369 qglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
370 qglGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB");
371 qglGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) SDL_GL_GetProcAddress("glGetAttachedObjectsARB");
372 qglGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB");
373 qglGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) SDL_GL_GetProcAddress("glGetActiveUniformARB");
374 qglGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) SDL_GL_GetProcAddress("glGetUniformfvARB");
375 qglGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) SDL_GL_GetProcAddress("glGetUniformivARB");
376 qglGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glGetShaderSourceARB");
377 ri.Printf(PRINT_ALL, result[1], extension);
378 //glRefConfig.shaderObjects = qtrue;
379 }
380 else
381 {
382 ri.Error(ERR_FATAL, result[2], extension);
383 }
384
385 // GL_ARB_vertex_shader
386 //glRefConfig.vertexShader = qfalse;
387 extension = "GL_ARB_vertex_shader";
388 qglBindAttribLocationARB = NULL;
389 qglGetActiveAttribARB = NULL;
390 qglGetAttribLocationARB = NULL;
391 if( GLimp_HaveExtension( extension ) )
392 {
393 //int reservedComponents;
394
395 //qglGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig.maxVertexUniforms);
396 //qglGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &glConfig.maxVaryingFloats);
397 //qglGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.maxVertexAttribs);
398
399 //reservedComponents = 16 * 10; // approximation how many uniforms we have besides the bone matrices
400
401 #if 0
402 if(glConfig.driverType == GLDRV_MESA)
114 }
115 else
116 {
117 ri.Printf(PRINT_ALL, result[2], extension);
118 }
119
120 // GL_ATI_meminfo
121 extension = "GL_ATI_meminfo";
122 if( GLimp_HaveExtension( extension ) )
123 {
124 if (glRefConfig.memInfo == MI_NONE)
403125 {
404 // HACK
405 // restrict to number of vertex uniforms to 512 because of:
406 // xreal.x86_64: nv50_program.c:4181: nv50_program_validate_data: Assertion `p->param_nr <= 512' failed
407
408 glConfig.maxVertexUniforms = Q_bound(0, glConfig.maxVertexUniforms, 512);
126 glRefConfig.memInfo = MI_ATI;
127
128 ri.Printf(PRINT_ALL, result[1], extension);
409129 }
410 #endif
411
412 //glConfig.maxVertexSkinningBones = (int) Q_bound(0.0, (Q_max(glConfig.maxVertexUniforms - reservedComponents, 0) / 16), MAX_BONES);
413 //glConfig.vboVertexSkinningAvailable = r_vboVertexSkinning->integer && ((glConfig.maxVertexSkinningBones >= 12) ? qtrue : qfalse);
414
415 qglBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) SDL_GL_GetProcAddress("glBindAttribLocationARB");
416 qglGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) SDL_GL_GetProcAddress("glGetActiveAttribARB");
417 qglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetAttribLocationARB");
418 ri.Printf(PRINT_ALL, result[1], extension);
419 //glRefConfig.vertexShader = qtrue;
420 }
421 else
422 {
423 ri.Error(ERR_FATAL, result[2], extension);
424 }
425
426 // GL_ARB_shading_language_100
427 extension = "GL_ARB_shading_language_100";
428 glRefConfig.textureFloat = qfalse;
429 if( GLimp_HaveExtension( extension ) )
430 {
431 char version[256];
432
433 Q_strncpyz( version, (char *) qglGetString (GL_SHADING_LANGUAGE_VERSION_ARB), sizeof( version ) );
434
435 sscanf(version, "%d.%d", &glRefConfig.glslMajorVersion, &glRefConfig.glslMinorVersion);
436
437 ri.Printf(PRINT_ALL, "...using GLSL version %s\n", version);
438 }
439 else
440 {
441 ri.Error(ERR_FATAL, result[2], extension);
442 }
443
444 glRefConfig.memInfo = MI_NONE;
445
446 if( GLimp_HaveExtension( "GL_NVX_gpu_memory_info" ) )
447 {
448 glRefConfig.memInfo = MI_NVX;
449 }
450 else if( GLimp_HaveExtension( "GL_ATI_meminfo" ) )
451 {
452 glRefConfig.memInfo = MI_ATI;
453 }
454
455 extension = "GL_ARB_texture_non_power_of_two";
456 glRefConfig.textureNonPowerOfTwo = qfalse;
457 if( GLimp_HaveExtension( extension ) )
458 {
459 if(1) //(r_ext_texture_non_power_of_two->integer)
130 else
460131 {
461 glRefConfig.textureNonPowerOfTwo = qtrue;
132 ri.Printf(PRINT_ALL, result[0], extension);
462133 }
463
464 ri.Printf(PRINT_ALL, result[glRefConfig.textureNonPowerOfTwo], extension);
465134 }
466135 else
467136 {
473142 glRefConfig.textureFloat = qfalse;
474143 if( GLimp_HaveExtension( extension ) )
475144 {
476 if( r_ext_texture_float->integer )
477 {
478 glRefConfig.textureFloat = qtrue;
479 }
145 glRefConfig.textureFloat = !!r_ext_texture_float->integer;
480146
481147 ri.Printf(PRINT_ALL, result[glRefConfig.textureFloat], extension);
482 }
483 else
484 {
485 ri.Printf(PRINT_ALL, result[2], extension);
486 }
487
488 // GL_ARB_half_float_pixel
489 extension = "GL_ARB_half_float_pixel";
490 glRefConfig.halfFloatPixel = qfalse;
491 if( GLimp_HaveExtension( extension ) )
492 {
493 if( r_arb_half_float_pixel->integer )
494 glRefConfig.halfFloatPixel = qtrue;
495
496 ri.Printf(PRINT_ALL, result[glRefConfig.halfFloatPixel], extension);
497148 }
498149 else
499150 {
505156 glRefConfig.framebufferObject = qfalse;
506157 if( GLimp_HaveExtension( extension ) )
507158 {
159 glRefConfig.framebufferObject = !!r_ext_framebuffer_object->integer;
160
508161 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &glRefConfig.maxRenderbufferSize);
509162 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &glRefConfig.maxColorAttachments);
510163
511 qglIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) SDL_GL_GetProcAddress("glIsRenderbufferEXT");
512 qglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) SDL_GL_GetProcAddress("glBindRenderbufferEXT");
513 qglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) SDL_GL_GetProcAddress("glDeleteRenderbuffersEXT");
514 qglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) SDL_GL_GetProcAddress("glGenRenderbuffersEXT");
515 qglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) SDL_GL_GetProcAddress("glRenderbufferStorageEXT");
516 qglGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) SDL_GL_GetProcAddress("glGetRenderbufferParameterivEXT");
517 qglIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) SDL_GL_GetProcAddress("glIsFramebufferEXT");
518 qglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) SDL_GL_GetProcAddress("glBindFramebufferEXT");
519 qglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
520 qglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) SDL_GL_GetProcAddress("glGenFramebuffersEXT");
521 qglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
522 qglFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) SDL_GL_GetProcAddress("glFramebufferTexture1DEXT");
523 qglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
524 qglFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) SDL_GL_GetProcAddress("glFramebufferTexture3DEXT");
525 qglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) SDL_GL_GetProcAddress("glFramebufferRenderbufferEXT");
526 qglGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameterivEXT");
527 qglGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) SDL_GL_GetProcAddress("glGenerateMipmapEXT");
528
529 if(r_ext_framebuffer_object->value)
530 glRefConfig.framebufferObject = qtrue;
164 QGL_EXT_framebuffer_object_PROCS;
531165
532166 ri.Printf(PRINT_ALL, result[glRefConfig.framebufferObject], extension);
533 }
534 else
535 {
536 ri.Printf(PRINT_ALL, result[2], extension);
537 }
538
539 // GL_EXT_packed_depth_stencil
540 extension = "GL_EXT_packed_depth_stencil";
541 glRefConfig.packedDepthStencil = qfalse;
542 if( GLimp_HaveExtension(extension))
543 {
544 glRefConfig.packedDepthStencil = qtrue;
545 ri.Printf(PRINT_ALL, result[glRefConfig.packedDepthStencil], extension);
546 }
547 else
548 {
549 ri.Printf(PRINT_ALL, result[2], extension);
550 }
551
552 // GL_ARB_occlusion_query
553 extension = "GL_ARB_occlusion_query";
554 glRefConfig.occlusionQuery = qfalse;
555 if (GLimp_HaveExtension(extension))
556 {
557 qglGenQueriesARB = (PFNGLGENQUERIESARBPROC) SDL_GL_GetProcAddress("glGenQueriesARB");
558 qglDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC) SDL_GL_GetProcAddress("glDeleteQueriesARB");
559 qglIsQueryARB = (PFNGLISQUERYARBPROC) SDL_GL_GetProcAddress("glIsQueryARB");
560 qglBeginQueryARB = (PFNGLBEGINQUERYARBPROC) SDL_GL_GetProcAddress("glBeginQueryARB");
561 qglEndQueryARB = (PFNGLENDQUERYARBPROC) SDL_GL_GetProcAddress("glEndQueryARB");
562 qglGetQueryivARB = (PFNGLGETQUERYIVARBPROC) SDL_GL_GetProcAddress("glGetQueryivARB");
563 qglGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC) SDL_GL_GetProcAddress("glGetQueryObjectivARB");
564 qglGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC) SDL_GL_GetProcAddress("glGetQueryObjectuivARB");
565 glRefConfig.occlusionQuery = qtrue;
566 ri.Printf(PRINT_ALL, result[glRefConfig.occlusionQuery], extension);
567167 }
568168 else
569169 {
575175 glRefConfig.framebufferBlit = qfalse;
576176 if (GLimp_HaveExtension(extension))
577177 {
578 qglBlitFramebufferEXT = (void *)SDL_GL_GetProcAddress("glBlitFramebufferEXT");
579178 glRefConfig.framebufferBlit = qtrue;
179
180 QGL_EXT_framebuffer_blit_PROCS;
181
580182 ri.Printf(PRINT_ALL, result[glRefConfig.framebufferBlit], extension);
581183 }
582184 else
583185 {
584186 ri.Printf(PRINT_ALL, result[2], extension);
585 }
586
587 // GL_ARB_texture_compression
588 extension = "GL_ARB_texture_compression";
589 glRefConfig.arbTextureCompression = qfalse;
590 if (GLimp_HaveExtension(extension))
591 {
592 qglCompressedTexImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage3DARB");
593 qglCompressedTexImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage2DARB");
594 qglCompressedTexImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage1DARB");
595 qglCompressedTexSubImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage3DARB");
596 qglCompressedTexSubImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage2DARB");
597 qglCompressedTexSubImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage1DARB");
598 qglGetCompressedTexImageARB = (void *)SDL_GL_GetProcAddress("glGetCompressedTexImageARB");
599 glRefConfig.arbTextureCompression = qtrue;
600 ri.Printf(PRINT_ALL, result[glRefConfig.arbTextureCompression], extension);
601187 }
602188
603189 // GL_EXT_framebuffer_multisample
605191 glRefConfig.framebufferMultisample = qfalse;
606192 if (GLimp_HaveExtension(extension))
607193 {
608 qglRenderbufferStorageMultisampleEXT = (void *)SDL_GL_GetProcAddress("glRenderbufferStorageMultisampleEXT");
609194 glRefConfig.framebufferMultisample = qtrue;
195
196 QGL_EXT_framebuffer_multisample_PROCS;
197
610198 ri.Printf(PRINT_ALL, result[glRefConfig.framebufferMultisample], extension);
611199 }
612200 else
620208 extension = "GL_ARB_texture_compression_rgtc";
621209 if (GLimp_HaveExtension(extension))
622210 {
623 if (r_ext_compressed_textures->integer && glRefConfig.arbTextureCompression)
211 qboolean useRgtc = r_ext_compressed_textures->integer >= 1;
212
213 if (useRgtc)
624214 glRefConfig.textureCompression |= TCR_RGTC;
625215
626 ri.Printf(PRINT_ALL, result[r_ext_compressed_textures->integer ? 1 : 0], extension);
216 ri.Printf(PRINT_ALL, result[useRgtc], extension);
627217 }
628218 else
629219 {
636226 extension = "GL_ARB_texture_compression_bptc";
637227 if (GLimp_HaveExtension(extension))
638228 {
639 if (r_ext_compressed_textures->integer >= 2)
229 qboolean useBptc = r_ext_compressed_textures->integer >= 2;
230
231 if (useBptc)
640232 glRefConfig.textureCompression |= TCR_BPTC;
641233
642 ri.Printf(PRINT_ALL, result[(r_ext_compressed_textures->integer >= 2) ? 1 : 0], extension);
643 }
644 else
645 {
646 ri.Printf(PRINT_ALL, result[2], extension);
647 }
648
649 // GL_ARB_draw_buffers
650 extension = "GL_ARB_draw_buffers";
651 qglDrawBuffersARB = NULL;
652 if( GLimp_HaveExtension( extension ) )
653 {
654 qglDrawBuffersARB = (void *) SDL_GL_GetProcAddress("glDrawBuffersARB");
655
656 ri.Printf(PRINT_ALL, result[1], extension);
234 ri.Printf(PRINT_ALL, result[useBptc], extension);
657235 }
658236 else
659237 {
666244 if( GLimp_HaveExtension( extension ) )
667245 {
668246 glRefConfig.depthClamp = qtrue;
669 ri.Printf(PRINT_ALL, result[1], extension);
247
248 ri.Printf(PRINT_ALL, result[glRefConfig.depthClamp], extension);
670249 }
671250 else
672251 {
678257 glRefConfig.seamlessCubeMap = qfalse;
679258 if( GLimp_HaveExtension( extension ) )
680259 {
681 if (r_arb_seamless_cube_map->integer)
682 glRefConfig.seamlessCubeMap = qtrue;
260 glRefConfig.seamlessCubeMap = !!r_arb_seamless_cube_map->integer;
683261
684262 ri.Printf(PRINT_ALL, result[glRefConfig.seamlessCubeMap], extension);
685263 }
687265 {
688266 ri.Printf(PRINT_ALL, result[2], extension);
689267 }
690
691 // GL_ARB_vertex_type_2_10_10_10_rev
692 extension = "GL_ARB_vertex_type_2_10_10_10_rev";
693 glRefConfig.packedNormalDataType = GL_BYTE;
694 if( GLimp_HaveExtension( extension ) )
695 {
696 if (r_arb_vertex_type_2_10_10_10_rev->integer)
697 glRefConfig.packedNormalDataType = GL_INT_2_10_10_10_REV;
698
699 ri.Printf(PRINT_ALL, result[r_arb_vertex_type_2_10_10_10_rev->integer ? 1 : 0], extension);
700 }
701 else
702 {
703 ri.Printf(PRINT_ALL, result[2], extension);
704 }
705
706 // use float lightmaps?
707 glRefConfig.floatLightmap = (glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer && r_hdr->integer);
708268
709269 // GL_ARB_vertex_array_object
710270 extension = "GL_ARB_vertex_array_object";
711271 glRefConfig.vertexArrayObject = qfalse;
712272 if( GLimp_HaveExtension( extension ) )
713273 {
714 qglBindVertexArrayARB = (void *) SDL_GL_GetProcAddress("glBindVertexArray");
715 qglDeleteVertexArraysARB = (void *) SDL_GL_GetProcAddress("glDeleteVertexArrays");
716 qglGenVertexArraysARB = (void *) SDL_GL_GetProcAddress("glGenVertexArrays");
717 qglIsVertexArrayARB = (void *) SDL_GL_GetProcAddress("glIsVertexArray");
718
719 if (r_arb_vertex_array_object->integer)
720 glRefConfig.vertexArrayObject = qtrue;
721
722 ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject ? 1 : 0], extension);
723 }
724 else
725 {
726 ri.Printf(PRINT_ALL, result[2], extension);
727 }
728
729 // GL_ARB_half_float_vertex
730 extension = "GL_ARB_half_float_vertex";
731 glRefConfig.packedTexcoordDataType = GL_FLOAT;
732 glRefConfig.packedTexcoordDataSize = sizeof(float) * 2;
733 glRefConfig.packedColorDataType = GL_FLOAT;
734 glRefConfig.packedColorDataSize = sizeof(float) * 4;
735 if( GLimp_HaveExtension( extension ) )
736 {
737 if (r_arb_half_float_vertex->integer)
274 glRefConfig.vertexArrayObject = !!r_arb_vertex_array_object->integer;
275
276 QGL_ARB_vertex_array_object_PROCS;
277
278 ri.Printf(PRINT_ALL, result[glRefConfig.vertexArrayObject], extension);
279 }
280 else
281 {
282 ri.Printf(PRINT_ALL, result[2], extension);
283 }
284
285 // GL_EXT_direct_state_access
286 extension = "GL_EXT_direct_state_access";
287 glRefConfig.directStateAccess = qfalse;
288 if (GLimp_HaveExtension(extension))
289 {
290 glRefConfig.directStateAccess = !!r_ext_direct_state_access->integer;
291
292 // QGL_*_PROCS becomes several functions, do not remove {}
293 if (glRefConfig.directStateAccess)
738294 {
739 glRefConfig.packedTexcoordDataType = GL_HALF_FLOAT;
740 glRefConfig.packedTexcoordDataSize = sizeof(uint16_t) * 2;
741 glRefConfig.packedColorDataType = GL_HALF_FLOAT;
742 glRefConfig.packedColorDataSize = sizeof(uint16_t) * 4;
295 QGL_EXT_direct_state_access_PROCS;
743296 }
744297
745 ri.Printf(PRINT_ALL, result[r_arb_half_float_vertex->integer ? 1 : 0], extension);
746 }
747 else
748 {
749 ri.Printf(PRINT_ALL, result[2], extension);
750 }
751
298 ri.Printf(PRINT_ALL, result[glRefConfig.directStateAccess], extension);
299 }
300 else
301 {
302 ri.Printf(PRINT_ALL, result[2], extension);
303 }
304
305 #undef GLE
752306 }
200200
201201 union f32_u {
202202 float f;
203 uint32_t i;
203 uint32_t ui;
204204 struct {
205205 unsigned int fraction:23;
206206 unsigned int exponent:8;
209209 };
210210
211211 union f16_u {
212 uint16_t i;
212 uint16_t ui;
213213 struct {
214214 unsigned int fraction:10;
215215 unsigned int exponent:5;
228228 f16.pack.fraction = f32.pack.fraction >> 13;
229229 f16.pack.sign = f32.pack.sign;
230230
231 return f16.i;
232 }
231 return f16.ui;
232 }
233
234 float HalfToFloat(uint16_t in)
235 {
236 union f32_u f32;
237 union f16_u f16;
238
239 f16.ui = in;
240
241 f32.pack.exponent = (int)(f16.pack.exponent) + 112;
242 f32.pack.fraction = f16.pack.fraction << 13;
243 f32.pack.sign = f16.pack.sign;
244
245 return f32.f;
246 }
9797
9898 int NextPowerOfTwo(int in);
9999 unsigned short FloatToHalf(float in);
100 float HalfToFloat(unsigned short in);
100101
101102 #endif
2222 // tr_fbo.c
2323 #include "tr_local.h"
2424
25 #include "tr_dsa.h"
26
2527 /*
2628 =============
2729 R_CheckFBO
2931 */
3032 qboolean R_CheckFBO(const FBO_t * fbo)
3133 {
32 int code;
33 int id;
34
35 qglGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &id);
36 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer);
37
38 code = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
34 GLenum code = qglCheckNamedFramebufferStatusEXT(fbo->frameBuffer, GL_FRAMEBUFFER_EXT);
3935
4036 if(code == GL_FRAMEBUFFER_COMPLETE_EXT)
41 {
42 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
4337 return qtrue;
44 }
4538
4639 // an error occured
4740 switch (code)
8275
8376 default:
8477 ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) unknown error 0x%X\n", fbo->name, code);
85 //ri.Error(ERR_FATAL, "R_CheckFBO: (%s) unknown error 0x%X", fbo->name, code);
86 //assert(0);
87 break;
88 }
89
90 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
78 break;
79 }
9180
9281 return qfalse;
9382 }
132121 return fbo;
133122 }
134123
124 /*
125 =================
126 FBO_CreateBuffer
127 =================
128 */
135129 void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
136130 {
137131 uint32_t *pRenderBuffer;
188182 if (absent)
189183 qglGenRenderbuffersEXT(1, pRenderBuffer);
190184
191 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *pRenderBuffer);
192185 if (multisample && glRefConfig.framebufferMultisample)
193 {
194 qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, format, fbo->width, fbo->height);
195 }
196 else
197 {
198 qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, fbo->width, fbo->height);
199 }
186 qglNamedRenderbufferStorageMultisampleEXT(*pRenderBuffer, multisample, format, fbo->width, fbo->height);
187 else
188 qglNamedRenderbufferStorageEXT(*pRenderBuffer, format, fbo->width, fbo->height);
200189
201190 if(absent)
202191 {
203192 if (attachment == 0)
204193 {
205 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
206 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
194 qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
195 qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer);
207196 }
208197 else
209 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer);
198 {
199 qglNamedFramebufferRenderbufferEXT(fbo->frameBuffer, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer);
200 }
210201 }
211202 }
212203
213204
214205 /*
215206 =================
216 R_AttachFBOTexture1D
207 FBO_AttachImage
217208 =================
218209 */
219 void R_AttachFBOTexture1D(int texId, int index)
220 {
221 if(index < 0 || index >= glRefConfig.maxColorAttachments)
222 {
223 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture1D: invalid attachment index %i\n", index);
224 return;
225 }
226
227 qglFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_1D, texId, 0);
228 }
229
230 /*
231 =================
232 R_AttachFBOTexture2D
233 =================
234 */
235 void R_AttachFBOTexture2D(int target, int texId, int index)
236 {
237 if(target != GL_TEXTURE_2D && (target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB))
238 {
239 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid target %i\n", target);
240 return;
241 }
242
243 if(index < 0 || index >= glRefConfig.maxColorAttachments)
244 {
245 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid attachment index %i\n", index);
246 return;
247 }
248
249 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, target, texId, 0);
250 }
251
252 /*
253 =================
254 R_AttachFBOTexture3D
255 =================
256 */
257 void R_AttachFBOTexture3D(int texId, int index, int zOffset)
258 {
259 if(index < 0 || index >= glRefConfig.maxColorAttachments)
260 {
261 ri.Printf(PRINT_WARNING, "R_AttachFBOTexture3D: invalid attachment index %i\n", index);
262 return;
263 }
264
265 qglFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_3D_EXT, texId, 0, zOffset);
266 }
267
268 /*
269 =================
270 R_AttachFBOTextureDepth
271 =================
272 */
273 void R_AttachFBOTextureDepth(int texId)
274 {
275 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0);
276 }
277
278 /*
279 =================
280 R_AttachFBOTexturePackedDepthStencil
281 =================
282 */
283 void R_AttachFBOTexturePackedDepthStencil(int texId)
284 {
285 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0);
286 qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0);
287 }
288
289 void FBO_AttachTextureImage(image_t *img, int index)
290 {
291 if (!glState.currentFBO)
292 {
293 ri.Printf(PRINT_WARNING, "FBO: attempted to attach a texture image with no FBO bound!\n");
294 return;
295 }
296
297 R_AttachFBOTexture2D(GL_TEXTURE_2D, img->texnum, index);
298 glState.currentFBO->colorImage[index] = img;
299 }
210 void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside)
211 {
212 GLenum target = GL_TEXTURE_2D;
213 int index;
214
215 if (image->flags & IMGFLAG_CUBEMAP)
216 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cubemapside;
217
218 qglNamedFramebufferTexture2DEXT(fbo->frameBuffer, attachment, target, image->texnum, 0);
219 index = attachment - GL_COLOR_ATTACHMENT0_EXT;
220 if (index >= 0 && index <= 15)
221 fbo->colorImage[index] = image;
222 }
223
300224
301225 /*
302226 ============
311235 if (r_logFile->integer)
312236 {
313237 // don't just call LogComment, or we will get a call to va() every frame!
314 if (fbo)
315 GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo->name));
316 else
317 GLimp_LogComment("--- FBO_Bind ( NULL ) ---\n");
318 }
319
320 if (!fbo)
321 {
322 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
323 //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
324 glState.currentFBO = NULL;
325
326 return;
327 }
328
329 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer);
330
331 /*
332 if(fbo->colorBuffers[0])
333 {
334 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->colorBuffers[0]);
335 }
336 */
337
338 /*
339 if(fbo->depthBuffer)
340 {
341 qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->depthBuffer);
342 qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depthBuffer);
343 }
344 */
345
238 GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL"));
239 }
240
241 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, fbo ? fbo->frameBuffer : 0);
346242 glState.currentFBO = fbo;
347243 }
348244
354250 void FBO_Init(void)
355251 {
356252 int i;
357 // int width, height, hdrFormat, multisample;
358 int hdrFormat, multisample;
253 int hdrFormat, multisample = 0;
359254
360255 ri.Printf(PRINT_ALL, "------- FBO_Init -------\n");
361256
368263
369264 R_IssuePendingRenderCommands();
370265
371 /* if(glRefConfig.textureNonPowerOfTwo)
372 {
373 width = glConfig.vidWidth;
374 height = glConfig.vidHeight;
375 }
376 else
377 {
378 width = NextPowerOfTwo(glConfig.vidWidth);
379 height = NextPowerOfTwo(glConfig.vidHeight);
380 } */
381
382266 hdrFormat = GL_RGBA8;
383267 if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat)
384 {
385268 hdrFormat = GL_RGBA16F_ARB;
386 }
387
388 qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
269
270 if (glRefConfig.framebufferMultisample)
271 qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
389272
390273 if (r_ext_framebuffer_multisample->integer < multisample)
391 {
392274 multisample = r_ext_framebuffer_multisample->integer;
393 }
394275
395276 if (multisample < 2 || !glRefConfig.framebufferBlit)
396277 multisample = 0;
397278
398279 if (multisample != r_ext_framebuffer_multisample->integer)
399 {
400280 ri.Cvar_SetValue("r_ext_framebuffer_multisample", (float)multisample);
401 }
402281
403282 // only create a render FBO if we need to resolve MSAA or do HDR
404283 // otherwise just render straight to the screen (tr.renderFbo = NULL)
405284 if (multisample && glRefConfig.framebufferMultisample)
406285 {
407286 tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
408 FBO_Bind(tr.renderFbo);
409
410287 FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, multisample);
411288 FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, multisample);
412
413289 R_CheckFBO(tr.renderFbo);
414290
415
416291 tr.msaaResolveFbo = FBO_Create("_msaaResolve", tr.renderDepthImage->width, tr.renderDepthImage->height);
417 FBO_Bind(tr.msaaResolveFbo);
418
419 //FBO_CreateBuffer(tr.msaaResolveFbo, hdrFormat, 0, 0);
420 FBO_AttachTextureImage(tr.renderImage, 0);
421
422 //FBO_CreateBuffer(tr.msaaResolveFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
423 R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
424
292 FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
293 FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
425294 R_CheckFBO(tr.msaaResolveFbo);
426295 }
427296 else if (r_hdr->integer)
428297 {
429298 tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
430 FBO_Bind(tr.renderFbo);
431
432 //FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, 0);
433 FBO_AttachTextureImage(tr.renderImage, 0);
434
435 //FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
436 R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
437
299 FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0);
300 FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
438301 R_CheckFBO(tr.renderFbo);
439302 }
440303
442305 // this fixes the corrupt screen bug with r_hdr 1 on older hardware
443306 if (tr.renderFbo)
444307 {
445 FBO_Bind(tr.renderFbo);
308 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, tr.renderFbo->frameBuffer);
446309 qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
447 FBO_Bind(NULL);
448 }
449
450 if (r_drawSunRays->integer)
310 }
311
312 if (tr.screenScratchImage)
313 {
314 tr.screenScratchFbo = FBO_Create("screenScratch", tr.screenScratchImage->width, tr.screenScratchImage->height);
315 FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0_EXT, 0);
316 FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
317 R_CheckFBO(tr.screenScratchFbo);
318 }
319
320 if (tr.sunRaysImage)
451321 {
452322 tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height);
453 FBO_Bind(tr.sunRaysFbo);
454
455 FBO_AttachTextureImage(tr.sunRaysImage, 0);
456
457 R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
458
323 FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0);
324 FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
459325 R_CheckFBO(tr.sunRaysFbo);
460326 }
461327
465331 for( i = 0; i < MAX_DRAWN_PSHADOWS; i++)
466332 {
467333 tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height);
468 FBO_Bind(tr.pshadowFbos[i]);
469
470 //FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0);
471 FBO_AttachTextureImage(tr.pshadowMaps[i], 0);
472
334 FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT, 0);
473335 FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0);
474 //R_AttachFBOTextureDepth(tr.textureDepthImage->texnum);
475
476336 R_CheckFBO(tr.pshadowFbos[i]);
477337 }
478338 }
479339
480340 if (tr.sunShadowDepthImage[0])
481341 {
482 for ( i = 0; i < 4; i++)
342 for (i = 0; i < 4; i++)
483343 {
484344 tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height);
485 FBO_Bind(tr.sunShadowFbo[i]);
486
487 //FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
488 //FBO_AttachTextureImage(tr.sunShadowImage, 0);
489 qglDrawBuffer(GL_NONE);
490 qglReadBuffer(GL_NONE);
491
492 //FBO_CreateBuffer(tr.sunShadowFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
493 R_AttachFBOTextureDepth(tr.sunShadowDepthImage[i]->texnum);
494
345 // FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments
346 // This at least gets sun shadows working on older GPUs (Intel)
347 FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
348 FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0);
495349 R_CheckFBO(tr.sunShadowFbo[i]);
496
497350 }
498
351 }
352
353 if (tr.screenShadowImage)
354 {
499355 tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
500 FBO_Bind(tr.screenShadowFbo);
501
502 FBO_AttachTextureImage(tr.screenShadowImage, 0);
503
356 FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0);
504357 R_CheckFBO(tr.screenShadowFbo);
505358 }
506359
507 for (i = 0; i < 2; i++)
508 {
509 tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
510 FBO_Bind(tr.textureScratchFbo[i]);
511
512 //FBO_CreateBuffer(tr.textureScratchFbo[i], GL_RGBA8, 0, 0);
513 FBO_AttachTextureImage(tr.textureScratchImage[i], 0);
514
515 R_CheckFBO(tr.textureScratchFbo[i]);
516 }
517
360 if (tr.textureScratchImage[0])
361 {
362 for (i = 0; i < 2; i++)
363 {
364 tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
365 FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
366 R_CheckFBO(tr.textureScratchFbo[i]);
367 }
368 }
369
370 if (tr.calcLevelsImage)
518371 {
519372 tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height);
520 FBO_Bind(tr.calcLevelsFbo);
521
522 //FBO_CreateBuffer(tr.calcLevelsFbo, hdrFormat, 0, 0);
523 FBO_AttachTextureImage(tr.calcLevelsImage, 0);
524
373 FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
525374 R_CheckFBO(tr.calcLevelsFbo);
526375 }
527376
377 if (tr.targetLevelsImage)
528378 {
529379 tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height);
530 FBO_Bind(tr.targetLevelsFbo);
531
532 //FBO_CreateBuffer(tr.targetLevelsFbo, hdrFormat, 0, 0);
533 FBO_AttachTextureImage(tr.targetLevelsImage, 0);
534
380 FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
535381 R_CheckFBO(tr.targetLevelsFbo);
536382 }
537383
538 for (i = 0; i < 2; i++)
539 {
540 tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
541 FBO_Bind(tr.quarterFbo[i]);
542
543 //FBO_CreateBuffer(tr.quarterFbo[i], hdrFormat, 0, 0);
544 FBO_AttachTextureImage(tr.quarterImage[i], 0);
545
546 R_CheckFBO(tr.quarterFbo[i]);
547 }
548
549 if (r_ssao->integer)
384 if (tr.quarterImage[0])
385 {
386 for (i = 0; i < 2; i++)
387 {
388 tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
389 FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
390 R_CheckFBO(tr.quarterFbo[i]);
391 }
392 }
393
394 if (tr.hdrDepthImage)
550395 {
551396 tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height);
552 FBO_Bind(tr.hdrDepthFbo);
553
554 FBO_AttachTextureImage(tr.hdrDepthImage, 0);
555
397 FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0);
556398 R_CheckFBO(tr.hdrDepthFbo);
557
399 }
400
401 if (tr.screenSsaoImage)
402 {
558403 tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height);
559 FBO_Bind(tr.screenSsaoFbo);
560
561 FBO_AttachTextureImage(tr.screenSsaoImage, 0);
562
404 FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0);
563405 R_CheckFBO(tr.screenSsaoFbo);
564406 }
565407
566408 if (tr.renderCubeImage)
567409 {
568410 tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height);
569 FBO_Bind(tr.renderCubeFbo);
570
571 //FBO_AttachTextureImage(tr.renderCubeImage, 0);
572 R_AttachFBOTexture2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, tr.renderCubeImage->texnum, 0);
573 glState.currentFBO->colorImage[0] = tr.renderCubeImage;
574
411 FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT, 0);
575412 FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
576
577413 R_CheckFBO(tr.renderCubeFbo);
578414 }
579415
580416 GL_CheckErrors();
581417
582 FBO_Bind(NULL);
418 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
419 glState.currentFBO = NULL;
583420 }
584421
585422 /*
649486 ri.Printf(PRINT_ALL, " %i FBOs\n", tr.numFBOs);
650487 }
651488
652 void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend)
653 {
654 ivec4_t dstBox, srcBox;
655 vec2_t srcTexScale;
489 void FBO_BlitFromTexture(struct image_s *src, vec4_t inSrcTexCorners, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend)
490 {
491 ivec4_t dstBox;
656492 vec4_t color;
657493 vec4_t quadVerts[4];
658494 vec2_t texCoords[4];
662498 int width, height;
663499
664500 if (!src)
501 {
502 ri.Printf(PRINT_WARNING, "Tried to blit from a NULL texture!\n");
665503 return;
666
667 if (inSrcBox)
668 {
669 VectorSet4(srcBox, inSrcBox[0], inSrcBox[1], inSrcBox[0] + inSrcBox[2], inSrcBox[1] + inSrcBox[3]);
670 }
671 else
672 {
673 VectorSet4(srcBox, 0, 0, src->width, src->height);
504 }
505
506 width = dst ? dst->width : glConfig.vidWidth;
507 height = dst ? dst->height : glConfig.vidHeight;
508
509 if (inSrcTexCorners)
510 {
511 VectorSet2(texCoords[0], inSrcTexCorners[0], inSrcTexCorners[1]);
512 VectorSet2(texCoords[1], inSrcTexCorners[2], inSrcTexCorners[1]);
513 VectorSet2(texCoords[2], inSrcTexCorners[2], inSrcTexCorners[3]);
514 VectorSet2(texCoords[3], inSrcTexCorners[0], inSrcTexCorners[3]);
515 }
516 else
517 {
518 VectorSet2(texCoords[0], 0.0f, 1.0f);
519 VectorSet2(texCoords[1], 1.0f, 1.0f);
520 VectorSet2(texCoords[2], 1.0f, 0.0f);
521 VectorSet2(texCoords[3], 0.0f, 0.0f);
674522 }
675523
676524 // framebuffers are 0 bottom, Y up.
677525 if (inDstBox)
678526 {
679 if (dst)
680 {
681 dstBox[0] = inDstBox[0];
682 dstBox[1] = dst->height - inDstBox[1] - inDstBox[3];
683 dstBox[2] = inDstBox[0] + inDstBox[2];
684 dstBox[3] = dst->height - inDstBox[1];
685 }
686 else
687 {
688 dstBox[0] = inDstBox[0];
689 dstBox[1] = glConfig.vidHeight - inDstBox[1] - inDstBox[3];
690 dstBox[2] = inDstBox[0] + inDstBox[2];
691 dstBox[3] = glConfig.vidHeight - inDstBox[1];
692 }
693 }
694 else if (dst)
695 {
696 VectorSet4(dstBox, 0, dst->height, dst->width, 0);
697 }
698 else
699 {
700 VectorSet4(dstBox, 0, glConfig.vidHeight, glConfig.vidWidth, 0);
527 dstBox[0] = inDstBox[0];
528 dstBox[1] = height - inDstBox[1] - inDstBox[3];
529 dstBox[2] = inDstBox[0] + inDstBox[2];
530 dstBox[3] = height - inDstBox[1];
531 }
532 else
533 {
534 VectorSet4(dstBox, 0, height, width, 0);
701535 }
702536
703537 if (inSrcTexScale)
704538 {
705 VectorCopy2(inSrcTexScale, srcTexScale);
706 }
707 else
708 {
709 srcTexScale[0] = srcTexScale[1] = 1.0f;
539 VectorCopy2(inSrcTexScale, invTexRes);
540 }
541 else
542 {
543 VectorSet2(invTexRes, 1.0f, 1.0f);
710544 }
711545
712546 if (inColor)
724558 }
725559
726560 FBO_Bind(dst);
727
728 if (glState.currentFBO)
729 {
730 width = glState.currentFBO->width;
731 height = glState.currentFBO->height;
732 }
733 else
734 {
735 width = glConfig.vidWidth;
736 height = glConfig.vidHeight;
737 }
738561
739562 qglViewport( 0, 0, width, height );
740563 qglScissor( 0, 0, width, height );
745568
746569 GL_BindToTMU(src, TB_COLORMAP);
747570
748 VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0, 1);
749 VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0, 1);
750 VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0, 1);
751 VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0, 1);
752
753 texCoords[0][0] = srcBox[0] / (float)src->width; texCoords[0][1] = 1.0f - srcBox[1] / (float)src->height;
754 texCoords[1][0] = srcBox[2] / (float)src->width; texCoords[1][1] = 1.0f - srcBox[1] / (float)src->height;
755 texCoords[2][0] = srcBox[2] / (float)src->width; texCoords[2][1] = 1.0f - srcBox[3] / (float)src->height;
756 texCoords[3][0] = srcBox[0] / (float)src->width; texCoords[3][1] = 1.0f - srcBox[3] / (float)src->height;
757
758 invTexRes[0] = 1.0f / src->width * srcTexScale[0];
759 invTexRes[1] = 1.0f / src->height * srcTexScale[1];
571 VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0.0f, 1.0f);
572 VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0.0f, 1.0f);
573 VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0.0f, 1.0f);
574 VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0.0f, 1.0f);
575
576 invTexRes[0] /= src->width;
577 invTexRes[1] /= src->height;
760578
761579 GL_State( blend );
762580
768586 GLSL_SetUniformVec2(shaderProgram, UNIFORM_AUTOEXPOSUREMINMAX, tr.refdef.autoExposureMinMax);
769587 GLSL_SetUniformVec3(shaderProgram, UNIFORM_TONEMINAVGMAXLINEAR, tr.refdef.toneMinAvgMaxLinear);
770588
771 RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
589 RB_InstantQuad2(quadVerts, texCoords);
772590
773591 FBO_Bind(oldFbo);
774592 }
775593
776594 void FBO_Blit(FBO_t *src, ivec4_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend)
777595 {
778 ivec4_t srcBox;
596 vec4_t srcTexCorners;
779597
780598 if (!src)
781599 {
783601 return;
784602 }
785603
786 // framebuffers are 0 bottom, Y up.
787604 if (inSrcBox)
788605 {
789 srcBox[0] = inSrcBox[0];
790 srcBox[1] = src->height - inSrcBox[1] - inSrcBox[3];
791 srcBox[2] = inSrcBox[2];
792 srcBox[3] = inSrcBox[3];
793 }
794 else
795 {
796 VectorSet4(srcBox, 0, src->height, src->width, -src->height);
797 }
798
799 FBO_BlitFromTexture(src->colorImage[0], srcBox, srcTexScale, dst, dstBox, shaderProgram, color, blend | GLS_DEPTHTEST_DISABLE);
606 srcTexCorners[0] = inSrcBox[0] / (float)src->width;
607 srcTexCorners[1] = (inSrcBox[1] + inSrcBox[3]) / (float)src->height;
608 srcTexCorners[2] = (inSrcBox[0] + inSrcBox[2]) / (float)src->width;
609 srcTexCorners[3] = inSrcBox[1] / (float)src->height;
610 }
611 else
612 {
613 VectorSet4(srcTexCorners, 0.0f, 0.0f, 1.0f, 1.0f);
614 }
615
616 FBO_BlitFromTexture(src->colorImage[0], srcTexCorners, srcTexScale, dst, dstBox, shaderProgram, color, blend | GLS_DEPTHTEST_DISABLE);
800617 }
801618
802619 void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter)
810627 return;
811628 }
812629
813 // get to a neutral state first
814 //FBO_Bind(NULL);
815
816630 srcFb = src ? src->frameBuffer : 0;
817631 dstFb = dst ? dst->frameBuffer : 0;
818632
819633 if (!srcBox)
820634 {
821 if (src)
822 {
823 VectorSet4(srcBoxFinal, 0, 0, src->width, src->height);
824 }
825 else
826 {
827 VectorSet4(srcBoxFinal, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
828 }
635 int width = src ? src->width : glConfig.vidWidth;
636 int height = src ? src->height : glConfig.vidHeight;
637
638 VectorSet4(srcBoxFinal, 0, 0, width, height);
829639 }
830640 else
831641 {
834644
835645 if (!dstBox)
836646 {
837 if (dst)
838 {
839 VectorSet4(dstBoxFinal, 0, 0, dst->width, dst->height);
840 }
841 else
842 {
843 VectorSet4(dstBoxFinal, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
844 }
647 int width = dst ? dst->width : glConfig.vidWidth;
648 int height = dst ? dst->height : glConfig.vidHeight;
649
650 VectorSet4(dstBoxFinal, 0, 0, width, height);
845651 }
846652 else
847653 {
848654 VectorSet4(dstBoxFinal, dstBox[0], dstBox[1], dstBox[0] + dstBox[2], dstBox[1] + dstBox[3]);
849655 }
850656
851 qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, srcFb);
852 qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dstFb);
657 GL_BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, srcFb);
658 GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, dstFb);
853659 qglBlitFramebufferEXT(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3],
854660 dstBoxFinal[0], dstBoxFinal[1], dstBoxFinal[2], dstBoxFinal[3],
855661 buffers, filter);
856662
857 qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
663 GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
858664 glState.currentFBO = NULL;
859665 }
5151 int height;
5252 } FBO_t;
5353
54 void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside);
5455 void FBO_Bind(FBO_t *fbo);
5556 void FBO_Init(void);
5657 void FBO_Shutdown(void);
5758
58 void FBO_BlitFromTexture(struct image_s *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
59 void FBO_BlitFromTexture(struct image_s *src, vec4_t inSrcTexCorners, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend);
5960 void FBO_Blit(FBO_t *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
6061 void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter);
6162
341341 ==================
342342 */
343343 void RB_TestFlare( flare_t *f ) {
344 qboolean visible;
345 float fade;
344 float depth;
345 qboolean visible;
346 float fade;
347 float screenZ;
348 FBO_t *oldFbo;
346349
347350 backEnd.pc.c_flareTests++;
348351
352 // doing a readpixels is as good as doing a glFinish(), so
353 // don't bother with another sync
354 glState.finishCalled = qfalse;
355
356 // if we're doing multisample rendering, read from the correct FBO
357 oldFbo = glState.currentFBO;
358 if (tr.msaaResolveFbo)
359 {
360 FBO_Bind(tr.msaaResolveFbo);
361 }
362
363 // read back the z buffer contents
364 qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
365
366 // if we're doing multisample rendering, switch to the old FBO
367 if (tr.msaaResolveFbo)
368 {
369 FBO_Bind(oldFbo);
370 }
371
372 screenZ = backEnd.viewParms.projectionMatrix[14] /
373 ( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
374
349375 visible = (qboolean)( f->flags & 1 );
376
377 if ( -f->eyeZ - -screenZ > 24 )
378 visible = qfalse;
350379
351380 if ( visible ) {
352381 if ( !f->visible ) {
353382 f->visible = qtrue;
354383 f->fadeTime = backEnd.refdef.time - 1;
355384 }
356 fade = ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
385 fade = ( ( backEnd.refdef.time - f->fadeTime ) /1000.0f ) * r_flareFade->value;
357386 } else {
358387 if ( f->visible ) {
359388 f->visible = qfalse;
437466 return;
438467 }
439468
440 iColor[0] = color[0] * fogFactors[0];
441 iColor[1] = color[1] * fogFactors[1];
442 iColor[2] = color[2] * fogFactors[2];
469 iColor[0] = color[0] * fogFactors[0] * 257;
470 iColor[1] = color[1] * fogFactors[1] * 257;
471 iColor[2] = color[2] * fogFactors[2] * 257;
443472
444473 if ( f->flags & 2 ) { // spotlight flare
445474 RB_BeginSurface( tr.spotFlareShader, f->fogNum, 0 );
452481 tess.xyz[tess.numVertexes][1] = f->windowY - size;
453482 tess.texCoords[tess.numVertexes][0][0] = 0;
454483 tess.texCoords[tess.numVertexes][0][1] = 0;
455 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
456 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
457 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
458 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
459 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
484 tess.color[tess.numVertexes][0] = iColor[0];
485 tess.color[tess.numVertexes][1] = iColor[1];
486 tess.color[tess.numVertexes][2] = iColor[2];
487 // tess.color[tess.numVertexes][3] = 65535; //rend2
488 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
460489 tess.numVertexes++;
461490
462491 tess.xyz[tess.numVertexes][0] = f->windowX - size;
463492 tess.xyz[tess.numVertexes][1] = f->windowY + size;
464493 tess.texCoords[tess.numVertexes][0][0] = 0;
465494 tess.texCoords[tess.numVertexes][0][1] = 1;
466 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
467 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
468 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
469 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
470 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
495 tess.color[tess.numVertexes][0] = iColor[0];
496 tess.color[tess.numVertexes][1] = iColor[1];
497 tess.color[tess.numVertexes][2] = iColor[2];
498 // tess.color[tess.numVertexes][3] = 65535; // rend2
499 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
471500 tess.numVertexes++;
472501
473502 tess.xyz[tess.numVertexes][0] = f->windowX + size;
474503 tess.xyz[tess.numVertexes][1] = f->windowY + size;
475504 tess.texCoords[tess.numVertexes][0][0] = 1;
476505 tess.texCoords[tess.numVertexes][0][1] = 1;
477 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
478 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
479 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
480 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
481 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
506 tess.color[tess.numVertexes][0] = iColor[0];
507 tess.color[tess.numVertexes][1] = iColor[1];
508 tess.color[tess.numVertexes][2] = iColor[2];
509 // tess.color[tess.numVertexes][3] = 65535; // rend2
510 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
482511 tess.numVertexes++;
483512
484513 tess.xyz[tess.numVertexes][0] = f->windowX + size;
485514 tess.xyz[tess.numVertexes][1] = f->windowY - size;
486515 tess.texCoords[tess.numVertexes][0][0] = 1;
487516 tess.texCoords[tess.numVertexes][0][1] = 0;
488 tess.vertexColors[tess.numVertexes][0] = iColor[0] / 255.0f;
489 tess.vertexColors[tess.numVertexes][1] = iColor[1] / 255.0f;
490 tess.vertexColors[tess.numVertexes][2] = iColor[2] / 255.0f;
491 tess.vertexColors[tess.numVertexes][3] = f->drawIntensity; //----(SA) mod for alpha blend rather than additive
492 // tess.vertexColors[tess.numVertexes][3] = 1.0f; // rend2
517 tess.color[tess.numVertexes][0] = iColor[0];
518 tess.color[tess.numVertexes][1] = iColor[1];
519 tess.color[tess.numVertexes][2] = iColor[2];
520 // tess.color[tess.numVertexes][3] = 65535; // rend2
521 tess.color[tess.numVertexes][3] = f->drawIntensity * 65535; //----(SA) mod for alpha blend rather than additive
493522 tess.numVertexes++;
494523
495524 tess.indexes[tess.numIndexes++] = 0;
7979 #include "../qcommon/qcommon.h"
8080
8181 #ifdef BUILD_FREETYPE
82 #include <ft2build.h>
82 #ifdef USE_LOCAL_HEADERS
83 #include "../freetype-2.6.4/include/ft2build.h"
84 #else
85 #include <ft2build.h>
86 #endif
8387 #include FT_FREETYPE_H
8488 #include FT_ERRORS_H
8589 #include FT_SYSTEM_H
2121 // tr_glsl.c
2222 #include "tr_local.h"
2323
24 void GLSL_BindNullProgram(void);
24 #include "tr_dsa.h"
2525
2626 extern const char *fallbackShader_bokeh_vp;
2727 extern const char *fallbackShader_bokeh_fp;
151151 { "u_ZFadeHighest", GLSL_FLOAT },
152152 };
153153
154
155 static void GLSL_PrintInfoLog(GLhandleARB object, qboolean developerOnly)
154 typedef enum
155 {
156 GLSL_PRINTLOG_PROGRAM_INFO,
157 GLSL_PRINTLOG_SHADER_INFO,
158 GLSL_PRINTLOG_SHADER_SOURCE
159 }
160 glslPrintLog_t;
161
162 static void GLSL_PrintLog(GLuint programOrShader, glslPrintLog_t type, qboolean developerOnly)
156163 {
157164 char *msg;
158165 static char msgPart[1024];
160167 int i;
161168 int printLevel = developerOnly ? PRINT_DEVELOPER : PRINT_ALL;
162169
163 qglGetObjectParameterivARB(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength);
170 switch (type)
171 {
172 case GLSL_PRINTLOG_PROGRAM_INFO:
173 ri.Printf(printLevel, "Program info log:\n");
174 qglGetProgramiv(programOrShader, GL_INFO_LOG_LENGTH, &maxLength);
175 break;
176
177 case GLSL_PRINTLOG_SHADER_INFO:
178 ri.Printf(printLevel, "Shader info log:\n");
179 qglGetShaderiv(programOrShader, GL_INFO_LOG_LENGTH, &maxLength);
180 break;
181
182 case GLSL_PRINTLOG_SHADER_SOURCE:
183 ri.Printf(printLevel, "Shader source:\n");
184 qglGetShaderiv(programOrShader, GL_SHADER_SOURCE_LENGTH, &maxLength);
185 break;
186 }
164187
165188 if (maxLength <= 0)
166189 {
167 ri.Printf(printLevel, "No compile log.\n");
168 return;
169 }
170
171 ri.Printf(printLevel, "compile log:\n");
190 ri.Printf(printLevel, "None.\n");
191 return;
192 }
172193
173194 if (maxLength < 1023)
174 {
175 qglGetInfoLogARB(object, maxLength, &maxLength, msgPart);
176
195 msg = msgPart;
196 else
197 msg = ri.Z_Malloc(maxLength);
198
199 switch (type)
200 {
201 case GLSL_PRINTLOG_PROGRAM_INFO:
202 qglGetProgramInfoLog(programOrShader, maxLength, &maxLength, msg);
203 break;
204
205 case GLSL_PRINTLOG_SHADER_INFO:
206 qglGetShaderInfoLog(programOrShader, maxLength, &maxLength, msg);
207 break;
208
209 case GLSL_PRINTLOG_SHADER_SOURCE:
210 qglGetShaderSource(programOrShader, maxLength, &maxLength, msg);
211 break;
212 }
213
214 if (maxLength < 1023)
215 {
177216 msgPart[maxLength + 1] = '\0';
178217
179218 ri.Printf(printLevel, "%s\n", msgPart);
180219 }
181220 else
182221 {
183 msg = ri.Z_Malloc(maxLength);
184
185 qglGetInfoLogARB(object, maxLength, &maxLength, msg);
186
187 for(i = 0; i < maxLength; i += 1024)
222 for(i = 0; i < maxLength; i += 1023)
188223 {
189224 Q_strncpyz(msgPart, msg + i, sizeof(msgPart));
190225
191 ri.Printf(printLevel, "%s\n", msgPart);
192 }
226 ri.Printf(printLevel, "%s", msgPart);
227 }
228
229 ri.Printf(printLevel, "\n");
193230
194231 ri.Free(msg);
195232 }
196 }
197
198 static void GLSL_PrintShaderSource(GLhandleARB object)
199 {
200 char *msg;
201 static char msgPart[1024];
202 int maxLength = 0;
203 int i;
204
205 qglGetObjectParameterivARB(object, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &maxLength);
206
207 msg = ri.Z_Malloc(maxLength);
208
209 qglGetShaderSourceARB(object, maxLength, &maxLength, msg);
210
211 for(i = 0; i < maxLength; i += 1024)
212 {
213 Q_strncpyz(msgPart, msg + i, sizeof(msgPart));
214 ri.Printf(PRINT_ALL, "%s\n", msgPart);
215 }
216
217 ri.Free(msg);
218 }
219
220 static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, char *dest, int size )
233
234 }
235
236 static void GLSL_GetShaderHeader( GLenum shaderType, const GLchar *extra, char *dest, int size )
221237 {
222238 float fbufWidthScale, fbufHeightScale;
223239
228244 {
229245 Q_strcat(dest, size, "#version 130\n");
230246
231 if(shaderType == GL_VERTEX_SHADER_ARB)
247 if(shaderType == GL_VERTEX_SHADER)
232248 {
233249 Q_strcat(dest, size, "#define attribute in\n");
234250 Q_strcat(dest, size, "#define varying out\n");
327343 Q_strcat(dest, size,
328344 va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale));
329345
330 if (r_materialGamma->value != 1.0f)
331 Q_strcat(dest, size, va("#ifndef r_materialGamma\n#define r_materialGamma %f\n#endif\n", r_materialGamma->value));
332
333 if (r_lightGamma->value != 1.0f)
334 Q_strcat(dest, size, va("#ifndef r_lightGamma\n#define r_lightGamma %f\n#endif\n", r_lightGamma->value));
335
336 if (r_framebufferGamma->value != 1.0f)
337 Q_strcat(dest, size, va("#ifndef r_framebufferGamma\n#define r_framebufferGamma %f\n#endif\n", r_framebufferGamma->value));
338
339 if (r_tonemapGamma->value != 1.0f)
340 Q_strcat(dest, size, va("#ifndef r_tonemapGamma\n#define r_tonemapGamma %f\n#endif\n", r_tonemapGamma->value));
346 if (r_pbr->integer)
347 Q_strcat(dest, size, "#define USE_PBR\n");
348
349 if (r_cubeMapping->integer)
350 {
351 int cubeMipSize = r_cubemapSize->integer;
352 int numRoughnessMips = 0;
353
354 while (cubeMipSize)
355 {
356 cubeMipSize >>= 1;
357 numRoughnessMips++;
358 }
359 numRoughnessMips = MAX(1, numRoughnessMips - 2);
360 Q_strcat(dest, size, va("#define ROUGHNESS_MIPS float(%d)\n", numRoughnessMips));
361 }
341362
342363 if (extra)
343364 {
349370 Q_strcat(dest, size, "#line 0\n");
350371 }
351372
352 static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, const GLcharARB *buffer, int size, GLenum shaderType)
373 static int GLSL_CompileGPUShader(GLuint program, GLuint *prevShader, const GLchar *buffer, int size, GLenum shaderType)
353374 {
354375 GLint compiled;
355 GLhandleARB shader;
356
357 shader = qglCreateShaderObjectARB(shaderType);
358
359 qglShaderSourceARB(shader, 1, (const GLcharARB **)&buffer, &size);
376 GLuint shader;
377
378 shader = qglCreateShader(shaderType);
379
380 qglShaderSource(shader, 1, (const GLchar **)&buffer, &size);
360381
361382 // compile shader
362 qglCompileShaderARB(shader);
383 qglCompileShader(shader);
363384
364385 // check if shader compiled
365 qglGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
386 qglGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
366387 if(!compiled)
367388 {
368 GLSL_PrintShaderSource(shader);
369 GLSL_PrintInfoLog(shader, qfalse);
389 GLSL_PrintLog(shader, GLSL_PRINTLOG_SHADER_SOURCE, qfalse);
390 GLSL_PrintLog(shader, GLSL_PRINTLOG_SHADER_INFO, qfalse);
370391 ri.Error(ERR_DROP, "Couldn't compile shader");
371392 return 0;
372393 }
373394
374 //GLSL_PrintInfoLog(shader, qtrue);
375 //GLSL_PrintShaderSource(shader);
376
377395 if (*prevShader)
378396 {
379 qglDetachObjectARB(program, *prevShader);
380 qglDeleteObjectARB(*prevShader);
397 qglDetachShader(program, *prevShader);
398 qglDeleteShader(*prevShader);
381399 }
382400
383401 // attach shader to program
384 qglAttachObjectARB(program, shader);
402 qglAttachShader(program, shader);
385403
386404 *prevShader = shader;
387405
392410 GLenum shaderType, char *dest, int destSize)
393411 {
394412 char filename[MAX_QPATH];
395 GLcharARB *buffer = NULL;
396 const GLcharARB *shaderText = NULL;
413 GLchar *buffer = NULL;
414 const GLchar *shaderText = NULL;
397415 int size;
398416 int result;
399417
400 if(shaderType == GL_VERTEX_SHADER_ARB)
418 if(shaderType == GL_VERTEX_SHADER)
401419 {
402420 Com_sprintf(filename, sizeof(filename), "glsl/%s_vp.glsl", name);
403421 }
451469 return result;
452470 }
453471
454 static void GLSL_LinkProgram(GLhandleARB program)
472 static void GLSL_LinkProgram(GLuint program)
455473 {
456474 GLint linked;
457475
458 qglLinkProgramARB(program);
459
460 qglGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
476 qglLinkProgram(program);
477
478 qglGetProgramiv(program, GL_LINK_STATUS, &linked);
461479 if(!linked)
462480 {
463 GLSL_PrintInfoLog(program, qfalse);
464 ri.Printf(PRINT_ALL, "\n");
481 GLSL_PrintLog(program, GLSL_PRINTLOG_PROGRAM_INFO, qfalse);
465482 ri.Error(ERR_DROP, "shaders failed to link");
466483 }
467484 }
468485
469 static void GLSL_ValidateProgram(GLhandleARB program)
486 static void GLSL_ValidateProgram(GLuint program)
470487 {
471488 GLint validated;
472489
473 qglValidateProgramARB(program);
474
475 qglGetObjectParameterivARB(program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated);
490 qglValidateProgram(program);
491
492 qglGetProgramiv(program, GL_VALIDATE_STATUS, &validated);
476493 if(!validated)
477494 {
478 GLSL_PrintInfoLog(program, qfalse);
479 ri.Printf(PRINT_ALL, "\n");
495 GLSL_PrintLog(program, GLSL_PRINTLOG_PROGRAM_INFO, qfalse);
480496 ri.Error(ERR_DROP, "shaders failed to validate");
481497 }
482498 }
483499
484 static void GLSL_ShowProgramUniforms(GLhandleARB program)
500 static void GLSL_ShowProgramUniforms(GLuint program)
485501 {
486502 int i, count, size;
487503 GLenum type;
488504 char uniformName[1000];
489505
490 // install the executables in the program object as part of current state.
491 qglUseProgramObjectARB(program);
492
493 // check for GL Errors
494
495506 // query the number of active uniforms
496 qglGetObjectParameterivARB(program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count);
507 qglGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count);
497508
498509 // Loop over each of the active uniforms, and set their value
499510 for(i = 0; i < count; i++)
500511 {
501 qglGetActiveUniformARB(program, i, sizeof(uniformName), NULL, &size, &type, uniformName);
512 qglGetActiveUniform(program, i, sizeof(uniformName), NULL, &size, &type, uniformName);
502513
503514 ri.Printf(PRINT_DEVELOPER, "active uniform: '%s'\n", uniformName);
504515 }
505
506 qglUseProgramObjectARB(0);
507516 }
508517
509518 static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int attribs, const char *vpCode, const char *fpCode)
517526
518527 Q_strncpyz(program->name, name, sizeof(program->name));
519528
520 program->program = qglCreateProgramObjectARB();
529 program->program = qglCreateProgram();
521530 program->attribs = attribs;
522531
523 if (!(GLSL_CompileGPUShader(program->program, &program->vertexShader, vpCode, strlen(vpCode), GL_VERTEX_SHADER_ARB)))
524 {
525 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name);
526 qglDeleteObjectARB(program->program);
532 if (!(GLSL_CompileGPUShader(program->program, &program->vertexShader, vpCode, strlen(vpCode), GL_VERTEX_SHADER)))
533 {
534 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_VERTEX_SHADER\n", name);
535 qglDeleteProgram(program->program);
527536 return 0;
528537 }
529538
530539 if(fpCode)
531540 {
532 if(!(GLSL_CompileGPUShader(program->program, &program->fragmentShader, fpCode, strlen(fpCode), GL_FRAGMENT_SHADER_ARB)))
533 {
534 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name);
535 qglDeleteObjectARB(program->program);
541 if(!(GLSL_CompileGPUShader(program->program, &program->fragmentShader, fpCode, strlen(fpCode), GL_FRAGMENT_SHADER)))
542 {
543 ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_FRAGMENT_SHADER\n", name);
544 qglDeleteProgram(program->program);
536545 return 0;
537546 }
538547 }
539548
540549 if(attribs & ATTR_POSITION)
541 qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position");
550 qglBindAttribLocation(program->program, ATTR_INDEX_POSITION, "attr_Position");
542551
543552 if(attribs & ATTR_TEXCOORD)
544 qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD, "attr_TexCoord0");
553 qglBindAttribLocation(program->program, ATTR_INDEX_TEXCOORD, "attr_TexCoord0");
545554
546555 if(attribs & ATTR_LIGHTCOORD)
547 qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTCOORD, "attr_TexCoord1");
556 qglBindAttribLocation(program->program, ATTR_INDEX_LIGHTCOORD, "attr_TexCoord1");
548557
549558 // if(attribs & ATTR_TEXCOORD2)
550 // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD2, "attr_TexCoord2");
559 // qglBindAttribLocation(program->program, ATTR_INDEX_TEXCOORD2, "attr_TexCoord2");
551560
552561 // if(attribs & ATTR_TEXCOORD3)
553 // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3");
562 // qglBindAttribLocation(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3");
554563
555564 if(attribs & ATTR_TANGENT)
556 qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
565 qglBindAttribLocation(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
557566
558567 if(attribs & ATTR_NORMAL)
559 qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal");
568 qglBindAttribLocation(program->program, ATTR_INDEX_NORMAL, "attr_Normal");
560569
561570 if(attribs & ATTR_COLOR)
562 qglBindAttribLocationARB(program->program, ATTR_INDEX_COLOR, "attr_Color");
571 qglBindAttribLocation(program->program, ATTR_INDEX_COLOR, "attr_Color");
563572
564573 if(attribs & ATTR_PAINTCOLOR)
565 qglBindAttribLocationARB(program->program, ATTR_INDEX_PAINTCOLOR, "attr_PaintColor");
574 qglBindAttribLocation(program->program, ATTR_INDEX_PAINTCOLOR, "attr_PaintColor");
566575
567576 if(attribs & ATTR_LIGHTDIRECTION)
568 qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTDIRECTION, "attr_LightDirection");
577 qglBindAttribLocation(program->program, ATTR_INDEX_LIGHTDIRECTION, "attr_LightDirection");
569578
570579 if(attribs & ATTR_POSITION2)
571 qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION2, "attr_Position2");
580 qglBindAttribLocation(program->program, ATTR_INDEX_POSITION2, "attr_Position2");
572581
573582 if(attribs & ATTR_NORMAL2)
574 qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2");
583 qglBindAttribLocation(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2");
575584
576585 if(attribs & ATTR_TANGENT2)
577 qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
586 qglBindAttribLocation(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
578587
579588 GLSL_LinkProgram(program->program);
580589
582591 }
583592
584593 static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name,
585 int attribs, qboolean fragmentShader, const GLcharARB *extra, qboolean addHeader,
594 int attribs, qboolean fragmentShader, const GLchar *extra, qboolean addHeader,
586595 const char *fallback_vp, const char *fallback_fp)
587596 {
588597 char vpCode[32000];
594603 size = sizeof(vpCode);
595604 if (addHeader)
596605 {
597 GLSL_GetShaderHeader(GL_VERTEX_SHADER_ARB, extra, vpCode, size);
606 GLSL_GetShaderHeader(GL_VERTEX_SHADER, extra, vpCode, size);
598607 postHeader = &vpCode[strlen(vpCode)];
599608 size -= strlen(vpCode);
600609 }
603612 postHeader = &vpCode[0];
604613 }
605614
606 if (!GLSL_LoadGPUShaderText(name, fallback_vp, GL_VERTEX_SHADER_ARB, postHeader, size))
615 if (!GLSL_LoadGPUShaderText(name, fallback_vp, GL_VERTEX_SHADER, postHeader, size))
607616 {
608617 return 0;
609618 }
613622 size = sizeof(fpCode);
614623 if (addHeader)
615624 {
616 GLSL_GetShaderHeader(GL_FRAGMENT_SHADER_ARB, extra, fpCode, size);
625 GLSL_GetShaderHeader(GL_FRAGMENT_SHADER, extra, fpCode, size);
617626 postHeader = &fpCode[strlen(fpCode)];
618627 size -= strlen(fpCode);
619628 }
622631 postHeader = &fpCode[0];
623632 }
624633
625 if (!GLSL_LoadGPUShaderText(name, fallback_fp, GL_FRAGMENT_SHADER_ARB, postHeader, size))
634 if (!GLSL_LoadGPUShaderText(name, fallback_fp, GL_FRAGMENT_SHADER, postHeader, size))
626635 {
627636 return 0;
628637 }
642651 size = 0;
643652 for (i = 0; i < UNIFORM_COUNT; i++)
644653 {
645 uniforms[i] = qglGetUniformLocationARB(program->program, uniformsInfo[i].name);
654 uniforms[i] = qglGetUniformLocation(program->program, uniformsInfo[i].name);
646655
647656 if (uniforms[i] == -1)
648657 continue;
708717
709718 *compare = value;
710719
711 qglUniform1iARB(uniforms[uniformNum], value);
720 qglProgramUniform1iEXT(program->program, uniforms[uniformNum], value);
712721 }
713722
714723 void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value)
732741
733742 *compare = value;
734743
735 qglUniform1fARB(uniforms[uniformNum], value);
744 qglProgramUniform1fEXT(program->program, uniforms[uniformNum], value);
736745 }
737746
738747 void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t v)
757766 compare[0] = v[0];
758767 compare[1] = v[1];
759768
760 qglUniform2fARB(uniforms[uniformNum], v[0], v[1]);
769 qglProgramUniform2fEXT(program->program, uniforms[uniformNum], v[0], v[1]);
761770 }
762771
763772 void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v)
781790
782791 VectorCopy(v, compare);
783792
784 qglUniform3fARB(uniforms[uniformNum], v[0], v[1], v[2]);
793 qglProgramUniform3fEXT(program->program, uniforms[uniformNum], v[0], v[1], v[2]);
785794 }
786795
787796 void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v)
805814
806815 VectorCopy4(v, compare);
807816
808 qglUniform4fARB(uniforms[uniformNum], v[0], v[1], v[2], v[3]);
817 qglProgramUniform4fEXT(program->program, uniforms[uniformNum], v[0], v[1], v[2], v[3]);
809818 }
810819
811820 void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_t v)
829838
830839 VectorCopy5(v, compare);
831840
832 qglUniform1fvARB(uniforms[uniformNum], 5, v);
841 qglProgramUniform1fvEXT(program->program, uniforms[uniformNum], 5, v);
833842 }
834843
835844 void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix)
853862
854863 Mat4Copy(matrix, compare);
855864
856 qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix);
865 qglProgramUniformMatrix4fvEXT(program->program, uniforms[uniformNum], 1, GL_FALSE, matrix);
857866 }
858867
859868 void GLSL_DeleteGPUShader(shaderProgram_t *program)
862871 {
863872 if (program->vertexShader)
864873 {
865 qglDetachObjectARB(program->program, program->vertexShader);
866 qglDeleteObjectARB(program->vertexShader);
874 qglDetachShader(program->program, program->vertexShader);
875 qglDeleteShader(program->vertexShader);
867876 }
868877
869878 if (program->fragmentShader)
870879 {
871 qglDetachObjectARB(program->program, program->fragmentShader);
872 qglDeleteObjectARB(program->fragmentShader);
873 }
874
875 qglDeleteObjectARB(program->program);
880 qglDetachShader(program->program, program->fragmentShader);
881 qglDeleteShader(program->fragmentShader);
882 }
883
884 qglDeleteProgram(program->program);
876885
877886 if (program->uniformBuffer)
878887 {
936945
937946 GLSL_InitUniforms(&tr.genericShader[i]);
938947
939 qglUseProgramObjectARB(tr.genericShader[i].program);
940948 GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
941949 GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP);
942 qglUseProgramObjectARB(0);
943950
944951 GLSL_FinishGPUShader(&tr.genericShader[i]);
945952
956963
957964 GLSL_InitUniforms(&tr.textureColorShader);
958965
959 qglUseProgramObjectARB(tr.textureColorShader.program);
960966 GLSL_SetUniformInt(&tr.textureColorShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
961 qglUseProgramObjectARB(0);
962967
963968 GLSL_FinishGPUShader(&tr.textureColorShader);
964969
10101015
10111016 GLSL_InitUniforms(&tr.dlightShader[i]);
10121017
1013 qglUseProgramObjectARB(tr.dlightShader[i].program);
10141018 GLSL_SetUniformInt(&tr.dlightShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
1015 qglUseProgramObjectARB(0);
10161019
10171020 GLSL_FinishGPUShader(&tr.dlightShader[i]);
10181021
10291032 if ((i & LIGHTDEF_USE_PARALLAXMAP) && !r_parallaxMapping->integer)
10301033 continue;
10311034
1032 if (!lightType && (i & LIGHTDEF_USE_PARALLAXMAP))
1033 continue;
1034
10351035 if (!lightType && (i & LIGHTDEF_USE_SHADOWMAP))
10361036 continue;
10371037
10391039
10401040 extradefines[0] = '\0';
10411041
1042 if (r_specularIsMetallic->value)
1043 Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n");
1044
1045 if (r_glossIsRoughness->value)
1046 Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n");
1047
10481042 if (r_dlightMode->integer >= 2)
10491043 Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
10501044
10511045 if (glRefConfig.swizzleNormalmap)
10521046 Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n");
1053
1054 if (r_hdr->integer && !glRefConfig.floatLightmap)
1055 Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n");
10561047
10571048 if (lightType)
10581049 {
10841075 {
10851076 Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n");
10861077
1087 #ifdef USE_VERT_TANGENT_SPACE
1088 Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n");
10891078 attribs |= ATTR_TANGENT;
1090 #endif
10911079
10921080 if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
10931081 {
11021090
11031091 if (r_cubeMapping->integer)
11041092 Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
1093
1094 switch (r_glossType->integer)
1095 {
1096 case 0:
1097 default:
1098 Q_strcat(extradefines, 1024, "#define GLOSS_IS_GLOSS\n");
1099 break;
1100 case 1:
1101 Q_strcat(extradefines, 1024, "#define GLOSS_IS_SMOOTHNESS\n");
1102 break;
1103 case 2:
1104 Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n");
1105 break;
1106 case 3:
1107 Q_strcat(extradefines, 1024, "#define GLOSS_IS_SHININESS\n");
1108 break;
1109 }
11051110 }
11061111
11071112 if (i & LIGHTDEF_USE_SHADOWMAP)
11251130 Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n");
11261131 attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
11271132
1128 #ifdef USE_VERT_TANGENT_SPACE
11291133 if (r_normalMapping->integer)
11301134 {
11311135 attribs |= ATTR_TANGENT2;
11321136 }
1133 #endif
11341137 }
11351138
11361139 if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackShader_lightall_vp, fallbackShader_lightall_fp))
11401143
11411144 GLSL_InitUniforms(&tr.lightallShader[i]);
11421145
1143 qglUseProgramObjectARB(tr.lightallShader[i].program);
11441146 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
11451147 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP);
11461148 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_NORMALMAP, TB_NORMALMAP);
11481150 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SPECULARMAP, TB_SPECULARMAP);
11491151 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SHADOWMAP, TB_SHADOWMAP);
11501152 GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_CUBEMAP, TB_CUBEMAP);
1151 qglUseProgramObjectARB(0);
11521153
11531154 GLSL_FinishGPUShader(&tr.lightallShader[i]);
11541155
11811182
11821183 GLSL_InitUniforms(&tr.pshadowShader);
11831184
1184 qglUseProgramObjectARB(tr.pshadowShader.program);
11851185 GLSL_SetUniformInt(&tr.pshadowShader, UNIFORM_SHADOWMAP, TB_DIFFUSEMAP);
1186 qglUseProgramObjectARB(0);
11871186
11881187 GLSL_FinishGPUShader(&tr.pshadowShader);
11891188
12001199
12011200 GLSL_InitUniforms(&tr.down4xShader);
12021201
1203 qglUseProgramObjectARB(tr.down4xShader.program);
12041202 GLSL_SetUniformInt(&tr.down4xShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
1205 qglUseProgramObjectARB(0);
12061203
12071204 GLSL_FinishGPUShader(&tr.down4xShader);
12081205
12191216
12201217 GLSL_InitUniforms(&tr.bokehShader);
12211218
1222 qglUseProgramObjectARB(tr.bokehShader.program);
12231219 GLSL_SetUniformInt(&tr.bokehShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
1224 qglUseProgramObjectARB(0);
12251220
12261221 GLSL_FinishGPUShader(&tr.bokehShader);
12271222
12381233
12391234 GLSL_InitUniforms(&tr.tonemapShader);
12401235
1241 qglUseProgramObjectARB(tr.tonemapShader.program);
12421236 GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_TEXTUREMAP, TB_COLORMAP);
12431237 GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_LEVELSMAP, TB_LEVELSMAP);
1244 qglUseProgramObjectARB(0);
12451238
12461239 GLSL_FinishGPUShader(&tr.tonemapShader);
12471240
12631256
12641257 GLSL_InitUniforms(&tr.calclevels4xShader[i]);
12651258
1266 qglUseProgramObjectARB(tr.calclevels4xShader[i].program);
12671259 GLSL_SetUniformInt(&tr.calclevels4xShader[i], UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
1268 qglUseProgramObjectARB(0);
12691260
12701261 GLSL_FinishGPUShader(&tr.calclevels4xShader[i]);
12711262
12961287
12971288 GLSL_InitUniforms(&tr.shadowmaskShader);
12981289
1299 qglUseProgramObjectARB(tr.shadowmaskShader.program);
13001290 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP);
13011291 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP, TB_SHADOWMAP);
13021292 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2);
13031293 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3);
13041294 GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4);
1305 qglUseProgramObjectARB(0);
13061295
13071296 GLSL_FinishGPUShader(&tr.shadowmaskShader);
13081297
13191308
13201309 GLSL_InitUniforms(&tr.ssaoShader);
13211310
1322 qglUseProgramObjectARB(tr.ssaoShader.program);
13231311 GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP);
1324 qglUseProgramObjectARB(0);
13251312
13261313 GLSL_FinishGPUShader(&tr.ssaoShader);
13271314
13281315 numEtcShaders++;
13291316
13301317
1331 for (i = 0; i < 2; i++)
1318 for (i = 0; i < 4; i++)
13321319 {
13331320 attribs = ATTR_POSITION | ATTR_TEXCOORD;
13341321 extradefines[0] = '\0';
13381325 else
13391326 Q_strcat(extradefines, 1024, "#define USE_HORIZONTAL_BLUR\n");
13401327
1328 if (!(i & 2))
1329 Q_strcat(extradefines, 1024, "#define USE_DEPTH\n");
1330
13411331
13421332 if (!GLSL_InitGPUShader(&tr.depthBlurShader[i], "depthBlur", attribs, qtrue, extradefines, qtrue, fallbackShader_depthblur_vp, fallbackShader_depthblur_fp))
13431333 {
13461336
13471337 GLSL_InitUniforms(&tr.depthBlurShader[i]);
13481338
1349 qglUseProgramObjectARB(tr.depthBlurShader[i].program);
13501339 GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENIMAGEMAP, TB_COLORMAP);
13511340 GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENDEPTHMAP, TB_LIGHTMAP);
1352 qglUseProgramObjectARB(0);
13531341
13541342 GLSL_FinishGPUShader(&tr.depthBlurShader[i]);
13551343
13671355
13681356 GLSL_InitUniforms(&tr.testcubeShader);
13691357
1370 qglUseProgramObjectARB(tr.testcubeShader.program);
13711358 GLSL_SetUniformInt(&tr.testcubeShader, UNIFORM_TEXTUREMAP, TB_COLORMAP);
1372 qglUseProgramObjectARB(0);
13731359
13741360 GLSL_FinishGPUShader(&tr.testcubeShader);
13751361
13911377 ri.Printf(PRINT_ALL, "------- GLSL_ShutdownGPUShaders -------\n");
13921378
13931379 for (i = 0; i < ATTR_INDEX_COUNT; i++)
1394 qglDisableVertexAttribArrayARB(i);
1395
1396 GLSL_BindNullProgram();
1380 qglDisableVertexAttribArray(i);
1381
1382 GL_BindNullProgram();
13971383
13981384 for ( i = 0; i < GENERICDEF_COUNT; i++)
13991385 GLSL_DeleteGPUShader(&tr.genericShader[i]);
14211407 GLSL_DeleteGPUShader(&tr.shadowmaskShader);
14221408 GLSL_DeleteGPUShader(&tr.ssaoShader);
14231409
1424 for ( i = 0; i < 2; i++)
1410 for ( i = 0; i < 4; i++)
14251411 GLSL_DeleteGPUShader(&tr.depthBlurShader[i]);
1426
1427 glState.currentProgram = 0;
1428 qglUseProgramObjectARB(0);
14291412 }
14301413
14311414
14321415 void GLSL_BindProgram(shaderProgram_t * program)
14331416 {
1434 if(!program)
1435 {
1436 GLSL_BindNullProgram();
1437 return;
1438 }
1417 GLuint programObject = program ? program->program : 0;
1418 char *name = program ? program->name : "NULL";
14391419
14401420 if(r_logFile->integer)
14411421 {
14421422 // don't just call LogComment, or we will get a call to va() every frame!
1443 GLimp_LogComment(va("--- GL_BindProgram( %s ) ---\n", program->name));
1444 }
1445
1446 if(glState.currentProgram != program)
1447 {
1448 qglUseProgramObjectARB(program->program);
1449 glState.currentProgram = program;
1423 GLimp_LogComment(va("--- GLSL_BindProgram( %s ) ---\n", name));
1424 }
1425
1426 if (GL_UseProgram(programObject))
14501427 backEnd.pc.c_glslShaderBinds++;
1451 }
1452 }
1453
1454
1455 void GLSL_BindNullProgram(void)
1456 {
1457 if(r_logFile->integer)
1458 {
1459 GLimp_LogComment("--- GL_BindNullProgram ---\n");
1460 }
1461
1462 if(glState.currentProgram)
1463 {
1464 qglUseProgramObjectARB(0);
1465 glState.currentProgram = NULL;
1466 }
1467 }
1428 }
1429
14681430
14691431
14701432 shaderProgram_t *GLSL_GetGenericShaderProgram(int stage, glfog_t *glFog)
3434
3535 #include "tr_local.h"
3636
37 #include "tr_dsa.h"
38
3739 static byte s_intensitytable[256];
3840 static unsigned char s_gammatable[256];
3941
4244
4345 #define FILE_HASH_SIZE 4096
4446 static image_t* hashTable[FILE_HASH_SIZE];
45
4647
4748 /*
4849 ** R_GammaCorrect
130131 // change all the existing mipmap texture objects
131132 for ( i = 0 ; i < tr.numImages ; i++ ) {
132133 glt = tr.images[ i ];
133 if ( glt->flags & IMGFLAG_MIPMAP ) {
134 GL_Bind( glt );
135 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min );
136 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max );
134 if ( glt->flags & IMGFLAG_MIPMAP && !(glt->flags & IMGFLAG_CUBEMAP) ) {
135 qglTextureParameterfEXT(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
136 qglTextureParameterfEXT(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
137137 }
138138 }
139139 }
163163 ===============
164164 */
165165 void R_ImageList_f( void ) {
166 #if 1
167166 int i;
168167 int estTotalSize = 0;
169168
170 ri.Printf(PRINT_ALL, "\n -w-- -h-- type -size- --name-------\n");
169 ri.Printf(PRINT_ALL, "\n -w-- -h-- -type-- -size- --name-------\n");
171170
172171 for ( i = 0 ; i < tr.numImages ; i++ )
173172 {
174173 image_t *image = tr.images[i];
175 char *format = "???? ";
174 char *format = "???? ";
176175 char *sizeSuffix;
177176 int estSize;
178177 int displaySize;
182181 switch(image->internalFormat)
183182 {
184183 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
185 format = "sDXT1";
184 format = "sDXT1 ";
186185 // 64 bits per 16 pixels, so 4 bits per pixel
187186 estSize /= 2;
188187 break;
189188 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
190 format = "sDXT5";
189 format = "sDXT5 ";
191190 // 128 bits per 16 pixels, so 1 byte per pixel
192191 break;
193192 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
194 format = "sBPTC";
193 format = "sBPTC ";
195194 // 128 bits per 16 pixels, so 1 byte per pixel
196195 break;
197196 case GL_COMPRESSED_RG_RGTC2:
198 format = "RGTC2";
197 format = "RGTC2 ";
199198 // 128 bits per 16 pixels, so 1 byte per pixel
200199 break;
201200 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
202 format = "DXT1 ";
201 format = "DXT1 ";
203202 // 64 bits per 16 pixels, so 4 bits per pixel
204203 estSize /= 2;
205204 break;
206205 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
207 format = "DXT1a";
206 format = "DXT1a ";
208207 // 64 bits per 16 pixels, so 4 bits per pixel
209208 estSize /= 2;
210209 break;
211210 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
212 format = "DXT5 ";
211 format = "DXT5 ";
213212 // 128 bits per 16 pixels, so 1 byte per pixel
214213 break;
215214 case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
216 format = "BPTC ";
215 format = "BPTC ";
217216 // 128 bits per 16 pixels, so 1 byte per pixel
218217 break;
219218 case GL_RGB4_S3TC:
220 format = "S3TC ";
219 format = "S3TC ";
221220 // same as DXT1?
222221 estSize /= 2;
222 break;
223 case GL_RGBA16F:
224 format = "RGBA16F";
225 // 8 bytes per pixel
226 estSize *= 8;
227 break;
228 case GL_RGBA16:
229 format = "RGBA16 ";
230 // 8 bytes per pixel
231 estSize *= 8;
223232 break;
224233 case GL_RGBA4:
225234 case GL_RGBA8:
226235 case GL_RGBA:
227 format = "RGBA ";
236 format = "RGBA ";
228237 // 4 bytes per pixel
229238 estSize *= 4;
230239 break;
231240 case GL_LUMINANCE8:
232241 case GL_LUMINANCE16:
233242 case GL_LUMINANCE:
234 format = "L ";
243 format = "L ";
235244 // 1 byte per pixel?
236245 break;
237246 case GL_RGB5:
238247 case GL_RGB8:
239248 case GL_RGB:
240 format = "RGB ";
249 format = "RGB ";
241250 // 3 bytes per pixel?
242251 estSize *= 3;
243252 break;
244253 case GL_LUMINANCE8_ALPHA8:
245254 case GL_LUMINANCE16_ALPHA16:
246255 case GL_LUMINANCE_ALPHA:
247 format = "LA ";
256 format = "LA ";
248257 // 2 bytes per pixel?
249258 estSize *= 2;
250259 break;
251260 case GL_SRGB_EXT:
252261 case GL_SRGB8_EXT:
253 format = "sRGB ";
262 format = "sRGB ";
254263 // 3 bytes per pixel?
255264 estSize *= 3;
256265 break;
257266 case GL_SRGB_ALPHA_EXT:
258267 case GL_SRGB8_ALPHA8_EXT:
259 format = "sRGBA";
268 format = "sRGBA ";
260269 // 4 bytes per pixel?
261270 estSize *= 4;
262271 break;
263272 case GL_SLUMINANCE_EXT:
264273 case GL_SLUMINANCE8_EXT:
265 format = "sL ";
274 format = "sL ";
266275 // 1 byte per pixel?
267276 break;
268277 case GL_SLUMINANCE_ALPHA_EXT:
269278 case GL_SLUMINANCE8_ALPHA8_EXT:
270 format = "sLA ";
279 format = "sLA ";
271280 // 2 byte per pixel?
272281 estSize *= 2;
273282 break;
283 case GL_DEPTH_COMPONENT16:
284 format = "Depth16";
285 // 2 bytes per pixel
286 estSize *= 2;
287 break;
288 case GL_DEPTH_COMPONENT24:
289 format = "Depth24";
290 // 3 bytes per pixel
291 estSize *= 3;
292 break;
293 case GL_DEPTH_COMPONENT:
294 case GL_DEPTH_COMPONENT32:
295 format = "Depth32";
296 // 4 bytes per pixel
297 estSize *= 4;
298 break;
274299 }
275300
276301 // mipmap adds about 50%
305330 ri.Printf (PRINT_ALL, " ---------\n");
306331 ri.Printf (PRINT_ALL, " approx %i bytes\n", estTotalSize);
307332 ri.Printf (PRINT_ALL, " %i total images\n\n", tr.numImages );
308 #else
309 int i;
310 image_t *image;
311 int texels;
312 const char *yesno[] = {
313 "no ", "yes"
314 };
315
316 ri.Printf( PRINT_ALL, "\n -w-- -h-- -mm- -TMU- -if-- wrap --name-------\n" );
317 texels = 0;
318
319 for ( i = 0 ; i < tr.numImages ; i++ ) {
320 image = tr.images[ i ];
321
322 texels += image->uploadWidth * image->uploadHeight;
323 ri.Printf( PRINT_ALL, "%4i: %4i %4i %s %d ",
324 i, image->uploadWidth, image->uploadHeight, yesno[(image->flags & IMGFLAG_MIPMAP) ? 1 : 0], image->TMU );
325 switch ( image->internalFormat ) {
326 case 1:
327 ri.Printf( PRINT_ALL, "I " );
328 break;
329 case 2:
330 ri.Printf( PRINT_ALL, "IA " );
331 break;
332 case 3:
333 ri.Printf( PRINT_ALL, "RGB " );
334 break;
335 case 4:
336 ri.Printf( PRINT_ALL, "RGBA " );
337 break;
338 case GL_RGBA8:
339 ri.Printf( PRINT_ALL, "RGBA8" );
340 break;
341 case GL_RGB8:
342 ri.Printf( PRINT_ALL, "RGB8" );
343 break;
344 case GL_RGB4_S3TC:
345 ri.Printf( PRINT_ALL, "S3TC4" );
346 break;
347 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
348 ri.Printf( PRINT_ALL, "DXT1 " );
349 break;
350 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
351 ri.Printf( PRINT_ALL, "DXT5 " );
352 break;
353 case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
354 ri.Printf( PRINT_ALL, "LATC " );
355 break;
356 case GL_RGBA4:
357 ri.Printf( PRINT_ALL, "RGBA4" );
358 break;
359 case GL_RGB5:
360 ri.Printf( PRINT_ALL, "RGB5 " );
361 break;
362 case GL_SRGB_EXT:
363 ri.Printf( PRINT_ALL, "sRGB " );
364 break;
365 case GL_SRGB8_EXT:
366 ri.Printf( PRINT_ALL, "sRGB8" );
367 break;
368 case GL_SRGB_ALPHA_EXT:
369 case GL_SRGB8_ALPHA8_EXT:
370 ri.Printf( PRINT_ALL, "sRGBA" );
371 break;
372 /*
373 case GL_SLUMINANCE_EXT:
374 break;
375 case GL_SLUMINANCE8_EXT:
376 break;
377 case GL_SLUMINANCE_ALPHA_EXT:
378 break;
379 case GL_SLUMINANCE8_ALPHA8_EXT:
380 break;
381 */
382 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
383 ri.Printf( PRINT_ALL, "sDXT1" );
384 break;
385 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
386 ri.Printf( PRINT_ALL, "sDXT5" );
387 break;
388 case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
389 ri.Printf( PRINT_ALL, "BPTC " );
390 break;
391 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
392 ri.Printf( PRINT_ALL, "sBPTC" );
393 break;
394 default:
395 ri.Printf( PRINT_ALL, "???? " );
396 }
397
398 if (image->flags & IMGFLAG_CLAMPTOEDGE)
399 ri.Printf( PRINT_ALL, "clmp " );
400 else
401 ri.Printf( PRINT_ALL, "rept " );
402
403 ri.Printf( PRINT_ALL, " %s\n", image->imgName );
404 }
405 ri.Printf( PRINT_ALL, " ---------\n" );
406 ri.Printf( PRINT_ALL, " %i total texels (not including mipmaps)\n", texels );
407 ri.Printf( PRINT_ALL, " %i total images\n\n", tr.numImages );
408 #endif
409333 }
410334
411335 //=======================================================================
15011425 R_RMSE
15021426 ================
15031427 */
1428 #if 0 // FIXME
15041429 static float R_RMSE( byte *in, int width, int height ) {
15051430 int i, j;
15061431 float out, rmse, rtemp;
15401465 rmse = sqrt( rmse / ( height * width * 4 ) );
15411466 return rmse;
15421467 }
1468 #endif
1469
15431470
15441471 /*
15451472 ==================
16141541 qboolean picmip = flags & IMGFLAG_PICMIP;
16151542 qboolean mipmap = flags & IMGFLAG_MIPMAP;
16161543 qboolean clampToEdge = flags & IMGFLAG_CLAMPTOEDGE;
1617 qboolean notScaled;
1544 qboolean scaled;
1545 #if 0
1546 static int rmse_saved = 0;
1547
1548 // do the root mean square error stuff first
1549 if ( r_rmse->value ) {
1550 while ( R_RMSE( *data, width, height ) < r_rmse->value ) {
1551 rmse_saved += ( height * width * 4 ) - ( ( width >> 1 ) * ( height >> 1 ) * 4 );
1552 *resampledBuffer = ri.Hunk_AllocateTempMemory( ( width >> 1 ) * ( height >> 1 ) * 4 );
1553 ResampleTexture( *data, width, height, *resampledBuffer, width >> 1, height >> 1 );
1554 *data = *resampledBuffer;
1555 width = width >> 1;
1556 height = height >> 1;
1557 ri.Printf( PRINT_ALL, "r_rmse of %f has saved %dkb\n", r_rmse->value, ( rmse_saved / 1024 ) );
1558 }
1559 }
1560 #endif
16181561
16191562 //
16201563 // convert to exact power of 2 sizes
16211564 //
1622 if (glRefConfig.textureNonPowerOfTwo && !mipmap)
1565 if (!mipmap)
16231566 {
16241567 scaled_width = width;
16251568 scaled_height = height;
16801623 YCoCgAtoRGBA(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height);
16811624 else if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
16821625 FillInNormalizedZ(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height);
1683
16841626
16851627 //endTime = ri.Milliseconds();
16861628
17261668 scaled_width = MAX(1, scaled_width);
17271669 scaled_height = MAX(1, scaled_height);
17281670
1729 notScaled = (width == scaled_width) && (height == scaled_height);
1671 scaled = (width != scaled_width) || (height != scaled_height);
17301672
17311673 //
17321674 // rescale texture to new size using existing mipmap functions
17481690 *inout_width = width;
17491691 *inout_height = height;
17501692
1751 return notScaled;
1693 return scaled;
17521694 }
17531695
17541696
17701712 return qfalse;
17711713 }
17721714
1773 static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean lightMap, imgType_t type, imgFlags_t flags)
1715 static GLenum RawImage_GetFormat(const byte *data, int numPixels, GLenum picFormat, qboolean lightMap, imgType_t type, imgFlags_t flags)
17741716 {
17751717 int samples = 3;
17761718 GLenum internalFormat = GL_RGB;
17771719 qboolean forceNoCompression = (flags & IMGFLAG_NO_COMPRESSION);
17781720 qboolean normalmap = (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT);
17791721
1722 if (picFormat != GL_RGBA8)
1723 return picFormat;
1724
17801725 if(normalmap)
17811726 {
1782 if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels))
1727 if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels) && r_parallaxMapping->integer)
17831728 {
17841729 if (!forceNoCompression && glRefConfig.textureCompression & TCR_BPTC)
17851730 {
19691914 }
19701915 }
19711916
1972 static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip)
1917 static void RawImage_UploadToRgtc2Texture(GLuint texture, int miplevel, int x, int y, int width, int height, byte *data)
19731918 {
1974 int wBlocks, hBlocks, y, x, size;
1919 int wBlocks, hBlocks, iy, ix, size;
19751920 byte *compressedData, *p;
19761921
19771922 wBlocks = (width + 3) / 4;
19791924 size = wBlocks * hBlocks * 16;
19801925
19811926 p = compressedData = ri.Hunk_AllocateTempMemory(size);
1982 for (y = 0; y < height; y += 4)
1983 {
1984 int oh = MIN(4, height - y);
1985
1986 for (x = 0; x < width; x += 4)
1927 for (iy = 0; iy < height; iy += 4)
1928 {
1929 int oh = MIN(4, height - iy);
1930
1931 for (ix = 0; ix < width; ix += 4)
19871932 {
19881933 byte workingData[16];
19891934 int component;
19901935
1991 int ow = MIN(4, width - x);
1936 int ow = MIN(4, width - ix);
19921937
19931938 for (component = 0; component < 2; component++)
19941939 {
19961941
19971942 for (oy = 0; oy < oh; oy++)
19981943 for (ox = 0; ox < ow; ox++)
1999 workingData[oy * 4 + ox] = data[((y + oy) * width + x + ox) * 4 + component];
1944 workingData[oy * 4 + ox] = data[((iy + oy) * width + ix + ox) * 4 + component];
20001945
20011946 // dupe data to fill
20021947 for (oy = 0; oy < 4; oy++)
20091954 }
20101955 }
20111956
2012 qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData);
1957 // FIXME: Won't work for x/y that aren't multiples of 4.
1958 qglCompressedTextureSubImage2DEXT(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, GL_COMPRESSED_RG_RGTC2, size, compressedData);
20131959
20141960 ri.Hunk_FreeTempMemory(compressedData);
20151961 }
20161962
2017 static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture )
1963 static int CalculateMipSize(int width, int height, GLenum picFormat)
20181964 {
2019 int dataFormat, dataType;
2020 qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2);
2021
2022 switch(internalFormat)
1965 int numBlocks = ((width + 3) / 4) * ((height + 3) / 4);
1966 int numPixels = width * height;
1967
1968 switch (picFormat)
1969 {
1970 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1971 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1972 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1973 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1974 case GL_COMPRESSED_RED_RGTC1:
1975 case GL_COMPRESSED_SIGNED_RED_RGTC1:
1976 return numBlocks * 8;
1977
1978 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1979 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1980 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1981 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1982 case GL_COMPRESSED_RG_RGTC2:
1983 case GL_COMPRESSED_SIGNED_RG_RGTC2:
1984 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
1985 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
1986 case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
1987 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
1988 return numBlocks * 16;
1989
1990 case GL_RGBA8:
1991 case GL_SRGB8_ALPHA8_EXT:
1992 return numPixels * 4;
1993
1994 case GL_RGBA16:
1995 return numPixels * 8;
1996
1997 default:
1998 ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat);
1999 return 0;
2000 }
2001
2002 return 0;
2003 }
2004
2005
2006 static GLenum PixelDataFormatFromInternalFormat(GLenum internalFormat)
2007 {
2008 switch (internalFormat)
20232009 {
20242010 case GL_DEPTH_COMPONENT:
20252011 case GL_DEPTH_COMPONENT16_ARB:
20262012 case GL_DEPTH_COMPONENT24_ARB:
20272013 case GL_DEPTH_COMPONENT32_ARB:
2028 dataFormat = GL_DEPTH_COMPONENT;
2029 dataType = GL_UNSIGNED_BYTE;
2014 return GL_DEPTH_COMPONENT;
2015 default:
2016 return GL_RGBA;
20302017 break;
2031 case GL_RGBA16F_ARB:
2032 dataFormat = GL_RGBA;
2033 dataType = GL_HALF_FLOAT_ARB;
2034 break;
2035 default:
2036 dataFormat = GL_RGBA;
2037 dataType = GL_UNSIGNED_BYTE;
2038 break;
2039 }
2040
2041 if ( subtexture )
2042 qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data );
2043 else
2044 {
2045 if (rgtc)
2046 RawImage_UploadToRgtc2Texture(data, width, height, 0);
2018 }
2019 }
2020
2021 static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum target, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture )
2022 {
2023 GLenum dataFormat, dataType;
2024 qboolean rgtc = internalFormat == GL_COMPRESSED_RG_RGTC2;
2025 qboolean rgba8 = picFormat == GL_RGBA8 || picFormat == GL_SRGB8_ALPHA8_EXT;
2026 qboolean rgba = rgba8 || picFormat == GL_RGBA16;
2027 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP);
2028 int size, miplevel;
2029 qboolean lastMip = qfalse;
2030
2031 dataFormat = PixelDataFormatFromInternalFormat(internalFormat);
2032 dataType = picFormat == GL_RGBA16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
2033
2034 miplevel = 0;
2035 do
2036 {
2037 lastMip = (width == 1 && height == 1) || !mipmap;
2038 size = CalculateMipSize(width, height, picFormat);
2039
2040 if (!rgba)
2041 {
2042 qglCompressedTextureSubImage2DEXT(texture, target, miplevel, x, y, width, height, picFormat, size, data);
2043 }
20472044 else
2048 qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data);
2049 }
2050
2051 if (flags & IMGFLAG_MIPMAP)
2052 {
2053 int miplevel;
2054
2055 miplevel = 0;
2056 while (width > 1 || height > 1)
2057 {
2058 if (data)
2045 {
2046 if (rgba8 && miplevel != 0 && r_colorMipLevels->integer)
2047 R_BlendOverTexture((byte *)data, width * height, mipBlendColors[miplevel]);
2048
2049 if (rgba8 && rgtc)
2050 RawImage_UploadToRgtc2Texture(texture, miplevel, x, y, width, height, data);
2051 else
2052 qglTextureSubImage2DEXT(texture, target, miplevel, x, y, width, height, dataFormat, dataType, data);
2053 }
2054
2055 if (!lastMip && numMips < 2)
2056 {
2057 if (glRefConfig.framebufferObject)
2058 {
2059 qglGenerateTextureMipmapEXT(texture, target);
2060 break;
2061 }
2062 else if (rgba8)
20592063 {
20602064 if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
2061 {
2062 R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap );
2063 }
2065 R_MipMapNormalHeight(data, data, width, height, glRefConfig.swizzleNormalmap);
20642066 else
2065 {
2066 R_MipMapsRGB( data, width, height );
2067 }
2068 }
2069
2070 width >>= 1;
2071 height >>= 1;
2072 if (width < 1)
2073 width = 1;
2074 if (height < 1)
2075 height = 1;
2076 miplevel++;
2077
2078 if ( data && r_colorMipLevels->integer )
2079 R_BlendOverTexture( (byte *)data, width * height, mipBlendColors[miplevel] );
2080
2081 if ( subtexture )
2082 {
2083 x >>= 1;
2084 y >>= 1;
2085 qglTexSubImage2D( GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data );
2086 }
2087 else
2088 {
2089 if (rgtc)
2090 RawImage_UploadToRgtc2Texture(data, width, height, miplevel);
2091 else
2092 qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data);
2093 }
2094 }
2095 }
2096 }
2067 R_MipMapsRGB(data, width, height);
2068 }
2069 }
2070
2071 x >>= 1;
2072 y >>= 1;
2073 width = MAX(1, width >> 1);
2074 height = MAX(1, height >> 1);
2075 miplevel++;
2076
2077 if (numMips > 1)
2078 {
2079 data += size;
2080 numMips--;
2081 }
2082 }
2083 while (!lastMip);
2084 }
2085
20972086
20982087 /*
20992088 ===============
21012090
21022091 ===============
21032092 */
2104 static void Upload32(byte *data, int x, int y, int width, int height, image_t *image)
2093 static void Upload32(byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, image_t *image, qboolean scaled)
21052094 {
2106 byte *resampledBuffer = NULL;
21072095 int i, c;
21082096 byte *scan;
2109 static int rmse_saved = 0;
2110
2111 // do the root mean square error stuff first
2112 if ( r_rmse->value ) {
2113 while ( R_RMSE( (byte *)data, width, height ) < r_rmse->value ) {
2114 rmse_saved += ( height * width * 4 ) - ( ( width >> 1 ) * ( height >> 1 ) * 4 );
2115 resampledBuffer = ri.Hunk_AllocateTempMemory( ( width >> 1 ) * ( height >> 1 ) * 4 );
2116 ResampleTexture( data, width, height, resampledBuffer, width >> 1, height >> 1 );
2117 data = resampledBuffer;
2118 width = width >> 1;
2119 height = height >> 1;
2120 ri.Printf( PRINT_ALL, "r_rmse of %f has saved %dkb\n", r_rmse->value, ( rmse_saved / 1024 ) );
2121 }
2122 }
21232097
21242098 imgType_t type = image->type;
21252099 imgFlags_t flags = image->flags;
21262100 GLenum internalFormat = image->internalFormat;
2127 qboolean subtexture = (x != 0) || (y != 0) || (width != image->width) || (height != image->height);
2128 qboolean notScaled = qtrue;
2129 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP);
2130
2131 if (!data)
2132 {
2133 RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL);
2134 RawImage_UploadTexture(NULL, 0, 0, width, height, internalFormat, type, flags, qfalse);
2135 goto done;
2136 }
2137 else if (!subtexture)
2138 {
2139 notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer);
2140 }
2141
2142 c = width*height;
2143 scan = data;
2144
2145 if( r_greyscale->integer )
2146 {
2147 for ( i = 0; i < c; i++ )
2148 {
2149 byte luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2150 scan[i*4] = luma;
2151 scan[i*4 + 1] = luma;
2152 scan[i*4 + 2] = luma;
2153 }
2154 }
2155 else if( r_greyscale->value )
2156 {
2157 for ( i = 0; i < c; i++ )
2158 {
2159 float luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2160 scan[i*4] = LERP(scan[i*4], luma, r_greyscale->value);
2161 scan[i*4 + 1] = LERP(scan[i*4 + 1], luma, r_greyscale->value);
2162 scan[i*4 + 2] = LERP(scan[i*4 + 2], luma, r_greyscale->value);
2163 }
2164 }
2165
2166 if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT))
2167 RawImage_SwizzleRA(data, width, height);
2168
2169 // This corresponds to what the OpenGL1 renderer does
2170 if (!(flags & IMGFLAG_NOLIGHTSCALE) && (!notScaled || mipmap))
2171 R_LightScaleTexture(data, width, height, !mipmap);
2172
2173 if (subtexture)
2174 {
2175 // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped
2176 RawImage_UploadTexture(data, x, y, width, height, internalFormat, type, flags, qtrue);
2177 GL_CheckErrors();
2178 return;
2179 }
2180
2181 RawImage_UploadTexture(data, 0, 0, width, height, internalFormat, type, flags, qfalse);
2182
2183 done:
2184
2185 image->uploadWidth = width;
2186 image->uploadHeight = height;
2187
2188 if (mipmap)
2189 {
2190 if ( textureFilterAnisotropic )
2191 qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
2192 (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) );
2193
2194 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
2195 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
2101 qboolean rgba8 = picFormat == GL_RGBA8 || picFormat == GL_SRGB8_ALPHA8_EXT;
2102 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP) && (rgba8 || numMips > 1);
2103 qboolean cubemap = !!(flags & IMGFLAG_CUBEMAP);
2104
2105 // These operations cannot be performed on non-rgba8 images.
2106 if (rgba8 && !cubemap)
2107 {
2108 c = width*height;
2109 scan = data;
2110
2111 if (type == IMGTYPE_COLORALPHA)
2112 {
2113 if( r_greyscale->integer )
2114 {
2115 for ( i = 0; i < c; i++ )
2116 {
2117 byte luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2118 scan[i*4] = luma;
2119 scan[i*4 + 1] = luma;
2120 scan[i*4 + 2] = luma;
2121 }
2122 }
2123 else if( r_greyscale->value )
2124 {
2125 for ( i = 0; i < c; i++ )
2126 {
2127 float luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]);
2128 scan[i*4] = LERP(scan[i*4], luma, r_greyscale->value);
2129 scan[i*4 + 1] = LERP(scan[i*4 + 1], luma, r_greyscale->value);
2130 scan[i*4 + 2] = LERP(scan[i*4 + 2], luma, r_greyscale->value);
2131 }
2132 }
2133
2134 // This corresponds to what the OpenGL1 renderer does.
2135 if (!(flags & IMGFLAG_NOLIGHTSCALE) && (scaled || mipmap))
2136 R_LightScaleTexture(data, width, height, !mipmap);
2137 }
2138
2139 if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT))
2140 RawImage_SwizzleRA(data, width, height);
2141 }
2142
2143 if (cubemap)
2144 {
2145 for (i = 0; i < 6; i++)
2146 {
2147 int w2 = width, h2 = height;
2148 RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, picFormat, numMips, internalFormat, type, flags, qfalse);
2149 for (c = numMips; c; c--)
2150 {
2151 data += CalculateMipSize(w2, h2, picFormat);
2152 w2 = MAX(1, w2 >> 1);
2153 h2 = MAX(1, h2 >> 1);
2154 }
2155 }
21962156 }
21972157 else
21982158 {
2199 if ( textureFilterAnisotropic )
2200 qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
2201
2202 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
2203 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
2204 }
2205
2206 // Fix for sampling depth buffer on old nVidia cards
2207 // from http://www.idevgames.com/forums/thread-4141-post-34844.html#pid34844
2208 switch(internalFormat)
2209 {
2210 case GL_DEPTH_COMPONENT:
2211 case GL_DEPTH_COMPONENT16_ARB:
2212 case GL_DEPTH_COMPONENT24_ARB:
2213 case GL_DEPTH_COMPONENT32_ARB:
2214 qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
2215 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2216 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2217 break;
2218 default:
2219 break;
2159 RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_TEXTURE_2D, picFormat, numMips, internalFormat, type, flags, qfalse);
22202160 }
22212161
22222162 GL_CheckErrors();
2223
2224 if ( resampledBuffer != NULL )
2225 ri.Hunk_FreeTempMemory( resampledBuffer );
22262163 }
22272164
22282165
22292166 //----(SA) modified
2230
22312167 /*
22322168 ================
2233 R_CreateImage
2169 R_CreateImageExt2
22342170
22352171 This is the only way any image_t are created
22362172 ================
22372173 */
2238 image_t *R_CreateImageExt( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat, qboolean characterMip )
2239 {
2240 image_t *image;
2241 qboolean isLightmap = qfalse;
2242 int glWrapClampMode;
2243 long hash;
2174 image_t *R_CreateImageExt2( const char *name, byte *pic, int width, int height, GLenum picFormat, int numMips, imgType_t type, imgFlags_t flags, int internalFormat, qboolean characterMip ) {
2175 byte *resampledBuffer = NULL;
2176 image_t *image;
2177 qboolean isLightmap = qfalse, scaled = qfalse;
2178 long hash;
2179 int glWrapClampMode, mipWidth, mipHeight, miplevel;
2180 qboolean rgba8 = picFormat == GL_RGBA8 || picFormat == GL_SRGB8_ALPHA8_EXT;
2181 qboolean mipmap = !!(flags & IMGFLAG_MIPMAP);
2182 qboolean cubemap = !!(flags & IMGFLAG_CUBEMAP);
2183 qboolean picmip = !!(flags & IMGFLAG_PICMIP);
2184 qboolean lastMip;
2185 GLenum textureTarget = cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
2186 GLenum dataFormat;
22442187
22452188 if ( strlen( name ) >= MAX_QPATH ) {
22462189 ri.Error( ERR_DROP, "R_CreateImage: \"%s\" is too long", name );
22702213 glWrapClampMode = GL_REPEAT;
22712214
22722215 if (!internalFormat)
2273 {
2274 if (image->flags & IMGFLAG_CUBEMAP)
2275 internalFormat = GL_RGBA8;
2216 internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags);
2217
2218 image->internalFormat = internalFormat;
2219
2220 // Possibly scale image before uploading.
2221 // if not rgba8 and uploading an image, skip picmips.
2222 if (!cubemap)
2223 {
2224 if (rgba8)
2225 scaled = RawImage_ScaleToPower2(&pic, &width, &height, type, flags, &resampledBuffer);
2226 else if (pic && picmip)
2227 {
2228 for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--)
2229 {
2230 int size = CalculateMipSize(width, height, picFormat);
2231 width = MAX(1, width >> 1);
2232 height = MAX(1, height >> 1);
2233 pic += size;
2234 }
2235 }
2236 }
2237
2238 image->uploadWidth = width;
2239 image->uploadHeight = height;
2240
2241 // Allocate texture storage so we don't have to worry about it later.
2242 dataFormat = PixelDataFormatFromInternalFormat(internalFormat);
2243 mipWidth = width;
2244 mipHeight = height;
2245 miplevel = 0;
2246 do
2247 {
2248 lastMip = !mipmap || (mipWidth == 1 && mipHeight == 1);
2249 if (cubemap)
2250 {
2251 int i;
2252
2253 for (i = 0; i < 6; i++)
2254 qglTextureImage2DEXT(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, miplevel, internalFormat, mipWidth, mipHeight, 0, dataFormat, GL_UNSIGNED_BYTE, NULL);
2255 }
22762256 else
2277 internalFormat = RawImage_GetFormat(pic, width * height, isLightmap, image->type, image->flags);
2278 }
2279
2280 image->internalFormat = internalFormat;
2281
2282 // lightmaps are always allocated on TMU 1
2283 if ( qglActiveTextureARB && isLightmap ) {
2284 image->TMU = 1;
2285 } else {
2286 image->TMU = 0;
2287 }
2288
2289 if ( qglActiveTextureARB ) {
2290 GL_SelectTexture( image->TMU );
2291 }
2292
2293 GL_Bind(image);
2294
2295 if (image->flags & IMGFLAG_CUBEMAP)
2296 {
2297 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2298 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2299 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
2300
2301 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2302
2303 if (image->flags & IMGFLAG_MIPMAP)
2304 {
2305 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2306 }
2307 else
2308 {
2309 qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2310 }
2311
2312 qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2313 qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2314 qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2315 qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2316 qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2317 qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
2318
2319 if (image->flags & IMGFLAG_MIPMAP)
2320 qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
2321
2322 image->uploadWidth = width;
2323 image->uploadHeight = height;
2324 }
2325 else
2326 {
2327 Upload32( pic, 0, 0, image->width, image->height, image );
2328
2329 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode );
2330 qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode );
2331 }
2332
2333 GL_SelectTexture( 0 );
2257 {
2258 qglTextureImage2DEXT(image->texnum, GL_TEXTURE_2D, miplevel, internalFormat, mipWidth, mipHeight, 0, dataFormat, GL_UNSIGNED_BYTE, NULL);
2259 }
2260
2261 mipWidth = MAX(1, mipWidth >> 1);
2262 mipHeight = MAX(1, mipHeight >> 1);
2263 miplevel++;
2264 }
2265 while (!lastMip);
2266
2267 // Upload data.
2268 if (pic)
2269 Upload32(pic, 0, 0, width, height, picFormat, numMips, image, scaled);
2270
2271 if (resampledBuffer != NULL)
2272 ri.Hunk_FreeTempMemory(resampledBuffer);
2273
2274 // Set all necessary texture parameters.
2275 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_WRAP_S, glWrapClampMode);
2276 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_WRAP_T, glWrapClampMode);
2277
2278 if (cubemap)
2279 qglTextureParameteriEXT(image->texnum, textureTarget, GL_TEXTURE_WRAP_R, glWrapClampMode);
2280
2281 if (textureFilterAnisotropic && !cubemap)
2282 qglTextureParameteriEXT(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT,
2283 mipmap ? (GLint)Com_Clamp(1, maxAnisotropy, r_ext_max_anisotropy->integer) : 1);
2284
2285 switch(internalFormat)
2286 {
2287 case GL_DEPTH_COMPONENT:
2288 case GL_DEPTH_COMPONENT16_ARB:
2289 case GL_DEPTH_COMPONENT24_ARB:
2290 case GL_DEPTH_COMPONENT32_ARB:
2291 // Fix for sampling depth buffer on old nVidia cards.
2292 // from http://www.idevgames.com/forums/thread-4141-post-34844.html#pid34844
2293 qglTextureParameterfEXT(image->texnum, textureTarget, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
2294 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2295 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2296 break;
2297 default:
2298 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, mipmap ? gl_filter_min : GL_LINEAR);
2299 qglTextureParameterfEXT(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, mipmap ? gl_filter_max : GL_LINEAR);
2300 break;
2301 }
2302
2303 GL_CheckErrors();
23342304
23352305 hash = generateHashValue( name );
23362306 image->next = hashTable[hash];
23422312 return image;
23432313 }
23442314
2345 image_t *R_CreateImage( const char *name, byte *pic, int width, int height,
2346 imgType_t type, imgFlags_t flags, int internalFormat ) {
2347 return R_CreateImageExt( name, pic, width, height, type, flags, internalFormat, qfalse );
2348 }
2349
2315
2316 /*
2317 ================
2318 R_CreateImage
2319
2320 Wrapper for R_CreateImageExt2(), for the old parameters.
2321 ================
2322 */
2323 image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat ) {
2324 return R_CreateImageExt2(name, pic, width, height, GL_RGBA8, 0, type, flags, internalFormat, qfalse);
2325 }
23502326 //----(SA) end
23512327
2352 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height )
2328 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height, GLenum picFormat )
23532329 {
2354 if (qglActiveTextureARB) {
2355 GL_SelectTexture(image->TMU);
2356 }
2357
2358 GL_Bind(image);
2359
2360 Upload32(pic, x, y, width, height, image);
2361
2362 GL_SelectTexture(0);
2330 Upload32(pic, x, y, width, height, picFormat, 0, image, qfalse);
23632331 }
23642332
23652333 //===================================================================
2334
2335 // Prototype for dds loader function which isn't common to both renderers
2336 void R_LoadDDS(const char *filename, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips);
23662337
23672338 typedef struct
23682339 {
23742345 // when there are multiple images of different formats available
23752346 static imageExtToLoaderMap_t imageLoaders[ ] =
23762347 {
2348 { "png", R_LoadPNG },
23772349 { "tga", R_LoadTGA },
23782350 { "jpg", R_LoadJPG },
23792351 { "jpeg", R_LoadJPG },
2380 { "png", R_LoadPNG },
23812352 { "pcx", R_LoadPCX },
23822353 { "bmp", R_LoadBMP }
23832354 };
2384
2355
23852356 static int numImageLoaders = ARRAY_LEN( imageLoaders );
2386
23872357
23882358 /*
23892359 =================
23932363 32 bit format.
23942364 =================
23952365 */
2396 void R_LoadImage( const char *name, byte **pic, int *width, int *height )
2366 void R_LoadImage( const char *name, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips )
23972367 {
23982368 qboolean orgNameFailed = qfalse;
23992369 int orgLoader = -1;
24052375 *pic = NULL;
24062376 *width = 0;
24072377 *height = 0;
2378 *picFormat = GL_RGBA8;
2379 *numMips = 0;
24082380
24092381 Q_strncpyz( localName, name, MAX_QPATH );
24102382
24112383 ext = COM_GetExtension( localName );
2384
2385 // If compressed textures are enabled, try loading a DDS first, it'll load fastest
2386 if (r_ext_compressed_textures->integer)
2387 {
2388 char ddsName[MAX_QPATH];
2389
2390 COM_StripExtension(name, ddsName, MAX_QPATH);
2391 Q_strcat(ddsName, MAX_QPATH, ".dds");
2392
2393 R_LoadDDS(ddsName, pic, width, height, picFormat, numMips);
2394
2395 // If loaded, we're done.
2396 if (*pic)
2397 return;
2398 }
24122399
24132400 if( *ext )
24142401 {
24772464 Returns NULL if it fails, not a default image.
24782465 ==============
24792466 */
2480
2481
24822467 image_t *R_FindImageFileExt( const char *name, imgType_t type, imgFlags_t flags, qboolean characterMIP ) {
24832468 image_t *image;
24842469 int width, height;
24852470 byte *pic;
2471 GLenum picFormat;
2472 int picNumMips;
24862473 long hash;
2474 imgFlags_t checkFlagsTrue, checkFlagsFalse;
24872475
24882476 if ( !name ) {
24892477 return NULL;
25122500 //
25132501 // load the pic from disk
25142502 //
2515 R_LoadImage( name, &pic, &width, &height );
2503 R_LoadImage( name, &pic, &width, &height, &picFormat, &picNumMips );
25162504 if ( pic == NULL ) {
25172505 return NULL;
25182506 }
25192507
2520 if (r_normalMapping->integer && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP))
2508 checkFlagsTrue = IMGFLAG_PICMIP | IMGFLAG_MIPMAP | IMGFLAG_GENNORMALMAP;
2509 checkFlagsFalse = IMGFLAG_CUBEMAP;
2510 if (r_normalMapping->integer && (picFormat == GL_RGBA8) && (type == IMGTYPE_COLORALPHA) &&
2511 ((flags & checkFlagsTrue) == checkFlagsTrue) && !(flags & checkFlagsFalse))
25212512 {
25222513 char normalName[MAX_QPATH];
25232514 image_t *normalImage;
26202611 }
26212612 }
26222613
2623 image = R_CreateImageExt( ( char * ) name, pic, width, height, type, flags, 0, characterMIP );
2614 // force mipmaps off if image is compressed but doesn't have enough mips
2615 if ((flags & IMGFLAG_MIPMAP) && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT)
2616 {
2617 int wh = MAX(width, height);
2618 int neededMips = 0;
2619 while (wh)
2620 {
2621 neededMips++;
2622 wh >>= 1;
2623 }
2624 if (neededMips > picNumMips)
2625 flags &= ~IMGFLAG_MIPMAP;
2626 }
2627
2628 image = R_CreateImageExt2( ( char * ) name, pic, width, height, picFormat, picNumMips, type, flags, 0, characterMIP );
26242629 ri.Free( pic );
26252630 return image;
26262631 }
28342839 {
28352840 int width, height, hdrFormat, rgbFormat;
28362841
2837 if(glRefConfig.textureNonPowerOfTwo)
2838 {
2839 width = glConfig.vidWidth;
2840 height = glConfig.vidHeight;
2841 }
2842 else
2843 {
2844 width = NextPowerOfTwo(glConfig.vidWidth);
2845 height = NextPowerOfTwo(glConfig.vidHeight);
2846 }
2842 width = glConfig.vidWidth;
2843 height = glConfig.vidHeight;
28472844
28482845 hdrFormat = GL_RGBA8;
28492846 if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat)
28532850
28542851 tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
28552852
2853 if (r_shadowBlur->integer)
2854 tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
2855
2856 if (r_shadowBlur->integer || r_ssao->integer)
2857 tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
2858
28562859 if (r_drawSunRays->integer)
28572860 tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
28582861
2859 if (glRefConfig.framebufferObject)
2860 {
2861 tr.renderDepthImage = R_CreateImage("*renderdepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2862 tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2863 }
2864
2865 {
2866 unsigned short sdata[4];
2862 tr.renderDepthImage = R_CreateImage("*renderdepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2863 tr.textureDepthImage = R_CreateImage("*texturedepth", NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2864
2865 {
28672866 void *p;
28682867
2869 if (hdrFormat == GL_RGBA16F_ARB)
2870 {
2871 sdata[0] = FloatToHalf(0.0f);
2872 sdata[1] = FloatToHalf(0.45f);
2873 sdata[2] = FloatToHalf(1.0f);
2874 sdata[3] = FloatToHalf(1.0f);
2875 p = &sdata[0];
2876 }
2877 else
2878 {
2879 data[0][0][0] = 0;
2880 data[0][0][1] = 0.45f * 255;
2881 data[0][0][2] = 255;
2882 data[0][0][3] = 255;
2883 p = data;
2884 }
2868 data[0][0][0] = 0;
2869 data[0][0][1] = 0.45f * 255;
2870 data[0][0][2] = 255;
2871 data[0][0][3] = 255;
2872 p = data;
28852873
28862874 tr.calcLevelsImage = R_CreateImage("*calcLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
28872875 tr.targetLevelsImage = R_CreateImage("*targetLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
29002888 if (r_ssao->integer)
29012889 {
29022890 tr.screenSsaoImage = R_CreateImage("*screenSsao", NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
2903 tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
29042891 }
29052892
29062893 if (r_shadows->integer == 4)
29162903 for ( x = 0; x < 4; x++)
29172904 {
29182905 tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
2919 GL_Bind(tr.sunShadowDepthImage[x]);
2920 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
2921 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
2922 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
2923 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
2906
2907 qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
2908 qglTextureParameterfEXT(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
29242909 }
29252910
29262911 tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
29282913
29292914 if (r_cubeMapping->integer)
29302915 {
2931 tr.renderCubeImage = R_CreateImage("*renderCube", NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
2916 tr.renderCubeImage = R_CreateImage("*renderCube", NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
29322917 }
29332918 }
29342919 }
29452930 int inf;
29462931
29472932 // setup the overbright lighting
2948 #if defined(USE_OVERBRIGHT)
29492933 tr.overbrightBits = r_overBrightBits->integer;
2950 #else
2951 tr.overbrightBits = 0;
2952 #endif
29532934
29542935 // allow 2 overbright bits
29552936 if ( tr.overbrightBits > 2 ) {
29582939 tr.overbrightBits = 0;
29592940 }
29602941
2942 // don't allow more overbright bits than map overbright bits
2943 if ( tr.overbrightBits > r_mapOverBrightBits->integer ) {
2944 tr.overbrightBits = r_mapOverBrightBits->integer;
2945 }
2946
29612947 tr.identityLight = 1.0f / ( 1 << tr.overbrightBits );
29622948 tr.identityLightByte = 255 * tr.identityLight;
29632949
30293015 for ( i = 0; i < tr.numImages ; i++ ) {
30303016 qglDeleteTextures( 1, &tr.images[i]->texnum );
30313017 }
3032 memset( tr.images, 0, sizeof( tr.images ) );
3033
3034 memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
3035 if ( qglActiveTextureARB ) {
3036 GL_SelectTexture( 1 );
3037 qglBindTexture( GL_TEXTURE_2D, 0 );
3038 GL_SelectTexture( 0 );
3039 qglBindTexture( GL_TEXTURE_2D, 0 );
3040 } else {
3041 qglBindTexture( GL_TEXTURE_2D, 0 );
3042 }
3018 Com_Memset( tr.images, 0, sizeof( tr.images ) );
3019
3020 tr.numImages = 0;
3021
3022 GL_BindNullTextures();
30433023 }
30443024
30453025 /*
38973877 #endif
38983878 byte *pic, *temppic;
38993879 int width, height, newWidth, newHeight;
3880 GLenum picFormat;
3881 int picNumMips;
39003882 char *pch;
39013883 int b,c,d,lastNumber;
39023884 int lastBox[2] = {0,0};
39203902 Com_sprintf( filename, sizeof( filename ), "%s/%s", dir, fileList[j] );
39213903 ri.Printf( PRINT_ALL, "...cropping '%s'.. ", filename );
39223904
3923 R_LoadImage( filename, &pic, &width, &height );
3905 R_LoadImage( filename, &pic, &width, &height, &picFormat, &picNumMips );
39243906 if ( !pic ) {
39253907 ri.Printf( PRINT_ALL, "error reading file, ignoring.\n" );
39263908 continue;
0 /*
1 ===========================================================================
2 Copyright (C) 1999-2005 Id Software, Inc.
3 2015 James Canete
4
5 This file is part of Quake III Arena source code.
6
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
21 */
22
23 #include "tr_local.h"
24
25 typedef unsigned int ui32_t;
26
27 typedef struct ddsHeader_s
28 {
29 ui32_t headerSize;
30 ui32_t flags;
31 ui32_t height;
32 ui32_t width;
33 ui32_t pitchOrFirstMipSize;
34 ui32_t volumeDepth;
35 ui32_t numMips;
36 ui32_t reserved1[11];
37 ui32_t always_0x00000020;
38 ui32_t pixelFormatFlags;
39 ui32_t fourCC;
40 ui32_t rgbBitCount;
41 ui32_t rBitMask;
42 ui32_t gBitMask;
43 ui32_t bBitMask;
44 ui32_t aBitMask;
45 ui32_t caps;
46 ui32_t caps2;
47 ui32_t caps3;
48 ui32_t caps4;
49 ui32_t reserved2;
50 }
51 ddsHeader_t;
52
53 // flags:
54 #define _DDSFLAGS_REQUIRED 0x001007
55 #define _DDSFLAGS_PITCH 0x8
56 #define _DDSFLAGS_MIPMAPCOUNT 0x20000
57 #define _DDSFLAGS_FIRSTMIPSIZE 0x80000
58 #define _DDSFLAGS_VOLUMEDEPTH 0x800000
59
60 // pixelFormatFlags:
61 #define DDSPF_ALPHAPIXELS 0x1
62 #define DDSPF_ALPHA 0x2
63 #define DDSPF_FOURCC 0x4
64 #define DDSPF_RGB 0x40
65 #define DDSPF_YUV 0x200
66 #define DDSPF_LUMINANCE 0x20000
67
68 // caps:
69 #define DDSCAPS_COMPLEX 0x8
70 #define DDSCAPS_MIPMAP 0x400000
71 #define DDSCAPS_REQUIRED 0x1000
72
73 // caps2:
74 #define DDSCAPS2_CUBEMAP 0xFE00
75 #define DDSCAPS2_VOLUME 0x200000
76
77 typedef struct ddsHeaderDxt10_s
78 {
79 ui32_t dxgiFormat;
80 ui32_t dimensions;
81 ui32_t miscFlags;
82 ui32_t arraySize;
83 ui32_t miscFlags2;
84 }
85 ddsHeaderDxt10_t;
86
87 // dxgiFormat
88 // from http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx
89 typedef enum DXGI_FORMAT {
90 DXGI_FORMAT_UNKNOWN = 0,
91 DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
92 DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
93 DXGI_FORMAT_R32G32B32A32_UINT = 3,
94 DXGI_FORMAT_R32G32B32A32_SINT = 4,
95 DXGI_FORMAT_R32G32B32_TYPELESS = 5,
96 DXGI_FORMAT_R32G32B32_FLOAT = 6,
97 DXGI_FORMAT_R32G32B32_UINT = 7,
98 DXGI_FORMAT_R32G32B32_SINT = 8,
99 DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
100 DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
101 DXGI_FORMAT_R16G16B16A16_UNORM = 11,
102 DXGI_FORMAT_R16G16B16A16_UINT = 12,
103 DXGI_FORMAT_R16G16B16A16_SNORM = 13,
104 DXGI_FORMAT_R16G16B16A16_SINT = 14,
105 DXGI_FORMAT_R32G32_TYPELESS = 15,
106 DXGI_FORMAT_R32G32_FLOAT = 16,
107 DXGI_FORMAT_R32G32_UINT = 17,
108 DXGI_FORMAT_R32G32_SINT = 18,
109 DXGI_FORMAT_R32G8X24_TYPELESS = 19,
110 DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
111 DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
112 DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
113 DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
114 DXGI_FORMAT_R10G10B10A2_UNORM = 24,
115 DXGI_FORMAT_R10G10B10A2_UINT = 25,
116 DXGI_FORMAT_R11G11B10_FLOAT = 26,
117 DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
118 DXGI_FORMAT_R8G8B8A8_UNORM = 28,
119 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
120 DXGI_FORMAT_R8G8B8A8_UINT = 30,
121 DXGI_FORMAT_R8G8B8A8_SNORM = 31,
122 DXGI_FORMAT_R8G8B8A8_SINT = 32,
123 DXGI_FORMAT_R16G16_TYPELESS = 33,
124 DXGI_FORMAT_R16G16_FLOAT = 34,
125 DXGI_FORMAT_R16G16_UNORM = 35,
126 DXGI_FORMAT_R16G16_UINT = 36,
127 DXGI_FORMAT_R16G16_SNORM = 37,
128 DXGI_FORMAT_R16G16_SINT = 38,
129 DXGI_FORMAT_R32_TYPELESS = 39,
130 DXGI_FORMAT_D32_FLOAT = 40,
131 DXGI_FORMAT_R32_FLOAT = 41,
132 DXGI_FORMAT_R32_UINT = 42,
133 DXGI_FORMAT_R32_SINT = 43,
134 DXGI_FORMAT_R24G8_TYPELESS = 44,
135 DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
136 DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
137 DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
138 DXGI_FORMAT_R8G8_TYPELESS = 48,
139 DXGI_FORMAT_R8G8_UNORM = 49,
140 DXGI_FORMAT_R8G8_UINT = 50,
141 DXGI_FORMAT_R8G8_SNORM = 51,
142 DXGI_FORMAT_R8G8_SINT = 52,
143 DXGI_FORMAT_R16_TYPELESS = 53,
144 DXGI_FORMAT_R16_FLOAT = 54,
145 DXGI_FORMAT_D16_UNORM = 55,
146 DXGI_FORMAT_R16_UNORM = 56,
147 DXGI_FORMAT_R16_UINT = 57,
148 DXGI_FORMAT_R16_SNORM = 58,
149 DXGI_FORMAT_R16_SINT = 59,
150 DXGI_FORMAT_R8_TYPELESS = 60,
151 DXGI_FORMAT_R8_UNORM = 61,
152 DXGI_FORMAT_R8_UINT = 62,
153 DXGI_FORMAT_R8_SNORM = 63,
154 DXGI_FORMAT_R8_SINT = 64,
155 DXGI_FORMAT_A8_UNORM = 65,
156 DXGI_FORMAT_R1_UNORM = 66,
157 DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
158 DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
159 DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
160 DXGI_FORMAT_BC1_TYPELESS = 70,
161 DXGI_FORMAT_BC1_UNORM = 71,
162 DXGI_FORMAT_BC1_UNORM_SRGB = 72,
163 DXGI_FORMAT_BC2_TYPELESS = 73,
164 DXGI_FORMAT_BC2_UNORM = 74,
165 DXGI_FORMAT_BC2_UNORM_SRGB = 75,
166 DXGI_FORMAT_BC3_TYPELESS = 76,
167 DXGI_FORMAT_BC3_UNORM = 77,
168 DXGI_FORMAT_BC3_UNORM_SRGB = 78,
169 DXGI_FORMAT_BC4_TYPELESS = 79,
170 DXGI_FORMAT_BC4_UNORM = 80,
171 DXGI_FORMAT_BC4_SNORM = 81,
172 DXGI_FORMAT_BC5_TYPELESS = 82,
173 DXGI_FORMAT_BC5_UNORM = 83,
174 DXGI_FORMAT_BC5_SNORM = 84,
175 DXGI_FORMAT_B5G6R5_UNORM = 85,
176 DXGI_FORMAT_B5G5R5A1_UNORM = 86,
177 DXGI_FORMAT_B8G8R8A8_UNORM = 87,
178 DXGI_FORMAT_B8G8R8X8_UNORM = 88,
179 DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
180 DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
181 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
182 DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
183 DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
184 DXGI_FORMAT_BC6H_TYPELESS = 94,
185 DXGI_FORMAT_BC6H_UF16 = 95,
186 DXGI_FORMAT_BC6H_SF16 = 96,
187 DXGI_FORMAT_BC7_TYPELESS = 97,
188 DXGI_FORMAT_BC7_UNORM = 98,
189 DXGI_FORMAT_BC7_UNORM_SRGB = 99,
190 DXGI_FORMAT_AYUV = 100,
191 DXGI_FORMAT_Y410 = 101,
192 DXGI_FORMAT_Y416 = 102,
193 DXGI_FORMAT_NV12 = 103,
194 DXGI_FORMAT_P010 = 104,
195 DXGI_FORMAT_P016 = 105,
196 DXGI_FORMAT_420_OPAQUE = 106,
197 DXGI_FORMAT_YUY2 = 107,
198 DXGI_FORMAT_Y210 = 108,
199 DXGI_FORMAT_Y216 = 109,
200 DXGI_FORMAT_NV11 = 110,
201 DXGI_FORMAT_AI44 = 111,
202 DXGI_FORMAT_IA44 = 112,
203 DXGI_FORMAT_P8 = 113,
204 DXGI_FORMAT_A8P8 = 114,
205 DXGI_FORMAT_B4G4R4A4_UNORM = 115,
206 DXGI_FORMAT_FORCE_UINT = 0xffffffffUL
207 } DXGI_FORMAT;
208
209 #define EncodeFourCC(x) ((((ui32_t)((x)[0])) ) | \
210 (((ui32_t)((x)[1])) << 8 ) | \
211 (((ui32_t)((x)[2])) << 16) | \
212 (((ui32_t)((x)[3])) << 24) )
213
214
215 void R_LoadDDS ( const char *filename, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips )
216 {
217 union {
218 byte *b;
219 void *v;
220 } buffer;
221 int len;
222 ddsHeader_t *ddsHeader = NULL;
223 ddsHeaderDxt10_t *ddsHeaderDxt10 = NULL;
224 byte *data;
225
226 if (!picFormat)
227 {
228 ri.Printf(PRINT_ERROR, "R_LoadDDS() called without picFormat parameter!");
229 return;
230 }
231
232 if (width)
233 *width = 0;
234 if (height)
235 *height = 0;
236 if (picFormat)
237 *picFormat = GL_RGBA8;
238 if (numMips)
239 *numMips = 1;
240
241 *pic = NULL;
242
243 //
244 // load the file
245 //
246 len = ri.FS_ReadFile( ( char * ) filename, &buffer.v);
247 if (!buffer.b || len < 0) {
248 return;
249 }
250
251 //
252 // reject files that are too small to hold even a header
253 //
254 if (len < 4 + sizeof(*ddsHeader))
255 {
256 ri.Printf(PRINT_ALL, "File %s is too small to be a DDS file.\n", filename);
257 ri.FS_FreeFile(buffer.v);
258 return;
259 }
260
261 //
262 // reject files that don't start with "DDS "
263 //
264 if (*((ui32_t *)(buffer.b)) != EncodeFourCC("DDS "))
265 {
266 ri.Printf(PRINT_ALL, "File %s is not a DDS file.\n", filename);
267 ri.FS_FreeFile(buffer.v);
268 return;
269 }
270
271 //
272 // parse header and dx10 header if available
273 //
274 ddsHeader = (ddsHeader_t *)(buffer.b + 4);
275 if ((ddsHeader->pixelFormatFlags & DDSPF_FOURCC) && ddsHeader->fourCC == EncodeFourCC("DX10"))
276 {
277 if (len < 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10))
278 {
279 ri.Printf(PRINT_ALL, "File %s indicates a DX10 header it is too small to contain.\n", filename);
280 ri.FS_FreeFile(buffer.v);
281 return;
282 }
283
284 ddsHeaderDxt10 = (ddsHeaderDxt10_t *)(buffer.b + 4 + sizeof(ddsHeader_t));
285 data = buffer.b + 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10);
286 len -= 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10);
287 }
288 else
289 {
290 data = buffer.b + 4 + sizeof(*ddsHeader);
291 len -= 4 + sizeof(*ddsHeader);
292 }
293
294 if (width)
295 *width = ddsHeader->width;
296 if (height)
297 *height = ddsHeader->height;
298
299 if (numMips)
300 {
301 if (ddsHeader->flags & _DDSFLAGS_MIPMAPCOUNT)
302 *numMips = ddsHeader->numMips;
303 else
304 *numMips = 1;
305 }
306
307 // FIXME: handle cube map
308 //if ((ddsHeader->caps2 & DDSCAPS2_CUBEMAP) == DDSCAPS2_CUBEMAP)
309
310 //
311 // Convert DXGI format/FourCC into OpenGL format
312 //
313 if (ddsHeaderDxt10)
314 {
315 switch (ddsHeaderDxt10->dxgiFormat)
316 {
317 case DXGI_FORMAT_BC1_TYPELESS:
318 case DXGI_FORMAT_BC1_UNORM:
319 // FIXME: check for GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
320 *picFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
321 break;
322
323 case DXGI_FORMAT_BC1_UNORM_SRGB:
324 // FIXME: check for GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
325 *picFormat = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
326 break;
327
328 case DXGI_FORMAT_BC2_TYPELESS:
329 case DXGI_FORMAT_BC2_UNORM:
330 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
331 break;
332
333 case DXGI_FORMAT_BC2_UNORM_SRGB:
334 *picFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
335 break;
336
337 case DXGI_FORMAT_BC3_TYPELESS:
338 case DXGI_FORMAT_BC3_UNORM:
339 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
340 break;
341
342 case DXGI_FORMAT_BC3_UNORM_SRGB:
343 *picFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
344 break;
345
346 case DXGI_FORMAT_BC4_TYPELESS:
347 case DXGI_FORMAT_BC4_UNORM:
348 *picFormat = GL_COMPRESSED_RED_RGTC1;
349 break;
350
351 case DXGI_FORMAT_BC4_SNORM:
352 *picFormat = GL_COMPRESSED_SIGNED_RED_RGTC1;
353 break;
354
355 case DXGI_FORMAT_BC5_TYPELESS:
356 case DXGI_FORMAT_BC5_UNORM:
357 *picFormat = GL_COMPRESSED_RG_RGTC2;
358 break;
359
360 case DXGI_FORMAT_BC5_SNORM:
361 *picFormat = GL_COMPRESSED_SIGNED_RG_RGTC2;
362 break;
363
364 case DXGI_FORMAT_BC6H_TYPELESS:
365 case DXGI_FORMAT_BC6H_UF16:
366 *picFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB;
367 break;
368
369 case DXGI_FORMAT_BC6H_SF16:
370 *picFormat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB;
371 break;
372
373 case DXGI_FORMAT_BC7_TYPELESS:
374 case DXGI_FORMAT_BC7_UNORM:
375 *picFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
376 break;
377
378 case DXGI_FORMAT_BC7_UNORM_SRGB:
379 *picFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB;
380 break;
381
382 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
383 *picFormat = GL_SRGB8_ALPHA8_EXT;
384 break;
385
386 case DXGI_FORMAT_R8G8B8A8_UNORM:
387 case DXGI_FORMAT_R8G8B8A8_SNORM:
388 *picFormat = GL_RGBA8;
389 break;
390
391 default:
392 ri.Printf(PRINT_ALL, "DDS File %s has unsupported DXGI format %d.", filename, ddsHeaderDxt10->dxgiFormat);
393 ri.FS_FreeFile(buffer.v);
394 return;
395 break;
396 }
397 }
398 else
399 {
400 if (ddsHeader->pixelFormatFlags & DDSPF_FOURCC)
401 {
402 if (ddsHeader->fourCC == EncodeFourCC("DXT1"))
403 *picFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
404 else if (ddsHeader->fourCC == EncodeFourCC("DXT2"))
405 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
406 else if (ddsHeader->fourCC == EncodeFourCC("DXT3"))
407 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
408 else if (ddsHeader->fourCC == EncodeFourCC("DXT4"))
409 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
410 else if (ddsHeader->fourCC == EncodeFourCC("DXT5"))
411 *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
412 else if (ddsHeader->fourCC == EncodeFourCC("ATI1"))
413 *picFormat = GL_COMPRESSED_RED_RGTC1;
414 else if (ddsHeader->fourCC == EncodeFourCC("BC4U"))
415 *picFormat = GL_COMPRESSED_RED_RGTC1;
416 else if (ddsHeader->fourCC == EncodeFourCC("BC4S"))
417 *picFormat = GL_COMPRESSED_SIGNED_RED_RGTC1;
418 else if (ddsHeader->fourCC == EncodeFourCC("ATI2"))
419 *picFormat = GL_COMPRESSED_RG_RGTC2;
420 else if (ddsHeader->fourCC == EncodeFourCC("BC5U"))
421 *picFormat = GL_COMPRESSED_RG_RGTC2;
422 else if (ddsHeader->fourCC == EncodeFourCC("BC5S"))
423 *picFormat = GL_COMPRESSED_SIGNED_RG_RGTC2;
424 else
425 {
426 ri.Printf(PRINT_ALL, "DDS File %s has unsupported FourCC.", filename);
427 ri.FS_FreeFile(buffer.v);
428 return;
429 }
430 }
431 else if (ddsHeader->pixelFormatFlags == (DDSPF_RGB | DDSPF_ALPHAPIXELS)
432 && ddsHeader->rgbBitCount == 32
433 && ddsHeader->rBitMask == 0x000000ff
434 && ddsHeader->gBitMask == 0x0000ff00
435 && ddsHeader->bBitMask == 0x00ff0000
436 && ddsHeader->aBitMask == 0xff000000)
437 {
438 *picFormat = GL_RGBA8;
439 }
440 else
441 {
442 ri.Printf(PRINT_ALL, "DDS File %s has unsupported RGBA format.", filename);
443 ri.FS_FreeFile(buffer.v);
444 return;
445 }
446 }
447
448 *pic = ri.Z_Malloc(len);
449 Com_Memcpy(*pic, data, len);
450
451 ri.FS_FreeFile(buffer.v);
452 }
453
454 void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth)
455 {
456 byte *data;
457 ddsHeader_t *ddsHeader;
458 int picSize, size;
459
460 if (!depth)
461 depth = 1;
462
463 picSize = width * height * depth * 4;
464 size = 4 + sizeof(*ddsHeader) + picSize;
465 data = ri.Z_Malloc(size);
466
467 data[0] = 'D';
468 data[1] = 'D';
469 data[2] = 'S';
470 data[3] = ' ';
471
472 ddsHeader = (ddsHeader_t *)(data + 4);
473 memset(ddsHeader, 0, sizeof(ddsHeader_t));
474
475 ddsHeader->headerSize = 0x7c;
476 ddsHeader->flags = _DDSFLAGS_REQUIRED;
477 ddsHeader->height = height;
478 ddsHeader->width = width;
479 ddsHeader->always_0x00000020 = 0x00000020;
480 ddsHeader->caps = DDSCAPS_COMPLEX | DDSCAPS_REQUIRED;
481
482 if (depth == 6)
483 ddsHeader->caps2 = DDSCAPS2_CUBEMAP;
484
485 ddsHeader->pixelFormatFlags = DDSPF_RGB | DDSPF_ALPHAPIXELS;
486 ddsHeader->rgbBitCount = 32;
487 ddsHeader->rBitMask = 0x000000ff;
488 ddsHeader->gBitMask = 0x0000ff00;
489 ddsHeader->bBitMask = 0x00ff0000;
490 ddsHeader->aBitMask = 0xff000000;
491
492 Com_Memcpy(data + 4 + sizeof(*ddsHeader), pic, picSize);
493
494 ri.FS_WriteFile(filename, data, size);
495
496 ri.Free(data);
497 }
2828 // tr_init.c -- functions that are not called every frame
2929
3030 #include "tr_local.h"
31
32 #include "tr_dsa.h"
3133
3234 glconfig_t glConfig;
3335 glRefConfig_t glRefConfig;
123125 cvar_t *r_ext_multi_draw_arrays;
124126 cvar_t *r_ext_framebuffer_object;
125127 cvar_t *r_ext_texture_float;
126 cvar_t *r_arb_half_float_pixel;
127 cvar_t *r_arb_half_float_vertex;
128128 cvar_t *r_ext_framebuffer_multisample;
129129 cvar_t *r_arb_seamless_cube_map;
130 cvar_t *r_arb_vertex_type_2_10_10_10_rev;
131130 cvar_t *r_arb_vertex_array_object;
131 cvar_t *r_ext_direct_state_access;
132132
133133 cvar_t *r_mergeMultidraws;
134134 cvar_t *r_mergeLeafSurfaces;
152152 cvar_t *r_forceAutoExposureMin;
153153 cvar_t *r_forceAutoExposureMax;
154154
155 cvar_t *r_materialGamma;
156 cvar_t *r_lightGamma;
157 cvar_t *r_framebufferGamma;
158 cvar_t *r_tonemapGamma;
159
160155 cvar_t *r_depthPrepass;
161156 cvar_t *r_ssao;
162157
165160 cvar_t *r_deluxeMapping;
166161 cvar_t *r_parallaxMapping;
167162 cvar_t *r_cubeMapping;
168 cvar_t *r_specularIsMetallic;
169 cvar_t *r_glossIsRoughness;
163 cvar_t *r_cubemapSize;
164 cvar_t *r_pbr;
170165 cvar_t *r_baseNormalX;
171166 cvar_t *r_baseNormalY;
172167 cvar_t *r_baseParallax;
173168 cvar_t *r_baseSpecular;
174169 cvar_t *r_baseGloss;
170 cvar_t *r_glossType;
175171 cvar_t *r_mergeLightmaps;
176172 cvar_t *r_dlightMode;
177173 cvar_t *r_pshadowDist;
180176 cvar_t *r_imageUpsampleType;
181177 cvar_t *r_genNormalMaps;
182178 cvar_t *r_forceSun;
183 cvar_t *r_forceSunMapLightScale;
184179 cvar_t *r_forceSunLightScale;
185180 cvar_t *r_forceSunAmbientScale;
186181 cvar_t *r_sunlightMode;
187182 cvar_t *r_drawSunRays;
188183 cvar_t *r_sunShadows;
189184 cvar_t *r_shadowFilter;
185 cvar_t *r_shadowBlur;
190186 cvar_t *r_shadowMapSize;
191187 cvar_t *r_shadowCascadeZNear;
192188 cvar_t *r_shadowCascadeZFar;
205201 cvar_t *r_drawBuffer;
206202 cvar_t *r_glIgnoreWicked3D;
207203 cvar_t *r_lightmap;
208 cvar_t *r_cgenVertexLit;
209204 cvar_t *r_vertexLight;
210205 cvar_t *r_uiFullScreen;
211206 cvar_t *r_shadows;
906901 if ( !silent ) {
907902 ri.Printf( PRINT_ALL, "Wrote %s\n", checkname );
908903 }
904 }
905
906 /*
907 ==================
908 R_ExportCubemaps
909 ==================
910 */
911 void R_ExportCubemaps(void)
912 {
913 exportCubemapsCommand_t *cmd;
914
915 cmd = R_GetCommandBuffer(sizeof(*cmd));
916 if (!cmd) {
917 return;
918 }
919 cmd->commandId = RC_EXPORT_CUBEMAPS;
920 }
921
922
923 /*
924 ==================
925 R_ExportCubemaps_f
926 ==================
927 */
928 void R_ExportCubemaps_f(void)
929 {
930 R_ExportCubemaps();
909931 }
910932
911933 //============================================================================
10011023
10021024 qglColor4f( 1,1,1,1 );
10031025
1004 // initialize downstream texture unit if we're running
1005 // in a multitexture environment
1006 if ( qglActiveTextureARB ) {
1007 GL_SelectTexture( 1 );
1008 GL_TextureMode( r_textureMode->string );
1009 GL_TexEnv( GL_MODULATE );
1010 qglDisable( GL_TEXTURE_2D );
1011 GL_SelectTexture( 0 );
1012 }
1026 GL_BindNullTextures();
1027 GL_BindNullFramebuffers();
10131028
10141029 qglEnable( GL_TEXTURE_2D );
10151030 GL_TextureMode( r_textureMode->string );
1016 GL_TexEnv( GL_MODULATE );
10171031
10181032 //qglShadeModel( GL_SMOOTH );
10191033 qglDepthFunc( GL_LEQUAL );
10261040 glState.faceCulling = CT_TWO_SIDED;
10271041 glState.faceCullFront = qtrue;
10281042
1029 glState.currentProgram = 0;
1030 qglUseProgramObjectARB(0);
1043 GL_BindNullProgram();
10311044
10321045 if (glRefConfig.vertexArrayObject)
1033 qglBindVertexArrayARB(0);
1034
1035 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1036 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1046 qglBindVertexArray(0);
1047
1048 qglBindBuffer(GL_ARRAY_BUFFER, 0);
1049 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
10371050 glState.currentVao = NULL;
10381051 glState.vertexAttribsEnabled = 0;
10391052
10901103 */
10911104 void R_PrintLongString(const char *string) {
10921105 char buffer[1024];
1093 const char *p;
1094 int size = strlen(string);
1095
1096 p = string;
1097 while(size > 0)
1106 const char *p = string;
1107 int remainingLength = strlen(string);
1108
1109 while (remainingLength > 0)
10981110 {
1099 Q_strncpyz(buffer, p, sizeof (buffer) );
1111 // Take as much characters as possible from the string without splitting words between buffers
1112 // This avoids the client console splitting a word up when one half fits on the current line,
1113 // but the second half would have to be written on a new line
1114 int charsToTake = sizeof(buffer) - 1;
1115 if (remainingLength > charsToTake) {
1116 while (p[charsToTake - 1] > ' ' && p[charsToTake] > ' ') {
1117 charsToTake--;
1118 if (charsToTake == 0) {
1119 charsToTake = sizeof(buffer) - 1;
1120 break;
1121 }
1122 }
1123 } else if (remainingLength < charsToTake) {
1124 charsToTake = remainingLength;
1125 }
1126
1127 Q_strncpyz( buffer, p, charsToTake + 1 );
11001128 ri.Printf( PRINT_ALL, "%s", buffer );
1101 p += 1023;
1102 size -= 1023;
1129 remainingLength -= charsToTake;
1130 p += charsToTake;
11031131 }
11041132 }
11051133
12721300 r_ext_multi_draw_arrays = ri.Cvar_Get( "r_ext_multi_draw_arrays", "1", CVAR_ARCHIVE | CVAR_LATCH);
12731301 r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", "1", CVAR_ARCHIVE | CVAR_LATCH);
12741302 r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH);
1275 r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH);
1276 r_arb_half_float_vertex = ri.Cvar_Get( "r_arb_half_float_vertex", "1", CVAR_ARCHIVE | CVAR_LATCH);
12771303 r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
12781304 r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH);
1279 r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( "r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH);
12801305 r_arb_vertex_array_object = ri.Cvar_Get( "r_arb_vertex_array_object", "1", CVAR_ARCHIVE | CVAR_LATCH);
1306 r_ext_direct_state_access = ri.Cvar_Get("r_ext_direct_state_access", "1", CVAR_ARCHIVE | CVAR_LATCH);
12811307
12821308 r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "0", CVAR_ARCHIVE | CVAR_LATCH );
12831309 r_ext_max_anisotropy = ri.Cvar_Get( "r_ext_max_anisotropy", "2", CVAR_ARCHIVE | CVAR_LATCH );
13031329 r_overBrightBits = ri.Cvar_Get( "r_overBrightBits", "0", CVAR_ARCHIVE | CVAR_LATCH );
13041330 r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH );
13051331 r_mode = ri.Cvar_Get( "r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH );
1306 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
1332 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "0", CVAR_ARCHIVE | CVAR_LATCH );
13071333 r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE | CVAR_LATCH );
13081334 r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
13091335 r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
13231349 r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH );
13241350 r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE );
13251351
1326 r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH );
1352 r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE );
13271353 r_forceToneMap = ri.Cvar_Get( "r_forceToneMap", "0", CVAR_CHEAT );
13281354 r_forceToneMapMin = ri.Cvar_Get( "r_forceToneMapMin", "-8.0", CVAR_CHEAT );
13291355 r_forceToneMapAvg = ri.Cvar_Get( "r_forceToneMapAvg", "-2.0", CVAR_CHEAT );
13351361 r_forceAutoExposureMax = ri.Cvar_Get( "r_forceAutoExposureMax", "2.0", CVAR_CHEAT );
13361362
13371363 r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT );
1338
1339 r_materialGamma = ri.Cvar_Get( "r_materialGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
1340 r_lightGamma = ri.Cvar_Get( "r_lightGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
1341 r_framebufferGamma = ri.Cvar_Get( "r_framebufferGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
1342 r_tonemapGamma = ri.Cvar_Get( "r_tonemapGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
13431364
13441365 r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE );
13451366 r_ssao = ri.Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE );
13491370 r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
13501371 r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
13511372 r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
1352 r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH );
1353 r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH);
1373 r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH );
1374 r_pbr = ri.Cvar_Get("r_pbr", "0", CVAR_ARCHIVE | CVAR_LATCH);
13541375 r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
13551376 r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
13561377 r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH );
13571378 r_baseSpecular = ri.Cvar_Get( "r_baseSpecular", "0.04", CVAR_ARCHIVE | CVAR_LATCH );
13581379 r_baseGloss = ri.Cvar_Get( "r_baseGloss", "0.1", CVAR_ARCHIVE | CVAR_LATCH );
1380 r_glossType = ri.Cvar_Get("r_glossType", "1", CVAR_ARCHIVE | CVAR_LATCH);
13591381 r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH );
13601382 r_pshadowDist = ri.Cvar_Get( "r_pshadowDist", "128", CVAR_ARCHIVE );
13611383 r_mergeLightmaps = ri.Cvar_Get( "r_mergeLightmaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
13651387 r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH );
13661388
13671389 r_forceSun = ri.Cvar_Get( "r_forceSun", "0", CVAR_ARCHIVE );
1368 r_forceSunMapLightScale = ri.Cvar_Get( "r_forceSunMapLightScale", "1.0", CVAR_CHEAT );
13691390 r_forceSunLightScale = ri.Cvar_Get( "r_forceSunLightScale", "1.0", CVAR_CHEAT );
13701391 r_forceSunAmbientScale = ri.Cvar_Get( "r_forceSunAmbientScale", "0.5", CVAR_CHEAT );
13711392 r_drawSunRays = ri.Cvar_Get( "r_drawSunRays", "0", CVAR_ARCHIVE | CVAR_LATCH );
13731394
13741395 r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH );
13751396 r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH );
1376 r_shadowMapSize = ri.Cvar_Get( "r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH );
1397 r_shadowBlur = ri.Cvar_Get("r_shadowBlur", "0", CVAR_ARCHIVE | CVAR_LATCH);
1398 r_shadowMapSize = ri.Cvar_Get("r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH);
13771399 r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "8", CVAR_ARCHIVE | CVAR_LATCH );
13781400 r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH );
13791401 r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH );
14561478 r_drawworld = ri.Cvar_Get( "r_drawworld", "1", CVAR_CHEAT );
14571479 r_lightmap = ri.Cvar_Get( "r_lightmap", "0", CVAR_CHEAT );
14581480 r_portalOnly = ri.Cvar_Get( "r_portalOnly", "0", CVAR_CHEAT );
1459
1460 r_cgenVertexLit = ri.Cvar_Get( "r_cgenVertexLit", "1", CVAR_ARCHIVE | CVAR_LATCH );
14611481
14621482 r_flareSize = ri.Cvar_Get( "r_flareSize", "40", CVAR_CHEAT );
14631483 r_flareFade = ri.Cvar_Get( "r_flareFade", "5", CVAR_CHEAT );
15111531 ri.Cmd_AddCommand( "gfxinfo", GfxInfo_f );
15121532 ri.Cmd_AddCommand( "minimize", GLimp_Minimize );
15131533 ri.Cmd_AddCommand( "gfxmeminfo", GfxMemInfo_f );
1534 ri.Cmd_AddCommand( "exportCubemaps", R_ExportCubemaps_f );
15141535 ri.Cmd_AddCommand( "taginfo", R_TagInfo_f );
15151536
15161537 // Ridah
15241545 return;
15251546
15261547 if (r_drawSunRays->integer)
1527 qglGenQueriesARB(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
1548 qglGenQueries(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
15281549 }
15291550
15301551 void R_ShutDownQueries(void)
15331554 return;
15341555
15351556 if (r_drawSunRays->integer)
1536 qglDeleteQueriesARB(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
1557 qglDeleteQueries(ARRAY_LEN(tr.sunFlareQuery), tr.sunFlareQuery);
15371558 }
15381559
15391560 /*
16631684 ri.Cmd_RemoveCommand( "modelist" );
16641685 ri.Cmd_RemoveCommand( "shaderstate" );
16651686 ri.Cmd_RemoveCommand( "gfxmeminfo" );
1687 ri.Cmd_RemoveCommand( "exportCubemaps" );
16661688 ri.Cmd_RemoveCommand( "taginfo" );
16671689
16681690 // Ridah
194194 byte *data;
195195 int lat, lng;
196196 vec3_t normal;
197
197 #if idppc
198 float d0, d1, d2, d3, d4, d5;
199 #endif
198200 factor = 1.0;
199201 data = gridData;
200202 for ( j = 0 ; j < 3 ; j++ ) {
212214 if ( j != 3 )
213215 continue;
214216
215 if (world->hdrLightGrid)
216 {
217 float *hdrData = world->hdrLightGrid + (int)(data - world->lightGridData) / 8 * 6;
218 if (!(hdrData[0]+hdrData[1]+hdrData[2]+hdrData[3]+hdrData[4]+hdrData[5]) ) {
217 if (world->lightGrid16)
218 {
219 uint16_t *data16 = world->lightGrid16 + (int)(data - world->lightGridData) / 8 * 6;
220 if (!(data16[0]+data16[1]+data16[2]+data16[3]+data16[4]+data16[5])) {
219221 continue; // ignore samples in walls
220222 }
221223 }
226228 }
227229 }
228230 totalFactor += factor;
229
230 if (world->hdrLightGrid)
231 #if idppc
232 d0 = data[0]; d1 = data[1]; d2 = data[2];
233 d3 = data[3]; d4 = data[4]; d5 = data[5];
234
235 ent->ambientLight[0] += factor * d0;
236 ent->ambientLight[1] += factor * d1;
237 ent->ambientLight[2] += factor * d2;
238
239 ent->directedLight[0] += factor * d3;
240 ent->directedLight[1] += factor * d4;
241 ent->directedLight[2] += factor * d5;
242 #else
243 if (world->lightGrid16)
231244 {
232245 // FIXME: this is hideous
233 float *hdrData = world->hdrLightGrid + (int)(data - world->lightGridData) / 8 * 6;
234
235 ent->ambientLight[0] += factor * hdrData[0];
236 ent->ambientLight[1] += factor * hdrData[1];
237 ent->ambientLight[2] += factor * hdrData[2];
238
239 ent->directedLight[0] += factor * hdrData[3];
240 ent->directedLight[1] += factor * hdrData[4];
241 ent->directedLight[2] += factor * hdrData[5];
246 uint16_t *data16 = world->lightGrid16 + (int)(data - world->lightGridData) / 8 * 6;
247
248 ent->ambientLight[0] += factor * data16[0] / 257.0f;
249 ent->ambientLight[1] += factor * data16[1] / 257.0f;
250 ent->ambientLight[2] += factor * data16[2] / 257.0f;
251
252 ent->directedLight[0] += factor * data16[3] / 257.0f;
253 ent->directedLight[1] += factor * data16[4] / 257.0f;
254 ent->directedLight[2] += factor * data16[5] / 257.0f;
242255 }
243256 else
244257 {
250263 ent->directedLight[1] += factor * data[4];
251264 ent->directedLight[2] += factor * data[5];
252265 }
253
266 #endif
254267 lat = data[7];
255268 lng = data[6];
256269 lat *= ( FUNCTABLE_SIZE / 256 );
412425 VectorMA( lightDir, d, dir, lightDir );
413426 }
414427
415 // clamp ambient
416 if ( !r_hdr->integer )
428 // clamp lights
429 // FIXME: old renderer clamps (ambient + NL * directed) per vertex
430 // check if that's worth implementing
417431 {
418 for ( i = 0 ; i < 3 ; i++ ) {
419 if ( ent->ambientLight[i] > tr.identityLightByte ) {
420 ent->ambientLight[i] = tr.identityLightByte;
421 }
432 float r, g, b, max;
433
434 r = ent->ambientLight[0];
435 g = ent->ambientLight[1];
436 b = ent->ambientLight[2];
437
438 max = MAX(MAX(r, g), b);
439
440 if (max > 255.0f)
441 {
442 max = 255.0f / max;
443 ent->ambientLight[0] *= max;
444 ent->ambientLight[1] *= max;
445 ent->ambientLight[2] *= max;
446 }
447
448 r = ent->directedLight[0];
449 g = ent->directedLight[1];
450 b = ent->directedLight[2];
451
452 max = MAX(MAX(r, g), b);
453
454 if (max > 255.0f)
455 {
456 max = 255.0f / max;
457 ent->directedLight[0] *= max;
458 ent->directedLight[1] *= max;
459 ent->directedLight[2] *= max;
422460 }
423461 }
424462
425463 if ( r_debugLight->integer ) {
426464 LogLight( ent );
427465 }
428
429 // save out the byte packet version
430 ( (byte *)&ent->ambientLightInt )[0] = ri.ftol( ent->ambientLight[0] );
431 ( (byte *)&ent->ambientLightInt )[1] = ri.ftol( ent->ambientLight[1] );
432 ( (byte *)&ent->ambientLightInt )[2] = ri.ftol( ent->ambientLight[2] );
433 ( (byte *)&ent->ambientLightInt )[3] = 0xff;
434466
435467 // transform the direction to local space
436468 VectorNormalize( lightDir );
2626 */
2727
2828
29
3029 #ifndef TR_LOCAL_H
3130 #define TR_LOCAL_H
3231
3433 #include "../qcommon/qfiles.h"
3534 #include "../qcommon/qcommon.h"
3635 #include "../renderer/tr_public.h"
37 #include "tr_extratypes.h"
38 #include "tr_extramath.h"
39 #include "tr_fbo.h"
40 #include "tr_postprocess.h"
4136 #include "qgl.h"
4237 #include "../renderer/iqm.h"
4338
6055 #define MAX_CALC_PSHADOWS 64
6156 #define MAX_DRAWN_PSHADOWS 32 // do not increase past 32, because bit flags are used on surfaces
6257 #define PSHADOW_MAP_SIZE 512
63 #define CUBE_MAP_MIPS 7
64 #define CUBE_MAP_SIZE (1 << CUBE_MAP_MIPS)
6558
66 #define USE_VERT_TANGENT_SPACE
67 #define USE_OVERBRIGHT
68
6959 // a trRefEntity_t has all the information passed in by
7060 // the client game, as well as some locally derived info
7161 typedef struct {
7969 vec3_t lightDir; // normalized direction towards light, in world space
8070 vec3_t modelLightDir; // normalized direction towards light, in model space
8171 vec3_t ambientLight; // color normalized to 0-255
82 int ambientLightInt; // 32 bit rgba packed
8372 vec3_t directedLight;
8473 float brightness;
8574 } trRefEntity_t;
133122
134123 struct image_s* next;
135124 } image_t;
125
126 #include "tr_extratypes.h"
127 #include "tr_extramath.h"
128 #include "tr_fbo.h"
129 #include "tr_postprocess.h"
136130
137131 // Ensure this is >= the ATTR_INDEX_COUNT enum below
138132 #define VAO_MAX_ATTRIBS 16
274268 CGEN_IDENTITY, // always (1,1,1,1)
275269 CGEN_ENTITY, // grabbed from entity's modulate field
276270 CGEN_ONE_MINUS_ENTITY, // grabbed from 1 - entity.modulate
277 CGEN_EXACT_VERTEX, // tess.vertexColors
278 CGEN_VERTEX, // tess.vertexColors * tr.identityLight
271 CGEN_EXACT_VERTEX, // tess.color
272 CGEN_VERTEX, // tess.color * tr.identityLight
279273 CGEN_EXACT_VERTEX_LIT, // like CGEN_EXACT_VERTEX but takes a light direction from the lightgrid
280274 CGEN_VERTEX_LIT, // like CGEN_VERTEX but takes a light direction from the lightgrid
281275 CGEN_ONE_MINUS_VERTEX,
559553 }
560554
561555 typedef struct cubemap_s {
556 char name[MAX_QPATH];
562557 vec3_t origin;
563558 float parallaxRadius;
564559 image_t *image;
802797 {
803798 char name[MAX_QPATH];
804799
805 GLhandleARB program;
806 GLhandleARB vertexShader;
807 GLhandleARB fragmentShader;
800 GLuint program;
801 GLuint vertexShader;
802 GLuint fragmentShader;
808803 uint32_t attribs; // vertex array attributes
809804
810805 // uniform parameters
860855 float sunDir[4];
861856 float sunCol[4];
862857 float sunAmbCol[4];
863 float colorScale;
864858
865859 float autoExposureMinMax[2];
866860 float toneMinAvgMaxLinear[3];
967961 SF_TRIANGLES,
968962 SF_POLY,
969963 SF_MDV,
970 SF_MDC,
971964 SF_MDS,
972965 SF_MDR,
973966 SF_IQM,
10151008 vec3_t xyz;
10161009 vec2_t st;
10171010 vec2_t lightmap;
1018 vec3_t normal;
1019 #ifdef USE_VERT_TANGENT_SPACE
1020 vec4_t tangent;
1021 #endif
1022 vec3_t lightdir;
1023 vec4_t vertexColors;
1011 int16_t normal[4];
1012 int16_t tangent[4];
1013 int16_t lightdir[4];
1014 uint16_t color[4];
10241015
10251016 #if DEBUG_OPTIMIZEVERTICES
10261017 unsigned int id;
10271018 #endif
10281019 } srfVert_t;
10291020
1030 #ifdef USE_VERT_TANGENT_SPACE
1031 #define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
1032 #else
1033 #define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
1034 #endif
1021 #define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}
10351022
10361023 // srfBspSurface_t covers SF_GRID, SF_TRIANGLES, SF_POLY, and SF_VAO_MESH
10371024 typedef struct srfBspSurface_s
12831270 vec3_t lightGridInverseSize;
12841271 int lightGridBounds[3];
12851272 byte *lightGridData;
1286 float *hdrLightGrid;
1273 uint16_t *lightGrid16;
12871274
12881275 int numClusters;
12891276 int clusterBytes;
13191306 typedef struct
13201307 {
13211308 vec3_t xyz;
1322 vec3_t normal;
1323 #ifdef USE_VERT_TANGENT_SPACE
1324 vec3_t tangent;
1325 vec3_t bitangent;
1326 #endif
1309 int16_t normal[4];
1310 int16_t tangent[4];
13271311 } mdvVertex_t;
13281312
13291313 typedef struct
14981482
14991483 // the renderer front end should never modify glstate_t
15001484 typedef struct {
1501 int currenttextures[NUM_TEXTURE_BUNDLES];
1502 int currenttmu;
15031485 qboolean finishCalled;
15041486 int texEnv[2];
15051487 int faceCulling;
15091491 float vertexAttribsInterpolation;
15101492 qboolean vertexAnimation;
15111493 uint32_t vertexAttribsEnabled; // global if no VAOs, tess only otherwise
1512 shaderProgram_t *currentProgram;
15131494 FBO_t *currentFBO;
15141495 vao_t *currentVao;
15151496 mat4_t modelview;
15321513 // We can't change glConfig_t without breaking DLL/vms compatibility, so
15331514 // store extensions we have here.
15341515 typedef struct {
1516 int openglMajorVersion;
1517 int openglMinorVersion;
1518
15351519 qboolean drawRangeElements;
15361520 qboolean multiDrawArrays;
15371521 qboolean occlusionQuery;
15451529 int maxRenderbufferSize;
15461530 int maxColorAttachments;
15471531
1548 qboolean textureNonPowerOfTwo;
15491532 qboolean textureFloat;
1550 qboolean halfFloatPixel;
1551 qboolean packedDepthStencil;
1552 qboolean arbTextureCompression;
15531533 textureCompressionRef_t textureCompression;
15541534 qboolean swizzleNormalmap;
15551535
15591539 qboolean depthClamp;
15601540 qboolean seamlessCubeMap;
15611541
1562 GLenum packedNormalDataType;
1563 GLenum packedTexcoordDataType;
1564 GLenum packedColorDataType;
1565 int packedTexcoordDataSize;
1566 int packedColorDataSize;
1567
1568 qboolean floatLightmap;
15691542 qboolean vertexArrayObject;
1543 qboolean directStateAccess;
15701544 } glRefConfig_t;
15711545
15721546 typedef struct {
16671641 image_t *sunRaysImage;
16681642 image_t *renderDepthImage;
16691643 image_t *pshadowMaps[MAX_DRAWN_PSHADOWS];
1644 image_t *screenScratchImage;
16701645 image_t *textureScratchImage[2];
16711646 image_t *quarterImage[2];
16721647 image_t *calcLevelsImage;
16851660 FBO_t *sunRaysFbo;
16861661 FBO_t *depthFbo;
16871662 FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS];
1663 FBO_t *screenScratchFbo;
16881664 FBO_t *textureScratchFbo[2];
16891665 FBO_t *quarterFbo[2];
16901666 FBO_t *calcLevelsFbo;
17121688 image_t **lightmaps;
17131689 image_t **deluxemaps;
17141690
1715 int fatLightmapSize;
1716 int fatLightmapStep;
1691 int fatLightmapCols;
1692 int fatLightmapRows;
17171693
17181694 int numCubemaps;
17191695 cubemap_t *cubemaps;
17401716 shaderProgram_t calclevels4xShader[2];
17411717 shaderProgram_t shadowmaskShader;
17421718 shaderProgram_t ssaoShader;
1743 shaderProgram_t depthBlurShader[2];
1719 shaderProgram_t depthBlurShader[4];
17441720 shaderProgram_t testcubeShader;
17451721
17461722
17581734
17591735 int viewCluster;
17601736
1761 float mapLightScale;
17621737 float sunShadowScale;
17631738
17641739 qboolean sunShadows;
19191894 extern cvar_t *r_ext_multi_draw_arrays;
19201895 extern cvar_t *r_ext_framebuffer_object;
19211896 extern cvar_t *r_ext_texture_float;
1922 extern cvar_t *r_arb_half_float_pixel;
1923 extern cvar_t *r_arb_half_float_vertex;
19241897 extern cvar_t *r_ext_framebuffer_multisample;
19251898 extern cvar_t *r_arb_seamless_cube_map;
1926 extern cvar_t *r_arb_vertex_type_2_10_10_10_rev;
19271899 extern cvar_t *r_arb_vertex_array_object;
1900 extern cvar_t *r_ext_direct_state_access;
19281901
19291902 extern cvar_t *r_waterFogColor; //----(SA) added
19301903 extern cvar_t *r_mapFogColor; //----(SA) added
19491922
19501923 extern cvar_t *r_fullbright; // avoid lightmap pass
19511924 extern cvar_t *r_lightmap; // render lightmaps only
1952 extern cvar_t *r_cgenVertexLit; // Use CGEN_VERTEX_LIT and CGEN_EXACT_VERTEX_LIT instead of CGEN_VERTEX and CGEN_EXACT_VERTEX
19531925 extern cvar_t *r_vertexLight; // vertex lighting mode for better performance
19541926 extern cvar_t *r_uiFullScreen; // ui is running fullscreen
19551927
19981970
19991971 extern cvar_t *r_cameraExposure;
20001972
2001 extern cvar_t *r_materialGamma;
2002 extern cvar_t *r_lightGamma;
2003 extern cvar_t *r_framebufferGamma;
2004 extern cvar_t *r_tonemapGamma;
2005
20061973 extern cvar_t *r_depthPrepass;
20071974 extern cvar_t *r_ssao;
20081975
20111978 extern cvar_t *r_deluxeMapping;
20121979 extern cvar_t *r_parallaxMapping;
20131980 extern cvar_t *r_cubeMapping;
2014 extern cvar_t *r_specularIsMetallic;
2015 extern cvar_t *r_glossIsRoughness;
1981 extern cvar_t *r_cubemapSize;
1982 extern cvar_t *r_pbr;
20161983 extern cvar_t *r_baseNormalX;
20171984 extern cvar_t *r_baseNormalY;
20181985 extern cvar_t *r_baseParallax;
20191986 extern cvar_t *r_baseSpecular;
20201987 extern cvar_t *r_baseGloss;
1988 extern cvar_t *r_glossType;
20211989 extern cvar_t *r_dlightMode;
20221990 extern cvar_t *r_pshadowDist;
20231991 extern cvar_t *r_mergeLightmaps;
20261994 extern cvar_t *r_imageUpsampleType;
20271995 extern cvar_t *r_genNormalMaps;
20281996 extern cvar_t *r_forceSun;
2029 extern cvar_t *r_forceSunMapLightScale;
20301997 extern cvar_t *r_forceSunLightScale;
20311998 extern cvar_t *r_forceSunAmbientScale;
20321999 extern cvar_t *r_sunlightMode;
20332000 extern cvar_t *r_drawSunRays;
20342001 extern cvar_t *r_sunShadows;
20352002 extern cvar_t *r_shadowFilter;
2003 extern cvar_t *r_shadowBlur;
20362004 extern cvar_t *r_shadowMapSize;
20372005 extern cvar_t *r_shadowCascadeZNear;
20382006 extern cvar_t *r_shadowCascadeZFar;
20992067
21002068 void R_CalcTexDirs(vec3_t sdir, vec3_t tdir, const vec3_t v1, const vec3_t v2,
21012069 const vec3_t v3, const vec2_t w1, const vec2_t w2, const vec2_t w3);
2102 void R_CalcTbnFromNormalAndTexDirs(vec3_t tangent, vec3_t bitangent, vec3_t normal, vec3_t sdir, vec3_t tdir);
2070 vec_t R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, const vec3_t normal, const vec3_t sdir, const vec3_t tdir);
21032071 qboolean R_CalcTangentVectors(srfVert_t * dv[3]);
21042072
21052073 #define CULL_IN 0 // completely unclipped
21192087 /*
21202088 ** GL wrapper/helper functions
21212089 */
2122 void GL_Bind( image_t *image );
21232090 void GL_BindToTMU( image_t *image, int tmu );
21242091 void GL_SetDefaultState( void );
2125 void GL_SelectTexture( int unit );
21262092 void GL_TextureMode( const char *string );
21272093 void GL_CheckErrs( char *file, int line );
21282094 #define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__)
21292095 void GL_State( unsigned long stateVector );
21302096 void GL_SetProjectionMatrix(mat4_t matrix);
21312097 void GL_SetModelviewMatrix(mat4_t matrix);
2132 void GL_TexEnv( int env );
21332098 void GL_Cull( int cullType );
21342099
21352100 #define GLS_SRCBLEND_ZERO 0x00000001
21972162 //----(SA) added (didn't want to modify all instances of R_CreateImage()
21982163 image_t *R_CreateImageExt( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat, qboolean characterMip );
21992164 //----(SA) end
2200 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height );
2165 void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height, GLenum picFormat );
22012166 qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
22022167
22032168 void R_SetColorMappings( void );
22802245 {
22812246 glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16);
22822247 vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16);
2283 uint32_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
2284 #ifdef USE_VERT_TANGENT_SPACE
2285 uint32_t tangent[SHADER_MAX_VERTEXES] QALIGN(16);
2286 #endif
2248 int16_t normal[SHADER_MAX_VERTEXES][4] QALIGN(16);
2249 int16_t tangent[SHADER_MAX_VERTEXES][4] QALIGN(16);
22872250 vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16);
2288 vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16);
2289 uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);
2251 uint16_t color[SHADER_MAX_VERTEXES][4] QALIGN(16);
2252 int16_t lightdir[SHADER_MAX_VERTEXES][4] QALIGN(16);
22902253 //int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16);
22912254
22922255 void *attribPointers[ATTR_INDEX_COUNT];
24262389
24272390 #define PATCH_STITCHING
24282391
2429 srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
2392 void R_SubdividePatchToGrid( srfBspSurface_t *grid, int width, int height,
24302393 srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] );
2431 srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror );
2432 srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror );
2433 void R_FreeSurfaceGridMesh( srfBspSurface_t *grid );
2394 void R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror );
2395 void R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror );
24342396
24352397 /*
24362398 ============================================================
24512413 ============================================================
24522414 */
24532415
2454 int R_VaoPackTangent(byte *out, vec4_t v);
2455 int R_VaoPackNormal(byte *out, vec3_t v);
2456 int R_VaoPackTexCoord(byte *out, vec2_t st);
2457 int R_VaoPackColors(byte *out, vec4_t color);
2458 void R_VaoUnpackTangent(vec4_t v, uint32_t b);
2459 void R_VaoUnpackNormal(vec3_t v, uint32_t b);
2416 void R_VaoPackTangent(int16_t *out, vec4_t v);
2417 void R_VaoPackNormal(int16_t *out, vec3_t v);
2418 void R_VaoPackColor(uint16_t *out, vec4_t c);
2419 void R_VaoUnpackTangent(vec4_t v, int16_t *pack);
2420 void R_VaoUnpackNormal(vec3_t v, int16_t *pack);
24602421
24612422 vao_t *R_CreateVao(const char *name, byte *vertexes, int vertexesSize, byte *indexes, int indexesSize, vaoUsage_t usage);
24622423 vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int numIndexes, glIndex_t *inIndexes);
24852446 void GLSL_ShutdownGPUShaders(void);
24862447 void GLSL_VertexAttribPointers(uint32_t attribBits);
24872448 void GLSL_BindProgram(shaderProgram_t * program);
2488 void GLSL_BindNullProgram(void);
24892449
24902450 void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value);
24912451 void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value);
27212681 viewParms_t viewParms;
27222682 } postProcessCommand_t;
27232683
2684 typedef struct {
2685 int commandId;
2686 } exportCubemapsCommand_t;
2687
27242688 typedef enum {
27252689 RC_END_OF_LIST,
27262690 RC_SET_COLOR,
27342698 RC_COLORMASK,
27352699 RC_CLEARDEPTH,
27362700 RC_CAPSHADOWMAP,
2737 RC_POSTPROCESS
2701 RC_POSTPROCESS,
2702 RC_EXPORT_CUBEMAPS
27382703 } renderCommand_t;
27392704
27402705
28292794 // done.
28302795 //------------------------------------------------------------------------------
28312796
2832 void R_LatLongToNormal( vec3_t outNormal, short latLong );
2833
28342797
28352798 /*
28362799 ============================================================
28442807 extern glfog_t glfogsettings[NUM_FOGS]; // [0] never used (FOG_NONE)
28452808 extern glfogType_t glfogNum; // fog type to use (from the fog_t enum list)
28462809
2847 extern qboolean fogIsOn;
2848
2849 extern void R_FogOff( void );
2850 extern void R_FogOn( void );
2851
28522810 extern void R_SetFog( int fogvar, int var1, int var2, float r, float g, float b, float density );
28532811
28542812 extern int skyboxportal;
5757 // fog stuff
5858 glfog_t glfogsettings[NUM_FOGS];
5959 glfogType_t glfogNum = FOG_NONE;
60 qboolean fogIsOn = qfalse;
61
62
63 /*
64 =================
65 R_Fog (void)
66 =================
67 */
68 void R_Fog( glfog_t *curfog ) {
69
70 if ( !r_wolffog->integer ) {
71 R_FogOff();
72 return;
73 }
74
75 if ( !curfog->registered ) { //----(SA)
76 R_FogOff();
77 return;
78 }
79
80 //----(SA) assme values of '0' for these parameters means 'use default'
81 if ( !curfog->density ) {
82 curfog->density = 1;
83 }
84 if ( !curfog->hint ) {
85 curfog->hint = GL_DONT_CARE;
86 }
87 if ( !curfog->mode ) {
88 curfog->mode = GL_LINEAR;
89 }
90 //----(SA) end
91
92
93 R_FogOn();
94 }
95
96 // Ridah, allow disabling fog temporarily
97 void R_FogOff( void ) {
98 if ( !fogIsOn ) {
99 return;
100 }
101 //qglDisable( GL_FOG );
102 fogIsOn = qfalse;
103 }
104
105 void R_FogOn( void ) {
106 if ( fogIsOn ) {
107 return;
108 }
109
110 // if(r_uiFullScreen->integer) { // don't fog in the menu
111 // R_FogOff();
112 // return;
113 // }
114
115 if ( backEnd.projection2D ) { // no fog in 2d
116 R_FogOff();
117 return;
118 }
119
120 if ( !r_wolffog->integer ) {
121 return;
122 }
123
124 // if(backEnd.viewParms.isGLFogged) {
125 // if(!(backEnd.viewParms.glFog.registered))
126 // return;
127 // }
128
129 if ( backEnd.refdef.rdflags & RDF_SKYBOXPORTAL ) { // don't force world fog on portal sky
130 if ( !( glfogsettings[FOG_PORTALVIEW].registered ) ) {
131 return;
132 }
133 } else if ( !glfogNum ) {
134 return;
135 }
136
137 //qglEnable( GL_FOG );
138 fogIsOn = qtrue;
139 }
140 // done.
141
142
14360
14461 //----(SA)
14562 /*
272189 return qtrue;
273190 }
274191
192
275193 /*
276194 =============
277 R_CalcNormalForTriangle
195 R_CalcTexDirs
196
197 Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
278198 =============
279 */
280 void R_CalcNormalForTriangle(vec3_t normal, const vec3_t v0, const vec3_t v1, const vec3_t v2)
281 {
282 vec3_t udir, vdir;
283
284 // compute the face normal based on vertex points
285 VectorSubtract(v2, v0, udir);
286 VectorSubtract(v1, v0, vdir);
287 CrossProduct(udir, vdir, normal);
288
289 VectorNormalize(normal);
290 }
291
292 /*
293 =============
294 R_CalcTangentsForTriangle
295 http://members.rogers.com/deseric/tangentspace.htm
296 =============
297 */
298 void R_CalcTangentsForTriangle(vec3_t tangent, vec3_t bitangent,
299 const vec3_t v0, const vec3_t v1, const vec3_t v2,
300 const vec2_t t0, const vec2_t t1, const vec2_t t2)
301 {
302 int i;
303 vec3_t planes[3];
304 vec3_t u, v;
305
306 for(i = 0; i < 3; i++)
307 {
308 VectorSet(u, v1[i] - v0[i], t1[0] - t0[0], t1[1] - t0[1]);
309 VectorSet(v, v2[i] - v0[i], t2[0] - t0[0], t2[1] - t0[1]);
310
311 VectorNormalize(u);
312 VectorNormalize(v);
313
314 CrossProduct(u, v, planes[i]);
315 }
316
317 //So your tangent space will be defined by this :
318 //Normal = Normal of the triangle or Tangent X Bitangent (careful with the cross product,
319 // you have to make sure the normal points in the right direction)
320 //Tangent = ( dp(Fx(s,t)) / ds, dp(Fy(s,t)) / ds, dp(Fz(s,t)) / ds ) or ( -Bx/Ax, -By/Ay, - Bz/Az )
321 //Bitangent = ( dp(Fx(s,t)) / dt, dp(Fy(s,t)) / dt, dp(Fz(s,t)) / dt ) or ( -Cx/Ax, -Cy/Ay, -Cz/Az )
322
323 // tangent...
324 tangent[0] = -planes[0][1] / planes[0][0];
325 tangent[1] = -planes[1][1] / planes[1][0];
326 tangent[2] = -planes[2][1] / planes[2][0];
327 VectorNormalize(tangent);
328
329 // bitangent...
330 bitangent[0] = -planes[0][2] / planes[0][0];
331 bitangent[1] = -planes[1][2] / planes[1][0];
332 bitangent[2] = -planes[2][2] / planes[2][0];
333 VectorNormalize(bitangent);
334 }
335
336
337
338
339 /*
340 =============
341 R_CalcTangentSpace
342 =============
343 */
344 void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal,
345 const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2)
346 {
347 vec3_t cp, u, v;
348 vec3_t faceNormal;
349
350 VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]);
351 VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]);
352
353 CrossProduct(u, v, cp);
354 if(fabs(cp[0]) > 10e-6)
355 {
356 tangent[0] = -cp[1] / cp[0];
357 bitangent[0] = -cp[2] / cp[0];
358 }
359
360 u[0] = v1[1] - v0[1];
361 v[0] = v2[1] - v0[1];
362
363 CrossProduct(u, v, cp);
364 if(fabs(cp[0]) > 10e-6)
365 {
366 tangent[1] = -cp[1] / cp[0];
367 bitangent[1] = -cp[2] / cp[0];
368 }
369
370 u[0] = v1[2] - v0[2];
371 v[0] = v2[2] - v0[2];
372
373 CrossProduct(u, v, cp);
374 if(fabs(cp[0]) > 10e-6)
375 {
376 tangent[2] = -cp[1] / cp[0];
377 bitangent[2] = -cp[2] / cp[0];
378 }
379
380 VectorNormalize(tangent);
381 VectorNormalize(bitangent);
382
383 // compute the face normal based on vertex points
384 if ( normal[0] == 0.0f && normal[1] == 0.0f && normal[2] == 0.0f )
385 {
386 VectorSubtract(v2, v0, u);
387 VectorSubtract(v1, v0, v);
388 CrossProduct(u, v, faceNormal);
389 }
390 else
391 {
392 VectorCopy(normal, faceNormal);
393 }
394
395 VectorNormalize(faceNormal);
396
397 #if 1
398 // Gram-Schmidt orthogonalize
399 //tangent[a] = (t - n * Dot(n, t)).Normalize();
400 VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent);
401 VectorNormalize(tangent);
402
403 // compute the cross product B=NxT
404 //CrossProduct(normal, tangent, bitangent);
405 #else
406 // normal, compute the cross product N=TxB
407 CrossProduct(tangent, bitangent, normal);
408 VectorNormalize(normal);
409
410 if(DotProduct(normal, faceNormal) < 0)
411 {
412 //VectorInverse(normal);
413 //VectorInverse(tangent);
414 //VectorInverse(bitangent);
415
416 // compute the cross product T=BxN
417 CrossProduct(bitangent, faceNormal, tangent);
418
419 // compute the cross product B=NxT
420 //CrossProduct(normal, tangent, bitangent);
421 }
422 #endif
423
424 VectorCopy(faceNormal, normal);
425 }
426
427 void R_CalcTangentSpaceFast(vec3_t tangent, vec3_t bitangent, vec3_t normal,
428 const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2)
429 {
430 vec3_t cp, u, v;
431 vec3_t faceNormal;
432
433 VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]);
434 VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]);
435
436 CrossProduct(u, v, cp);
437 if(fabs(cp[0]) > 10e-6)
438 {
439 tangent[0] = -cp[1] / cp[0];
440 bitangent[0] = -cp[2] / cp[0];
441 }
442
443 u[0] = v1[1] - v0[1];
444 v[0] = v2[1] - v0[1];
445
446 CrossProduct(u, v, cp);
447 if(fabs(cp[0]) > 10e-6)
448 {
449 tangent[1] = -cp[1] / cp[0];
450 bitangent[1] = -cp[2] / cp[0];
451 }
452
453 u[0] = v1[2] - v0[2];
454 v[0] = v2[2] - v0[2];
455
456 CrossProduct(u, v, cp);
457 if(fabs(cp[0]) > 10e-6)
458 {
459 tangent[2] = -cp[1] / cp[0];
460 bitangent[2] = -cp[2] / cp[0];
461 }
462
463 VectorNormalizeFast(tangent);
464 VectorNormalizeFast(bitangent);
465
466 // compute the face normal based on vertex points
467 VectorSubtract(v2, v0, u);
468 VectorSubtract(v1, v0, v);
469 CrossProduct(u, v, faceNormal);
470
471 VectorNormalizeFast(faceNormal);
472
473 #if 0
474 // normal, compute the cross product N=TxB
475 CrossProduct(tangent, bitangent, normal);
476 VectorNormalizeFast(normal);
477
478 if(DotProduct(normal, faceNormal) < 0)
479 {
480 VectorInverse(normal);
481 //VectorInverse(tangent);
482 //VectorInverse(bitangent);
483
484 CrossProduct(normal, tangent, bitangent);
485 }
486
487 VectorCopy(faceNormal, normal);
488 #else
489 // Gram-Schmidt orthogonalize
490 //tangent[a] = (t - n * Dot(n, t)).Normalize();
491 VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent);
492 VectorNormalizeFast(tangent);
493 #endif
494
495 VectorCopy(faceNormal, normal);
496 }
497
498 /*
499 http://www.terathon.com/code/tangent.html
500199 */
501200 void R_CalcTexDirs(vec3_t sdir, vec3_t tdir, const vec3_t v1, const vec3_t v2,
502201 const vec3_t v3, const vec2_t w1, const vec2_t w2, const vec2_t w3)
516215 t1 = w2[1] - w1[1];
517216 t2 = w3[1] - w1[1];
518217
519 r = 1.0f / (s1 * t2 - s2 * t1);
218 r = s1 * t2 - s2 * t1;
219 if (r) r = 1.0f / r;
520220
521221 VectorSet(sdir, (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
522222 VectorSet(tdir, (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
523223 }
524224
525
526 void R_CalcTbnFromNormalAndTexDirs(vec3_t tangent, vec3_t bitangent, vec3_t normal, vec3_t sdir, vec3_t tdir)
225 /*
226 =============
227 R_CalcTangentSpace
228
229 Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
230 =============
231 */
232 vec_t R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, const vec3_t normal, const vec3_t sdir, const vec3_t tdir)
527233 {
528234 vec3_t n_cross_t;
529235 vec_t n_dot_t, handedness;
537243 CrossProduct(normal, sdir, n_cross_t);
538244 handedness = (DotProduct(n_cross_t, tdir) < 0.0f) ? -1.0f : 1.0f;
539245
540 // Calculate bitangent
541 CrossProduct(normal, tangent, bitangent);
542 VectorScale(bitangent, handedness, bitangent);
543 }
544
545 void R_CalcTBN2(vec3_t tangent, vec3_t bitangent, vec3_t normal,
546 const vec3_t v1, const vec3_t v2, const vec3_t v3, const vec2_t t1, const vec2_t t2, const vec2_t t3)
547 {
548 vec3_t v2v1;
549 vec3_t v3v1;
550
551 float c2c1_T;
552 float c2c1_B;
553
554 float c3c1_T;
555 float c3c1_B;
556
557 float denominator;
558 float scale1, scale2;
559
560 vec3_t T, B, N, C;
561
562
563 // Calculate the tangent basis for each vertex of the triangle
564 // UPDATE: In the 3rd edition of the accompanying article, the for-loop located here has
565 // been removed as it was redundant (the entire TBN matrix was calculated three times
566 // instead of just one).
567 //
568 // Please note, that this function relies on the fact that the input geometry are triangles
569 // and the tangent basis for each vertex thus is identical!
570 //
571
572 // Calculate the vectors from the current vertex to the two other vertices in the triangle
573 VectorSubtract(v2, v1, v2v1);
574 VectorSubtract(v3, v1, v3v1);
575
576 // The equation presented in the article states that:
577 // c2c1_T = V2.texcoord.x - V1.texcoord.x
578 // c2c1_B = V2.texcoord.y - V1.texcoord.y
579 // c3c1_T = V3.texcoord.x - V1.texcoord.x
580 // c3c1_B = V3.texcoord.y - V1.texcoord.y
581
582 // Calculate c2c1_T and c2c1_B
583 c2c1_T = t2[0] - t1[0];
584 c2c1_B = t2[1] - t2[1];
585
586 // Calculate c3c1_T and c3c1_B
587 c3c1_T = t3[0] - t1[0];
588 c3c1_B = t3[1] - t1[1];
589
590 denominator = c2c1_T * c3c1_B - c3c1_T * c2c1_B;
591 //if(ROUNDOFF(fDenominator) == 0.0f)
592 if(denominator == 0.0f)
593 {
594 // We won't risk a divide by zero, so set the tangent matrix to the identity matrix
595 VectorSet(tangent, 1, 0, 0);
596 VectorSet(bitangent, 0, 1, 0);
597 VectorSet(normal, 0, 0, 1);
598 }
599 else
600 {
601 // Calculate the reciprocal value once and for all (to achieve speed)
602 scale1 = 1.0f / denominator;
603
604 // T and B are calculated just as the equation in the article states
605 VectorSet(T, (c3c1_B * v2v1[0] - c2c1_B * v3v1[0]) * scale1,
606 (c3c1_B * v2v1[1] - c2c1_B * v3v1[1]) * scale1,
607 (c3c1_B * v2v1[2] - c2c1_B * v3v1[2]) * scale1);
608
609 VectorSet(B, (-c3c1_T * v2v1[0] + c2c1_T * v3v1[0]) * scale1,
610 (-c3c1_T * v2v1[1] + c2c1_T * v3v1[1]) * scale1,
611 (-c3c1_T * v2v1[2] + c2c1_T * v3v1[2]) * scale1);
612
613 // The normal N is calculated as the cross product between T and B
614 CrossProduct(T, B, N);
615
616 #if 0
617 VectorCopy(T, tangent);
618 VectorCopy(B, bitangent);
619 VectorCopy(N, normal);
620 #else
621 // Calculate the reciprocal value once and for all (to achieve speed)
622 scale2 = 1.0f / ((T[0] * B[1] * N[2] - T[2] * B[1] * N[0]) +
623 (B[0] * N[1] * T[2] - B[2] * N[1] * T[0]) +
624 (N[0] * T[1] * B[2] - N[2] * T[1] * B[0]));
625
626 // Calculate the inverse if the TBN matrix using the formula described in the article.
627 // We store the basis vectors directly in the provided TBN matrix: pvTBNMatrix
628 CrossProduct(B, N, C); tangent[0] = C[0] * scale2;
629 CrossProduct(N, T, C); tangent[1] = -C[0] * scale2;
630 CrossProduct(T, B, C); tangent[2] = C[0] * scale2;
631 VectorNormalize(tangent);
632
633 CrossProduct(B, N, C); bitangent[0] = -C[1] * scale2;
634 CrossProduct(N, T, C); bitangent[1] = C[1] * scale2;
635 CrossProduct(T, B, C); bitangent[2] = -C[1] * scale2;
636 VectorNormalize(bitangent);
637
638 CrossProduct(B, N, C); normal[0] = C[2] * scale2;
639 CrossProduct(N, T, C); normal[1] = -C[2] * scale2;
640 CrossProduct(T, B, C); normal[2] = C[2] * scale2;
641 VectorNormalize(normal);
642 #endif
643 }
644 }
645
646
647 #ifdef USE_VERT_TANGENT_SPACE
246 // Calculate orthogonal bitangent, if necessary
247 if (bitangent)
248 CrossProduct(normal, tangent, bitangent);
249
250 return handedness;
251 }
252
253
648254 qboolean R_CalcTangentVectors(srfVert_t * dv[3])
649255 {
650256 int i;
660266 /* do each vertex */
661267 for(i = 0; i < 3; i++)
662268 {
663 vec3_t bitangent, nxt;
269 vec4_t tangent;
270 vec3_t normal, bitangent, nxt;
664271
665272 // calculate s tangent vector
666273 s = dv[i]->st[0] + 10.0f;
669276 bary[1] = ((dv[2]->st[0] - s) * (dv[0]->st[1] - t) - (dv[0]->st[0] - s) * (dv[2]->st[1] - t)) / bb;
670277 bary[2] = ((dv[0]->st[0] - s) * (dv[1]->st[1] - t) - (dv[1]->st[0] - s) * (dv[0]->st[1] - t)) / bb;
671278
672 dv[i]->tangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
673 dv[i]->tangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
674 dv[i]->tangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
675
676 VectorSubtract(dv[i]->tangent, dv[i]->xyz, dv[i]->tangent);
677 VectorNormalize(dv[i]->tangent);
279 tangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
280 tangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
281 tangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
282
283 VectorSubtract(tangent, dv[i]->xyz, tangent);
284 VectorNormalize(tangent);
678285
679286 // calculate t tangent vector
680287 s = dv[i]->st[0];
691298 VectorNormalize(bitangent);
692299
693300 // store bitangent handedness
694 CrossProduct(dv[i]->normal, dv[i]->tangent, nxt);
695 dv[i]->tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f;
301 R_VaoUnpackNormal(normal, dv[i]->normal);
302 CrossProduct(normal, tangent, nxt);
303 tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f;
304
305 R_VaoPackTangent(dv[i]->tangent, tangent);
696306
697307 // debug code
698308 //% Sys_FPrintf( SYS_VRB, "%d S: (%f %f %f) T: (%f %f %f)\n", i,
701311
702312 return qtrue;
703313 }
704 #endif
705314
706315 /*
707316 =================
23431952 return;
23441953 }
23451954
2346 R_FogOff(); // moved this in here to keep from /always/ doing the fog state change
2347
23481955 R_IssuePendingRenderCommands();
23491956
2350 GL_Bind( tr.whiteImage );
1957 GL_BindToTMU(tr.whiteImage, TB_COLORMAP);
23511958 GL_Cull( CT_FRONT_SIDED );
23521959 ri.CM_DrawDebugSurface( R_DebugPolygon );
23531960 }
23972004 R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, numDrawSurfs - firstDrawSurf );
23982005
23992006 // draw main system development information (surface outlines, etc)
2400 R_FogOff();
24012007 R_DebugGraphics();
2402 R_FogOn();
2403
24042008 }
24052009
24062010 void R_RenderDlightCubemaps(const refdef_t *fd)
31852789 {
31862790 refdef_t refdef;
31872791 viewParms_t parms;
3188 float oldColorScale = tr.refdef.colorScale;
31892792
31902793 memset( &refdef, 0, sizeof( refdef ) );
31912794 refdef.rdflags = 0;
32582861
32592862 {
32602863 vec3_t ambient, directed, lightDir;
2864 float scale;
2865
32612866 R_LightForPoint(tr.refdef.vieworg, ambient, directed, lightDir);
3262 tr.refdef.colorScale = 1.0f; //766.0f / (directed[0] + directed[1] + directed[2] + 1.0f);
2867 scale = directed[0] + directed[1] + directed[2] + ambient[0] + ambient[1] + ambient[2] + 1.0f;
2868
32632869 // only print message for first side
3264 if (directed[0] + directed[1] + directed[2] == 0 && cubemapSide == 0)
2870 if (scale < 1.0001f && cubemapSide == 0)
32652871 {
3266 ri.Printf(PRINT_ALL, "cubemap %d (%f, %f, %f) is outside the lightgrid!\n", cubemapIndex, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]);
2872 ri.Printf(PRINT_ALL, "cubemap %d %s (%f, %f, %f) is outside the lightgrid or inside a wall!\n", cubemapIndex, tr.cubemaps[cubemapIndex].name, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]);
32672873 }
32682874 }
32692875
33002906
33012907 R_RenderView(&parms);
33022908
3303 if (subscene)
3304 {
3305 tr.refdef.colorScale = oldColorScale;
3306 }
3307 else
3308 {
2909 if (!subscene)
33092910 RE_EndScene();
3310 }
3311 }
3312
2911 }
2912
372372 // The offset is added in the vertex normal vector direction
373373 // so all triangles will still fit together.
374374 // The 2 unit offset should avoid pretty much all LOD problems.
375 vec3_t fNormal;
375376
376377 numClipPoints = 3;
377378
378379 dv = cv->verts + m * cv->width + n;
379380
380381 VectorCopy( dv[0].xyz, clipPoints[0][0] );
381 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0] );
382 R_VaoUnpackNormal(fNormal, dv[0].normal);
383 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
382384 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
383 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
385 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
386 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
384387 VectorCopy( dv[1].xyz, clipPoints[0][2] );
385 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2] );
388 R_VaoUnpackNormal(fNormal, dv[1].normal);
389 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
386390 // check the normal of this triangle
387391 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
388392 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
402406 }
403407
404408 VectorCopy( dv[1].xyz, clipPoints[0][0] );
405 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0] );
409 R_VaoUnpackNormal(fNormal, dv[1].normal);
410 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
406411 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
407 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
412 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
413 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
408414 VectorCopy( dv[cv->width + 1].xyz, clipPoints[0][2] );
409 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[cv->width + 1].normal, clipPoints[0][2] );
415 R_VaoUnpackNormal(fNormal, dv[cv->width + 1].normal);
416 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
410417 // check the normal of this triangle
411418 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
412419 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
461468 {
462469 for(j = 0; j < 3; j++)
463470 {
471 vec3_t fNormal;
464472 v = surf->verts[tri[j]].xyz;
465 VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]);
473 R_VaoUnpackNormal(fNormal, surf->verts[tri[j]].normal);
474 VectorMA(v, MARKER_OFFSET, fNormal, clipPoints[0][j]);
466475 }
467476
468477 // add the fragments of this face
603612 // The offset is added in the vertex normal vector direction
604613 // so all triangles will still fit together.
605614 // The 2 unit offset should avoid pretty much all LOD problems.
615 vec3_t fNormal;
606616
607617 numClipPoints = 3;
608618
609619 dv = cv->verts + m * cv->width + n;
610620
611621 VectorCopy( dv[0].xyz, clipPoints[0][0] );
612 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0] );
622 R_VaoUnpackNormal(fNormal, dv[0].normal);
623 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
613624 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
614 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
625 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
626 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
615627 VectorCopy( dv[1].xyz, clipPoints[0][2] );
616 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2] );
628 R_VaoUnpackNormal(fNormal, dv[1].normal);
629 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
617630 // check the normal of this triangle
618631 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
619632 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
633646 }
634647
635648 VectorCopy( dv[1].xyz, clipPoints[0][0] );
636 VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0] );
649 R_VaoUnpackNormal(fNormal, dv[1].normal);
650 VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]);
637651 VectorCopy( dv[cv->width].xyz, clipPoints[0][1] );
638 VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] );
652 R_VaoUnpackNormal(fNormal, dv[cv->width].normal);
653 VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]);
639654 VectorCopy( dv[cv->width + 1].xyz, clipPoints[0][2] );
640 VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[cv->width + 1].normal, clipPoints[0][2] );
655 R_VaoUnpackNormal(fNormal, dv[cv->width + 1].normal);
656 VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]);
641657 // check the normal of this triangle
642658 VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 );
643659 VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 );
801817 {
802818 for(j = 0; j < 3; j++)
803819 {
820 vec3_t fNormal;
804821 v = surf->verts[tri[j]].xyz;
805 VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]);
822 R_VaoUnpackNormal(fNormal, surf->verts[tri[j]].normal);
823 VectorMA(v, MARKER_OFFSET, fNormal, clipPoints[0][j]);
806824 }
807825
808826 // add the fragments of this face
823823 {
824824 unsigned lat, lng;
825825 unsigned short normal;
826 vec3_t fNormal;
826827
827828 v->xyz[0] = md3xyz->xyz[0] * MD3_XYZ_SCALE;
828829 v->xyz[1] = md3xyz->xyz[1] * MD3_XYZ_SCALE;
835836 lat *= (FUNCTABLE_SIZE/256);
836837 lng *= (FUNCTABLE_SIZE/256);
837838
838 v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
839 v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
840 v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
839 // decode X as cos( lat ) * sin( long )
840 // decode Y as sin( lat ) * sin( long )
841 // decode Z as cos( long )
842
843 fNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
844 fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
845 fNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
846
847 R_VaoPackNormal(v->normal, fNormal);
841848 }
842849 }
843850
856863 for(k = 0; k < mdcSurf->numVerts; k++, mdcxyzComp++, v++)
857864 {
858865 vec3_t ofsVec;
859 R_MDC_DecodeXyzCompressed( mdcxyzComp->ofsVec, ofsVec, v->normal );
866 vec3_t fNormal;
867
868 R_MDC_DecodeXyzCompressed(mdcxyzComp->ofsVec, ofsVec, fNormal);
860869 VectorAdd( v->xyz, ofsVec, v->xyz );
861870
871 R_VaoPackNormal(v->normal, fNormal);
862872 }
863873 }
864874 }
865875
866 #ifdef USE_VERT_TANGENT_SPACE
867876 // calc tangent spaces
868877 {
878 vec3_t *sdirs = ri.Z_Malloc(sizeof(*sdirs) * surf->numVerts * mdvModel->numFrames);
879 vec3_t *tdirs = ri.Z_Malloc(sizeof(*tdirs) * surf->numVerts * mdvModel->numFrames);
880
869881 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
870882 {
871 VectorClear(v->tangent);
872 VectorClear(v->bitangent);
883 VectorClear(sdirs[j]);
884 VectorClear(tdirs[j]);
873885 }
874886
875887 for(f = 0; f < mdvModel->numFrames; f++)
894906
895907 R_CalcTexDirs(sdir, tdir, v0, v1, v2, t0, t1, t2);
896908
897 VectorAdd(sdir, surf->verts[index0].tangent, surf->verts[index0].tangent);
898 VectorAdd(sdir, surf->verts[index1].tangent, surf->verts[index1].tangent);
899 VectorAdd(sdir, surf->verts[index2].tangent, surf->verts[index2].tangent);
900 VectorAdd(tdir, surf->verts[index0].bitangent, surf->verts[index0].bitangent);
901 VectorAdd(tdir, surf->verts[index1].bitangent, surf->verts[index1].bitangent);
902 VectorAdd(tdir, surf->verts[index2].bitangent, surf->verts[index2].bitangent);
909 VectorAdd(sdir, sdirs[index0], sdirs[index0]);
910 VectorAdd(sdir, sdirs[index1], sdirs[index1]);
911 VectorAdd(sdir, sdirs[index2], sdirs[index2]);
912 VectorAdd(tdir, tdirs[index0], tdirs[index0]);
913 VectorAdd(tdir, tdirs[index1], tdirs[index1]);
914 VectorAdd(tdir, tdirs[index2], tdirs[index2]);
903915 }
904916 }
905917
906918 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
907919 {
908 vec3_t sdir, tdir;
909
910 VectorCopy(v->tangent, sdir);
911 VectorCopy(v->bitangent, tdir);
912
913 VectorNormalize(sdir);
914 VectorNormalize(tdir);
915
916 R_CalcTbnFromNormalAndTexDirs(v->tangent, v->bitangent, v->normal, sdir, tdir);
917 }
918 }
919 #endif
920 vec3_t normal;
921 vec4_t tangent;
922
923 VectorNormalize(sdirs[j]);
924 VectorNormalize(tdirs[j]);
925
926 R_VaoUnpackNormal(normal, v->normal);
927
928 tangent[3] = R_CalcTangentSpace(tangent, NULL, normal, sdirs[j], tdirs[j]);
929
930 R_VaoPackTangent(v->tangent, tangent);
931 }
932
933 ri.Free(sdirs);
934 ri.Free(tdirs);
935 }
920936
921937 // find the next surface
922938 mdcSurf = (mdcSurface_t *) ((byte *) mdcSurf + mdcSurf->ofsEnd);
942958 {
943959 // vertex animation, store texcoords first, then position/normal/tangents
944960 offset_st = 0;
945 offset_xyz = surf->numVerts * glRefConfig.packedTexcoordDataSize;
961 offset_xyz = surf->numVerts * sizeof(vec2_t);
946962 offset_normal = offset_xyz + sizeof(vec3_t);
947 offset_tangent = offset_normal + sizeof(uint32_t);
948 stride_st = glRefConfig.packedTexcoordDataSize;
949 stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
950 #ifdef USE_VERT_TANGENT_SPACE
951 stride_xyz += sizeof(uint32_t);
952 #endif
963 offset_tangent = offset_normal + sizeof(int16_t) * 4;
964 stride_st = sizeof(vec2_t);
965 stride_xyz = sizeof(vec3_t) + sizeof(int16_t) * 4;
966 stride_xyz += sizeof(int16_t) * 4;
953967 stride_normal = stride_tangent = stride_xyz;
954968
955969 dataSize = offset_xyz + surf->numVerts * mdvModel->numFrames * stride_xyz;
959973 // no animation, interleave everything
960974 offset_xyz = 0;
961975 offset_st = offset_xyz + sizeof(vec3_t);
962 offset_normal = offset_st + glRefConfig.packedTexcoordDataSize;
963 offset_tangent = offset_normal + sizeof(uint32_t);
964 #ifdef USE_VERT_TANGENT_SPACE
965 stride_xyz = offset_tangent + sizeof(uint32_t);
966 #else
967 stride_xyz = offset_normal + sizeof(uint32_t);
968 #endif
976 offset_normal = offset_st + sizeof(vec2_t);
977 offset_tangent = offset_normal + sizeof(int16_t) * 4;
978 stride_xyz = offset_tangent + sizeof(int16_t) * 4;
969979 stride_st = stride_normal = stride_tangent = stride_xyz;
970980
971981 dataSize = surf->numVerts * stride_xyz;
979989 {
980990 st = surf->st;
981991 for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
982 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
992 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
993 dataOfs += sizeof(st->st);
983994 }
984995
985996 v = surf->verts;
986997 for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ )
987998 {
988 #ifdef USE_VERT_TANGENT_SPACE
989 vec3_t nxt;
990 vec4_t tangent;
991 #endif
992999 // xyz
9931000 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
9941001 dataOfs += sizeof(vec3_t);
9951002
9961003 // normal
997 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
998
999 #ifdef USE_VERT_TANGENT_SPACE
1000 CrossProduct(v->normal, v->tangent, nxt);
1001 VectorCopy(v->tangent, tangent);
1002 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1004 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1005 dataOfs += sizeof(int16_t) * 4;
10031006
10041007 // tangent
1005 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1006 #endif
1008 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1009 dataOfs += sizeof(int16_t) * 4;
10071010 }
10081011 }
10091012 else
10121015 st = surf->st;
10131016 for ( j = 0; j < surf->numVerts; j++, v++, st++ )
10141017 {
1015 #ifdef USE_VERT_TANGENT_SPACE
1016 vec3_t nxt;
1017 vec4_t tangent;
1018 #endif
10191018 // xyz
10201019 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
10211020 dataOfs += sizeof(v->xyz);
10221021
10231022 // st
1024 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
1023 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
1024 dataOfs += sizeof(st->st);
10251025
10261026 // normal
1027 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
1028
1029 #ifdef USE_VERT_TANGENT_SPACE
1030 CrossProduct(v->normal, v->tangent, nxt);
1031 VectorCopy(v->tangent, tangent);
1032 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1027 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1028 dataOfs += sizeof(int16_t) * 4;
10331029
10341030 // tangent
1035 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1036 #endif
1031 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1032 dataOfs += sizeof(int16_t) * 4;
10371033 }
10381034 }
10391035
10511047 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
10521048 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
10531049 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
1054 #ifdef USE_VERT_TANGENT_SPACE
10551050 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
1056 #endif
10571051 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
10581052 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
10591053 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].count = 4;
10601054 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
10611055
10621056 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = GL_FLOAT;
1063 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = glRefConfig.packedTexcoordDataType;
1064 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
1065 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
1057 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = GL_FLOAT;
1058 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
1059 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
10661060
10671061 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = GL_FALSE;
10681062 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = GL_FALSE;
13281322 {
13291323 unsigned lat, lng;
13301324 unsigned short normal;
1325 vec3_t fNormal;
13311326
13321327 v->xyz[0] = LittleShort(md3xyz->xyz[0]) * MD3_XYZ_SCALE;
13331328 v->xyz[1] = LittleShort(md3xyz->xyz[1]) * MD3_XYZ_SCALE;
13401335 lat *= (FUNCTABLE_SIZE/256);
13411336 lng *= (FUNCTABLE_SIZE/256);
13421337
1343
1344
1345 v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1346 v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1347 v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1338 // decode X as cos( lat ) * sin( long )
1339 // decode Y as sin( lat ) * sin( long )
1340 // decode Z as cos( long )
1341
1342 fNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1343 fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1344 fNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1345
1346 R_VaoPackNormal(v->normal, fNormal);
13481347 }
13491348
13501349 // swap all the ST
13571356 st->st[1] = LittleFloat(md3st->st[1]);
13581357 }
13591358
1360 #ifdef USE_VERT_TANGENT_SPACE
13611359 // calc tangent spaces
13621360 {
1361 vec3_t *sdirs = ri.Z_Malloc(sizeof(*sdirs) * surf->numVerts * mdvModel->numFrames);
1362 vec3_t *tdirs = ri.Z_Malloc(sizeof(*tdirs) * surf->numVerts * mdvModel->numFrames);
1363
13631364 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
13641365 {
1365 VectorClear(v->tangent);
1366 VectorClear(v->bitangent);
1366 VectorClear(sdirs[j]);
1367 VectorClear(tdirs[j]);
13671368 }
13681369
13691370 for(f = 0; f < mdvModel->numFrames; f++)
13881389
13891390 R_CalcTexDirs(sdir, tdir, v0, v1, v2, t0, t1, t2);
13901391
1391 VectorAdd(sdir, surf->verts[index0].tangent, surf->verts[index0].tangent);
1392 VectorAdd(sdir, surf->verts[index1].tangent, surf->verts[index1].tangent);
1393 VectorAdd(sdir, surf->verts[index2].tangent, surf->verts[index2].tangent);
1394 VectorAdd(tdir, surf->verts[index0].bitangent, surf->verts[index0].bitangent);
1395 VectorAdd(tdir, surf->verts[index1].bitangent, surf->verts[index1].bitangent);
1396 VectorAdd(tdir, surf->verts[index2].bitangent, surf->verts[index2].bitangent);
1392 VectorAdd(sdir, sdirs[index0], sdirs[index0]);
1393 VectorAdd(sdir, sdirs[index1], sdirs[index1]);
1394 VectorAdd(sdir, sdirs[index2], sdirs[index2]);
1395 VectorAdd(tdir, tdirs[index0], tdirs[index0]);
1396 VectorAdd(tdir, tdirs[index1], tdirs[index1]);
1397 VectorAdd(tdir, tdirs[index2], tdirs[index2]);
13971398 }
13981399 }
13991400
14001401 for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
14011402 {
1402 vec3_t sdir, tdir;
1403
1404 VectorCopy(v->tangent, sdir);
1405 VectorCopy(v->bitangent, tdir);
1406
1407 VectorNormalize(sdir);
1408 VectorNormalize(tdir);
1409
1410 R_CalcTbnFromNormalAndTexDirs(v->tangent, v->bitangent, v->normal, sdir, tdir);
1411 }
1412 }
1413 #endif
1403 vec3_t normal;
1404 vec4_t tangent;
1405
1406 VectorNormalize(sdirs[j]);
1407 VectorNormalize(tdirs[j]);
1408
1409 R_VaoUnpackNormal(normal, v->normal);
1410
1411 tangent[3] = R_CalcTangentSpace(tangent, NULL, normal, sdirs[j], tdirs[j]);
1412
1413 R_VaoPackTangent(v->tangent, tangent);
1414 }
1415
1416 ri.Free(sdirs);
1417 ri.Free(tdirs);
1418 }
14141419
14151420 // find the next surface
14161421 md3Surf = (md3Surface_t *) ((byte *) md3Surf + md3Surf->ofsEnd);
14361441 {
14371442 // vertex animation, store texcoords first, then position/normal/tangents
14381443 offset_st = 0;
1439 offset_xyz = surf->numVerts * glRefConfig.packedTexcoordDataSize;
1444 offset_xyz = surf->numVerts * sizeof(vec2_t);
14401445 offset_normal = offset_xyz + sizeof(vec3_t);
1441 offset_tangent = offset_normal + sizeof(uint32_t);
1442 stride_st = glRefConfig.packedTexcoordDataSize;
1443 stride_xyz = sizeof(vec3_t) + sizeof(uint32_t);
1444 #ifdef USE_VERT_TANGENT_SPACE
1445 stride_xyz += sizeof(uint32_t);
1446 #endif
1446 offset_tangent = offset_normal + sizeof(int16_t) * 4;
1447 stride_st = sizeof(vec2_t);
1448 stride_xyz = sizeof(vec3_t) + sizeof(int16_t) * 4;
1449 stride_xyz += sizeof(int16_t) * 4;
14471450 stride_normal = stride_tangent = stride_xyz;
14481451
14491452 dataSize = offset_xyz + surf->numVerts * mdvModel->numFrames * stride_xyz;
14531456 // no animation, interleave everything
14541457 offset_xyz = 0;
14551458 offset_st = offset_xyz + sizeof(vec3_t);
1456 offset_normal = offset_st + glRefConfig.packedTexcoordDataSize;
1457 offset_tangent = offset_normal + sizeof(uint32_t);
1458 #ifdef USE_VERT_TANGENT_SPACE
1459 stride_xyz = offset_tangent + sizeof(uint32_t);
1460 #else
1461 stride_xyz = offset_normal + sizeof(uint32_t);
1462 #endif
1459 offset_normal = offset_st + sizeof(vec2_t);
1460 offset_tangent = offset_normal + sizeof(int16_t) * 4;
1461 stride_xyz = offset_tangent + sizeof(int16_t) * 4;
14631462 stride_st = stride_normal = stride_tangent = stride_xyz;
14641463
14651464 dataSize = surf->numVerts * stride_xyz;
14731472 {
14741473 st = surf->st;
14751474 for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
1476 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
1475 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
1476 dataOfs += sizeof(st->st);
14771477 }
14781478
14791479 v = surf->verts;
14801480 for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ )
14811481 {
1482 #ifdef USE_VERT_TANGENT_SPACE
1483 vec3_t nxt;
1484 vec4_t tangent;
1485 #endif
14861482 // xyz
14871483 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
14881484 dataOfs += sizeof(vec3_t);
14891485
14901486 // normal
1491 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
1492
1493 #ifdef USE_VERT_TANGENT_SPACE
1494 CrossProduct(v->normal, v->tangent, nxt);
1495 VectorCopy(v->tangent, tangent);
1496 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1487 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1488 dataOfs += sizeof(int16_t) * 4;
14971489
14981490 // tangent
1499 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1500 #endif
1491 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1492 dataOfs += sizeof(int16_t) * 4;
15011493 }
15021494 }
15031495 else
15061498 st = surf->st;
15071499 for ( j = 0; j < surf->numVerts; j++, v++, st++ )
15081500 {
1509 #ifdef USE_VERT_TANGENT_SPACE
1510 vec3_t nxt;
1511 vec4_t tangent;
1512 #endif
15131501 // xyz
15141502 memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t));
15151503 dataOfs += sizeof(v->xyz);
15161504
15171505 // st
1518 dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st);
1506 memcpy(data + dataOfs, &st->st, sizeof(vec2_t));
1507 dataOfs += sizeof(st->st);
15191508
15201509 // normal
1521 dataOfs += R_VaoPackNormal(data + dataOfs, v->normal);
1522
1523 #ifdef USE_VERT_TANGENT_SPACE
1524 CrossProduct(v->normal, v->tangent, nxt);
1525 VectorCopy(v->tangent, tangent);
1526 tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
1510 memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4);
1511 dataOfs += sizeof(int16_t) * 4;
15271512
15281513 // tangent
1529 dataOfs += R_VaoPackTangent(data + dataOfs, tangent);
1530 #endif
1514 memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4);
1515 dataOfs += sizeof(int16_t) * 4;
15311516 }
15321517 }
15331518
15451530 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].enabled = 1;
15461531 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].enabled = 1;
15471532 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
1548 #ifdef USE_VERT_TANGENT_SPACE
15491533 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
1550 #endif
15511534 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].count = 3;
15521535 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].count = 2;
15531536 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].count = 4;
15541537 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].count = 4;
15551538
15561539 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = GL_FLOAT;
1557 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = glRefConfig.packedTexcoordDataType;
1558 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
1559 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
1540 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = GL_FLOAT;
1541 vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
1542 vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
15601543
15611544 vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = GL_FALSE;
15621545 vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = GL_FALSE;
20412024 LL( surf->ofsEnd );
20422025 }
20432026
2027 // change to surface identifier
2028 surf->ident = SF_MDS;
2029
20442030 if ( surf->numVerts >= SHADER_MAX_VERTEXES ) {
20452031 ri.Printf(PRINT_WARNING, "R_LoadMDS: %s has more than %i verts on %s (%i).\n",
20462032 mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
10231023 int i;
10241024
10251025 vec4_t *outXYZ;
1026 uint32_t *outNormal;
1027 #ifdef USE_VERT_TANGENT_SPACE
1028 uint32_t *outTangent;
1029 #endif
1026 int16_t *outNormal;
1027 int16_t *outTangent;
10301028 vec2_t (*outTexCoord)[2];
1031 vec4_t *outColor;
1029 uint16_t *outColor;
10321030
10331031 int frame = data->num_frames ? backEnd.currentEntity->e.frame % data->num_frames : 0;
10341032 int oldframe = data->num_frames ? backEnd.currentEntity->e.oldframe % data->num_frames : 0;
10411039 RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
10421040
10431041 outXYZ = &tess.xyz[tess.numVertexes];
1044 outNormal = &tess.normal[tess.numVertexes];
1045 #ifdef USE_VERT_TANGENT_SPACE
1046 outTangent = &tess.tangent[tess.numVertexes];
1047 #endif
1042 outNormal = tess.normal[tess.numVertexes];
1043 outTangent = tess.tangent[tess.numVertexes];
10481044 outTexCoord = &tess.texCoords[tess.numVertexes];
1049 outColor = &tess.vertexColors[tess.numVertexes];
1045 outColor = tess.color[tess.numVertexes];
10501046
10511047 // compute interpolated joint matrices
10521048 if ( data->num_poses > 0 ) {
10551051
10561052 // transform vertexes and fill other data
10571053 for( i = 0; i < surf->num_vertexes;
1058 i++, outXYZ++, outNormal++, outTexCoord++, outColor++ ) {
1054 i++, outXYZ++, outNormal+=4, outTexCoord++, outColor+=4 ) {
10591055 int j, k;
10601056 float vtxMat[12];
10611057 float nrmMat[9];
11291125 normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]);
11301126 normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]);
11311127
1132 R_VaoPackNormal((byte *)outNormal, normal);
1133
1134 #ifdef USE_VERT_TANGENT_SPACE
1128 R_VaoPackNormal(outNormal, normal);
1129
11351130 tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]);
11361131 tangent[1] = DotProduct(&nrmMat[3], &data->tangents[4*vtx]);
11371132 tangent[2] = DotProduct(&nrmMat[6], &data->tangents[4*vtx]);
11381133 tangent[3] = data->tangents[4*vtx+3];
11391134
1140 R_VaoPackTangent((byte *)outTangent++, tangent);
1141 #endif
1142 }
1143
1144 (*outColor)[0] = data->colors[4*vtx+0] / 255.0f;
1145 (*outColor)[1] = data->colors[4*vtx+1] / 255.0f;
1146 (*outColor)[2] = data->colors[4*vtx+2] / 255.0f;
1147 (*outColor)[3] = data->colors[4*vtx+3] / 255.0f;
1135 R_VaoPackTangent(outTangent, tangent);
1136 outTangent+=4;
1137 }
1138
1139 outColor[0] = data->colors[4*vtx+0] * 257;
1140 outColor[1] = data->colors[4*vtx+1] * 257;
1141 outColor[2] = data->colors[4*vtx+2] * 257;
1142 outColor[3] = data->colors[4*vtx+3] * 257;
11481143 }
11491144
11501145 tri = data->triangles + 3 * surf->first_triangle;
182182 FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, 0);
183183 }
184184
185 FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, &tr.textureColorShader, NULL, 0);
185 FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0);
186186 }
187187 #else // higher quality blur, but slower
188188 else if (blur > 1.0f)
216216 FBO_Blit(tr.quarterFbo[0], NULL, blurTexScale, tr.quarterFbo[1], NULL, &tr.bokehShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
217217 }
218218
219 FBO_Blit(tr.quarterFbo[1], NULL, NULL, dst, dstBox, &tr.textureColorShader, NULL, 0);
219 FBO_Blit(tr.quarterFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0);
220220 }
221221 #endif
222222 }
226226 static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretch, float x, float y, float w, float h, float xcenter, float ycenter, float alpha)
227227 {
228228 ivec4_t srcBox, dstBox;
229 int srcWidth, srcHeight;
229230 vec4_t color;
230231 const float inc = 1.f / passes;
231232 const float mul = powf(stretch, inc);
232233 float scale;
233234
234 {
235 vec2_t texScale;
236
237 texScale[0] =
238 texScale[1] = 1.0f;
239
240 alpha *= inc;
241 VectorSet4(color, alpha, alpha, alpha, 1.0f);
242
243 VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height);
244 VectorSet4(dstBox, x, y, w, h);
245 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0);
246
235 alpha *= inc;
236 VectorSet4(color, alpha, alpha, alpha, 1.0f);
237
238 srcWidth = srcFbo ? srcFbo->width : glConfig.vidWidth;
239 srcHeight = srcFbo ? srcFbo->height : glConfig.vidHeight;
240
241 VectorSet4(srcBox, 0, 0, srcWidth, srcHeight);
242
243 VectorSet4(dstBox, x, y, w, h);
244 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0);
245
246 --passes;
247 scale = mul;
248 while (passes > 0)
249 {
250 float iscale = 1.f / scale;
251 float s0 = xcenter * (1.f - iscale);
252 float t0 = (1.0f - ycenter) * (1.f - iscale);
253
254 srcBox[0] = s0 * srcWidth;
255 srcBox[1] = t0 * srcHeight;
256 srcBox[2] = iscale * srcWidth;
257 srcBox[3] = iscale * srcHeight;
258
259 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
260
261 scale *= mul;
247262 --passes;
248 scale = mul;
249 while (passes > 0)
250 {
251 float iscale = 1.f / scale;
252 float s0 = xcenter * (1.f - iscale);
253 float t0 = (1.0f - ycenter) * (1.f - iscale);
254 float s1 = iscale + s0;
255 float t1 = iscale + t0;
256
257 if (srcFbo)
258 {
259 srcBox[0] = s0 * srcFbo->width;
260 srcBox[1] = t0 * srcFbo->height;
261 srcBox[2] = (s1 - s0) * srcFbo->width;
262 srcBox[3] = (t1 - t0) * srcFbo->height;
263 }
264 else
265 {
266 srcBox[0] = s0 * glConfig.vidWidth;
267 srcBox[1] = t0 * glConfig.vidHeight;
268 srcBox[2] = (s1 - s0) * glConfig.vidWidth;
269 srcBox[3] = (t1 - t0) * glConfig.vidHeight;
270 }
271
272 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
273
274 scale *= mul;
275 --passes;
276 }
277263 }
278264 }
279265
295281 for (iter=0 ; ; ++iter)
296282 {
297283 GLint available = 0;
298 qglGetQueryObjectivARB(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
284 qglGetQueryObjectiv(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_AVAILABLE, &available);
299285 if (available)
300286 break;
301287 }
303289 ri.Printf(PRINT_DEVELOPER, "Waited %d iterations\n", iter);
304290 }
305291
306 qglGetQueryObjectuivARB(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_ARB, &sampleCount);
292 qglGetQueryObjectuiv(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT, &sampleCount);
307293 return sampleCount > 0;
308294 }
309295
328314 // From RB_DrawSun()
329315 {
330316 float dist;
331 mat4_t trans, model, mvp;
317 mat4_t trans, model;
332318
333319 Mat4Translation( backEnd.viewParms.or.origin, trans );
334320 Mat4Multiply( backEnd.viewParms.world.modelMatrix, trans, model );
352338 // initialize quarter buffers
353339 {
354340 float mul = 1.f;
355 vec2_t texScale;
356341 ivec4_t rayBox, quarterBox;
357
358 texScale[0] =
359 texScale[1] = 1.0f;
342 int srcWidth = srcFbo ? srcFbo->width : glConfig.vidWidth;
343 int srcHeight = srcFbo ? srcFbo->height : glConfig.vidHeight;
360344
361345 VectorSet4(color, mul, mul, mul, 1);
362346
363 if (srcFbo)
364 {
365 rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcFbo->width;
366 rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcFbo->height;
367 rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcFbo->width;
368 rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcFbo->height;
369 }
370 else
371 {
372 rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / glConfig.vidWidth;
373 rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / glConfig.vidHeight;
374 rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / glConfig.vidWidth;
375 rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / glConfig.vidHeight;
376 }
347 rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcWidth;
348 rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcHeight;
349 rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcWidth;
350 rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcHeight;
377351
378352 quarterBox[0] = 0;
379353 quarterBox[1] = tr.quarterFbo[0]->height;
407381 // add result back on top of the main buffer
408382 {
409383 float mul = 1.f;
410 vec2_t texScale;
411
412 texScale[0] =
413 texScale[1] = 1.0f;
414384
415385 VectorSet4(color, mul, mul, mul, 1);
416386
417 FBO_Blit(tr.quarterFbo[0], NULL, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
387 FBO_Blit(tr.quarterFbo[0], NULL, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
418388 }
419389 }
420390
442412 {
443413 ivec4_t srcBox, dstBox;
444414 vec4_t color;
445 vec2_t texScale;
446
447 texScale[0] =
448 texScale[1] = 1.0f;
449415
450416 VectorSet4(color, weights[0], weights[0], weights[0], 1.0f);
451417 VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height);
452418 VectorSet4(dstBox, 0, 0, dstFbo->width, dstFbo->height);
453 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0 );
419 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0);
454420
455421 VectorSet4(color, weights[1], weights[1], weights[1], 1.0f);
456422 dx = offsets[1] * xmul;
457423 dy = offsets[1] * ymul;
458424 VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height);
459 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
425 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
460426 VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height);
461 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
427 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
462428
463429 VectorSet4(color, weights[2], weights[2], weights[2], 1.0f);
464430 dx = offsets[2] * xmul;
465431 dy = offsets[2] * ymul;
466432 VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height);
467 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
433 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
468434 VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height);
469 FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
435 FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
470436 }
471437 }
472438
491457 {
492458 ivec4_t srcBox, dstBox;
493459 vec4_t color;
494 vec2_t texScale;
495
496 texScale[0] =
497 texScale[1] = 1.0f;
498460
499461 VectorSet4(color, 1, 1, 1, 1);
500462
503465 FBO_FastBlit(tr.quarterFbo[0], NULL, tr.textureScratchFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
504466
505467 // set the alpha channel
506 VectorSet4(srcBox, 0, 0, tr.whiteImage->width, tr.whiteImage->height);
507 VectorSet4(dstBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height);
508468 qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
509 FBO_BlitFromTexture(tr.whiteImage, srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.textureColorShader, color, GLS_DEPTHTEST_DISABLE);
469 FBO_BlitFromTexture(tr.whiteImage, NULL, NULL, tr.textureScratchFbo[0], NULL, NULL, color, GLS_DEPTHTEST_DISABLE);
510470 qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
511471
512472 // blur the tiny buffer horizontally and vertically
517477 VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height);
518478 VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
519479 color[3] = factor;
520 FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
521 }
522 }
480 FBO_Blit(tr.textureScratchFbo[0], srcBox, NULL, NULL, dstBox, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
481 }
482 }
457457
458458 VectorCopy(tr.sunDirection, tr.refdef.sunDir);
459459 if ( (tr.refdef.rdflags & RDF_NOWORLDMODEL) || !(r_depthPrepass->value) ){
460 tr.refdef.colorScale = 1.0f;
461460 VectorSet(tr.refdef.sunCol, 0, 0, 0);
462461 VectorSet(tr.refdef.sunAmbCol, 0, 0, 0);
463462 }
464463 else
465464 {
466 #if defined(USE_OVERBRIGHT)
467 float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8);
468 #else
469465 float scale = (1 << r_mapOverBrightBits->integer) / 255.0f;
470 #endif
471 tr.refdef.colorScale = r_forceSun->integer ? r_forceSunMapLightScale->value : tr.mapLightScale;
472466
473467 if (r_forceSun->integer)
474468 VectorScale(tr.sunLight, scale * r_forceSunLightScale->value, tr.refdef.sunCol);
2727 // tr_shade.c
2828
2929 #include "tr_local.h"
30 #if idppc_altivec && !defined(MACOS_X)
30 #if idppc_altivec && !defined(__APPLE__)
3131 #include <altivec.h>
3232 #endif
3333
4242 void R_DrawElementsVao( int numIndexes, glIndex_t firstIndex, glIndex_t minIndex, glIndex_t maxIndex )
4343 {
4444 if (glRefConfig.drawRangeElements)
45 qglDrawRangeElementsEXT(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
45 qglDrawRangeElements(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
4646 else
4747 qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
4848
5454 {
5555 if (glRefConfig.multiDrawArrays && multiDrawPrimitives > 1)
5656 {
57 qglMultiDrawElementsEXT(GL_TRIANGLES, multiDrawNumIndexes, GL_INDEX_TYPE, (const GLvoid **)multiDrawFirstIndex, multiDrawPrimitives);
57 qglMultiDrawElements(GL_TRIANGLES, multiDrawNumIndexes, GL_INDEX_TYPE, (const GLvoid **)multiDrawFirstIndex, multiDrawPrimitives);
5858 }
5959 else
6060 {
6464 {
6565 for (i = 0; i < multiDrawPrimitives; i++)
6666 {
67 qglDrawRangeElementsEXT(GL_TRIANGLES, multiDrawMinIndex[i], multiDrawMaxIndex[i], multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]);
67 qglDrawRangeElements(GL_TRIANGLES, multiDrawMinIndex[i], multiDrawMaxIndex[i], multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]);
6868 }
6969 }
7070 else
9999 int index;
100100
101101 if ( bundle->isVideoMap ) {
102 int oldtmu = glState.currenttmu;
103 GL_SelectTexture(tmu);
104102 ri.CIN_RunCinematic(bundle->videoMapHandle);
105103 ri.CIN_UploadCinematic(bundle->videoMapHandle);
106 GL_SelectTexture(oldtmu);
104 GL_BindToTMU(tr.scratchImage[bundle->videoMapHandle], tmu);
107105 return;
108106 }
109107
142140 ================
143141 */
144142 static void DrawTris (shaderCommands_t *input) {
145 GL_Bind( tr.whiteImage );
143 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
146144
147145 GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
148146 qglDepthRange( 0, 0 );
442440 vector[3] = scale;
443441 GLSL_SetUniformVec4(sp, UNIFORM_DLIGHTINFO, vector);
444442
445 GL_Bind( tr.dlightImage );
443 GL_BindToTMU( tr.dlightImage, TB_COLORMAP );
446444
447445 // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
448446 // where they aren't rendered
477475 || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR)
478476 || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR);
479477
480 #if defined(USE_OVERBRIGHT)
481 float exactLight = 1.0f;
482 #else
483 qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL);
484 float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer);
485 #endif
478 qboolean is2DDraw = backEnd.currentEntity == &backEnd.entity2D;
479
480 float overbright = (isBlend || is2DDraw) ? 1.0f : (float)(1 << tr.overbrightBits);
481
482 fog_t *fog;
486483
487484 baseColor[0] =
488485 baseColor[1] =
489 baseColor[2] = exactLight;
486 baseColor[2] =
490487 baseColor[3] = 1.0f;
491488
492489 vertColor[0] =
499496 //
500497 switch ( pStage->rgbGen )
501498 {
502 case CGEN_IDENTITY_LIGHTING:
503 baseColor[0] =
504 baseColor[1] =
505 baseColor[2] = tr.identityLight;
506 break;
507499 case CGEN_EXACT_VERTEX:
508500 case CGEN_EXACT_VERTEX_LIT:
509501 baseColor[0] =
513505
514506 vertColor[0] =
515507 vertColor[1] =
516 vertColor[2] = exactLight;
508 vertColor[2] = overbright;
517509 vertColor[3] = 1.0f;
518510 break;
519511 case CGEN_CONST:
523515 baseColor[3] = pStage->constantColor[3] / 255.0f;
524516 break;
525517 case CGEN_VERTEX:
526 baseColor[0] =
518 case CGEN_VERTEX_LIT:
519 baseColor[0] =
527520 baseColor[1] =
528521 baseColor[2] =
529522 baseColor[3] = 0.0f;
530523
531524 vertColor[0] =
532525 vertColor[1] =
533 vertColor[2] = tr.identityLight;
526 vertColor[2] =
534527 vertColor[3] = 1.0f;
535 break;
536 case CGEN_VERTEX_LIT:
537 baseColor[0] =
538 baseColor[1] =
539 baseColor[2] =
540 baseColor[3] = 0.0f;
541
542 vertColor[0] =
543 vertColor[1] =
544 vertColor[2] =
545 vertColor[3] = tr.identityLight;
546528 break;
547529 case CGEN_ONE_MINUS_VERTEX:
548530 baseColor[0] =
549531 baseColor[1] =
550 baseColor[2] = tr.identityLight;
532 baseColor[2] = 1.0f;
551533
552534 vertColor[0] =
553535 vertColor[1] =
554 vertColor[2] = -tr.identityLight;
536 vertColor[2] = -1.0f;
555537 break;
556538 case CGEN_FOG:
557 {
558 fog_t *fog;
559
560 fog = tr.world->fogs + tess.fogNum;
561
562 baseColor[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f;
563 baseColor[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f;
564 baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
565 baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
566 }
539 fog = tr.world->fogs + tess.fogNum;
540
541 baseColor[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f;
542 baseColor[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f;
543 baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
544 baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
567545 break;
568546 case CGEN_WAVEFORM:
569547 baseColor[0] =
590568 break;
591569 case CGEN_IDENTITY:
592570 case CGEN_LIGHTING_DIFFUSE:
571 baseColor[0] =
572 baseColor[1] =
573 baseColor[2] = overbright;
574 break;
575 case CGEN_IDENTITY_LIGHTING:
593576 case CGEN_BAD:
594577 break;
595578 }
646629 baseColor[3] = 1.0f;
647630 vertColor[3] = 0.0f;
648631 break;
649 }
650
651 // multiply color by overbrightbits if this isn't a blend
652 if (tr.overbrightBits && !isBlend)
653 {
654 float scale = 1 << tr.overbrightBits;
655
656 baseColor[0] *= scale;
657 baseColor[1] *= scale;
658 baseColor[2] *= scale;
659 vertColor[0] *= scale;
660 vertColor[1] *= scale;
661 vertColor[2] *= scale;
662632 }
663633
664634 // FIXME: find some way to implement this.
953923 }
954924
955925 if (r_dlightMode->integer >= 2)
956 {
957 GL_SelectTexture(TB_SHADOWMAP);
958 GL_Bind(tr.shadowCubemaps[l]);
959 GL_SelectTexture(0);
960 }
926 GL_BindToTMU(tr.shadowCubemaps[l], TB_SHADOWMAP);
961927
962928 ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
963929 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
10591025 }
10601026 }
10611027
1062 extern qboolean fogIsOn;
10631028
10641029 /*
10651030 ===================
10831048 return;
10841049 }
10851050
1086 if (!fogIsOn)
1087 return;
1088
10891051 if (wolfFog)
10901052 {
1091 // from R_Fog(), altered slightly
10921053 if ( backEnd.projection2D ) {
10931054 return;
10941055 }
12201181 if (vertexAttribs & ATTR_NORMAL)
12211182 {
12221183 vertexAttribs |= ATTR_NORMAL2;
1223 #ifdef USE_VERT_TANGENT_SPACE
12241184 vertexAttribs |= ATTR_TANGENT2;
1225 #endif
12261185 }
12271186 }
12281187
12401199 int deformGen;
12411200 vec5_t deformParams;
12421201
1202 qboolean renderToCubemap = tr.renderCubeFbo && glState.currentFBO == tr.renderCubeFbo;
1203
12431204 ComputeDeformValues(&deformGen, deformParams);
12441205
12451206 for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
13101271 index |= LIGHTDEF_USE_SHADOWMAP;
13111272 }
13121273
1313 if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP)
1314 {
1315 index = LIGHTDEF_USE_LIGHTMAP;
1274 if (r_lightmap->integer && ((index & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHTMAP))
1275 {
1276 index = LIGHTDEF_USE_TCGEN_AND_TCMOD;
13161277 }
13171278
13181279 sp = &pStage->glslShaderGroup[index];
14451406 }
14461407 //----(SA) end
14471408
1448 if ((backEnd.refdef.colorScale != 1.0f) && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL))
1449 {
1450 // use VectorScale to only scale first three values, not alpha
1451 VectorScale(baseColor, backEnd.refdef.colorScale, baseColor);
1452 VectorScale(vertColor, backEnd.refdef.colorScale, vertColor);
1453 }
1454
14551409 GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor);
14561410 GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor);
14571411 }
14591413 if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE)
14601414 {
14611415 vec4_t vec;
1462 vec_t cap = 1.0f / (1 << tr.overbrightBits);
14631416
14641417 VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec);
1465 if ((vec[0] > cap) || (vec[1] > cap) || (vec[2] > cap))
1466 {
1467 vec_t hi = MAX(vec[0], vec[1]);
1468 hi = MAX(hi, vec[2]);
1469
1470 VectorScale(vec, cap / hi, vec);
1471 }
14721418 GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, vec);
14731419
14741420 VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec);
1475 if ((vec[0] > cap) || (vec[1] > cap) || (vec[2] > cap))
1476 {
1477 vec_t hi = MAX(vec[0], vec[1]);
1478 hi = MAX(hi, vec[2]);
1479
1480 VectorScale(vec, cap / hi, vec);
1481 }
14821421 GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, vec);
14831422
14841423 VectorCopy(backEnd.currentEntity->lightDir, vec);
15271466 GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask);
15281467 }
15291468
1530 ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
1531 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
1532 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
1533
1534 GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
1535 if (pStage->bundle[0].tcGen == TCGEN_VECTOR)
1536 {
1537 vec3_t vec;
1538
1539 VectorCopy(pStage->bundle[0].tcGenVectors[0], vec);
1540 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec);
1541 VectorCopy(pStage->bundle[0].tcGenVectors[1], vec);
1542 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec);
1469 if (r_lightmap->integer)
1470 {
1471 vec4_t v;
1472 VectorSet4(v, 1.0f, 0.0f, 0.0f, 1.0f);
1473 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, v);
1474 VectorSet4(v, 0.0f, 0.0f, 0.0f, 0.0f);
1475 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, v);
1476
1477 GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, TCGEN_LIGHTMAP);
1478 }
1479 else
1480 {
1481 ComputeTexMods(pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb);
1482 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
1483 GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
1484
1485 GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
1486 if (pStage->bundle[0].tcGen == TCGEN_VECTOR)
1487 {
1488 vec3_t vec;
1489
1490 VectorCopy(pStage->bundle[0].tcGenVectors[0], vec);
1491 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec);
1492 VectorCopy(pStage->bundle[0].tcGenVectors[1], vec);
1493 GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec);
1494 }
15431495 }
15441496
15451497 GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
15461498
15471499 GLSL_SetUniformVec4(sp, UNIFORM_NORMALSCALE, pStage->normalScale);
1548 GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale);
1500
1501 {
1502 vec4_t specularScale;
1503 Vector4Copy(pStage->specularScale, specularScale);
1504
1505 if (renderToCubemap)
1506 {
1507 // force specular to nonmetal if rendering cubemaps
1508 if (r_pbr->integer)
1509 specularScale[1] = 0.0f;
1510 }
1511
1512 GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, specularScale);
1513 }
15491514
15501515 //GLSL_SetUniformFloat(sp, UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale);
15511516
15551520 if ( backEnd.depthFill )
15561521 {
15571522 if (!(pStage->stateBits & GLS_ATEST_BITS))
1558 GL_BindToTMU( tr.whiteImage, 0 );
1523 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
15591524 else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 )
15601525 R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP );
15611526 }
15661531
15671532 if (r_sunlightMode->integer && (backEnd.viewParms.flags & VPF_USESUNLIGHT) && (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK))
15681533 {
1569 GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
1534 // FIXME: screenShadowImage is NULL if no framebuffers
1535 if (tr.screenShadowImage)
1536 GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
15701537 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol);
1571 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol);
1538 if (r_pbr->integer)
1539 {
1540 vec3_t color;
1541
1542 color[0] = backEnd.refdef.sunCol[0] * backEnd.refdef.sunCol[0];
1543 color[1] = backEnd.refdef.sunCol[1] * backEnd.refdef.sunCol[1];
1544 color[2] = backEnd.refdef.sunCol[2] * backEnd.refdef.sunCol[2];
1545 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, color);
1546 }
1547 else
1548 {
1549 GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol);
1550 }
15721551 GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir);
15731552 }
15741553
15771556 {
15781557 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
15791558 {
1580 if (i == TB_LIGHTMAP)
1559 if (i == TB_COLORMAP)
15811560 R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i);
15821561 else
15831562 GL_BindToTMU( tr.whiteImage, i );
15871566 {
15881567 for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
15891568 {
1590 if (i == TB_LIGHTMAP)
1569 if (i == TB_COLORMAP)
15911570 R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i);
15921571 else
15931572 GL_BindToTMU( tr.whiteImage, i );
16681647 vec4_t vec;
16691648 cubemap_t *cubemap = &tr.cubemaps[input->cubemapIndex - 1];
16701649
1671 GL_BindToTMU( cubemap->image, TB_CUBEMAP);
1650 // FIXME: cubemap image could be NULL if cubemap isn't renderer or loaded
1651 if (cubemap->image)
1652 GL_BindToTMU( cubemap->image, TB_CUBEMAP);
16721653
16731654 VectorSubtract(cubemap->origin, backEnd.viewParms.or.origin, vec);
16741655 vec[3] = 1.0f;
116116 vec3_t offset;
117117 float scale;
118118 float *xyz = ( float * ) tess.xyz;
119 uint32_t *normal = tess.normal;
119 int16_t *normal = tess.normal[0];
120120 float *table;
121121
122122 // Ridah
146146
147147 table = TableForFunc( ds->deformationWave.func );
148148
149 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
149 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
150150 {
151151 float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
152152 float dot;
153153 vec3_t fNormal;
154154
155 R_VaoUnpackNormal(fNormal, *normal);
155 R_VaoUnpackNormal(fNormal, normal);
156156
157157 scale = WAVEVALUE( table, ds->deformationWave.base,
158158 ds->deformationWave.amplitude,
178178 else if ( ds->deformationWave.frequency == 0 ) {
179179 scale = EvalWaveForm( &ds->deformationWave );
180180
181 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
181 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
182182 {
183 R_VaoUnpackNormal(offset, *normal);
183 R_VaoUnpackNormal(offset, normal);
184184
185185 xyz[0] += offset[0] * scale;
186186 xyz[1] += offset[1] * scale;
187187 xyz[2] += offset[2] * scale;
188188 }
189 } else
190 {
189 }
190 else {
191191 table = TableForFunc( ds->deformationWave.func );
192192
193 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
193 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
194194 {
195195 float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
196196
199199 ds->deformationWave.phase + off,
200200 ds->deformationWave.frequency );
201201
202 R_VaoUnpackNormal(offset, *normal);
202 R_VaoUnpackNormal(offset, normal);
203203
204204 xyz[0] += offset[0] * scale;
205205 xyz[1] += offset[1] * scale;
219219 int i;
220220 float scale;
221221 float *xyz = ( float * ) tess.xyz;
222 uint32_t *normal = tess.normal;
223
224 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) {
222 int16_t *normal = tess.normal[0];
223
224 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) {
225225 vec3_t fNormal;
226226
227 R_VaoUnpackNormal(fNormal, *normal);
227 R_VaoUnpackNormal(fNormal, normal);
228228
229229 scale = 0.98f;
230230 scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
243243
244244 VectorNormalizeFast( fNormal );
245245
246 R_VaoPackNormal((byte *)normal, fNormal);
246 R_VaoPackNormal(normal, fNormal);
247247 }
248248 }
249249
257257 int i;
258258 const float *st = ( const float * ) tess.texCoords[0];
259259 float *xyz = ( float * ) tess.xyz;
260 uint32_t *normal = tess.normal;
260 int16_t *normal = tess.normal[0];
261261 float now;
262262
263263 now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
264264
265 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal++ ) {
265 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
266266 int off;
267267 float scale;
268268 vec3_t fNormal;
269269
270 R_VaoUnpackNormal(fNormal, *normal);
270 R_VaoUnpackNormal(fNormal, normal);
271271
272272 off = (float)( FUNCTABLE_SIZE / ( M_PI * 2 ) ) * ( st[0] * ds->bulgeWidth + now );
273273
438438 }
439439
440440 for ( i = 0 ; i < oldVerts ; i += 4 ) {
441 vec4_t color;
441442 // find the midpoint
442443 xyz = tess.xyz[i];
443444
468469 VectorScale( up, axisLength, up );
469470 }
470471
471 RB_AddQuadStamp( mid, left, up, tess.vertexColors[i] );
472 VectorScale4(tess.color[i], 1.0f / 65535.0f, color);
473 RB_AddQuadStamp( mid, left, up, color );
472474 }
473475 }
474476
810812 void RB_CalcFireRiseEnvTexCoords( float *st ) {
811813 int i;
812814 float *v;
813 uint32_t *normal = tess.normal;
815 int16_t *normal = tess.normal[0];
814816 vec3_t fNormal, viewer, reflected;
815817 float d;
816818
821823 {
822824 VectorNormalizeFast( viewer );
823825
824 R_VaoUnpackNormal(fNormal, *normal);
826 R_VaoUnpackNormal(fNormal, normal);
825827
826828 d = DotProduct( fNormal, viewer );
827829
909909 ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name );
910910 continue;
911911 }
912 stage->specularScale[0] =
913 stage->specularScale[1] =
914 stage->specularScale[2] = atof( token );
912
913 if (r_pbr->integer)
914 {
915 // interpret specularReflectance < 0.5 as nonmetal
916 stage->specularScale[1] = (atof(token) < 0.5f) ? 0.0f : 1.0f;
917 }
918 else
919 {
920 stage->specularScale[0] =
921 stage->specularScale[1] =
922 stage->specularScale[2] = atof( token );
923 }
915924 }
916925 //
917926 // specularExponent <value>
929938
930939 exponent = atof( token );
931940
932 if (r_glossIsRoughness->integer)
933 stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25);
941 if (r_pbr->integer)
942 stage->specularScale[0] = 1.0f - powf(2.0f / (exponent + 2.0), 0.25);
934943 else
935944 {
936945 // Change shininess to gloss
955964
956965 gloss = atof(token);
957966
958 if (r_glossIsRoughness->integer)
959 stage->specularScale[3] = exp2f(-3.0f * gloss);
967 if (r_pbr->integer)
968 stage->specularScale[0] = 1.0f - exp2f(-3.0f * gloss);
960969 else
961970 stage->specularScale[3] = gloss;
962971 }
976985
977986 roughness = atof(token);
978987
979 if (r_glossIsRoughness->integer)
980 stage->specularScale[3] = roughness;
988 if (r_pbr->integer)
989 stage->specularScale[0] = 1.0 - roughness;
981990 else
982991 {
983992 if (roughness >= 0.125)
10371046 }
10381047 //
10391048 // specularScale <rgb> <gloss>
1049 // or specularScale <metallic> <smoothness> with r_pbr 1
10401050 // or specularScale <r> <g> <b>
10411051 // or specularScale <r> <g> <b> <gloss>
10421052 //
10631073 token = COM_ParseExt(text, qfalse);
10641074 if ( token[0] == 0 )
10651075 {
1066 // two values, rgb then gloss
1067 stage->specularScale[3] = stage->specularScale[1];
1068 stage->specularScale[1] =
1069 stage->specularScale[2] = stage->specularScale[0];
1076 if (r_pbr->integer)
1077 {
1078 // two values, metallic then smoothness
1079 float smoothness = stage->specularScale[1];
1080 stage->specularScale[1] = (stage->specularScale[0] < 0.5f) ? 0.0f : 1.0f;
1081 stage->specularScale[0] = smoothness;
1082 }
1083 {
1084 // two values, rgb then gloss
1085 stage->specularScale[3] = stage->specularScale[1];
1086 stage->specularScale[1] =
1087 stage->specularScale[2] = stage->specularScale[0];
1088 }
10701089 continue;
10711090 }
10721091
11151134 } else if ( !Q_stricmp( token, "oneMinusEntity" ) ) {
11161135 stage->rgbGen = CGEN_ONE_MINUS_ENTITY;
11171136 } else if ( !Q_stricmp( token, "vertex" ) ) {
1118 if ( r_cgenVertexLit->integer ) {
1119 stage->rgbGen = CGEN_VERTEX_LIT;
1120 } else {
1121 stage->rgbGen = CGEN_VERTEX;
1122 }
1137 stage->rgbGen = CGEN_VERTEX;
11231138 if ( stage->alphaGen == 0 ) {
11241139 stage->alphaGen = AGEN_VERTEX;
11251140 }
11261141 } else if ( !Q_stricmp( token, "exactVertex" ) ) {
1127 if ( r_cgenVertexLit->integer ) {
1128 stage->rgbGen = CGEN_EXACT_VERTEX_LIT;
1129 } else {
1130 stage->rgbGen = CGEN_EXACT_VERTEX;
1131 }
1142 stage->rgbGen = CGEN_EXACT_VERTEX;
11321143 } else if ( !Q_stricmp( token, "vertexLit" ) ) {
11331144 stage->rgbGen = CGEN_VERTEX_LIT;
1134 if ( stage->alphaGen == 0 )
1145 if ( stage->alphaGen == 0 ) {
11351146 stage->alphaGen = AGEN_VERTEX;
1147 }
11361148 } else if ( !Q_stricmp( token, "exactVertexLit" ) ) {
11371149 stage->rgbGen = CGEN_EXACT_VERTEX_LIT;
11381150 } else if ( !Q_stricmp( token, "lightingDiffuse" ) ) {
17741786 if (isGL2Sun)
17751787 {
17761788 token = COM_ParseExt( text, qfalse );
1777 tr.mapLightScale = atof(token);
1778
1789 tr.sunShadowScale = atof(token);
1790
1791 // parse twice, since older shaders may include mapLightScale before sunShadowScale
17791792 token = COM_ParseExt( text, qfalse );
1780 tr.sunShadowScale = atof(token);
1793 if (token[0])
1794 tr.sunShadowScale = atof(token);
17811795 }
17821796
17831797 SkipRestOfLine( text );
21932207 {
21942208 shader.vertexAttribs |= ATTR_NORMAL;
21952209
2196 #ifdef USE_VERT_TANGENT_SPACE
21972210 if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && !(r_normalMapping->integer == 0 && r_specularMapping->integer == 0))
21982211 {
21992212 shader.vertexAttribs |= ATTR_TANGENT;
22002213 }
2201 #endif
22022214
22032215 switch (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK)
22042216 {
23242336 image_t *normalImg;
23252337 imgFlags_t normalFlags = (diffuseImg->flags & ~(IMGFLAG_GENNORMALMAP | IMGFLAG_SRGB)) | IMGFLAG_NOLIGHTSCALE;
23262338
2339 // try a normalheight image first
23272340 COM_StripExtension(diffuseImg->imgName, normalName, MAX_QPATH);
2328 Q_strcat(normalName, MAX_QPATH, "_n");
2329
2330 normalImg = R_FindImageFile(normalName, IMGTYPE_NORMAL, normalFlags);
2341 Q_strcat(normalName, MAX_QPATH, "_nh");
2342
2343 normalImg = R_FindImageFile(normalName, IMGTYPE_NORMALHEIGHT, normalFlags);
2344
2345 if (normalImg)
2346 {
2347 parallax = qtrue;
2348 }
2349 else
2350 {
2351 // try a normal image ("_n" suffix)
2352 normalName[strlen(normalName) - 1] = '\0';
2353 normalImg = R_FindImageFile(normalName, IMGTYPE_NORMAL, normalFlags);
2354 }
23312355
23322356 if (normalImg)
23332357 {
29612985
29622986 // default normal/specular
29632987 VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f);
2964 stages[i].specularScale[0] =
2965 stages[i].specularScale[1] =
2966 stages[i].specularScale[2] = r_baseSpecular->value;
2967 stages[i].specularScale[3] = r_baseGloss->value;
2988 if (r_pbr->integer)
2989 {
2990 stages[i].specularScale[0] = r_baseGloss->value;
2991 }
2992 else
2993 {
2994 stages[i].specularScale[0] =
2995 stages[i].specularScale[1] =
2996 stages[i].specularScale[2] = r_baseSpecular->value;
2997 stages[i].specularScale[3] = r_baseGloss->value;
2998 }
29682999 }
29693000 }
29703001
31173148 //
31183149 // if we are in r_vertexLight mode, never use a lightmap texture
31193150 //
3120 if ( stage > 1 && ( ( r_vertexLight->integer && !r_uiFullScreen->integer ) || glConfig.hardwareType == GLHW_PERMEDIA2 ) ) {
3151 if ( 0 && ( stage > 1 && ( ( r_vertexLight->integer && !r_uiFullScreen->integer ) || glConfig.hardwareType == GLHW_PERMEDIA2 ) ) ) {
31213152 VertexLightingCollapse();
31223153 hasLightmapStage = qfalse;
31233154 }
32063237 pShaderString = pShaderString->next;
32073238 }
32083239 }
3209
32103240 // done.
32113241
32123242 /*
32213251
32223252 if ( token[0] == '{' ) {
32233253 // skip the definition
3224 SkipBracedSection( &p );
3254 SkipBracedSection( &p, 0 );
32253255 } else if ( !Q_stricmp( token, shadername ) ) {
32263256 return p;
32273257 } else {
37483778
37493779 if ( !Q_stricmp( token, "{" ) ) {
37503780 // skip braced section
3751 SkipBracedSection( &p );
3781 SkipBracedSection( &p, 0 );
37523782 continue;
37533783 }
37543784
37913821 char *p;
37923822 int numShaderFiles;
37933823 int i;
3794 char *oldp, *token, *textEnd;
3824 char *token, *textEnd;
3825 char shaderName[MAX_QPATH];
3826 int shaderLine;
37953827
37963828 long sum = 0, summand;
37973829 // scan for shader files
38333865
38343866 // Do a simple check on the shader structure in that file to make sure one bad shader file cannot fuck up all other shaders.
38353867 p = buffers[i];
3868 COM_BeginParseSession(filename);
38363869 while(1)
38373870 {
38383871 token = COM_ParseExt(&p, qtrue);
38393872
38403873 if(!*token)
38413874 break;
3842
3843 oldp = p;
3844
3875
3876 Q_strncpyz(shaderName, token, sizeof(shaderName));
3877 shaderLine = COM_GetCurrentParseLine();
3878
38453879 token = COM_ParseExt(&p, qtrue);
3846 if(token[0] != '{' && token[1] != '\0')
3847 {
3848 ri.Printf(PRINT_WARNING, "WARNING: Bad shader file %s has incorrect syntax.\n", filename);
3880 if( !Q_stricmp( shaderName, token ) ) {
3881 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Invalid shader name \"%s\" on line %d.\n",
3882 filename, shaderName, shaderLine);
3883 break;
3884 }
3885
3886 if(token[0] != '{' || token[1] != '\0')
3887 {
3888 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing opening brace",
3889 filename, shaderName, shaderLine);
3890 if (token[0])
3891 {
3892 ri.Printf(PRINT_WARNING, " (found \"%s\" on line %d)", token, COM_GetCurrentParseLine());
3893 }
3894 ri.Printf(PRINT_WARNING, "...Ignored\n");
38493895 ri.FS_FreeFile(buffers[i]);
38503896 buffers[i] = NULL;
38513897 break;
38523898 }
38533899
3854 SkipBracedSection(&oldp);
3855 p = oldp;
3900 if(!SkipBracedSection(&p, 1))
3901 {
3902 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing closing brace",
3903 filename, shaderName, shaderLine);
3904 if( !Q_stricmp( filename, "common.shader" ) ) { // HACK...Broken shader in pak0.pk3
3905 ri.Printf(PRINT_WARNING, "...Ignored\n");
3906 ri.FS_FreeFile(buffers[i]);
3907 buffers[i] = NULL;
3908 break;
3909 } else {
3910 ri.Printf(PRINT_WARNING, ".\n");
3911 }
3912 }
38563913 }
38573914
38583915 if (buffers[i])
212212
213213 // draw the silhouette edges
214214
215 GL_Bind( tr.whiteImage );
215 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
216216 GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
217217 qglColor3f( 0.2f, 0.2f, 0.2f );
218218
261261 qglDisable( GL_CLIP_PLANE0 );
262262 GL_Cull( CT_TWO_SIDED );
263263
264 GL_Bind( tr.whiteImage );
264 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
265265
266266 qglLoadIdentity();
267267
384384 //tess.numIndexes = 0;
385385 tess.firstIndex = tess.numIndexes;
386386
387 GL_Bind( image );
387 GL_BindToTMU( image, TB_COLORMAP );
388388 GL_Cull( CT_TWO_SIDED );
389389
390390 for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
457457
458458 color[0] =
459459 color[1] =
460 color[2] = backEnd.refdef.colorScale;
460 color[2] =
461461 color[3] = 1.0f;
462462 GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, color);
463463
501501 //tess.numIndexes = 0;
502502 tess.firstIndex = tess.numIndexes;
503503
504 GL_Bind( image );
504 GL_BindToTMU( image, TB_COLORMAP );
505505 GL_Cull( CT_TWO_SIDED );
506506
507507 for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
574574
575575 color[0] =
576576 color[1] =
577 color[2] = backEnd.refdef.colorScale;
577 color[2] =
578578 color[3] = 1.0f;
579579 GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, color);
580580
10721072 qglDepthRange( 0.0, 1.0 );
10731073 }
10741074
1075 extern void R_Fog( glfog_t *curfog );
1076
10771075 /*
10781076 ================
10791077 RB_StageIteratorSky
11271125 mat4_t oldmodelview;
11281126
11291127 GL_State( 0 );
1128 GL_Cull( CT_FRONT_SIDED );
11301129 //qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
11311130
11321131 {
11571156 mat4_t oldmodelview;
11581157
11591158 GL_State( 0 );
1159 GL_Cull( CT_FRONT_SIDED );
11601160 //qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
11611161
11621162 {
2727
2828 // tr_surf.c
2929 #include "tr_local.h"
30 #if idppc_altivec && !defined(MACOS_X)
30 #if idppc_altivec && !defined(__APPLE__)
3131 #include <altivec.h>
3232 #endif
3333
9393 */
9494 void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 ) {
9595 vec3_t normal;
96 uint32_t pNormal;
96 int16_t iNormal[4];
97 uint16_t iColor[4];
9798 int ndx;
9899
99100 RB_CheckVao(tess.vao);
131132 // constant normal all the way around
132133 VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );
133134
134 R_VaoPackNormal((byte *)&pNormal, normal);
135 tess.normal[ndx] =
136 tess.normal[ndx+1] =
137 tess.normal[ndx+2] =
138 tess.normal[ndx+3] = pNormal;
135 R_VaoPackNormal(iNormal, normal);
136
137 VectorCopy4(iNormal, tess.normal[ndx]);
138 VectorCopy4(iNormal, tess.normal[ndx + 1]);
139 VectorCopy4(iNormal, tess.normal[ndx + 2]);
140 VectorCopy4(iNormal, tess.normal[ndx + 3]);
139141
140142 // standard square texture coordinates
141143 VectorSet2(tess.texCoords[ndx ][0], s1, t1);
152154
153155 // constant color all the way around
154156 // should this be identity and let the shader specify from entity?
155 VectorCopy4(color, tess.vertexColors[ndx]);
156 VectorCopy4(color, tess.vertexColors[ndx+1]);
157 VectorCopy4(color, tess.vertexColors[ndx+2]);
158 VectorCopy4(color, tess.vertexColors[ndx+3]);
157
158 R_VaoPackColor(iColor, color);
159
160 VectorCopy4(iColor, tess.color[ndx]);
161 VectorCopy4(iColor, tess.color[ndx + 1]);
162 VectorCopy4(iColor, tess.color[ndx + 2]);
163 VectorCopy4(iColor, tess.color[ndx + 3]);
159164
160165 tess.numVertexes += 4;
161166 tess.numIndexes += 6;
322327 VectorCopy( p->verts[i].xyz, tess.xyz[numv] );
323328 tess.texCoords[numv][0][0] = p->verts[i].st[0];
324329 tess.texCoords[numv][0][1] = p->verts[i].st[1];
325 tess.vertexColors[numv][0] = p->verts[ i ].modulate[0] / 255.0f;
326 tess.vertexColors[numv][1] = p->verts[ i ].modulate[1] / 255.0f;
327 tess.vertexColors[numv][2] = p->verts[ i ].modulate[2] / 255.0f;
328 tess.vertexColors[numv][3] = p->verts[ i ].modulate[3] / 255.0f;
330 tess.color[numv][0] = (int)p->verts[i].modulate[0] * 257;
331 tess.color[numv][1] = (int)p->verts[i].modulate[1] * 257;
332 tess.color[numv][2] = (int)p->verts[i].modulate[2] * 257;
333 tess.color[numv][3] = (int)p->verts[i].modulate[3] * 257;
329334
330335 numv++;
331336 }
347352 glIndex_t *inIndex;
348353 srfVert_t *dv;
349354 float *xyz, *texCoords, *lightCoords;
350 uint32_t *lightdir;
351 uint32_t *normal;
352 #ifdef USE_VERT_TANGENT_SPACE
353 uint32_t *tangent;
354 #endif
355 int16_t *lightdir;
356 int16_t *normal;
357 int16_t *tangent;
355358 glIndex_t *outIndex;
356 float *color;
359 uint16_t *color;
357360
358361 RB_CheckVao(tess.vao);
359362
377380 if ( tess.shader->vertexAttribs & ATTR_NORMAL )
378381 {
379382 dv = verts;
380 normal = &tess.normal[ tess.numVertexes ];
381 for ( i = 0 ; i < numVerts ; i++, dv++, normal++ )
382 R_VaoPackNormal((byte *)normal, dv->normal);
383 }
384
385 #ifdef USE_VERT_TANGENT_SPACE
383 normal = tess.normal[ tess.numVertexes ];
384 for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 )
385 VectorCopy4(dv->normal, normal);
386 }
387
386388 if ( tess.shader->vertexAttribs & ATTR_TANGENT )
387389 {
388390 dv = verts;
389 tangent = &tess.tangent[ tess.numVertexes ];
390 for ( i = 0 ; i < numVerts ; i++, dv++, tangent++ )
391 R_VaoPackTangent((byte *)tangent, dv->tangent);
392 }
393 #endif
391 tangent = tess.tangent[ tess.numVertexes ];
392 for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 )
393 VectorCopy4(dv->tangent, tangent);
394 }
394395
395396 if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
396397 {
411412 if ( tess.shader->vertexAttribs & ATTR_COLOR )
412413 {
413414 dv = verts;
414 color = tess.vertexColors[ tess.numVertexes ];
415 color = tess.color[ tess.numVertexes ];
415416 for ( i = 0 ; i < numVerts ; i++, dv++, color+=4 )
416 VectorCopy4(dv->vertexColors, color);
417 VectorCopy4(dv->color, color);
417418 }
418419
419420 if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
420421 {
421422 dv = verts;
422 lightdir = &tess.lightdir[ tess.numVertexes ];
423 for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ )
424 R_VaoPackNormal((byte *)lightdir, dv->lightdir);
423 lightdir = tess.lightdir[ tess.numVertexes ];
424 for ( i = 0 ; i < numVerts ; i++, dv++, lightdir+=4 )
425 VectorCopy4(dv->lightdir, lightdir);
425426 }
426427
427428 #if 0 // nothing even uses vertex dlightbits
600601 VectorAdd( start_points[i], direction, end_points[i] );
601602 }
602603
603 GL_Bind( tr.whiteImage );
604 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
604605
605606 GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
606607
666667 VectorMA( start, spanWidth, up, tess.xyz[tess.numVertexes] );
667668 tess.texCoords[tess.numVertexes][0][0] = 0;
668669 tess.texCoords[tess.numVertexes][0][1] = 0;
669 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25 / 255.0f;
670 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25 / 255.0f;
671 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25 / 255.0f;
670 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25f * 257.0f;
671 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25f * 257.0f;
672 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25f * 257.0f;
672673 tess.numVertexes++;
673674
674675 VectorMA( start, spanWidth2, up, tess.xyz[tess.numVertexes] );
675676 tess.texCoords[tess.numVertexes][0][0] = 0;
676677 tess.texCoords[tess.numVertexes][0][1] = 1;
677 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
678 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
679 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
678 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
679 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
680 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
680681 tess.numVertexes++;
681682
682683 VectorMA( end, spanWidth, up, tess.xyz[tess.numVertexes] );
683684
684685 tess.texCoords[tess.numVertexes][0][0] = t;
685686 tess.texCoords[tess.numVertexes][0][1] = 0;
686 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
687 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
688 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
687 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
688 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
689 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
689690 tess.numVertexes++;
690691
691692 VectorMA( end, spanWidth2, up, tess.xyz[tess.numVertexes] );
692693 tess.texCoords[tess.numVertexes][0][0] = t;
693694 tess.texCoords[tess.numVertexes][0][1] = 1;
694 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
695 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
696 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
695 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
696 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
697 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
697698 tess.numVertexes++;
698699
699700 tess.indexes[tess.numIndexes++] = vbase;
750751 VectorCopy( pos[j], tess.xyz[tess.numVertexes] );
751752 tess.texCoords[tess.numVertexes][0][0] = ( j < 2 );
752753 tess.texCoords[tess.numVertexes][0][1] = ( j && j != 3 );
753 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] / 255.0f;
754 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] / 255.0f;
755 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] / 255.0f;
754 tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
755 tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
756 tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
756757 tess.numVertexes++;
757758
758759 VectorAdd( pos[j], dir, pos[j] );
865866 }
866867 }
867868
868 /*
869 ** VectorArrayNormalize
870 *
871 * The inputs to this routing seem to always be close to length = 1.0 (about 0.6 to 2.0)
872 * This means that we don't have to worry about zero length or enormously long vectors.
873 */
874 #if 0 // Unused in rend2
875 static void VectorArrayNormalize( vec4_t *normals, unsigned int count ) {
876 // assert(count);
877
878 #if idppc
879 {
880 register float half = 0.5;
881 register float one = 1.0;
882 float *components = (float *)normals;
883
884 // Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction,
885 // runs *much* faster than calling sqrt(). We'll use a single Newton-Raphson
886 // refinement step to get a little more precision. This seems to yeild results
887 // that are correct to 3 decimal places and usually correct to at least 4 (sometimes 5).
888 // (That is, for the given input range of about 0.6 to 2.0).
889 do {
890 float x, y, z;
891 float B, y0, y1;
892
893 x = components[0];
894 y = components[1];
895 z = components[2];
896 components += 4;
897 B = x * x + y * y + z * z;
898
899 #ifdef __GNUC__
900 asm ( "frsqrte %0,%1" : "=f" ( y0 ) : "f" ( B ) );
901 #else
902 y0 = __frsqrte( B );
903 #endif
904 y1 = y0 + half * y0 * ( one - B * y0 * y0 );
905
906 x = x * y1;
907 y = y * y1;
908 components[-4] = x;
909 z = z * y1;
910 components[-3] = y;
911 components[-2] = z;
912 } while ( count-- );
913 }
914 #else // No assembly version for this architecture, or C_ONLY defined
915 // given the input, it's safe to call VectorNormalizeFast
916 while ( count-- ) {
917 VectorNormalizeFast( normals[0] );
918 normals++;
919 }
920 #endif
921 }
922 #endif
923
924
925
926 /*
927 ** LerpMeshVertexes
928 */
929 #if 0 // Unused
930 #if idppc_altivec
931 static void LerpMeshVertexes_altivec(md3Surface_t *surf, float backlerp)
869 static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp)
932870 {
933 short *oldXyz, *newXyz, *oldNormals, *newNormals;
934 float *outXyz, *outNormal;
935 float oldXyzScale QALIGN(16);
936 float newXyzScale QALIGN(16);
937 float oldNormalScale QALIGN(16);
938 float newNormalScale QALIGN(16);
871 float *outXyz;
872 int16_t *outNormal, *outTangent;
873 mdvVertex_t *newVerts;
939874 int vertNum;
940 unsigned lat, lng;
941 int numVerts;
942
943 outXyz = tess.xyz[tess.numVertexes];
944 outNormal = tess.normal[tess.numVertexes];
945
946 newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
947 + (backEnd.currentEntity->e.frame * surf->numVerts * 4);
948 newNormals = newXyz + 3;
949
950 newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
951 newNormalScale = 1.0 - backlerp;
952
953 numVerts = surf->numVerts;
954
955 if ( backlerp == 0 ) {
956 vector signed short newNormalsVec0;
957 vector signed short newNormalsVec1;
958 vector signed int newNormalsIntVec;
959 vector float newNormalsFloatVec;
960 vector float newXyzScaleVec;
961 vector unsigned char newNormalsLoadPermute;
962 vector unsigned char newNormalsStorePermute;
963 vector float zero;
964
965 newNormalsStorePermute = vec_lvsl(0,(float *)&newXyzScaleVec);
966 newXyzScaleVec = *(vector float *)&newXyzScale;
967 newXyzScaleVec = vec_perm(newXyzScaleVec,newXyzScaleVec,newNormalsStorePermute);
968 newXyzScaleVec = vec_splat(newXyzScaleVec,0);
969 newNormalsLoadPermute = vec_lvsl(0,newXyz);
970 newNormalsStorePermute = vec_lvsr(0,outXyz);
971 zero = (vector float)vec_splat_s8(0);
875
876 newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts;
877
878 outXyz = tess.xyz[tess.numVertexes];
879 outNormal = tess.normal[tess.numVertexes];
880 outTangent = tess.tangent[tess.numVertexes];
881
882 if (backlerp == 0)
883 {
972884 //
973885 // just copy the vertexes
974886 //
975 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
976 newXyz += 4, newNormals += 4,
977 outXyz += 4, outNormal += 4)
887
888 for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
978889 {
979 newNormalsLoadPermute = vec_lvsl(0,newXyz);
980 newNormalsStorePermute = vec_lvsr(0,outXyz);
981 newNormalsVec0 = vec_ld(0,newXyz);
982 newNormalsVec1 = vec_ld(16,newXyz);
983 newNormalsVec0 = vec_perm(newNormalsVec0,newNormalsVec1,newNormalsLoadPermute);
984 newNormalsIntVec = vec_unpackh(newNormalsVec0);
985 newNormalsFloatVec = vec_ctf(newNormalsIntVec,0);
986 newNormalsFloatVec = vec_madd(newNormalsFloatVec,newXyzScaleVec,zero);
987 newNormalsFloatVec = vec_perm(newNormalsFloatVec,newNormalsFloatVec,newNormalsStorePermute);
988 //outXyz[0] = newXyz[0] * newXyzScale;
989 //outXyz[1] = newXyz[1] * newXyzScale;
990 //outXyz[2] = newXyz[2] * newXyzScale;
991
992 lat = ( newNormals[0] >> 8 ) & 0xff;
993 lng = ( newNormals[0] & 0xff );
994 lat *= (FUNCTABLE_SIZE/256);
995 lng *= (FUNCTABLE_SIZE/256);
996
997 // decode X as cos( lat ) * sin( long )
998 // decode Y as sin( lat ) * sin( long )
999 // decode Z as cos( long )
1000
1001 outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1002 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1003 outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1004
1005 vec_ste(newNormalsFloatVec,0,outXyz);
1006 vec_ste(newNormalsFloatVec,4,outXyz);
1007 vec_ste(newNormalsFloatVec,8,outXyz);
1008 }
1009 } else {
890 VectorCopy(newVerts->xyz, outXyz);
891
892 VectorCopy4(newVerts->normal, outNormal);
893 VectorCopy4(newVerts->tangent, outTangent);
894
895 newVerts++;
896 outXyz += 4;
897 outNormal += 4;
898 outTangent += 4;
899 }
900 }
901 else
902 {
1010903 //
1011904 // interpolate and copy the vertex and normal
1012905 //
1013 oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
1014 + (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
1015 oldNormals = oldXyz + 3;
1016
1017 oldXyzScale = MD3_XYZ_SCALE * backlerp;
1018 oldNormalScale = backlerp;
1019
1020 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
1021 oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
1022 outXyz += 4, outNormal += 4)
1023 {
1024 vec3_t uncompressedOldNormal, uncompressedNewNormal;
1025
1026 // interpolate the xyz
1027 outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
1028 outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
1029 outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
1030
1031 // FIXME: interpolate lat/long instead?
1032 lat = ( newNormals[0] >> 8 ) & 0xff;
1033 lng = ( newNormals[0] & 0xff );
1034 lat *= 4;
1035 lng *= 4;
1036 uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1037 uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1038 uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1039
1040 lat = ( oldNormals[0] >> 8 ) & 0xff;
1041 lng = ( oldNormals[0] & 0xff );
1042 lat *= 4;
1043 lng *= 4;
1044
1045 uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1046 uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1047 uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1048
1049 outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
1050 outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
1051 outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
1052
1053 // VectorNormalize (outNormal);
1054 }
1055 VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
1056 }
1057 }
1058 #endif
1059 #endif
1060
1061 static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
1062 {
1063 #if 0
1064 short *oldXyz, *newXyz, *oldNormals, *newNormals;
1065 float *outXyz, *outNormal;
1066 float oldXyzScale, newXyzScale;
1067 float oldNormalScale, newNormalScale;
1068 int vertNum;
1069 unsigned lat, lng;
1070 int numVerts;
1071
1072 outXyz = tess.xyz[tess.numVertexes];
1073 outNormal = tess.normal[tess.numVertexes];
1074
1075 newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
1076 + (backEnd.currentEntity->e.frame * surf->numVerts * 4);
1077 newNormals = newXyz + 3;
1078
1079 newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
1080 newNormalScale = 1.0 - backlerp;
1081
1082 numVerts = surf->numVerts;
1083
1084 if ( backlerp == 0 ) {
1085 //
1086 // just copy the vertexes
1087 //
1088 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
1089 newXyz += 4, newNormals += 4,
1090 outXyz += 4, outNormal += 4)
1091 {
1092
1093 outXyz[0] = newXyz[0] * newXyzScale;
1094 outXyz[1] = newXyz[1] * newXyzScale;
1095 outXyz[2] = newXyz[2] * newXyzScale;
1096
1097 lat = ( newNormals[0] >> 8 ) & 0xff;
1098 lng = ( newNormals[0] & 0xff );
1099 lat *= (FUNCTABLE_SIZE/256);
1100 lng *= (FUNCTABLE_SIZE/256);
1101
1102 // decode X as cos( lat ) * sin( long )
1103 // decode Y as sin( lat ) * sin( long )
1104 // decode Z as cos( long )
1105
1106 outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1107 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1108 outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1109 }
1110 } else {
1111 //
1112 // interpolate and copy the vertex and normal
1113 //
1114 oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
1115 + (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
1116 oldNormals = oldXyz + 3;
1117
1118 oldXyzScale = MD3_XYZ_SCALE * backlerp;
1119 oldNormalScale = backlerp;
1120
1121 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
1122 oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
1123 outXyz += 4, outNormal += 4)
1124 {
1125 vec3_t uncompressedOldNormal, uncompressedNewNormal;
1126
1127 // interpolate the xyz
1128 outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
1129 outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
1130 outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
1131
1132 // FIXME: interpolate lat/long instead?
1133 lat = ( newNormals[0] >> 8 ) & 0xff;
1134 lng = ( newNormals[0] & 0xff );
1135 lat *= 4;
1136 lng *= 4;
1137 uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1138 uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1139 uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1140
1141 lat = ( oldNormals[0] >> 8 ) & 0xff;
1142 lng = ( oldNormals[0] & 0xff );
1143 lat *= 4;
1144 lng *= 4;
1145
1146 uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
1147 uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1148 uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
1149
1150 outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
1151 outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
1152 outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
1153
1154 // VectorNormalize (outNormal);
1155 }
1156 VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
1157 }
1158 #endif
1159 float *outXyz;
1160 uint32_t *outNormal;
1161 mdvVertex_t *newVerts;
1162 int vertNum;
1163
1164 newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts;
1165
1166 outXyz = tess.xyz[tess.numVertexes];
1167 outNormal = &tess.normal[tess.numVertexes];
1168
1169 if (backlerp == 0)
1170 {
1171 //
1172 // just copy the vertexes
1173 //
906
907 mdvVertex_t *oldVerts;
908
909 oldVerts = surf->verts + backEnd.currentEntity->e.oldframe * surf->numVerts;
1174910
1175911 for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
1176912 {
1177 vec3_t normal;
1178
1179 VectorCopy(newVerts->xyz, outXyz);
1180 VectorCopy(newVerts->normal, normal);
1181
1182 R_VaoPackNormal((byte *)outNormal, normal);
1183
1184 newVerts++;
1185 outXyz += 4;
1186 outNormal++;
1187 }
1188 }
1189 else
1190 {
1191 //
1192 // interpolate and copy the vertex and normal
1193 //
1194
1195 mdvVertex_t *oldVerts;
1196
1197 oldVerts = surf->verts + backEnd.currentEntity->e.oldframe * surf->numVerts;
1198
1199 for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
1200 {
1201 vec3_t normal;
1202
1203913 VectorLerp(newVerts->xyz, oldVerts->xyz, backlerp, outXyz);
1204 VectorLerp(newVerts->normal, oldVerts->normal, backlerp, normal);
1205 VectorNormalize(normal);
1206
1207 R_VaoPackNormal((byte *)outNormal, normal);
914
915 outNormal[0] = (int16_t)(newVerts->normal[0] * (1.0f - backlerp) + oldVerts->normal[0] * backlerp);
916 outNormal[1] = (int16_t)(newVerts->normal[1] * (1.0f - backlerp) + oldVerts->normal[1] * backlerp);
917 outNormal[2] = (int16_t)(newVerts->normal[2] * (1.0f - backlerp) + oldVerts->normal[2] * backlerp);
918 outNormal[3] = 0;
919
920 outTangent[0] = (int16_t)(newVerts->tangent[0] * (1.0f - backlerp) + oldVerts->tangent[0] * backlerp);
921 outTangent[1] = (int16_t)(newVerts->tangent[1] * (1.0f - backlerp) + oldVerts->tangent[1] * backlerp);
922 outTangent[2] = (int16_t)(newVerts->tangent[2] * (1.0f - backlerp) + oldVerts->tangent[2] * backlerp);
923 outTangent[3] = newVerts->tangent[3];
1208924
1209925 newVerts++;
1210926 oldVerts++;
1211927 outXyz += 4;
1212 outNormal++;
1213 }
1214 }
1215 }
1216
1217 static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp)
1218 {
1219 #if 0
1220 #if idppc_altivec
1221 if (com_altivec->integer) {
1222 // must be in a seperate function or G3 systems will crash.
1223 LerpMeshVertexes_altivec( surf, backlerp );
1224 return;
1225 }
1226 #endif // idppc_altivec
1227 #endif
1228 LerpMeshVertexes_scalar( surf, backlerp );
928 outNormal += 4;
929 outTangent += 4;
930 }
931 }
1229932 }
1230933
1231934
1280983
1281984 }
1282985
1283 /*
1284 ** R_LatLongToNormal
1285 */
1286 void R_LatLongToNormal( vec3_t outNormal, short latLong ) {
1287 unsigned lat, lng;
1288
1289 lat = ( latLong >> 8 ) & 0xff;
1290 lng = ( latLong & 0xff );
1291 lat *= ( FUNCTABLE_SIZE / 256 );
1292 lng *= ( FUNCTABLE_SIZE / 256 );
1293
1294 // decode X as cos( lat ) * sin( long )
1295 // decode Y as sin( lat ) * sin( long )
1296 // decode Z as cos( long )
1297
1298 outNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1299 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1300 outNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1301 }
1302
1303 // Ridah
1304 /*
1305 ** LerpCMeshVertexes
1306 */
1307 static void LerpCMeshVertexes( mdcSurface_t *surf, float backlerp ) {
1308 short *oldXyz, *newXyz, *oldNormals, *newNormals;
1309 float *outXyz;
1310 uint32_t *outNormal;
1311 vec3_t fNormal;
1312 float oldXyzScale, newXyzScale;
1313 float oldNormalScale, newNormalScale;
1314 int vertNum;
1315 unsigned lat, lng;
1316 int numVerts;
1317
1318 int oldBase, newBase;
1319 short *oldComp = NULL, *newComp = NULL; // TTimo: init
1320 mdcXyzCompressed_t *oldXyzComp = NULL, *newXyzComp = NULL; // TTimo: init
1321 vec3_t oldOfsVec, newOfsVec;
1322
1323 qboolean hasComp;
1324
1325 outXyz = tess.xyz[tess.numVertexes];
1326 outNormal = &tess.normal[tess.numVertexes];
1327
1328 newBase = (int)*( ( short * )( (byte *)surf + surf->ofsFrameBaseFrames ) + backEnd.currentEntity->e.frame );
1329 newXyz = ( short * )( (byte *)surf + surf->ofsXyzNormals )
1330 + ( newBase * surf->numVerts * 4 );
1331 newNormals = newXyz + 3;
1332
1333 hasComp = ( surf->numCompFrames > 0 );
1334 if ( hasComp ) {
1335 newComp = ( ( short * )( (byte *)surf + surf->ofsFrameCompFrames ) + backEnd.currentEntity->e.frame );
1336 if ( *newComp >= 0 ) {
1337 newXyzComp = ( mdcXyzCompressed_t * )( (byte *)surf + surf->ofsXyzCompressed )
1338 + ( *newComp * surf->numVerts );
1339 }
1340 }
1341
1342 newXyzScale = MD3_XYZ_SCALE * ( 1.0 - backlerp );
1343 newNormalScale = 1.0 - backlerp;
1344
1345 numVerts = surf->numVerts;
1346
1347 if ( backlerp == 0 ) {
1348 //
1349 // just copy the vertexes
1350 //
1351 for ( vertNum = 0 ; vertNum < numVerts ; vertNum++,
1352 newXyz += 4, newNormals += 4,
1353 outXyz += 4, outNormal++ )
1354 {
1355
1356 outXyz[0] = newXyz[0] * newXyzScale;
1357 outXyz[1] = newXyz[1] * newXyzScale;
1358 outXyz[2] = newXyz[2] * newXyzScale;
1359
1360 // add the compressed ofsVec
1361 if ( hasComp && *newComp >= 0 ) {
1362 R_MDC_DecodeXyzCompressed( newXyzComp->ofsVec, newOfsVec, fNormal );
1363 newXyzComp++;
1364 VectorAdd( outXyz, newOfsVec, outXyz );
1365 } else {
1366 lat = ( newNormals[0] >> 8 ) & 0xff;
1367 lng = ( newNormals[0] & 0xff );
1368 lat *= 4;
1369 lng *= 4;
1370
1371 fNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1372 fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1373 fNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1374 }
1375
1376 R_VaoPackNormal((byte *)outNormal, fNormal);
1377 }
1378 } else {
1379 //
1380 // interpolate and copy the vertex and normal
1381 //
1382 oldBase = (int)*( ( short * )( (byte *)surf + surf->ofsFrameBaseFrames ) + backEnd.currentEntity->e.oldframe );
1383 oldXyz = ( short * )( (byte *)surf + surf->ofsXyzNormals )
1384 + ( oldBase * surf->numVerts * 4 );
1385 oldNormals = oldXyz + 3;
1386
1387 if ( hasComp ) {
1388 oldComp = ( ( short * )( (byte *)surf + surf->ofsFrameCompFrames ) + backEnd.currentEntity->e.oldframe );
1389 if ( *oldComp >= 0 ) {
1390 oldXyzComp = ( mdcXyzCompressed_t * )( (byte *)surf + surf->ofsXyzCompressed )
1391 + ( *oldComp * surf->numVerts );
1392 }
1393 }
1394
1395 oldXyzScale = MD3_XYZ_SCALE * backlerp;
1396 oldNormalScale = backlerp;
1397
1398 for ( vertNum = 0 ; vertNum < numVerts ; vertNum++,
1399 oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
1400 outXyz += 4, outNormal++ )
1401 {
1402 vec3_t uncompressedOldNormal, uncompressedNewNormal;
1403
1404 // interpolate the xyz
1405 outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
1406 outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
1407 outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
1408
1409 // add the compressed ofsVec
1410 if ( hasComp && *newComp >= 0 ) {
1411 R_MDC_DecodeXyzCompressed( newXyzComp->ofsVec, newOfsVec, uncompressedNewNormal );
1412 newXyzComp++;
1413 VectorMA( outXyz, 1.0 - backlerp, newOfsVec, outXyz );
1414 } else {
1415 lat = ( newNormals[0] >> 8 ) & 0xff;
1416 lng = ( newNormals[0] & 0xff );
1417 lat *= 4;
1418 lng *= 4;
1419
1420 uncompressedNewNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1421 uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1422 uncompressedNewNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1423 }
1424
1425 if ( hasComp && *oldComp >= 0 ) {
1426 R_MDC_DecodeXyzCompressed( oldXyzComp->ofsVec, oldOfsVec, uncompressedOldNormal );
1427 oldXyzComp++;
1428 VectorMA( outXyz, backlerp, oldOfsVec, outXyz );
1429 } else {
1430 lat = ( oldNormals[0] >> 8 ) & 0xff;
1431 lng = ( oldNormals[0] & 0xff );
1432 lat *= 4;
1433 lng *= 4;
1434
1435 uncompressedOldNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng];
1436 uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
1437 uncompressedOldNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK];
1438 }
1439
1440 fNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
1441 fNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
1442 fNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
1443
1444 VectorNormalize( fNormal );
1445
1446 R_VaoPackNormal((byte *)outNormal, fNormal);
1447 }
1448 }
1449 }
1450
1451 /*
1452 =============
1453 RB_SurfaceCMesh
1454 =============
1455 */
1456 void RB_SurfaceCMesh( mdcSurface_t *surface ) {
1457 int j;
1458 float backlerp;
1459 int *triangles;
1460 float *texCoords;
1461 int indexes;
1462 int Bob, Doug;
1463 int numVerts;
1464
1465 // RF, check for REFLAG_HANDONLY
1466 if ( backEnd.currentEntity->e.reFlags & REFLAG_ONLYHAND ) {
1467 if ( !strstr( surface->name, "hand" ) ) {
1468 return;
1469 }
1470 }
1471
1472 if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
1473 backlerp = 0;
1474 } else {
1475 backlerp = backEnd.currentEntity->e.backlerp;
1476 }
1477
1478 RB_CheckVao(tess.vao);
1479
1480 RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles * 3 );
1481
1482 LerpCMeshVertexes( surface, backlerp );
1483
1484 triangles = ( int * )( (byte *)surface + surface->ofsTriangles );
1485 indexes = surface->numTriangles * 3;
1486 Bob = tess.numIndexes;
1487 Doug = tess.numVertexes;
1488 for ( j = 0 ; j < indexes ; j++ ) {
1489 tess.indexes[Bob + j] = Doug + triangles[j];
1490 }
1491 tess.numIndexes += indexes;
1492
1493 texCoords = ( float * )( (byte *)surface + surface->ofsSt );
1494
1495 numVerts = surface->numVerts;
1496 for ( j = 0; j < numVerts; j++ ) {
1497 tess.texCoords[Doug + j][0][0] = texCoords[j * 2 + 0];
1498 tess.texCoords[Doug + j][0][1] = texCoords[j * 2 + 1];
1499 // FIXME: fill in lightmapST for completeness?
1500 }
1501
1502 tess.numVertexes += surface->numVerts;
1503 }
1504 // done.
1505986
1506987 /*
1507988 ==============
15611042 int i, j;
15621043 float *xyz;
15631044 float *texCoords, *lightCoords;
1564 uint32_t *normal;
1565 #ifdef USE_VERT_TANGENT_SPACE
1566 uint32_t *tangent;
1567 #endif
1568 float *color;
1569 uint32_t *lightdir;
1045 int16_t *normal;
1046 int16_t *tangent;
1047 uint16_t *color;
1048 int16_t *lightdir;
15701049 srfVert_t *dv;
15711050 int rows, irows, vrows;
15721051 int used;
16511130 numVertexes = tess.numVertexes;
16521131
16531132 xyz = tess.xyz[numVertexes];
1654 normal = &tess.normal[numVertexes];
1655 #ifdef USE_VERT_TANGENT_SPACE
1656 tangent = &tess.tangent[numVertexes];
1657 #endif
1133 normal = tess.normal[numVertexes];
1134 tangent = tess.tangent[numVertexes];
16581135 texCoords = tess.texCoords[numVertexes][0];
16591136 lightCoords = tess.texCoords[numVertexes][1];
1660 color = tess.vertexColors[numVertexes];
1661 lightdir = &tess.lightdir[numVertexes];
1137 color = tess.color[numVertexes];
1138 lightdir = tess.lightdir[numVertexes];
16621139 //vDlightBits = &tess.vertexDlightBits[numVertexes];
16631140
16641141 for ( i = 0 ; i < rows ; i++ ) {
16741151
16751152 if ( tess.shader->vertexAttribs & ATTR_NORMAL )
16761153 {
1677 R_VaoPackNormal((byte *)normal++, dv->normal);
1154 VectorCopy4(dv->normal, normal);
1155 normal += 4;
16781156 }
16791157
1680 #ifdef USE_VERT_TANGENT_SPACE
16811158 if ( tess.shader->vertexAttribs & ATTR_TANGENT )
16821159 {
1683 R_VaoPackTangent((byte *)tangent++, dv->tangent);
1160 VectorCopy4(dv->tangent, tangent);
1161 tangent += 4;
16841162 }
1685 #endif
16861163
16871164 if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
16881165 {
16981175
16991176 if ( tess.shader->vertexAttribs & ATTR_COLOR )
17001177 {
1701 VectorCopy4(dv->vertexColors, color);
1178 VectorCopy4(dv->color, color);
17021179 color += 4;
17031180 }
17041181
17051182 if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
17061183 {
1707 R_VaoPackNormal((byte *)lightdir++, dv->lightdir);
1184 VectorCopy4(dv->lightdir, lightdir);
1185 lightdir += 4;
17081186 }
17091187
17101188 //*vDlightBits++ = dlightBits;
17681246 */
17691247 static void RB_SurfaceAxis( void ) {
17701248 #if 0
1771 GL_Bind( tr.whiteImage );
1249 GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
17721250 GL_State( GLS_DEFAULT );
17731251 qglLineWidth( 3 );
17741252 qglBegin( GL_LINES );
18441322
18451323 GLimp_LogComment("--- RB_SurfaceVaoMdvMesh ---\n");
18461324
1325 if (ShaderRequiresCPUDeforms(tess.shader))
1326 {
1327 RB_SurfaceMesh(surface->mdvSurface);
1328 return;
1329 }
1330
18471331 if(!surface->vao)
18481332 return;
18491333
18761360
18771361 if (glRefConfig.vertexArrayObject)
18781362 {
1879 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, surface->vao->vertexesVBO);
1363 qglBindBuffer(GL_ARRAY_BUFFER, surface->vao->vertexesVBO);
18801364 }
18811365
18821366 frameOffset = refEnt->frame * surface->vao->frameSize;
18831367
18841368 attribIndex = ATTR_INDEX_POSITION;
18851369 vAtb = &surface->vao->attribs[attribIndex];
1886 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1370 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
18871371
18881372 attribIndex = ATTR_INDEX_NORMAL;
18891373 vAtb = &surface->vao->attribs[attribIndex];
1890 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1374 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
18911375
18921376 attribIndex = ATTR_INDEX_TANGENT;
18931377 vAtb = &surface->vao->attribs[attribIndex];
1894 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1378 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
18951379
18961380 frameOffset = refEnt->oldframe * surface->vao->frameSize;
18971381
18981382 attribIndex = ATTR_INDEX_POSITION2;
18991383 vAtb = &surface->vao->attribs[attribIndex];
1900 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1384 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
19011385
19021386 attribIndex = ATTR_INDEX_NORMAL2;
19031387 vAtb = &surface->vao->attribs[attribIndex];
1904 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1388 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
19051389
19061390 attribIndex = ATTR_INDEX_TANGENT2;
19071391 vAtb = &surface->vao->attribs[attribIndex];
1908 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
1392 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
19091393
19101394
19111395 if (!glRefConfig.vertexArrayObject)
19121396 {
19131397 attribIndex = ATTR_INDEX_TEXCOORD;
19141398 vAtb = &surface->vao->attribs[attribIndex];
1915 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
1399 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
19161400 }
19171401 }
19181402
19341418 ( void( * ) ( void* ) )RB_SurfaceTriangles, // SF_TRIANGLES,
19351419 ( void( * ) ( void* ) )RB_SurfacePolychain, // SF_POLY,
19361420 ( void( * ) ( void* ) )RB_SurfaceMesh, // SF_MDV,
1937 ( void( * ) ( void* ) )RB_SurfaceCMesh, // SF_MDC,
19381421 ( void( * ) ( void* ) )RB_SurfaceAnim, // SF_MDS,
19391422 ( void( * ) ( void* ) )RB_MDRSurfaceAnim, // SF_MDR,
19401423 ( void( * ) ( void* ) )RB_IQMSurfaceAnim, // SF_IQM,
2222 #include "tr_local.h"
2323
2424
25 union pack10_u {
26 struct {
27 signed int x:10;
28 signed int y:10;
29 signed int z:10;
30 signed int w:2;
31 } pack;
32 uint32_t i;
33 };
34
35 union pack8_u {
36 struct {
37 signed int x:8;
38 signed int y:8;
39 signed int z:8;
40 signed int w:8;
41 } pack;
42 uint32_t i;
43 };
44
45
46 int R_VaoPackTangent(byte *out, vec4_t v)
47 {
48 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
49 {
50 union pack10_u *num = (union pack10_u *)out;
51
52 num->pack.x = v[0] * 511.0f;
53 num->pack.y = v[1] * 511.0f;
54 num->pack.z = v[2] * 511.0f;
55 num->pack.w = v[3];
56 }
57 else
58 {
59 union pack8_u *num = (union pack8_u *)out;
60
61 num->pack.x = v[0] * 127.0f;
62 num->pack.y = v[1] * 127.0f;
63 num->pack.z = v[2] * 127.0f;
64 num->pack.w = v[3] * 127.0f;
65 }
66
67 return 4;
68 }
69
70 int R_VaoPackNormal(byte *out, vec3_t v)
71 {
72 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
73 {
74 union pack10_u *num = (union pack10_u *)out;
75
76 num->pack.x = v[0] * 511.0f;
77 num->pack.y = v[1] * 511.0f;
78 num->pack.z = v[2] * 511.0f;
79 num->pack.w = 0;
80 }
81 else
82 {
83 union pack8_u *num = (union pack8_u *)out;
84
85 num->pack.x = v[0] * 127.0f;
86 num->pack.y = v[1] * 127.0f;
87 num->pack.z = v[2] * 127.0f;
88 num->pack.w = 0;
89 }
90
91 return 4;
92 }
93
94 int R_VaoPackTexCoord(byte *out, vec2_t st)
95 {
96 if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
97 {
98 uint16_t *num = (uint16_t *)out;
99
100 *num++ = FloatToHalf(st[0]);
101 *num++ = FloatToHalf(st[1]);
102
103 return sizeof(*num) * 2;
104 }
105 else
106 {
107 float *num = (float *)out;
108
109 *num++ = st[0];
110 *num++ = st[1];
111
112 return sizeof(*num) * 2;
113 }
114 }
115
116 int R_VaoPackColors(byte *out, vec4_t color)
117 {
118 if (glRefConfig.packedTexcoordDataType == GL_HALF_FLOAT)
119 {
120 uint16_t *num = (uint16_t *)out;
121
122 *num++ = FloatToHalf(color[0]);
123 *num++ = FloatToHalf(color[1]);
124 *num++ = FloatToHalf(color[2]);
125 *num++ = FloatToHalf(color[3]);
126
127 return sizeof(*num) * 4;
128 }
129 else
130 {
131 float *num = (float *)out;
132
133 *num++ = color[0];
134 *num++ = color[1];
135 *num++ = color[2];
136 *num++ = color[3];
137
138 return sizeof(*num) * 4;
139 }
140 }
141
142
143 void R_VaoUnpackTangent(vec4_t v, uint32_t b)
144 {
145 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
146 {
147 union pack10_u *num = (union pack10_u *)&b;
148
149 v[0] = num->pack.x / 511.0f;
150 v[1] = num->pack.y / 511.0f;
151 v[2] = num->pack.z / 511.0f;
152 v[3] = num->pack.w;
153 }
154 else
155 {
156 union pack8_u *num = (union pack8_u *)&b;
157
158 v[0] = num->pack.x / 127.0f;
159 v[1] = num->pack.y / 127.0f;
160 v[2] = num->pack.z / 127.0f;
161 v[3] = num->pack.w / 127.0f;
162 }
163 }
164
165 void R_VaoUnpackNormal(vec3_t v, uint32_t b)
166 {
167 if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV)
168 {
169 union pack10_u *num = (union pack10_u *)&b;
170
171 v[0] = num->pack.x / 511.0f;
172 v[1] = num->pack.y / 511.0f;
173 v[2] = num->pack.z / 511.0f;
174 }
175 else
176 {
177 union pack8_u *num = (union pack8_u *)&b;
178
179 v[0] = num->pack.x / 127.0f;
180 v[1] = num->pack.y / 127.0f;
181 v[2] = num->pack.z / 127.0f;
182 }
183 }
184
25 void R_VaoPackTangent(int16_t *out, vec4_t v)
26 {
27 out[0] = v[0] * 32767.0f + (v[0] > 0.0f ? 0.5f : -0.5f);
28 out[1] = v[1] * 32767.0f + (v[1] > 0.0f ? 0.5f : -0.5f);
29 out[2] = v[2] * 32767.0f + (v[2] > 0.0f ? 0.5f : -0.5f);
30 out[3] = v[3] * 32767.0f + (v[3] > 0.0f ? 0.5f : -0.5f);
31 }
32
33 void R_VaoPackNormal(int16_t *out, vec3_t v)
34 {
35 out[0] = v[0] * 32767.0f + (v[0] > 0.0f ? 0.5f : -0.5f);
36 out[1] = v[1] * 32767.0f + (v[1] > 0.0f ? 0.5f : -0.5f);
37 out[2] = v[2] * 32767.0f + (v[2] > 0.0f ? 0.5f : -0.5f);
38 out[3] = 0;
39 }
40
41 void R_VaoPackColor(uint16_t *out, vec4_t c)
42 {
43 out[0] = c[0] * 65535.0f + 0.5f;
44 out[1] = c[1] * 65535.0f + 0.5f;
45 out[2] = c[2] * 65535.0f + 0.5f;
46 out[3] = c[3] * 65535.0f + 0.5f;
47 }
48
49 void R_VaoUnpackTangent(vec4_t v, int16_t *pack)
50 {
51 v[0] = pack[0] / 32767.0f;
52 v[1] = pack[1] / 32767.0f;
53 v[2] = pack[2] / 32767.0f;
54 v[3] = pack[3] / 32767.0f;
55 }
56
57 void R_VaoUnpackNormal(vec3_t v, int16_t *pack)
58 {
59 v[0] = pack[0] / 32767.0f;
60 v[1] = pack[1] / 32767.0f;
61 v[2] = pack[2] / 32767.0f;
62 }
18563
18664 void Vao_SetVertexPointers(vao_t *vao)
18765 {
19573
19674 if (vAtb->enabled)
19775 {
198 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
76 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
19977 if (glRefConfig.vertexArrayObject || !(glState.vertexAttribsEnabled & attribBit))
200 qglEnableVertexAttribArrayARB(attribIndex);
78 qglEnableVertexAttribArray(attribIndex);
20179
20280 if (!glRefConfig.vertexArrayObject || vao == tess.vao)
20381 glState.vertexAttribsEnabled |= attribBit;
20785 // don't disable vertex attribs when using vertex array objects
20886 // Vao_SetVertexPointers is only called during init when using VAOs, and vertex attribs start disabled anyway
20987 if (!glRefConfig.vertexArrayObject && (glState.vertexAttribsEnabled & attribBit))
210 qglDisableVertexAttribArrayARB(attribIndex);
88 qglDisableVertexAttribArray(attribIndex);
21189
21290 if (!glRefConfig.vertexArrayObject || vao == tess.vao)
21391 glState.vertexAttribsEnabled &= ~attribBit;
228106 switch (usage)
229107 {
230108 case VAO_USAGE_STATIC:
231 glUsage = GL_STATIC_DRAW_ARB;
109 glUsage = GL_STATIC_DRAW;
232110 break;
233111
234112 case VAO_USAGE_DYNAMIC:
235 glUsage = GL_DYNAMIC_DRAW_ARB;
113 glUsage = GL_DYNAMIC_DRAW;
236114 break;
237115
238116 default:
261139
262140 if (glRefConfig.vertexArrayObject)
263141 {
264 qglGenVertexArraysARB(1, &vao->vao);
265 qglBindVertexArrayARB(vao->vao);
142 qglGenVertexArrays(1, &vao->vao);
143 qglBindVertexArray(vao->vao);
266144 }
267145
268146
269147 vao->vertexesSize = vertexesSize;
270148
271 qglGenBuffersARB(1, &vao->vertexesVBO);
272
273 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
274 qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexesSize, vertexes, glUsage);
149 qglGenBuffers(1, &vao->vertexesVBO);
150
151 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
152 qglBufferData(GL_ARRAY_BUFFER, vertexesSize, vertexes, glUsage);
275153
276154
277155 vao->indexesSize = indexesSize;
278156
279 qglGenBuffersARB(1, &vao->indexesIBO);
280
281 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesIBO);
282 qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexesSize, indexes, glUsage);
157 qglGenBuffers(1, &vao->indexesIBO);
158
159 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
160 qglBufferData(GL_ELEMENT_ARRAY_BUFFER, indexesSize, indexes, glUsage);
283161
284162
285163 glState.currentVao = vao;
303181 int dataSize;
304182 int dataOfs;
305183
306 int glUsage = GL_STATIC_DRAW_ARB;
184 int glUsage = GL_STATIC_DRAW;
307185
308186 if(!numVertexes || !numIndexes)
309187 return NULL;
329207 // since these vertex attributes are never altered, interleave them
330208 vao->attribs[ATTR_INDEX_POSITION ].enabled = 1;
331209 vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
332 #ifdef USE_VERT_TANGENT_SPACE
333210 vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
334 #endif
335211 vao->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1;
336212 vao->attribs[ATTR_INDEX_LIGHTCOORD ].enabled = 1;
337213 vao->attribs[ATTR_INDEX_COLOR ].enabled = 1;
346222 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4;
347223
348224 vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT;
349 vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
350 vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
351 vao->attribs[ATTR_INDEX_TEXCOORD ].type = glRefConfig.packedTexcoordDataType;
352 vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = glRefConfig.packedTexcoordDataType;
353 vao->attribs[ATTR_INDEX_COLOR ].type = glRefConfig.packedColorDataType;
354 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType;
225 vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
226 vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
227 vao->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT;
228 vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT;
229 vao->attribs[ATTR_INDEX_COLOR ].type = GL_UNSIGNED_SHORT;
230 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = GL_SHORT;
355231
356232 vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE;
357233 vao->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE;
358234 vao->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE;
359235 vao->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE;
360236 vao->attribs[ATTR_INDEX_LIGHTCOORD ].normalized = GL_FALSE;
361 vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_FALSE;
237 vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_TRUE;
362238 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE;
363239
364240 vao->attribs[ATTR_INDEX_POSITION ].offset = 0; dataSize = sizeof(verts[0].xyz);
365 vao->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(uint32_t);
366 #ifdef USE_VERT_TANGENT_SPACE
367 vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(uint32_t);
368 #endif
369 vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize;
370 vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize;
371 vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += glRefConfig.packedColorDataSize;
372 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(uint32_t);
241 vao->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(verts[0].normal);
242 vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(verts[0].tangent);
243 vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += sizeof(verts[0].st);
244 vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += sizeof(verts[0].lightmap);
245 vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += sizeof(verts[0].color);
246 vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(verts[0].lightdir);
373247
374248 vao->attribs[ATTR_INDEX_POSITION ].stride = dataSize;
375249 vao->attribs[ATTR_INDEX_NORMAL ].stride = dataSize;
382256
383257 if (glRefConfig.vertexArrayObject)
384258 {
385 qglGenVertexArraysARB(1, &vao->vao);
386 qglBindVertexArrayARB(vao->vao);
259 qglGenVertexArrays(1, &vao->vao);
260 qglBindVertexArray(vao->vao);
387261 }
388262
389263
399273 dataOfs += sizeof(verts[i].xyz);
400274
401275 // normal
402 dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].normal);
403
404 #ifdef USE_VERT_TANGENT_SPACE
276 memcpy(data + dataOfs, &verts[i].normal, sizeof(verts[i].normal));
277 dataOfs += sizeof(verts[i].normal);
278
405279 // tangent
406 dataOfs += R_VaoPackTangent(data + dataOfs, verts[i].tangent);
407 #endif
280 memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent));
281 dataOfs += sizeof(verts[i].tangent);
408282
409283 // texcoords
410 dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].st);
284 memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st));
285 dataOfs += sizeof(verts[i].st);
411286
412287 // lightmap texcoords
413 dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].lightmap);
288 memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap));
289 dataOfs += sizeof(verts[i].lightmap);
414290
415291 // colors
416 dataOfs += R_VaoPackColors(data + dataOfs, verts[i].vertexColors);
292 memcpy(data + dataOfs, &verts[i].color, sizeof(verts[i].color));
293 dataOfs += sizeof(verts[i].color);
417294
418295 // light directions
419 dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].lightdir);
296 memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
297 dataOfs += sizeof(verts[i].lightdir);
420298 }
421299
422300 vao->vertexesSize = dataSize;
423301
424 qglGenBuffersARB(1, &vao->vertexesVBO);
425
426 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
427 qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vao->vertexesSize, data, glUsage);
302 qglGenBuffers(1, &vao->vertexesVBO);
303
304 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
305 qglBufferData(GL_ARRAY_BUFFER, vao->vertexesSize, data, glUsage);
428306
429307
430308 // create IBO
431309 vao->indexesSize = numIndexes * sizeof(glIndex_t);
432310
433 qglGenBuffersARB(1, &vao->indexesIBO);
434
435 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesIBO);
436 qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesSize, indexes, glUsage);
311 qglGenBuffers(1, &vao->indexesIBO);
312
313 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
314 qglBufferData(GL_ELEMENT_ARRAY_BUFFER, vao->indexesSize, indexes, glUsage);
437315
438316
439317 Vao_SetVertexPointers(vao);
479357
480358 if (glRefConfig.vertexArrayObject)
481359 {
482 qglBindVertexArrayARB(vao->vao);
360 qglBindVertexArray(vao->vao);
483361
484362 // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel?
485363 if (1)
486 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
364 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
487365
488366 // tess VAO always has buffers bound
489367 if (vao == tess.vao)
490 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
368 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
491369 }
492370 else
493371 {
494 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO);
495 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesIBO);
372 qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO);
373 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO);
496374
497375 // tess VAO doesn't have vertex pointers set until data is uploaded
498376 if (vao != tess.vao)
514392 {
515393 if (glRefConfig.vertexArrayObject)
516394 {
517 qglBindVertexArrayARB(0);
395 qglBindVertexArray(0);
518396
519397 // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel?
520 if (1) qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
398 if (1) qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
521399 }
522400 else
523401 {
524 qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
525 qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
402 qglBindBuffer(GL_ARRAY_BUFFER, 0);
403 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
526404 }
527405 glState.currentVao = NULL;
528406 }
547425
548426 vertexesSize = sizeof(tess.xyz[0]);
549427 vertexesSize += sizeof(tess.normal[0]);
550 #ifdef USE_VERT_TANGENT_SPACE
551428 vertexesSize += sizeof(tess.tangent[0]);
552 #endif
553 vertexesSize += sizeof(tess.vertexColors[0]);
429 vertexesSize += sizeof(tess.color[0]);
554430 vertexesSize += sizeof(tess.texCoords[0][0]) * 2;
555431 vertexesSize += sizeof(tess.lightdir[0]);
556432 vertexesSize *= SHADER_MAX_VERTEXES;
563439
564440 tess.vao->attribs[ATTR_INDEX_POSITION ].enabled = 1;
565441 tess.vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1;
566 #ifdef USE_VERT_TANGENT_SPACE
567442 tess.vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1;
568 #endif
569443 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1;
570444 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].enabled = 1;
571445 tess.vao->attribs[ATTR_INDEX_COLOR ].enabled = 1;
580454 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4;
581455
582456 tess.vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT;
583 tess.vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType;
584 tess.vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType;
457 tess.vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT;
458 tess.vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT;
585459 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT;
586460 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT;
587 tess.vao->attribs[ATTR_INDEX_COLOR ].type = GL_FLOAT;
588 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType;
461 tess.vao->attribs[ATTR_INDEX_COLOR ].type = GL_UNSIGNED_SHORT;
462 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = GL_SHORT;
589463
590464 tess.vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE;
591465 tess.vao->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE;
592466 tess.vao->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE;
593467 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE;
594468 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].normalized = GL_FALSE;
595 tess.vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_FALSE;
469 tess.vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_TRUE;
596470 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE;
597471
598472 tess.vao->attribs[ATTR_INDEX_POSITION ].offset = offset; offset += sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES;
599473 tess.vao->attribs[ATTR_INDEX_NORMAL ].offset = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES;
600 #ifdef USE_VERT_TANGENT_SPACE
601474 tess.vao->attribs[ATTR_INDEX_TANGENT ].offset = offset; offset += sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES;
602 #endif
603475 // these next two are actually interleaved
604476 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].offset = offset;
605477 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = offset + sizeof(tess.texCoords[0][0]);
606478 offset += sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES;
607479
608 tess.vao->attribs[ATTR_INDEX_COLOR ].offset = offset; offset += sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES;
480 tess.vao->attribs[ATTR_INDEX_COLOR ].offset = offset; offset += sizeof(tess.color[0]) * SHADER_MAX_VERTEXES;
609481 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = offset;
610482
611483 tess.vao->attribs[ATTR_INDEX_POSITION ].stride = sizeof(tess.xyz[0]);
612484 tess.vao->attribs[ATTR_INDEX_NORMAL ].stride = sizeof(tess.normal[0]);
613 #ifdef USE_VERT_TANGENT_SPACE
614485 tess.vao->attribs[ATTR_INDEX_TANGENT ].stride = sizeof(tess.tangent[0]);
615 #endif
616 tess.vao->attribs[ATTR_INDEX_COLOR ].stride = sizeof(tess.vertexColors[0]);
486 tess.vao->attribs[ATTR_INDEX_COLOR ].stride = sizeof(tess.color[0]);
617487 tess.vao->attribs[ATTR_INDEX_TEXCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2;
618488 tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].stride = sizeof(tess.texCoords[0][0]) * 2;
619489 tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].stride = sizeof(tess.lightdir[0]);
621491 tess.attribPointers[ATTR_INDEX_POSITION] = tess.xyz;
622492 tess.attribPointers[ATTR_INDEX_TEXCOORD] = tess.texCoords;
623493 tess.attribPointers[ATTR_INDEX_NORMAL] = tess.normal;
624 #ifdef USE_VERT_TANGENT_SPACE
625494 tess.attribPointers[ATTR_INDEX_TANGENT] = tess.tangent;
626 #endif
627 tess.attribPointers[ATTR_INDEX_COLOR] = tess.vertexColors;
495 tess.attribPointers[ATTR_INDEX_COLOR] = tess.color;
628496 tess.attribPointers[ATTR_INDEX_LIGHTDIRECTION] = tess.lightdir;
629497
630498 Vao_SetVertexPointers(tess.vao);
653521 vao = tr.vaos[i];
654522
655523 if(vao->vao)
656 qglDeleteVertexArraysARB(1, &vao->vao);
524 qglDeleteVertexArrays(1, &vao->vao);
657525
658526 if(vao->vertexesVBO)
659527 {
660 qglDeleteBuffersARB(1, &vao->vertexesVBO);
528 qglDeleteBuffers(1, &vao->vertexesVBO);
661529 }
662530
663531 if(vao->indexesIBO)
664532 {
665 qglDeleteBuffersARB(1, &vao->indexesIBO);
533 qglDeleteBuffers(1, &vao->indexesIBO);
666534 }
667535 }
668536
736604 R_BindVao(tess.vao);
737605
738606 // orphan old vertex buffer so we don't stall on it
739 qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vao->vertexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
607 qglBufferData(GL_ARRAY_BUFFER, tess.vao->vertexesSize, NULL, GL_DYNAMIC_DRAW);
740608
741609 // if nothing to set, set everything
742610 if(!(attribBits & ATTR_BITS))
760628 if (attribUpload & attribBit)
761629 {
762630 // note: tess has a VBO where stride == size
763 qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vAtb->offset, tess.numVertexes * vAtb->stride, tess.attribPointers[attribIndex]);
631 qglBufferSubData(GL_ARRAY_BUFFER, vAtb->offset, tess.numVertexes * vAtb->stride, tess.attribPointers[attribIndex]);
764632 }
765633
766634 if (attribBits & attribBit)
767635 {
768636 if (!glRefConfig.vertexArrayObject)
769 qglVertexAttribPointerARB(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
637 qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset));
770638
771639 if (!(glState.vertexAttribsEnabled & attribBit))
772640 {
773 qglEnableVertexAttribArrayARB(attribIndex);
641 qglEnableVertexAttribArray(attribIndex);
774642 glState.vertexAttribsEnabled |= attribBit;
775643 }
776644 }
778646 {
779647 if ((glState.vertexAttribsEnabled & attribBit))
780648 {
781 qglDisableVertexAttribArrayARB(attribIndex);
649 qglDisableVertexAttribArray(attribIndex);
782650 glState.vertexAttribsEnabled &= ~attribBit;
783651 }
784652 }
785653 }
786654
787655 // orphan old index buffer so we don't stall on it
788 qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, tess.vao->indexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
789
790 qglBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes);
791 }
792 }
656 qglBufferData(GL_ELEMENT_ARRAY_BUFFER, tess.vao->indexesSize, NULL, GL_DYNAMIC_DRAW);
657
658 qglBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes);
659 }
660 }
499499 R_RecursiveWorldNode
500500 ================
501501 */
502 static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits, int pshadowBits ) {
502 static void R_RecursiveWorldNode( mnode_t *node, uint32_t planeBits, uint32_t dlightBits, uint32_t pshadowBits ) {
503503
504504 do {
505 int newDlights[2];
506 unsigned int newPShadows[2];
505 uint32_t newDlights[2];
506 uint32_t newPShadows[2];
507507
508508 // if the node wasn't marked as potentially visible, exit
509509 // pvs is skipped for depth shadows
845845 =============
846846 */
847847 void R_AddWorldSurfaces( void ) {
848 int planeBits, dlightBits, pshadowBits;
848 uint32_t planeBits, dlightBits, pshadowBits;
849849
850850 if ( !r_drawworld->integer ) {
851851 return;
866866 ClearBounds( tr.viewParms.visBounds[0], tr.viewParms.visBounds[1] );
867867
868868 // perform frustum culling and flag all the potentially visible surfaces
869 if ( tr.refdef.num_dlights > 32 ) {
870 tr.refdef.num_dlights = 32 ;
871 }
872
873 if ( tr.refdef.num_pshadows > 32 ) {
874 tr.refdef.num_pshadows = 32 ;
869 if ( tr.refdef.num_dlights > MAX_DLIGHTS ) {
870 tr.refdef.num_dlights = MAX_DLIGHTS ;
871 }
872
873 if ( tr.refdef.num_pshadows > MAX_DRAWN_PSHADOWS ) {
874 tr.refdef.num_pshadows = MAX_DRAWN_PSHADOWS;
875875 }
876876
877877 planeBits = (tr.viewParms.flags & VPF_FARPLANEFRUSTUM) ? 31 : 15;
883883 }
884884 else if ( !(tr.viewParms.flags & VPF_SHADOWMAP) )
885885 {
886 dlightBits = ( 1 << tr.refdef.num_dlights ) - 1;
887 pshadowBits = ( 1 << tr.refdef.num_pshadows ) - 1;
886 dlightBits = ( 1ULL << tr.refdef.num_dlights ) - 1;
887 pshadowBits = ( 1ULL << tr.refdef.num_pshadows ) - 1;
888888 }
889889 else
890890 {
891 dlightBits = ( 1 << tr.refdef.num_dlights ) - 1;
891 dlightBits = ( 1ULL << tr.refdef.num_dlights ) - 1;
892892 pshadowBits = 0;
893893 }
894894
00 /*
11 ===========================================================================
2 Copyright (C) 1999-2005 Id Software, Inc.
3
4 This file is part of Quake III Arena source code.
5
6 Quake III Arena source code is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 Quake III Arena source code is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
2
3 Return to Castle Wolfenstein single player GPL Source Code
4 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
5
6 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”).
7
8 RTCW SP Source Code is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 RTCW SP Source Code is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
1315 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1416 GNU General Public License for more details.
1517
1618 You should have received a copy of the GNU General Public License
17 along with Quake III Arena source code; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 along with RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
20
21 In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below.
22
23 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
24
1925 ===========================================================================
2026 */
27
2128 /*
2229 ** QGL.H
2330 */
4451 #endif
4552 #endif
4653
47 extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
48 extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
49 extern void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
50
51 extern void ( APIENTRY * qglLockArraysEXT )( GLint, GLint );
52 extern void ( APIENTRY * qglUnlockArraysEXT )( void );
54 extern void (APIENTRYP qglActiveTextureARB) (GLenum texture);
55 extern void (APIENTRYP qglClientActiveTextureARB) (GLenum texture);
56 extern void (APIENTRYP qglMultiTexCoord2fARB) (GLenum target, GLfloat s, GLfloat t);
57
58 extern void (APIENTRYP qglLockArraysEXT) (GLint first, GLsizei count);
59 extern void (APIENTRYP qglUnlockArraysEXT) (void);
5360
5461 #ifdef USE_OPENGLES
5562 #define GLdouble GLfloat
8491 // GL_ATI_pn_triangles
8592 #ifndef GL_ATI_pn_triangles
8693 #define GL_ATI_pn_triangles 1
87 #ifndef MACOS_X //DAJ BUGFIX changed the numbers
94 #ifndef __APPLE__ //DAJ BUGFIX changed the numbers
8895 #define GL_PN_TRIANGLES_ATI 0x6090
8996 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x6091
9097 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x6092
105112 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
106113 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
107114 #endif
108 typedef void ( APIENTRY * PFNGLPNTRIANGLESIATIPROC )( GLenum pname, GLint param );
109 typedef void ( APIENTRY * PFNGLPNTRIANGLESFATIPROC )( GLenum pname, GLfloat param );
115 typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC)(GLenum pname, GLint param);
116 typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param);
110117 #endif
111118
112119 //----(SA) added
113 extern void ( APIENTRY * qglPNTrianglesiATI )( GLenum pname, GLint param );
114 extern void ( APIENTRY * qglPNTrianglesfATI )( GLenum pname, GLfloat param );
120 extern void (APIENTRYP qglPNTrianglesiATI)(GLenum pname, GLint param);
121 extern void (APIENTRYP qglPNTrianglesfATI)(GLenum pname, GLfloat param);
115122 //----(SA) end
116123
117124 // for NV fog distance
511518 #define qglVertexPointer glVertexPointer
512519 #define qglViewport glViewport
513520
514 // GL_EXT_draw_range_elements
515 extern void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
516
517 // GL_EXT_multi_draw_arrays
518 extern void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
519 extern void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
520
521 #ifndef USE_OPENGLES
522 // rend2
523
524 // GL_ARB_shading_language_100
525 #ifndef GL_ARB_shading_language_100
526 #define GL_ARB_shading_language_100
527 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
528 #endif
529
530 // GL_ARB_vertex_program
531 extern void (APIENTRY * qglVertexAttrib4fARB) (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
532 extern void (APIENTRY * qglVertexAttrib4fvARB) (GLuint, const GLfloat *);
533 extern void (APIENTRY * qglVertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized,
534 GLsizei stride, const GLvoid * pointer);
535 extern void (APIENTRY * qglEnableVertexAttribArrayARB) (GLuint index);
536 extern void (APIENTRY * qglDisableVertexAttribArrayARB) (GLuint index);
537
538 // GL_ARB_vertex_buffer_object
539 extern void (APIENTRY * qglBindBufferARB) (GLenum target, GLuint buffer);
540 extern void (APIENTRY * qglDeleteBuffersARB) (GLsizei n, const GLuint * buffers);
541 extern void (APIENTRY * qglGenBuffersARB) (GLsizei n, GLuint * buffers);
542 extern GLboolean(APIENTRY * qglIsBufferARB) (GLuint buffer);
543 extern void (APIENTRY * qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
544 extern void (APIENTRY * qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
545 extern void (APIENTRY * qglGetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data);
546 extern void (APIENTRY * qglGetBufferParameterivARB) (GLenum target, GLenum pname, GLint * params);
547 extern void (APIENTRY * qglGetBufferPointervARB) (GLenum target, GLenum pname, GLvoid * *params);
548
549 // GL_ARB_shader_objects
550 extern void (APIENTRY * qglDeleteObjectARB) (GLhandleARB obj);
551 extern GLhandleARB(APIENTRY * qglGetHandleARB) (GLenum pname);
552 extern void (APIENTRY * qglDetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj);
553 extern GLhandleARB(APIENTRY * qglCreateShaderObjectARB) (GLenum shaderType);
554 extern void (APIENTRY * qglShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB * *string,
555 const GLint * length);
556 extern void (APIENTRY * qglCompileShaderARB) (GLhandleARB shaderObj);
557 extern GLhandleARB(APIENTRY * qglCreateProgramObjectARB) (void);
558 extern void (APIENTRY * qglAttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj);
559 extern void (APIENTRY * qglLinkProgramARB) (GLhandleARB programObj);
560 extern void (APIENTRY * qglUseProgramObjectARB) (GLhandleARB programObj);
561 extern void (APIENTRY * qglValidateProgramARB) (GLhandleARB programObj);
562 extern void (APIENTRY * qglUniform1fARB) (GLint location, GLfloat v0);
563 extern void (APIENTRY * qglUniform2fARB) (GLint location, GLfloat v0, GLfloat v1);
564 extern void (APIENTRY * qglUniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
565 extern void (APIENTRY * qglUniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
566 extern void (APIENTRY * qglUniform1iARB) (GLint location, GLint v0);
567 extern void (APIENTRY * qglUniform2iARB) (GLint location, GLint v0, GLint v1);
568 extern void (APIENTRY * qglUniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2);
569 extern void (APIENTRY * qglUniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
570 extern void (APIENTRY * qglUniform1fvARB) (GLint location, GLsizei count, const GLfloat * value);
571 extern void (APIENTRY * qglUniform2fvARB) (GLint location, GLsizei count, const GLfloat * value);
572 extern void (APIENTRY * qglUniform3fvARB) (GLint location, GLsizei count, const GLfloat * value);
573 extern void (APIENTRY * qglUniform4fvARB) (GLint location, GLsizei count, const GLfloat * value);
574 extern void (APIENTRY * qglUniform2ivARB) (GLint location, GLsizei count, const GLint * value);
575 extern void (APIENTRY * qglUniform3ivARB) (GLint location, GLsizei count, const GLint * value);
576 extern void (APIENTRY * qglUniform4ivARB) (GLint location, GLsizei count, const GLint * value);
577 extern void (APIENTRY * qglUniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
578 extern void (APIENTRY * qglUniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
579 extern void (APIENTRY * qglUniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
580 extern void (APIENTRY * qglGetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat * params);
581 extern void (APIENTRY * qglGetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint * params);
582 extern void (APIENTRY * qglGetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog);
583 extern void (APIENTRY * qglGetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count,
584 GLhandleARB * obj);
585 extern GLint(APIENTRY * qglGetUniformLocationARB) (GLhandleARB programObj, const GLcharARB * name);
586 extern void (APIENTRY * qglGetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxIndex, GLsizei * length,
587 GLint * size, GLenum * type, GLcharARB * name);
588 extern void (APIENTRY * qglGetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat * params);
589 extern void (APIENTRY * qglGetUniformivARB) (GLhandleARB programObj, GLint location, GLint * params);
590 extern void (APIENTRY * qglGetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source);
591
592 // GL_ARB_vertex_shader
593 extern void (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB * name);
594 extern void (APIENTRY * qglGetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length,
595 GLint * size, GLenum * type, GLcharARB * name);
596 extern GLint(APIENTRY * qglGetAttribLocationARB) (GLhandleARB programObj, const GLcharARB * name);
597
598 // GL_ARB_texture_compression
599 extern void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
600 GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
601 extern void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
602 GLint border, GLsizei imageSize, const GLvoid *data);
603 extern void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
604 GLsizei imageSize, const GLvoid *data);
605 extern void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
606 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
607 extern void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
608 GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
609 extern void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
610 GLsizei imageSize, const GLvoid *data);
611 extern void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
612 GLvoid *img);
521 // GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
522
523 // OpenGL 1.2, was GL_EXT_draw_range_elements
524 #define QGL_1_2_PROCS \
525 GLE(void, DrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) \
526
527 // OpenGL 1.3, was GL_ARB_texture_compression
528 #define QGL_1_3_PROCS \
529 GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
530 GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
531
532 // OpenGL 1.4, was GL_EXT_multi_draw_arrays
533 #define QGL_1_4_PROCS \
534 GLE(void, MultiDrawElements, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) \
535
536 // OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
537 #define QGL_1_5_PROCS \
538 GLE(void, GenQueries, GLsizei n, GLuint *ids) \
539 GLE(void, DeleteQueries, GLsizei n, const GLuint *ids) \
540 GLE(void, BeginQuery, GLenum target, GLuint id) \
541 GLE(void, EndQuery, GLenum target) \
542 GLE(void, GetQueryObjectiv, GLuint id, GLenum pname, GLint *params) \
543 GLE(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params) \
544 GLE(void, BindBuffer, GLenum target, GLuint buffer) \
545 GLE(void, DeleteBuffers, GLsizei n, const GLuint *buffers) \
546 GLE(void, GenBuffers, GLsizei n, GLuint *buffers) \
547 GLE(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) \
548 GLE(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) \
549
550 // OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
551 #define QGL_2_0_PROCS \
552 GLE(void, AttachShader, GLuint program, GLuint shader) \
553 GLE(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) \
554 GLE(void, CompileShader, GLuint shader) \
555 GLE(GLuint, CreateProgram, void) \
556 GLE(GLuint, CreateShader, GLenum type) \
557 GLE(void, DeleteProgram, GLuint program) \
558 GLE(void, DeleteShader, GLuint shader) \
559 GLE(void, DetachShader, GLuint program, GLuint shader) \
560 GLE(void, DisableVertexAttribArray, GLuint index) \
561 GLE(void, EnableVertexAttribArray, GLuint index) \
562 GLE(void, GetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) \
563 GLE(void, GetProgramiv, GLuint program, GLenum pname, GLint *params) \
564 GLE(void, GetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
565 GLE(void, GetShaderiv, GLuint shader, GLenum pname, GLint *params) \
566 GLE(void, GetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
567 GLE(void, GetShaderSource, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) \
568 GLE(GLint, GetUniformLocation, GLuint program, const GLchar *name) \
569 GLE(void, LinkProgram, GLuint program) \
570 GLE(void, ShaderSource, GLuint shader, GLsizei count, const GLchar* *string, const GLint *length) \
571 GLE(void, UseProgram, GLuint program) \
572 GLE(void, Uniform1f, GLint location, GLfloat v0) \
573 GLE(void, Uniform2f, GLint location, GLfloat v0, GLfloat v1) \
574 GLE(void, Uniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
575 GLE(void, Uniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
576 GLE(void, Uniform1i, GLint location, GLint v0) \
577 GLE(void, Uniform1fv, GLint location, GLsizei count, const GLfloat *value) \
578 GLE(void, UniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
579 GLE(void, ValidateProgram, GLuint program) \
580 GLE(void, VertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) \
613581
614582 // GL_NVX_gpu_memory_info
615583 #ifndef GL_NVX_gpu_memory_info
660628 #endif
661629
662630 // GL_EXT_framebuffer_object
663 extern GLboolean (APIENTRY * qglIsRenderbufferEXT)(GLuint renderbuffer);
664 extern void (APIENTRY * qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
665 extern void (APIENTRY * qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
666 extern void (APIENTRY * qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
667 extern void (APIENTRY * qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
668 extern void (APIENTRY * qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
669 extern GLboolean (APIENTRY * qglIsFramebufferEXT)(GLuint framebuffer);
670 extern void (APIENTRY * qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
671 extern void (APIENTRY * qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
672 extern void (APIENTRY * qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
673 extern GLenum (APIENTRY * qglCheckFramebufferStatusEXT)(GLenum target);
674 extern void (APIENTRY * qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
675 GLint level);
676 extern void (APIENTRY * qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
677 GLint level);
678 extern void (APIENTRY * qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
679 GLint level, GLint zoffset);
680 extern void (APIENTRY * qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget,
681 GLuint renderbuffer);
682 extern void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
683 extern void (APIENTRY * qglGenerateMipmapEXT)(GLenum target);
631 #define QGL_EXT_framebuffer_object_PROCS \
632 GLE(void, BindRenderbufferEXT, GLenum target, GLuint renderbuffer) \
633 GLE(void, DeleteRenderbuffersEXT, GLsizei n, const GLuint *renderbuffers) \
634 GLE(void, GenRenderbuffersEXT, GLsizei n, GLuint *renderbuffers) \
635 GLE(void, RenderbufferStorageEXT, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
636 GLE(void, BindFramebufferEXT, GLenum target, GLuint framebuffer) \
637 GLE(void, DeleteFramebuffersEXT, GLsizei n, const GLuint *framebuffers) \
638 GLE(void, GenFramebuffersEXT, GLsizei n, GLuint *framebuffers) \
639 GLE(GLenum, CheckFramebufferStatusEXT, GLenum target) \
640 GLE(void, FramebufferTexture2DEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
641 GLE(void, FramebufferRenderbufferEXT, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
642 GLE(void, GenerateMipmapEXT, GLenum target) \
684643
685644 #ifndef GL_EXT_framebuffer_object
686645 #define GL_EXT_framebuffer_object
737696 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
738697 #endif
739698
740 // GL_EXT_packed_depth_stencil
741 #ifndef GL_EXT_packed_depth_stencil
742 #define GL_EXT_packed_depth_stencil
743 #define GL_DEPTH_STENCIL_EXT 0x84F9
744 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA
745 #define GL_DEPTH24_STENCIL8_EXT 0x88F0
746 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
747 #endif
748
749 // GL_ARB_occlusion_query
750 extern void (APIENTRY * qglGenQueriesARB)(GLsizei n, GLuint *ids);
751 extern void (APIENTRY * qglDeleteQueriesARB)(GLsizei n, const GLuint *ids);
752 extern GLboolean (APIENTRY * qglIsQueryARB)(GLuint id);
753 extern void (APIENTRY * qglBeginQueryARB)(GLenum target, GLuint id);
754 extern void (APIENTRY * qglEndQueryARB)(GLenum target);
755 extern void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
756 extern void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
757 extern void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
758
759 #ifndef GL_ARB_occlusion_query
760 #define GL_ARB_occlusion_query
761 #define GL_SAMPLES_PASSED_ARB 0x8914
762 #define GL_QUERY_COUNTER_BITS_ARB 0x8864
763 #define GL_CURRENT_QUERY_ARB 0x8865
764 #define GL_QUERY_RESULT_ARB 0x8866
765 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
766 #endif
767
768699 // GL_EXT_framebuffer_blit
769 extern void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
770 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
771 GLbitfield mask, GLenum filter);
700 #define QGL_EXT_framebuffer_blit_PROCS \
701 GLE(void, BlitFramebufferEXT, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
772702
773703 #ifndef GL_EXT_framebuffer_blit
774704 #define GL_EXT_framebuffer_blit
779709 #endif
780710
781711 // GL_EXT_framebuffer_multisample
782 extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
783 GLenum internalformat, GLsizei width, GLsizei height);
712 #define QGL_EXT_framebuffer_multisample_PROCS \
713 GLE(void, RenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
784714
785715 #ifndef GL_EXT_framebuffer_multisample
786716 #define GL_EXT_framebuffer_multisample
789719 #define GL_MAX_SAMPLES_EXT 0x8D57
790720 #endif
791721
792 #ifndef GL_EXT_texture_sRGB
793 #define GL_EXT_texture_sRGB
794 #define GL_SRGB_EXT 0x8C40
795 #define GL_SRGB8_EXT 0x8C41
796 #define GL_SRGB_ALPHA_EXT 0x8C42
797 #define GL_SRGB8_ALPHA8_EXT 0x8C43
798 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44
799 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
800 #define GL_SLUMINANCE_EXT 0x8C46
801 #define GL_SLUMINANCE8_EXT 0x8C47
802 #define GL_COMPRESSED_SRGB_EXT 0x8C48
803 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
804 #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
805 #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
806 #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
807 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
808 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
809 #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
810 #endif
811
812 #ifndef GL_EXT_framebuffer_sRGB
813 #define GL_EXT_framebuffer_sRGB
814 #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
815 #endif
816
817 #ifndef GL_EXT_texture_compression_latc
818 #define GL_EXT_texture_compression_latc
819 #define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
820 #define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
821 #define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
822 #define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
722 #ifndef GL_ARB_texture_compression_rgtc
723 #define GL_ARB_texture_compression_rgtc
724 #define GL_COMPRESSED_RED_RGTC1 0x8DBB
725 #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
726 #define GL_COMPRESSED_RG_RGTC2 0x8DBD
727 #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
823728 #endif
824729
825730 #ifndef GL_ARB_texture_compression_bptc
830735 #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
831736 #endif
832737
833 // GL_ARB_draw_buffers
834 extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
835 #ifndef GL_ARB_draw_buffers
836 #define GL_ARB_draw_buffers
837 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824
838 #define GL_DRAW_BUFFER0_ARB 0x8825
839 #define GL_DRAW_BUFFER1_ARB 0x8826
840 #define GL_DRAW_BUFFER2_ARB 0x8827
841 #define GL_DRAW_BUFFER3_ARB 0x8828
842 #define GL_DRAW_BUFFER4_ARB 0x8829
843 #define GL_DRAW_BUFFER5_ARB 0x882A
844 #define GL_DRAW_BUFFER6_ARB 0x882B
845 #define GL_DRAW_BUFFER7_ARB 0x882C
846 #define GL_DRAW_BUFFER8_ARB 0x882D
847 #define GL_DRAW_BUFFER9_ARB 0x882E
848 #define GL_DRAW_BUFFER10_ARB 0x882F
849 #define GL_DRAW_BUFFER11_ARB 0x8830
850 #define GL_DRAW_BUFFER12_ARB 0x8831
851 #define GL_DRAW_BUFFER13_ARB 0x8832
852 #define GL_DRAW_BUFFER14_ARB 0x8833
853 #define GL_DRAW_BUFFER15_ARB 0x8834
854 #endif
855
856738 #ifndef GL_ARB_depth_clamp
857739 #define GL_ARB_depth_clamp
858740 #define GL_DEPTH_CLAMP 0x864F
864746 #endif
865747
866748 // GL_ARB_vertex_array_object
867 extern void (APIENTRY * qglBindVertexArrayARB)(GLuint array);
868 extern void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays);
869 extern void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
870 extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
749 #define QGL_ARB_vertex_array_object_PROCS \
750 GLE(void, BindVertexArray, GLuint array) \
751 GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
752 GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
753
871754 #ifndef GL_ARB_vertex_array_object
872755 #define GL_ARB_vertex_array_object
873756 #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5
874757 #endif
875758
876 #if defined(WIN32)
877 // WGL_ARB_create_context
878 #ifndef WGL_ARB_create_context
879 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
880 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
881 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
882 #define WGL_CONTEXT_FLAGS_ARB 0x2094
883 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
884 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
885 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
886 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
887 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
888 #define ERROR_INVALID_VERSION_ARB 0x2095
889 #define ERROR_INVALID_PROFILE_ARB 0x2096
890 #endif
891
892 extern HGLRC(APIENTRY * qwglCreateContextAttribsARB) (HDC hdC, HGLRC hShareContext, const int *attribList);
893 #endif
894
895 #if 0 //defined(__linux__)
896 // GLX_ARB_create_context
897 #ifndef GLX_ARB_create_context
898 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
899 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
900 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
901 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
902 #define GLX_CONTEXT_FLAGS_ARB 0x2094
903 #endif
904
905 extern GLXContext (APIENTRY * qglXCreateContextAttribsARB) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
906 #endif
907
908 #endif // USE_OPENGLES
759 // GL_EXT_direct_state_access
760 #define QGL_EXT_direct_state_access_PROCS \
761 GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
762 GLE(GLvoid, TextureParameterfEXT, GLuint texture, GLenum target, GLenum pname, GLfloat param) \
763 GLE(GLvoid, TextureParameteriEXT, GLuint texture, GLenum target, GLenum pname, GLint param) \
764 GLE(GLvoid, TextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
765 GLE(GLvoid, TextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
766 GLE(GLvoid, CopyTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) \
767 GLE(GLvoid, CompressedTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) \
768 GLE(GLvoid, CompressedTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) \
769 GLE(GLvoid, GenerateTextureMipmapEXT, GLuint texture, GLenum target) \
770 GLE(GLvoid, ProgramUniform1iEXT, GLuint program, GLint location, GLint v0) \
771 GLE(GLvoid, ProgramUniform1fEXT, GLuint program, GLint location, GLfloat v0) \
772 GLE(GLvoid, ProgramUniform2fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1) \
773 GLE(GLvoid, ProgramUniform3fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
774 GLE(GLvoid, ProgramUniform4fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
775 GLE(GLvoid, ProgramUniform1fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value) \
776 GLE(GLvoid, ProgramUniformMatrix4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
777 GLE(GLvoid, NamedRenderbufferStorageEXT, GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) \
778 GLE(GLvoid, NamedRenderbufferStorageMultisampleEXT, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
779 GLE(GLenum, CheckNamedFramebufferStatusEXT, GLuint framebuffer, GLenum target) \
780 GLE(GLvoid, NamedFramebufferTexture2DEXT, GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
781 GLE(GLvoid, NamedFramebufferRenderbufferEXT, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
782
783 #define GLE(ret, name, ...) typedef ret APIENTRY name##proc(__VA_ARGS__); extern name##proc * qgl##name;
784 QGL_1_2_PROCS;
785 QGL_1_3_PROCS;
786 QGL_1_4_PROCS;
787 QGL_1_5_PROCS;
788 QGL_2_0_PROCS;
789 QGL_EXT_framebuffer_object_PROCS;
790 QGL_EXT_framebuffer_blit_PROCS;
791 QGL_EXT_framebuffer_multisample_PROCS;
792 QGL_ARB_vertex_array_object_PROCS;
793 QGL_EXT_direct_state_access_PROCS;
794 #undef GLE
909795
910796 #endif // __QGL_H__
4343 //#define DBG_PROFILE_BONES
4444
4545 //-----------------------------------------------------------------------------
46 // Static Vars, ugly but easiest (and fastest) means of seperating RB_SurfaceAnim
46 // Static Vars, ugly but easiest (and fastest) means of separating RB_SurfaceAnim
4747 // and R_CalcBones
4848
4949 static float frontlerp, backlerp;
341341 ==================
342342 */
343343 void RB_TestFlare( flare_t *f ) {
344 qboolean visible;
345 float fade;
344 float depth;
345 qboolean visible;
346 float fade;
347 float screenZ;
346348
347349 backEnd.pc.c_flareTests++;
348350
351 // doing a readpixels is as good as doing a glFinish(), so
352 // don't bother with another sync
353 glState.finishCalled = qfalse;
354
355 // read back the z buffer contents
356 #ifdef USE_OPENGLES
357 screenZ = 0;
358 #else
359 qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
360
361 screenZ = backEnd.viewParms.projectionMatrix[14] /
362 ( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
363 #endif
364
349365 visible = (qboolean)( f->flags & 1 );
366
367 if ( -f->eyeZ - -screenZ > 24 )
368 visible = qfalse;
350369
351370 if ( visible ) {
352371 if ( !f->visible ) {
353372 f->visible = qtrue;
354373 f->fadeTime = backEnd.refdef.time - 1;
355374 }
356 fade = ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
375 fade = ( ( backEnd.refdef.time - f->fadeTime ) /1000.0f ) * r_flareFade->value;
357376 } else {
358377 if ( f->visible ) {
359378 f->visible = qfalse;
7979 #include "../qcommon/qcommon.h"
8080
8181 #ifdef BUILD_FREETYPE
82 #include <ft2build.h>
82 #ifdef USE_LOCAL_HEADERS
83 #include "../freetype-2.6.4/include/ft2build.h"
84 #else
85 #include <ft2build.h>
86 #endif
8387 #include FT_FREETYPE_H
8488 #include FT_ERRORS_H
8589 #include FT_SYSTEM_H
17291729 for ( i = 0; i < tr.numImages ; i++ ) {
17301730 qglDeleteTextures( 1, &tr.images[i]->texnum );
17311731 }
1732 memset( tr.images, 0, sizeof( tr.images ) );
1733
1734 memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
1732 Com_Memset( tr.images, 0, sizeof( tr.images ) );
1733
1734 tr.numImages = 0;
1735
1736 Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
17351737 if ( qglActiveTextureARB ) {
17361738 GL_SelectTexture( 1 );
17371739 qglBindTexture( GL_TEXTURE_2D, 0 );
10151015 */
10161016 void R_PrintLongString(const char *string) {
10171017 char buffer[1024];
1018 const char *p;
1019 int size = strlen(string);
1020
1021 p = string;
1022 while(size > 0)
1018 const char *p = string;
1019 int remainingLength = strlen(string);
1020
1021 while (remainingLength > 0)
10231022 {
1024 Q_strncpyz(buffer, p, sizeof (buffer) );
1023 // Take as much characters as possible from the string without splitting words between buffers
1024 // This avoids the client console splitting a word up when one half fits on the current line,
1025 // but the second half would have to be written on a new line
1026 int charsToTake = sizeof(buffer) - 1;
1027 if (remainingLength > charsToTake) {
1028 while (p[charsToTake - 1] > ' ' && p[charsToTake] > ' ') {
1029 charsToTake--;
1030 if (charsToTake == 0) {
1031 charsToTake = sizeof(buffer) - 1;
1032 break;
1033 }
1034 }
1035 } else if (remainingLength < charsToTake) {
1036 charsToTake = remainingLength;
1037 }
1038
1039 Q_strncpyz( buffer, p, charsToTake + 1 );
10251040 ri.Printf( PRINT_ALL, "%s", buffer );
1026 p += 1023;
1027 size -= 1023;
1041 remainingLength -= charsToTake;
1042 p += charsToTake;
10281043 }
10291044 }
10301045
12001215 r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH );
12011216 #ifdef USE_OPENGLES
12021217 r_mode = ri.Cvar_Get( "r_mode", "-2", CVAR_ARCHIVE | CVAR_LATCH );
1218 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
12031219 #else
12041220 r_mode = ri.Cvar_Get( "r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH );
1221 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "0", CVAR_ARCHIVE | CVAR_LATCH );
12051222 #endif
1206 r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
12071223 r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE | CVAR_LATCH );
12081224 r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
12091225 r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
189189 byte *data;
190190 int lat, lng;
191191 vec3_t normal;
192
192 #if idppc
193 float d0, d1, d2, d3, d4, d5;
194 #endif
193195 factor = 1.0;
194196 data = gridData;
195197 for ( j = 0 ; j < 3 ; j++ ) {
211213 continue; // ignore samples in walls
212214 }
213215 totalFactor += factor;
214
216 #if idppc
217 d0 = data[0]; d1 = data[1]; d2 = data[2];
218 d3 = data[3]; d4 = data[4]; d5 = data[5];
219
220 ent->ambientLight[0] += factor * d0;
221 ent->ambientLight[1] += factor * d1;
222 ent->ambientLight[2] += factor * d2;
223
224 ent->directedLight[0] += factor * d3;
225 ent->directedLight[1] += factor * d4;
226 ent->directedLight[2] += factor * d5;
227 #else
215228 ent->ambientLight[0] += factor * data[0];
216229 ent->ambientLight[1] += factor * data[1];
217230 ent->ambientLight[2] += factor * data[2];
219232 ent->directedLight[0] += factor * data[3];
220233 ent->directedLight[1] += factor * data[4];
221234 ent->directedLight[2] += factor * data[5];
222
235 #endif
223236 lat = data[7];
224237 lng = data[6];
225238 lat *= ( FUNCTABLE_SIZE / 256 );
392405 LogLight( ent );
393406 }
394407
395 // save out the byte packet version
396 ( (byte *)&ent->ambientLightInt )[0] = ri.ftol( ent->ambientLight[0] );
397 ( (byte *)&ent->ambientLightInt )[1] = ri.ftol( ent->ambientLight[1] );
398 ( (byte *)&ent->ambientLightInt )[2] = ri.ftol( ent->ambientLight[2] );
399 ( (byte *)&ent->ambientLightInt )[3] = 0xff;
400
401408 // transform the direction to local space
402409 VectorNormalize( lightDir );
403410 ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
2424
2525 ===========================================================================
2626 */
27
2827
2928
3029 #ifndef TR_LOCAL_H
7069 qboolean lightingCalculated;
7170 vec3_t lightDir; // normalized direction towards light
7271 vec3_t ambientLight; // color normalized to 0-255
73 int ambientLightInt; // 32 bit rgba packed
7472 vec3_t directedLight;
7573 float brightness;
7674 } trRefEntity_t;
2828 // tr_shade.c
2929
3030 #include "tr_local.h"
31 #if idppc_altivec && !defined(MACOS_X)
31 #if idppc_altivec && !defined(__APPLE__)
3232 #include <altivec.h>
3333 #endif
3434
2828 // tr_shade_calc.c
2929
3030 #include "tr_local.h"
31 #if idppc_altivec && !defined(MACOS_X)
31 #if idppc_altivec && !defined(__APPLE__)
3232 #include <altivec.h>
3333 #endif
3434
11791179 int i;
11801180 float *v, *normal;
11811181 trRefEntity_t *ent;
1182 int ambientLightInt;
11831182 vec3_t lightDir;
11841183 int numVertexes;
11851184 vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
11961195 vector signed short jVecShort;
11971196 vector unsigned char jVecChar, normalPerm;
11981197 ent = backEnd.currentEntity;
1199 ambientLightInt = ent->ambientLightInt;
12001198 // A lot of this could be simplified if we made sure
12011199 // entities light info was 16-byte aligned.
12021200 jVecChar = vec_lvsl(0, ent->ambientLight);
12501248 float *v, *normal;
12511249 float incoming;
12521250 trRefEntity_t *ent;
1253 int ambientLightInt;
12541251 vec3_t ambientLight;
12551252 vec3_t lightDir;
12561253 vec3_t directedLight;
12571254 int numVertexes;
12581255
12591256 ent = backEnd.currentEntity;
1260 ambientLightInt = ent->ambientLightInt;
12611257 VectorCopy( ent->ambientLight, ambientLight );
12621258 VectorCopy( ent->directedLight, directedLight );
12631259 VectorCopy( ent->lightDir, lightDir );
12691265 for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
12701266 incoming = DotProduct (normal, lightDir);
12711267 if ( incoming <= 0 ) {
1272 *(int *)&colors[i * 4] = ambientLightInt;
1273 continue;
1268 incoming = 0.0;
12741269 }
12751270 j = ri.ftol( ambientLight[0] + incoming * directedLight[0] );
12761271 if ( j > 255 ) {
24092409 //
24102410 // if we are in r_vertexLight mode, never use a lightmap texture
24112411 //
2412 if ( stage > 1 && ( ( r_vertexLight->integer && !r_uiFullScreen->integer ) || glConfig.hardwareType == GLHW_PERMEDIA2 ) ) {
2412 if ( 0 && ( stage > 1 && ( ( r_vertexLight->integer && !r_uiFullScreen->integer ) || glConfig.hardwareType == GLHW_PERMEDIA2 ) ) ) {
24132413 VertexLightingCollapse();
24142414 stage = 1;
24152415 hasLightmapStage = qfalse;
24952495 pShaderString = pShaderString->next;
24962496 }
24972497 }
2498
24992498 // done.
25002499
25012500 /*
25102509
25112510 if ( token[0] == '{' ) {
25122511 // skip the definition
2513 SkipBracedSection( &p );
2512 SkipBracedSection( &p, 0 );
25142513 } else if ( !Q_stricmp( token, shadername ) ) {
25152514 return p;
25162515 } else {
30593058
30603059 if ( !Q_stricmp( token, "{" ) ) {
30613060 // skip braced section
3062 SkipBracedSection( &p );
3061 SkipBracedSection( &p, 0 );
30633062 continue;
30643063 }
30653064
31023101 char *p;
31033102 int numShaderFiles;
31043103 int i;
3105 char *oldp, *token, *textEnd;
3104 char *token, *textEnd;
3105 char shaderName[MAX_QPATH];
3106 int shaderLine;
31063107
31073108 long sum = 0, summand;
31083109 // scan for shader files
31283129
31293130 if ( !buffers[i] )
31303131 ri.Error( ERR_DROP, "Couldn't load %s", filename );
3131
3132
31323133 // Do a simple check on the shader structure in that file to make sure one bad shader file cannot fuck up all other shaders.
31333134 p = buffers[i];
3135 COM_BeginParseSession(filename);
31343136 while(1)
31353137 {
31363138 token = COM_ParseExt(&p, qtrue);
31373139
31383140 if(!*token)
31393141 break;
3140
3141 oldp = p;
3142
3142
3143 Q_strncpyz(shaderName, token, sizeof(shaderName));
3144 shaderLine = COM_GetCurrentParseLine();
3145
31433146 token = COM_ParseExt(&p, qtrue);
3144 if(token[0] != '{' && token[1] != '\0')
3147 if( !Q_stricmp( shaderName, token ) ) {
3148 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Invalid shader name \"%s\" on line %d.\n",
3149 filename, shaderName, shaderLine);
3150 break;
3151 }
3152
3153 if(token[0] != '{' || token[1] != '\0')
31453154 {
3146 ri.Printf(PRINT_WARNING, "WARNING: Bad shader file %s has incorrect syntax.\n", filename);
3155 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing opening brace",
3156 filename, shaderName, shaderLine);
3157 if (token[0])
3158 {
3159 ri.Printf(PRINT_WARNING, " (found \"%s\" on line %d)", token, COM_GetCurrentParseLine());
3160 }
3161 ri.Printf(PRINT_WARNING, "...Ignored\n");
31473162 ri.FS_FreeFile(buffers[i]);
31483163 buffers[i] = NULL;
31493164 break;
31503165 }
31513166
3152 SkipBracedSection(&oldp);
3153 p = oldp;
3154 }
3155
3167 if(!SkipBracedSection(&p, 1))
3168 {
3169 ri.Printf(PRINT_WARNING, "WARNING: In shader file %s...Shader \"%s\" on line %d is missing closing brace",
3170 filename, shaderName, shaderLine);
3171 if( !Q_stricmp( filename, "common.shader" ) ) { // HACK...Broken shader in pak0.pk3
3172 ri.Printf(PRINT_WARNING, "...Ignored\n");
3173 ri.FS_FreeFile(buffers[i]);
3174 buffers[i] = NULL;
3175 break;
3176 } else {
3177 ri.Printf(PRINT_WARNING, ".\n");
3178 }
3179 }
3180 }
3181
31563182 if (buffers[i])
3157 sum += summand;
3183 sum += summand;
31583184 }
31593185
31603186 // build single large buffer
10141014
10151015 qglPushMatrix();
10161016 GL_State( 0 );
1017 GL_Cull( CT_FRONT_SIDED );
10171018 qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
10181019
10191020 DrawSkyBox( tess.shader );
10341035
10351036 qglPushMatrix();
10361037 GL_State( 0 );
1038 GL_Cull( CT_FRONT_SIDED );
10371039 qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] );
10381040
10391041 DrawSkyBoxInner( tess.shader );
2727
2828 // tr_surf.c
2929 #include "tr_local.h"
30 #if idppc_altivec && !defined(MACOS_X)
30 #if idppc_altivec && !defined(__APPLE__)
3131 #include <altivec.h>
3232 #endif
3333
406406 R_RecursiveWorldNode
407407 ================
408408 */
409 static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits ) {
409 static void R_RecursiveWorldNode( mnode_t *node, unsigned int planeBits, unsigned int dlightBits ) {
410410
411411 do {
412 int newDlights[2];
412 unsigned int newDlights[2];
413413
414414 // if the node wasn't marked as potentially visible, exit
415415 if ( node->visframe != tr.visCount ) {
702702 ClearBounds( tr.viewParms.visBounds[0], tr.viewParms.visBounds[1] );
703703
704704 // perform frustum culling and add all the potentially visible surfaces
705 if ( tr.refdef.num_dlights > 32 ) {
706 tr.refdef.num_dlights = 32 ;
707 }
708 R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1 );
709 }
705 if ( tr.refdef.num_dlights > MAX_DLIGHTS ) {
706 tr.refdef.num_dlights = MAX_DLIGHTS ;
707 }
708 R_RecursiveWorldNode( tr.world->nodes, 15, ( 1ULL << tr.refdef.num_dlights ) - 1 );
709 }
3434
3535 static cvar_t *in_keyboardDebug = NULL;
3636
37 static SDL_GameController *gamepad = NULL;
3738 static SDL_Joystick *stick = NULL;
3839
3940 static qboolean mouseAvailable = qfalse;
246247 case SDLK_LCTRL:
247248 case SDLK_RCTRL: key = K_CTRL; break;
248249
249 #ifdef MACOS_X
250 #ifdef __APPLE__
250251 case SDLK_RGUI:
251252 case SDLK_LGUI: key = K_COMMAND; break;
252253 #else
409410
410411 struct
411412 {
412 qboolean buttons[16]; // !!! FIXME: these might be too many.
413 qboolean buttons[SDL_CONTROLLER_BUTTON_MAX + 1]; // +1 because old max was 16, current SDL_CONTROLLER_BUTTON_MAX is 15
413414 unsigned int oldaxes;
414415 int oldaaxes[MAX_JOYSTICK_AXIS];
415416 unsigned int oldhats;
427428 int total = 0;
428429 char buf[16384] = "";
429430
431 if (gamepad)
432 SDL_GameControllerClose(gamepad);
433
430434 if (stick != NULL)
431435 SDL_JoystickClose(stick);
432436
433437 stick = NULL;
438 gamepad = NULL;
434439 memset(&stick_state, '\0', sizeof (stick_state));
435440
441 // SDL 2.0.4 requires SDL_INIT_JOYSTICK to be initialized separately from
442 // SDL_INIT_GAMECONTROLLER for SDL_JoystickOpen() to work correctly,
443 // despite https://wiki.libsdl.org/SDL_Init (retrieved 2016-08-16)
444 // indicating SDL_INIT_JOYSTICK should be initialized automatically.
436445 if (!SDL_WasInit(SDL_INIT_JOYSTICK))
437446 {
438447 Com_DPrintf("Calling SDL_Init(SDL_INIT_JOYSTICK)...\n");
444453 Com_DPrintf("SDL_Init(SDL_INIT_JOYSTICK) passed.\n");
445454 }
446455
456 if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER))
457 {
458 Com_DPrintf("Calling SDL_Init(SDL_INIT_GAMECONTROLLER)...\n");
459 if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0)
460 {
461 Com_DPrintf("SDL_Init(SDL_INIT_GAMECONTROLLER) failed: %s\n", SDL_GetError());
462 return;
463 }
464 Com_DPrintf("SDL_Init(SDL_INIT_GAMECONTROLLER) passed.\n");
465 }
466
447467 total = SDL_NumJoysticks();
448468 Com_DPrintf("%d possible joysticks\n", total);
449469
458478
459479 if( !in_joystick->integer ) {
460480 Com_DPrintf( "Joystick is not active.\n" );
461 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
481 SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
462482 return;
463483 }
464484
471491 stick = SDL_JoystickOpen( in_joystickNo->integer );
472492
473493 if (stick == NULL) {
474 Com_DPrintf( "No joystick opened.\n" );
494 Com_DPrintf( "No joystick opened: %s\n", SDL_GetError() );
475495 return;
476496 }
497
498 if (SDL_IsGameController(in_joystickNo->integer))
499 gamepad = SDL_GameControllerOpen(in_joystickNo->integer);
477500
478501 Com_DPrintf( "Joystick %d opened\n", in_joystickNo->integer );
479502 Com_DPrintf( "Name: %s\n", SDL_JoystickNameForIndex(in_joystickNo->integer) );
482505 Com_DPrintf( "Buttons: %d\n", SDL_JoystickNumButtons(stick) );
483506 Com_DPrintf( "Balls: %d\n", SDL_JoystickNumBalls(stick) );
484507 Com_DPrintf( "Use Analog: %s\n", in_joystickUseAnalog->integer ? "Yes" : "No" );
508 Com_DPrintf( "Is gamepad: %s\n", gamepad ? "Yes" : "No" );
485509
486510 SDL_JoystickEventState(SDL_QUERY);
511 SDL_GameControllerEventState(SDL_QUERY);
487512 }
488513
489514 /*
493518 */
494519 static void IN_ShutdownJoystick( void )
495520 {
521 if ( !SDL_WasInit( SDL_INIT_GAMECONTROLLER ) )
522 return;
523
496524 if ( !SDL_WasInit( SDL_INIT_JOYSTICK ) )
497525 return;
498526
527 if (gamepad)
528 {
529 SDL_GameControllerClose(gamepad);
530 gamepad = NULL;
531 }
532
499533 if (stick)
500534 {
501535 SDL_JoystickClose(stick);
502536 stick = NULL;
503537 }
504538
539 SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
505540 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
506541 }
542
543
544 static qboolean KeyToAxisAndSign(int keynum, int *outAxis, int *outSign)
545 {
546 char *bind;
547
548 if (!keynum)
549 return qfalse;
550
551 bind = Key_GetBinding(keynum);
552
553 if (!bind || *bind != '+')
554 return qfalse;
555
556 *outSign = 0;
557
558 if (Q_stricmp(bind, "+forward") == 0)
559 {
560 *outAxis = j_forward_axis->integer;
561 *outSign = j_forward->value > 0.0f ? 1 : -1;
562 }
563 else if (Q_stricmp(bind, "+back") == 0)
564 {
565 *outAxis = j_forward_axis->integer;
566 *outSign = j_forward->value > 0.0f ? -1 : 1;
567 }
568 else if (Q_stricmp(bind, "+moveleft") == 0)
569 {
570 *outAxis = j_side_axis->integer;
571 *outSign = j_side->value > 0.0f ? -1 : 1;
572 }
573 else if (Q_stricmp(bind, "+moveright") == 0)
574 {
575 *outAxis = j_side_axis->integer;
576 *outSign = j_side->value > 0.0f ? 1 : -1;
577 }
578 else if (Q_stricmp(bind, "+lookup") == 0)
579 {
580 *outAxis = j_pitch_axis->integer;
581 *outSign = j_pitch->value > 0.0f ? -1 : 1;
582 }
583 else if (Q_stricmp(bind, "+lookdown") == 0)
584 {
585 *outAxis = j_pitch_axis->integer;
586 *outSign = j_pitch->value > 0.0f ? 1 : -1;
587 }
588 else if (Q_stricmp(bind, "+left") == 0)
589 {
590 *outAxis = j_yaw_axis->integer;
591 *outSign = j_yaw->value > 0.0f ? 1 : -1;
592 }
593 else if (Q_stricmp(bind, "+right") == 0)
594 {
595 *outAxis = j_yaw_axis->integer;
596 *outSign = j_yaw->value > 0.0f ? -1 : 1;
597 }
598 else if (Q_stricmp(bind, "+moveup") == 0)
599 {
600 *outAxis = j_up_axis->integer;
601 *outSign = j_up->value > 0.0f ? 1 : -1;
602 }
603 else if (Q_stricmp(bind, "+movedown") == 0)
604 {
605 *outAxis = j_up_axis->integer;
606 *outSign = j_up->value > 0.0f ? -1 : 1;
607 }
608
609 return *outSign != 0;
610 }
611
612 /*
613 ===============
614 IN_GamepadMove
615 ===============
616 */
617 static void IN_GamepadMove( void )
618 {
619 int i;
620 int translatedAxes[MAX_JOYSTICK_AXIS];
621 qboolean translatedAxesSet[MAX_JOYSTICK_AXIS];
622
623 SDL_GameControllerUpdate();
624
625 // check buttons
626 for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++)
627 {
628 qboolean pressed = SDL_GameControllerGetButton(gamepad, SDL_CONTROLLER_BUTTON_A + i);
629 if (pressed != stick_state.buttons[i])
630 {
631 Com_QueueEvent(0, SE_KEY, K_PAD0_A + i, pressed, 0, NULL);
632 stick_state.buttons[i] = pressed;
633 }
634 }
635
636 // must defer translated axes until all real axes are processed
637 // must be done this way to prevent a later mapped axis from zeroing out a previous one
638 if (in_joystickUseAnalog->integer)
639 {
640 for (i = 0; i < MAX_JOYSTICK_AXIS; i++)
641 {
642 translatedAxes[i] = 0;
643 translatedAxesSet[i] = qfalse;
644 }
645 }
646
647 // check axes
648 for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++)
649 {
650 int axis = SDL_GameControllerGetAxis(gamepad, SDL_CONTROLLER_AXIS_LEFTX + i);
651 int oldAxis = stick_state.oldaaxes[i];
652
653 // Smoothly ramp from dead zone to maximum value
654 float f = ((float)abs(axis) / 32767.0f - in_joystickThreshold->value) / (1.0f - in_joystickThreshold->value);
655
656 if (f < 0.0f)
657 f = 0.0f;
658
659 axis = (int)(32767 * ((axis < 0) ? -f : f));
660
661 if (axis != oldAxis)
662 {
663 const int negMap[SDL_CONTROLLER_AXIS_MAX] = { K_PAD0_LEFTSTICK_LEFT, K_PAD0_LEFTSTICK_UP, K_PAD0_RIGHTSTICK_LEFT, K_PAD0_RIGHTSTICK_UP, 0, 0 };
664 const int posMap[SDL_CONTROLLER_AXIS_MAX] = { K_PAD0_LEFTSTICK_RIGHT, K_PAD0_LEFTSTICK_DOWN, K_PAD0_RIGHTSTICK_RIGHT, K_PAD0_RIGHTSTICK_DOWN, K_PAD0_LEFTTRIGGER, K_PAD0_RIGHTTRIGGER };
665
666 qboolean posAnalog = qfalse, negAnalog = qfalse;
667 int negKey = negMap[i];
668 int posKey = posMap[i];
669
670 if (in_joystickUseAnalog->integer)
671 {
672 int posAxis = 0, posSign = 0, negAxis = 0, negSign = 0;
673
674 // get axes and axes signs for keys if available
675 posAnalog = KeyToAxisAndSign(posKey, &posAxis, &posSign);
676 negAnalog = KeyToAxisAndSign(negKey, &negAxis, &negSign);
677
678 // positive to negative/neutral -> keyup if axis hasn't yet been set
679 if (posAnalog && !translatedAxesSet[posAxis] && oldAxis > 0 && axis <= 0)
680 {
681 translatedAxes[posAxis] = 0;
682 translatedAxesSet[posAxis] = qtrue;
683 }
684
685 // negative to positive/neutral -> keyup if axis hasn't yet been set
686 if (negAnalog && !translatedAxesSet[negAxis] && oldAxis < 0 && axis >= 0)
687 {
688 translatedAxes[negAxis] = 0;
689 translatedAxesSet[negAxis] = qtrue;
690 }
691
692 // negative/neutral to positive -> keydown
693 if (posAnalog && axis > 0)
694 {
695 translatedAxes[posAxis] = axis * posSign;
696 translatedAxesSet[posAxis] = qtrue;
697 }
698
699 // positive/neutral to negative -> keydown
700 if (negAnalog && axis < 0)
701 {
702 translatedAxes[negAxis] = -axis * negSign;
703 translatedAxesSet[negAxis] = qtrue;
704 }
705 }
706
707 // keyups first so they get overridden by keydowns later
708
709 // positive to negative/neutral -> keyup
710 if (!posAnalog && posKey && oldAxis > 0 && axis <= 0)
711 Com_QueueEvent(0, SE_KEY, posKey, qfalse, 0, NULL);
712
713 // negative to positive/neutral -> keyup
714 if (!negAnalog && negKey && oldAxis < 0 && axis >= 0)
715 Com_QueueEvent(0, SE_KEY, negKey, qfalse, 0, NULL);
716
717 // negative/neutral to positive -> keydown
718 if (!posAnalog && posKey && oldAxis <= 0 && axis > 0)
719 Com_QueueEvent(0, SE_KEY, posKey, qtrue, 0, NULL);
720
721 // positive/neutral to negative -> keydown
722 if (!negAnalog && negKey && oldAxis >= 0 && axis < 0)
723 Com_QueueEvent(0, SE_KEY, negKey, qtrue, 0, NULL);
724
725 stick_state.oldaaxes[i] = axis;
726 }
727 }
728
729 // set translated axes
730 if (in_joystickUseAnalog->integer)
731 {
732 for (i = 0; i < MAX_JOYSTICK_AXIS; i++)
733 {
734 if (translatedAxesSet[i])
735 Com_QueueEvent(0, SE_JOYSTICK_AXIS, i, translatedAxes[i], 0, NULL);
736 }
737 }
738 }
739
507740
508741 /*
509742 ===============
516749 unsigned int hats = 0;
517750 int total = 0;
518751 int i = 0;
752
753 if (gamepad)
754 {
755 IN_GamepadMove();
756 return;
757 }
519758
520759 if (!stick)
521760 return;
7921031 Com_QueueEvent( 0, SE_KEY, K_CONSOLE, qtrue, 0, NULL );
7931032 Com_QueueEvent( 0, SE_KEY, K_CONSOLE, qfalse, 0, NULL );
7941033 }
1034 else if( utf32 == 0xDC ) // latin big letter u with diaeresis (U+00DC)
1035 {
1036 Com_QueueEvent( 0, SE_CHAR, 'U', 0, 0, NULL );
1037 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1038 }
1039 else if( utf32 == 0xFC ) // latin small letter u with diaeresis (U+00FC)
1040 {
1041 Com_QueueEvent( 0, SE_CHAR, 'u', 0, 0, NULL );
1042 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1043 }
1044 else if( utf32 == 0xD6 ) // latin big letter o with diaeresis (U+00D6)
1045 {
1046 Com_QueueEvent( 0, SE_CHAR, 'O', 0, 0, NULL );
1047 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1048 }
1049 else if( utf32 == 0xF6 ) // latin small letter o with diaeresis (U+00FC)
1050 {
1051 Com_QueueEvent( 0, SE_CHAR, 'o', 0, 0, NULL );
1052 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1053 }
1054 else if( utf32 == 0xC4 ) // latin big letter a with diaeresis (U+00C4)
1055 {
1056 Com_QueueEvent( 0, SE_CHAR, 'A', 0, 0, NULL );
1057 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1058 }
1059 else if( utf32 == 0xE4 ) // latin small letter a with diaeresis (U+00E4)
1060 {
1061 Com_QueueEvent( 0, SE_CHAR, 'a', 0, 0, NULL );
1062 Com_QueueEvent( 0, SE_CHAR, 'e', 0, 0, NULL );
1063 }
7951064 else
7961065 Com_QueueEvent( 0, SE_CHAR, utf32, 0, 0, NULL );
7971066 }
798 }
799 }
1067 }
1068 }
8001069 break;
8011070
8021071 case SDL_MOUSEMOTION:
8391108 }
8401109 break;
8411110
1111 case SDL_CONTROLLERDEVICEADDED:
1112 case SDL_CONTROLLERDEVICEREMOVED:
1113 if (in_joystick->integer)
1114 IN_InitJoystick();
1115 break;
1116
8421117 case SDL_QUIT:
8431118 Cbuf_ExecuteText(EXEC_NOW, "quit Closed window\n");
8441119 break;
290290 }
291291
292292
293 // save the map name here cause on a map restart we reload the q3config.cfg
293 // save the map name here cause on a map restart we reload the wolfconfig_server.cfg
294294 // and thus nuke the arguments of the map command
295295 Q_strncpyz( mapname, map, sizeof( mapname ) );
296296
713713 }
714714
715715 #ifndef STANDALONE
716 #ifdef USE_AUTHORIZE_SERVER
716717 // these functions require the auth server which of course is not available anymore for stand-alone games.
717718
718719 /*
824825 Com_Printf( "%s was banned from coming back\n", cl->name );
825826 }
826827 }
828 #endif
827829 #endif
828830
829831 /*
16231625 Cmd_AddCommand( "heartbeat", SV_Heartbeat_f );
16241626 Cmd_AddCommand( "kick", SV_Kick_f );
16251627 #ifndef STANDALONE
1628 #ifdef USE_AUTHORIZE_SERVER
16261629 if(!com_standalone->integer)
16271630 {
16281631 Cmd_AddCommand ("banUser", SV_Ban_f);
16291632 Cmd_AddCommand ("banClient", SV_BanNum_f);
16301633 }
1634 #endif
16311635 #endif
16321636 Cmd_AddCommand ("kickbots", SV_KickBots_f);
16331637 Cmd_AddCommand ("kickall", SV_KickAll_f);
151151 challenge->time = svs.time;
152152
153153 #ifndef STANDALONE
154 #ifdef USE_AUTHORIZE_SERVER
154155 // Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
155156 // Drop also for addresses coming in on local LAN and for stand-alone games independent from id's assets.
156157 if(challenge->adr.type == NA_IP && !com_standalone->integer && !Sys_IsLANAddress(from))
202203 }
203204 }
204205 #endif
206 #endif
205207
206208 challenge->pingTime = svs.time;
207209 NET_OutOfBandPrint(NS_SERVER, challenge->adr, "challengeResponse %d %d %d",
209211 }
210212
211213 #ifndef STANDALONE
214 #ifdef USE_AUTHORIZE_SERVER
212215 /*
213216 ====================
214217 SV_AuthorizeIpPacket
282285 // clear the challenge record so it won't timeout and let them through
283286 Com_Memset( challengeptr, 0, sizeof(*challengeptr) );
284287 }
288 #endif
285289 #endif
286290
287291 /*
18831887 // gamestate it was at. This allows it to keep downloading even when
18841888 // the gamestate changes. After the download is finished, we'll
18851889 // notice and send it a new game state
1886 if ( serverId != sv.serverId &&
1887 !*cl->downloadName ) {
1888 if ( serverId == sv.restartedServerId ) {
1889 // they just haven't caught the map_restart yet
1890 return;
1890 //
1891 // show_bug.cgi?id=536
1892 // don't drop as long as previous command was a nextdl, after a dl is done, downloadName is set back to ""
1893 // but we still need to read the next message to move to next download or send gamestate
1894 // I don't like this hack though, it must have been working fine at some point, suspecting the fix is somewhere else
1895 if ( serverId != sv.serverId && !*cl->downloadName && !strstr( cl->lastClientCommandString, "nextdl" ) ) {
1896 if ( serverId >= sv.restartedServerId && serverId < sv.serverId ) { // TTimo - use a comparison here to catch multiple map_restart
1897 if ( strstr( cl->lastClientCommandString, "donedl" ) ) {
1898 SV_DoneDownload_f( cl );
1899 } else {
1900 // they just haven't caught the map_restart yet
1901 Com_DPrintf( "%s : ignoring pre map_restart / outdated client message\n", cl->name );
1902 return;
1903 }
18911904 }
18921905 // if we can tell that the client has dropped the last
18931906 // gamestate we sent them, resend it
10441044 Cvar_Get ("sv_dlURL", "", CVAR_SERVERINFO | CVAR_ARCHIVE);
10451045
10461046 // sv_master[0] = Cvar_Get("sv_master1", MASTER_SERVER_NAME, 0);
1047 // sv_master[1] = Cvar_Get("sv_master2", "master.ioquake3.org", 0);
1047 // sv_master[1] = Cvar_Get("sv_master2", "master.iortcw.org", 0);
10481048 for(index = 2; index < MAX_MASTER_SERVERS; index++)
10491049 sv_master[index] = Cvar_Get(va("sv_master%d", index + 1), "", CVAR_ARCHIVE);
10501050
253253 void SV_MasterHeartbeat(const char *message)
254254 {
255255 static netadr_t adr[MAX_MASTER_SERVERS][2]; // [2] for v4 and v6 address for the same address string.
256 int i;
256 int i;
257257 int res;
258258 int netenabled;
259 static qboolean firstRes = qtrue;
259260
260261 netenabled = Cvar_VariableIntegerValue("net_enabled");
261262
262263 // "dedicated 1" is for lan play, "dedicated 2" is for inet public play
263264 if (!com_dedicated || com_dedicated->integer != 2 || !(netenabled & (NET_ENABLEV4 | NET_ENABLEV6)))
264 return; // only dedicated servers send heartbeats
265 return; // only dedicated servers send heartbeats
265266
266267 // if not time yet, don't send anything
267268 if ( svs.time < svs.nextHeartbeatTime )
279280 continue;
280281
281282 // see if we haven't already resolved the name
282 // resolving usually causes hitches on win95, so only
283 // do it when needed
283 // if server did not resolve on first attempt, do not attempt another dns lookup
284 // if server did resolve on first attempt, attempt resolution on subsequent heartbeats
284285 if(sv_master[i]->modified || (adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD))
285286 {
286287 sv_master[i]->modified = qfalse;
287
288
288289 if(netenabled & NET_ENABLEV4)
289290 {
290 Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
291 res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);
292
293 if(res == 2)
294 {
295 // if no port was specified, use the default master port
296 adr[i][0].port = BigShort(PORT_MASTER);
291 if(firstRes || adr[i][0].type != NA_BAD) {
292 Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
293 res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);
294
295 if(res == 2)
296 {
297 // if no port was specified, use the default master port
298 adr[i][0].port = BigShort(PORT_MASTER);
299 }
300
301 if(res) {
302 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
303
304 if(adr[i][0].type != NA_BAD) {
305 Com_Printf ("Sending heartbeat to %s (IPv4)\n", sv_master[i]->string );
306 NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", message);
307 }
308 sv_master[i]->modified = qtrue;
309 } else {
310 Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
311 }
297312 }
298
299 if(res)
300 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
301 else
302 Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
303313 }
304314
305315 if(netenabled & NET_ENABLEV6)
306316 {
307 Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
308 res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);
309
310 if(res == 2)
311 {
312 // if no port was specified, use the default master port
313 adr[i][1].port = BigShort(PORT_MASTER);
317 if(firstRes || adr[i][1].type != NA_BAD) {
318 Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
319 res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);
320
321 if(res == 2)
322 {
323 // if no port was specified, use the default master port
324 adr[i][1].port = BigShort(PORT_MASTER);
325 }
326
327 if(res) {
328 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
329 if(adr[i][1].type != NA_BAD) {
330 Com_Printf ("Sending heartbeat to %s (IPv6)\n", sv_master[i]->string );
331 NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", message);
332 }
333 sv_master[i]->modified = qtrue;
334 } else {
335 Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
336 }
314337 }
315
316 if(res)
317 Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
318 else
319 Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
320338 }
321339
322340 if(adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD)
323341 {
324
325 // if the address failed to resolve, clear it
342 // if the address failed to resolve in both ipv4 or ipv6, clear it
326343 // so we don't take repeated dns hits
327344 Com_Printf("Couldn't resolve address: %s\n", sv_master[i]->string);
328345 Cvar_Set(sv_master[i]->name, "");
330347 continue;
331348 }
332349 }
333
334
335 Com_Printf( "Sending heartbeat to %s\n", sv_master[i]->string );
336 // this command should be changed if the server info / status format
337 // ever incompatably changes
338 if(adr[i][0].type != NA_BAD)
339 NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", message);
340 if(adr[i][1].type != NA_BAD)
341 NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", message);
342 }
350 }
351
352 firstRes = qfalse;
343353 }
344354
345355 /*
355365 SV_MasterHeartbeat(FLATLINE_FOR_MASTER);
356366
357367 // send it again to minimize chance of drops
358 svs.nextHeartbeatTime = -9999;
359 SV_MasterHeartbeat(FLATLINE_FOR_MASTER);
368 // svs.nextHeartbeatTime = -9999;
369 // SV_MasterHeartbeat(FLATLINE_FOR_MASTER);
360370
361371 // when the master tries to poll the server, it won't respond, so
362372 // it will be removed from the list
822832 } else if ( !Q_stricmp( c,"connect" ) ) {
823833 SV_DirectConnect( from );
824834 #ifndef STANDALONE
835 #ifdef USE_AUTHORIZE_SERVER
825836 } else if ( !Q_stricmp( c,"ipAuthorize" ) ) {
826837 SV_AuthorizeIpPacket( from );
838 #endif
827839 #endif
828840 } else if ( !Q_stricmp( c, "rcon" ) ) {
829841 SVC_RemoteCommand( from, msg );
3535 #include <time.h>
3636 #include <ctype.h>
3737
38 #ifndef MACOS_X
38 #ifndef __APPLE__
3939 #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
4040 #endif
4141
5454 #define BASEGAME "main"
5555 #define CLIENT_WINDOW_TITLE "Return To Castle Wolfenstein"
5656 #define CLIENT_WINDOW_MIN_TITLE "iowolfsp"
57 #define HOMEPATH_NAME_UNIX ".iortcw"
57 #ifdef USE_XDG
58 #define HOMEPATH_NAME_UNIX "iortcw"
59 #else
60 #define HOMEPATH_NAME_UNIX ".wolf"
61 #endif
5862 #define HOMEPATH_NAME_WIN "RTCW"
5963 #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
6064 #define GAMENAME_FOR_MASTER "wolfsp"
4343 unsigned int CON_LogWrite( const char *in );
4444 unsigned int CON_LogRead( char *out, unsigned int outSize );
4545
46 #ifdef MACOS_X
46 #ifdef __APPLE__
4747 char *Sys_StripAppBundle( char *pwd );
4848 #endif
4949
166166 Sys_PIDFileName
167167 =================
168168 */
169 static char *Sys_PIDFileName( void )
169 static char *Sys_PIDFileName( const char *gamedir )
170170 {
171171 const char *homePath = Cvar_VariableString( "fs_homepath" );
172172
173173 if( *homePath != '\0' )
174 return va( "%s/%s", homePath, PID_FILENAME );
174 return va( "%s/%s/%s", homePath, gamedir, PID_FILENAME );
175175
176176 return NULL;
177177 }
178178
179179 /*
180180 =================
181 Sys_RemovePIDFile
182 =================
183 */
184 void Sys_RemovePIDFile( const char *gamedir )
185 {
186 char *pidFile = Sys_PIDFileName( gamedir );
187
188 if( pidFile != NULL )
189 remove( pidFile );
190 }
191
192 /*
193 =================
181194 Sys_WritePIDFile
182195
183196 Return qtrue if there is an existing stale PID file
184197 =================
185198 */
186 qboolean Sys_WritePIDFile( void )
187 {
188 char *pidFile = Sys_PIDFileName( );
199 static qboolean Sys_WritePIDFile( const char *gamedir )
200 {
201 char *pidFile = Sys_PIDFileName( gamedir );
189202 FILE *f;
190203 qboolean stale = qfalse;
191204
211224 stale = qtrue;
212225 }
213226
227 if( FS_CreatePath( pidFile ) ) {
228 return 0;
229 }
230
214231 if( ( f = fopen( pidFile, "w" ) ) != NULL )
215232 {
216233 fprintf( f, "%d", Sys_PID( ) );
224241
225242 /*
226243 =================
244 Sys_InitPIDFile
245 =================
246 */
247 void Sys_InitPIDFile( const char *gamedir ) {
248 if( Sys_WritePIDFile( gamedir ) ) {
249 #ifndef DEDICATED
250 char message[1024];
251 char modName[MAX_OSPATH];
252
253 FS_GetModDescription( gamedir, modName, sizeof ( modName ) );
254 Q_CleanStr( modName );
255
256 Com_sprintf( message, sizeof (message), "The last time %s ran, "
257 "it didn't exit properly. This may be due to inappropriate video "
258 "settings. Would you like to start with \"safe\" video settings?", modName );
259
260 if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) {
261 Cvar_Set( "com_abnormalExit", "1" );
262 }
263 #endif
264 }
265 }
266
267 /*
268 =================
227269 Sys_Exit
228270
229271 Single exit point (regular exit or in case of error)
237279 SDL_Quit( );
238280 #endif
239281
240 if( exitCode < 2 )
282 if( exitCode < 2 && com_fullyInitialized )
241283 {
242284 // Normal exit
243 char *pidFile = Sys_PIDFileName( );
244
245 if( pidFile != NULL )
246 remove( pidFile );
285 Sys_RemovePIDFile( FS_GetCurrentGameDir() );
247286 }
248287
249288 NET_Shutdown( );
273312 cpuFeatures_t features = 0;
274313
275314 #ifndef DEDICATED
276 if( SDL_HasRDTSC( ) ) features |= CF_RDTSC;
277 if( SDL_HasMMX( ) ) features |= CF_MMX;
278 if( SDL_HasSSE( ) ) features |= CF_SSE;
279 if( SDL_HasSSE2( ) ) features |= CF_SSE2;
315 if( SDL_HasRDTSC( ) ) features |= CF_RDTSC;
316 if( SDL_Has3DNow( ) ) features |= CF_3DNOW;
317 if( SDL_HasMMX( ) ) features |= CF_MMX;
318 if( SDL_HasSSE( ) ) features |= CF_SSE;
319 if( SDL_HasSSE2( ) ) features |= CF_SSE2;
320 if( SDL_HasAltiVec( ) ) features |= CF_ALTIVEC;
280321 #endif
281322
282323 return features;
550591 if( !strcmp( argv[1], "--version" ) ||
551592 !strcmp( argv[1], "-v" ) )
552593 {
553 const char* date = __DATE__;
594 const char* date = PRODUCT_DATE;
554595 #ifdef DEDICATED
555596 fprintf( stdout, Q3_VERSION " dedicated server (%s)\n", date );
556597 #else
562603 }
563604
564605 #ifndef DEFAULT_BASEDIR
565 # ifdef MACOS_X
606 # ifdef __APPLE__
566607 # define DEFAULT_BASEDIR Sys_StripAppBundle(Sys_BinaryPath())
567608 # else
568609 # define DEFAULT_BASEDIR Sys_BinaryPath()
643684 // Set the initial time base
644685 Sys_Milliseconds( );
645686
646 #ifdef MACOS_X
687 #ifdef __APPLE__
647688 // This is passed if we are launched by double-clicking
648689 if ( argc >= 2 && Q_strncmp ( argv[1], "-psn", 4 ) == 0 )
649690 argc = 1;
1919 ===========================================================================
2020 */
2121
22 #ifndef MACOS_X
22 #ifndef __APPLE__
2323 #error This file is for Mac OS X only. You probably should not compile it.
2424 #endif
2525
4242
4343 // Used to determine where to store user-specific files
4444 static char homePath[ MAX_OSPATH ] = { 0 };
45 #ifdef USE_XDG
46 static const char DEFAULT_XDG_DATA_HOME[] = {'.', 'l', 'o', 'c', 'a', 'l', PATH_SEP, 's', 'h', 'a', 'r', 'e', '\0'};
47 #endif
4548
4649 #ifndef STANDALONE
4750 // Used to store the Steam RTCW installation path
5558 */
5659 char *Sys_DefaultHomePath(void)
5760 {
58 char *p;
61 char *p1;
62 #ifdef USE_XDG
63 char *p2;
64 #endif
5965
6066 if( !*homePath && com_homepath != NULL )
6167 {
62 if( ( p = getenv( "HOME" ) ) != NULL )
68 #ifdef __APPLE__
69 if( ( p1 = getenv( "HOME" ) ) != NULL )
6370 {
64 Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP);
65 #ifdef MACOS_X
71 Com_sprintf(homePath, sizeof(homePath), "%s%c", p1, PATH_SEP);
72
6673 Q_strcat(homePath, sizeof(homePath),
6774 "Library/Application Support/");
6875
7077 Q_strcat(homePath, sizeof(homePath), com_homepath->string);
7178 else
7279 Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
80 }
7381 #else
82 #ifdef USE_XDG
83 if( ( p1 = getenv( "XDG_DATA_HOME" ) ) != NULL )
84 {
85 Com_sprintf(homePath, sizeof(homePath), "%s%c", p1, PATH_SEP);
86
87 }
88 else if( ( p2 = getenv( "HOME" ) ) != NULL)
89 {
90 Com_sprintf(homePath, sizeof(homePath), "%s%c%s%c", p2, PATH_SEP, DEFAULT_XDG_DATA_HOME, PATH_SEP);
91 }
92
93 if (p1 || p2)
94 {
7495 if(com_homepath->string[0])
7596 Q_strcat(homePath, sizeof(homePath), com_homepath->string);
7697 else
7798 Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
78 #endif
79 }
99 }
100 #else
101 if( ( p1 = getenv( "HOME" ) ) != NULL )
102 {
103 Com_sprintf(homePath, sizeof(homePath), "%s%c", p1, PATH_SEP);
104
105 if(com_homepath->string[0])
106 Q_strcat(homePath, sizeof(homePath), com_homepath->string);
107 else
108 Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
109 }
110 #endif // USE_XDG
111 #endif // __APPLE__
80112 }
81113
82114 return homePath;
96128
97129 if( ( p = getenv( "HOME" ) ) != NULL )
98130 {
99 #ifdef MACOS_X
131 #ifdef __APPLE__
100132 char *steamPathEnd = "/Library/Application Support/Steam/SteamApps/common/" STEAMPATH_NAME;
101133 #else
102134 char *steamPathEnd = "/.steam/steam/SteamApps/common/" STEAMPATH_NAME;
580612 close( f );
581613 }
582614
583 #ifndef MACOS_X
615 #ifndef __APPLE__
584616 static char execBuffer[ 1024 ];
585617 static char *execBufferPointer;
586618 static char *execArgv[ 16 ];
10261058 // build the command line
10271059 Com_sprintf( cmdline, MAX_CMD, "%s '%s' &", fn, url );
10281060
1029 Sys_StartProcess( cmdline, doexit );
1061 if ( doexit ) {
1062 Sys_StartProcess( cmdline, qtrue );
1063 } else {
1064 Sys_StartProcess( cmdline, qfalse );
1065 }
10301066
10311067 }
10321068
476476 acc = (acc << 2) | (acc >> 30);
477477 acc &= 0xffffffffU;
478478 }
479 return abs(acc);
479 return acc;
480480 }
481481
482482
20822082 UI_PlayerInfo_SetModel( &info2, model );
20832083 #endif // #ifdef MISSIONPACK
20842084 UI_PlayerInfo_SetInfo( &info2, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MP40, qfalse );
2085 #ifdef MISSIONPACK
2086 UI_RegisterClientModelname( &info2, model, headmodel, team );
2087 #else
20852088 UI_RegisterClientModelname( &info2, model );
2089 #endif // #ifdef MISSIONPACK
20862090 updateOpponentModel = qfalse;
20872091 }
20882092
29382942 return vis;
29392943 }
29402944
2941 static qboolean UI_Handicap_HandleKey( int flags, float *special, int key ) {
2942 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
2945 static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) {
2946 int select = UI_SelectForKey(key);
2947 if (select != 0) {
29432948 int h;
2944 h = Com_Clamp( 5, 100, trap_Cvar_VariableValue( "handicap" ) );
2945 if ( key == K_MOUSE2 ) {
2946 h -= 5;
2947 } else {
2948 h += 5;
2949 }
2950 if ( h > 100 ) {
2949
2950 h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
2951 h += 5 * select;
2952
2953 if (h > 100) {
29512954 h = 5;
2952 } else if ( h < 5 ) {
2955 } else if (h < 5) {
29532956 h = 100;
29542957 }
2955 trap_Cvar_Set( "handicap", va( "%i", h ) );
2958
2959 trap_Cvar_SetValue( "handicap", h );
29562960 return qtrue;
29572961 }
29582962 return qfalse;
29592963 }
29602964
2961 static qboolean UI_Effects_HandleKey( int flags, float *special, int key ) {
2962 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
2963
2964 if ( key == K_MOUSE2 ) {
2965 uiInfo.effectsColor--;
2966 } else {
2967 uiInfo.effectsColor++;
2968 }
2969
2970 if ( uiInfo.effectsColor > 6 ) {
2965 static qboolean UI_Effects_HandleKey(int flags, float *special, int key) {
2966 int select = UI_SelectForKey(key);
2967 if (select != 0) {
2968 uiInfo.effectsColor += select;
2969
2970 if( uiInfo.effectsColor > 6 ) {
29712971 uiInfo.effectsColor = 0;
2972 } else if ( uiInfo.effectsColor < 0 ) {
2972 } else if (uiInfo.effectsColor < 0) {
29732973 uiInfo.effectsColor = 6;
29742974 }
29752975
29782978 }
29792979 return qfalse;
29802980 }
2981
29822981
29832982 //----(SA) added
29842983 static qboolean UI_SavegameName_HandleKey( int flags, float *special, int key ) {
29862985 // disable
29872986 return qfalse;
29882987 #if 0
2989 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
2988 int select = UI_SelectForKey(key);
2989 if (select != 0) {
29902990 int i;
2991
29912992 i = UI_SavegameIndexFromName( ui_savegameName.string );
29922993
2993 if ( key == K_MOUSE2 ) {
2994 i--;
2995 } else {
2996 i++;
2997 }
2998 if ( i >= uiInfo.savegameCount ) {
2994 i += select;
2995
2996 if (i >= uiInfo.savegameCount) {
29992997 i = 0;
3000 } else if ( i < 0 ) {
2998 } else if (i < 0) {
30012999 i = uiInfo.savegameCount - 1;
30023000 }
30033001
30133011 }
30143012 //----(SA) end
30153013
3016
3017 static qboolean UI_ClanName_HandleKey( int flags, float *special, int key ) {
3018 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3014 static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) {
3015 int select = UI_SelectForKey(key);
3016 if (select != 0) {
30193017 int i;
3020 i = UI_TeamIndexFromName( UI_Cvar_VariableString( "ui_teamName" ) );
3021 if ( uiInfo.teamList[i].cinematic >= 0 ) {
3022 trap_CIN_StopCinematic( uiInfo.teamList[i].cinematic );
3018
3019 i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
3020
3021 if (uiInfo.teamList[i].cinematic >= 0) {
3022 trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic);
30233023 uiInfo.teamList[i].cinematic = -1;
30243024 }
3025 if ( key == K_MOUSE2 ) {
3026 i--;
3027 } else {
3028 i++;
3029 }
3030 if ( i >= uiInfo.teamCount ) {
3025
3026 i += select;
3027
3028 if (i >= uiInfo.teamCount) {
30313029 i = 0;
3032 } else if ( i < 0 ) {
3030 } else if (i < 0) {
30333031 i = uiInfo.teamCount - 1;
30343032 }
3035 trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName );
3033
3034 trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName);
30363035 updateModel = qtrue;
30373036 return qtrue;
30383037 }
30393038 return qfalse;
30403039 }
30413040
3042 static qboolean UI_GameType_HandleKey( int flags, float *special, int key, qboolean resetMap ) {
3041 static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) {
30433042 #ifdef MISSIONPACK
3044 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3045 int oldCount = UI_MapCountByGameType( qtrue );
3043 int select = UI_SelectForKey(key);
3044 if (select != 0) {
3045 int oldCount = UI_MapCountByGameType(qtrue);
30463046
30473047 // hard coded mess here
3048 if ( key == K_MOUSE2 ) {
3048 if (select < 0) {
30493049 ui_gameType.integer--;
3050 if ( ui_gameType.integer == 2 ) {
3050 if (ui_gameType.integer == 2) {
30513051 ui_gameType.integer = 1;
3052 } else if ( ui_gameType.integer < 2 ) {
3052 } else if (ui_gameType.integer < 2) {
30533053 ui_gameType.integer = uiInfo.numGameTypes - 1;
30543054 }
30553055 } else {
30563056 ui_gameType.integer++;
3057 if ( ui_gameType.integer >= uiInfo.numGameTypes ) {
3057 if (ui_gameType.integer >= uiInfo.numGameTypes) {
30583058 ui_gameType.integer = 1;
3059 } else if ( ui_gameType.integer == 2 ) {
3059 } else if (ui_gameType.integer == 2) {
30603060 ui_gameType.integer = 3;
30613061 }
30623062 }
3063
3064 if ( uiInfo.gameTypes[ui_gameType.integer].gtEnum == GT_TOURNAMENT ) {
3065 trap_Cvar_Set( "ui_Q3Model", "1" );
3063
3064 if (uiInfo.gameTypes[ui_gameType.integer].gtEnum < GT_TEAM) {
3065 trap_Cvar_SetValue( "ui_Q3Model", 1 );
30663066 } else {
3067 trap_Cvar_Set( "ui_Q3Model", "0" );
3068 }
3069
3070 trap_Cvar_Set( "ui_gameType", va( "%d", ui_gameType.integer ) );
3071 UI_SetCapFragLimits( qtrue );
3072 UI_LoadBestScores( uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum );
3073 if ( resetMap && oldCount != UI_MapCountByGameType( qtrue ) ) {
3074 trap_Cvar_Set( "ui_currentMap", "0" );
3075 Menu_SetFeederSelection( NULL, FEEDER_MAPS, 0, NULL );
3067 trap_Cvar_SetValue( "ui_Q3Model", 0 );
3068 }
3069
3070 trap_Cvar_SetValue("ui_gameType", ui_gameType.integer);
3071 UI_SetCapFragLimits(qtrue);
3072 UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
3073 if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) {
3074 trap_Cvar_SetValue( "ui_currentMap", 0);
3075 Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL);
30763076 }
30773077 return qtrue;
30783078 }
30803080 return qfalse;
30813081 }
30823082
3083 static qboolean UI_NetGameType_HandleKey( int flags, float *special, int key ) {
3083 static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) {
30843084 #ifdef MISSIONPACK
3085 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3086
3087 if ( key == K_MOUSE2 ) {
3088 ui_netGameType.integer--;
3089 } else {
3090 ui_netGameType.integer++;
3091 }
3092
3093 if ( ui_netGameType.integer < 0 ) {
3085 int select = UI_SelectForKey(key);
3086 if (select != 0) {
3087 ui_netGameType.integer += select;
3088
3089 if (ui_netGameType.integer < 0) {
30943090 ui_netGameType.integer = uiInfo.numGameTypes - 1;
3095 } else if ( ui_netGameType.integer >= uiInfo.numGameTypes ) {
3091 } else if (ui_netGameType.integer >= uiInfo.numGameTypes) {
30963092 ui_netGameType.integer = 0;
30973093 }
30983094
3099 trap_Cvar_Set( "ui_netGameType", va( "%d", ui_netGameType.integer ) );
3100 trap_Cvar_Set( "ui_actualnetGameType", va( "%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) );
3101 trap_Cvar_Set( "ui_currentNetMap", "0" );
3102 UI_MapCountByGameType( qfalse );
3103 Menu_SetFeederSelection( NULL, FEEDER_ALLMAPS, 0, NULL );
3095 trap_Cvar_SetValue( "ui_netGameType", ui_netGameType.integer);
3096 trap_Cvar_SetValue( "ui_actualnetGameType", uiInfo.gameTypes[ui_netGameType.integer].gtEnum);
3097 trap_Cvar_SetValue( "ui_currentNetMap", 0);
3098 UI_MapCountByGameType(qfalse);
3099 Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL);
31043100 return qtrue;
31053101 }
31063102 #endif // #ifdef MISSIONPACK
31073103 return qfalse;
31083104 }
31093105
3110 static qboolean UI_JoinGameType_HandleKey( int flags, float *special, int key ) {
3106 static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
31113107 #ifdef MISSIONPACK
3112 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3113
3114 if ( key == K_MOUSE2 ) {
3115 ui_joinGameType.integer--;
3116 } else {
3117 ui_joinGameType.integer++;
3118 }
3119
3120 if ( ui_joinGameType.integer < 0 ) {
3108 int select = UI_SelectForKey(key);
3109 if (select != 0) {
3110 ui_joinGameType.integer += select;
3111
3112 if (ui_joinGameType.integer < 0) {
31213113 ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1;
3122 } else if ( ui_joinGameType.integer >= uiInfo.numJoinGameTypes ) {
3114 } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) {
31233115 ui_joinGameType.integer = 0;
31243116 }
31253117
3126 trap_Cvar_Set( "ui_joinGameType", va( "%d", ui_joinGameType.integer ) );
3127 UI_BuildServerDisplayList( qtrue );
3118 trap_Cvar_SetValue( "ui_joinGameType", ui_joinGameType.integer);
3119 UI_BuildServerDisplayList(qtrue);
31283120 return qtrue;
31293121 }
31303122 #endif // #ifdef MISSIONPACK
31333125
31343126
31353127
3136 static qboolean UI_Skill_HandleKey( int flags, float *special, int key ) {
3137 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3128 static qboolean UI_Skill_HandleKey(int flags, float *special, int key) {
3129 int select = UI_SelectForKey(key);
3130 if (select != 0) {
31383131 int i = trap_Cvar_VariableValue( "g_spSkill" );
31393132
3140 if ( key == K_MOUSE2 ) {
3141 i--;
3142 } else {
3143 i++;
3144 }
3145
3146 if ( i < 1 ) {
3133 i += select;
3134
3135 if (i < 1) {
31473136 i = numSkillLevels;
3148 } else if ( i > numSkillLevels ) {
3137 } else if (i > numSkillLevels) {
31493138 i = 1;
31503139 }
31513140
3152 trap_Cvar_Set( "g_spSkill", va( "%i", i ) );
3141 trap_Cvar_SetValue("g_spSkill", i);
31533142 return qtrue;
31543143 }
31553144 return qfalse;
31563145 }
31573146
3158 static qboolean UI_TeamName_HandleKey( int flags, float *special, int key, qboolean blue ) {
3159 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3147 static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) {
3148 int select = UI_SelectForKey(key);
3149 if (select != 0) {
31603150 int i;
3161 i = UI_TeamIndexFromName( UI_Cvar_VariableString( ( blue ) ? "ui_blueTeam" : "ui_redTeam" ) );
3162
3163 if ( key == K_MOUSE2 ) {
3164 i--;
3165 } else {
3166 i++;
3167 }
3168
3169 if ( i >= uiInfo.teamCount ) {
3151
3152 i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
3153 i += select;
3154
3155 if (i >= uiInfo.teamCount) {
31703156 i = 0;
3171 } else if ( i < 0 ) {
3157 } else if (i < 0) {
31723158 i = uiInfo.teamCount - 1;
31733159 }
31743160
3175 trap_Cvar_Set( ( blue ) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName );
3176
3161 trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName);
31773162 return qtrue;
31783163 }
31793164 return qfalse;
31803165 }
31813166
3182 static qboolean UI_TeamMember_HandleKey( int flags, float *special, int key, qboolean blue, int num ) {
3183 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3167 static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) {
3168 int select = UI_SelectForKey(key);
3169 if (select != 0) {
31843170 // 0 - None
31853171 // 1 - Human
31863172 // 2..NumCharacters - Bot
3187 char *cvar = va( blue ? "ui_blueteam%i" : "ui_redteam%i", num );
3188 int value = trap_Cvar_VariableValue( cvar );
3189
3190 if ( key == K_MOUSE2 ) {
3191 value--;
3173 char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num);
3174 int value = trap_Cvar_VariableValue(cvar);
3175
3176 value += select;
3177
3178 if (ui_actualNetGameType.integer >= GT_TEAM) {
3179 if (value >= uiInfo.characterCount + 2) {
3180 value = 0;
3181 } else if (value < 0) {
3182 value = uiInfo.characterCount + 2 - 1;
3183 }
31923184 } else {
3193 value++;
3194 }
3195
3196 if ( ui_actualNetGameType.integer >= GT_TEAM ) {
3197 if ( value >= uiInfo.characterCount + 2 ) {
3185 if (value >= UI_GetNumBots() + 2) {
31983186 value = 0;
3199 } else if ( value < 0 ) {
3200 value = uiInfo.characterCount + 2 - 1;
3201 }
3202 } else {
3203 if ( value >= UI_GetNumBots() + 2 ) {
3204 value = 0;
3205 } else if ( value < 0 ) {
3187 } else if (value < 0) {
32063188 value = UI_GetNumBots() + 2 - 1;
32073189 }
32083190 }
32093191
3210 trap_Cvar_Set( cvar, va( "%i", value ) );
3192 trap_Cvar_SetValue(cvar, value);
32113193 return qtrue;
32123194 }
32133195 return qfalse;
32153197
32163198 static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
32173199 #ifdef MISSIONPACK
3218 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
3219
3220 if (key == K_MOUSE2) {
3221 ui_netSource.integer--;
3222 } else {
3223 ui_netSource.integer++;
3224 }
3200 int select = UI_SelectForKey(key);
3201 if (select != 0) {
3202 ui_netSource.integer += select;
32253203
32263204 if(ui_netSource.integer >= UIAS_GLOBAL1 && ui_netSource.integer <= UIAS_GLOBAL5)
32273205 {
32333211 trap_Cvar_VariableStringBuffer(cvarname, masterstr, sizeof(masterstr));
32343212 if(*masterstr)
32353213 break;
3236
3237 if (key == K_MOUSE2) {
3238 ui_netSource.integer--;
3239 } else {
3240 ui_netSource.integer++;
3241 }
3214
3215 ui_netSource.integer += select;
32423216 }
32433217 }
32443218
32453219 if (ui_netSource.integer >= numNetSources) {
32463220 ui_netSource.integer = 0;
3247 } else if ( ui_netSource.integer < 0 ) {
3221 } else if (ui_netSource.integer < 0) {
32483222 ui_netSource.integer = numNetSources - 1;
32493223 }
32503224
32523226 if (!(ui_netSource.integer >= UIAS_GLOBAL1 && ui_netSource.integer <= UIAS_GLOBAL5)) {
32533227 UI_StartServerRefresh(qtrue);
32543228 }
3255 trap_Cvar_Set( "ui_netSource", va( "%d", ui_netSource.integer ) );
3229 trap_Cvar_SetValue( "ui_netSource", ui_netSource.integer);
32563230 return qtrue;
32573231 }
32583232 #endif // #ifdef MISSIONPACK
32593233 return qfalse;
32603234 }
32613235
3262 static qboolean UI_NetFilter_HandleKey( int flags, float *special, int key ) {
3236 static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) {
32633237 #ifdef MISSIONPACK
3264 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3265
3266 if ( key == K_MOUSE2 ) {
3267 ui_serverFilterType.integer--;
3268 } else {
3269 ui_serverFilterType.integer++;
3270 }
3271
3272 if ( ui_serverFilterType.integer >= numServerFilters ) {
3238 int select = UI_SelectForKey(key);
3239 if (select != 0) {
3240 ui_serverFilterType.integer += select;
3241
3242 if (ui_serverFilterType.integer >= numServerFilters) {
32733243 ui_serverFilterType.integer = 0;
3274 } else if ( ui_serverFilterType.integer < 0 ) {
3244 } else if (ui_serverFilterType.integer < 0) {
32753245 ui_serverFilterType.integer = numServerFilters - 1;
32763246 }
3277 UI_BuildServerDisplayList( qtrue );
3247 UI_BuildServerDisplayList(qtrue);
32783248 return qtrue;
32793249 }
32803250 #endif // #ifdef MISSIONPACK
32813251 return qfalse;
32823252 }
32833253
3284 static qboolean UI_OpponentName_HandleKey( int flags, float *special, int key ) {
3285 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3286 if ( key == K_MOUSE2 ) {
3254 static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) {
3255 int select = UI_SelectForKey(key);
3256 if (select != 0) {
3257 if (select < 0) {
32873258 UI_PriorOpponent();
32883259 } else {
32893260 UI_NextOpponent();
32933264 return qfalse;
32943265 }
32953266
3296 static qboolean UI_BotName_HandleKey( int flags, float *special, int key ) {
3297 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3298 int game = trap_Cvar_VariableValue( "g_gametype" );
3267 static qboolean UI_BotName_HandleKey(int flags, float *special, int key) {
3268 int select = UI_SelectForKey(key);
3269 if (select != 0) {
3270 int game = trap_Cvar_VariableValue("g_gametype");
32993271 int value = uiInfo.botIndex;
33003272
3301 if ( key == K_MOUSE2 ) {
3302 value--;
3273 value += select;
3274
3275 if (game >= GT_TEAM) {
3276 if (value >= uiInfo.characterCount + 2) {
3277 value = 0;
3278 } else if (value < 0) {
3279 value = uiInfo.characterCount + 2 - 1;
3280 }
33033281 } else {
3304 value++;
3305 }
3306
3307 if ( game >= GT_TEAM ) {
3308 if ( value >= uiInfo.characterCount + 2 ) {
3282 if (value >= UI_GetNumBots() + 2) {
33093283 value = 0;
3310 } else if ( value < 0 ) {
3311 value = uiInfo.characterCount + 2 - 1;
3312 }
3313 } else {
3314 if ( value >= UI_GetNumBots() + 2 ) {
3315 value = 0;
3316 } else if ( value < 0 ) {
3284 } else if (value < 0) {
33173285 value = UI_GetNumBots() + 2 - 1;
33183286 }
33193287 }
33233291 return qfalse;
33243292 }
33253293
3326 static qboolean UI_BotSkill_HandleKey( int flags, float *special, int key ) {
3327 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3328 if ( key == K_MOUSE2 ) {
3329 uiInfo.skillIndex--;
3330 } else {
3331 uiInfo.skillIndex++;
3332 }
3333 if ( uiInfo.skillIndex >= numSkillLevels ) {
3294 static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) {
3295 int select = UI_SelectForKey(key);
3296 if (select != 0) {
3297 uiInfo.skillIndex += select;
3298
3299 if (uiInfo.skillIndex >= numSkillLevels) {
33343300 uiInfo.skillIndex = 0;
3335 } else if ( uiInfo.skillIndex < 0 ) {
3336 uiInfo.skillIndex = numSkillLevels - 1;
3301 } else if (uiInfo.skillIndex < 0) {
3302 uiInfo.skillIndex = numSkillLevels-1;
33373303 }
33383304 return qtrue;
33393305 }
33403306 return qfalse;
33413307 }
33423308
3343 static qboolean UI_RedBlue_HandleKey( int flags, float *special, int key ) {
3344 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3309 static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) {
3310 int select = UI_SelectForKey(key);
3311 if (select != 0) {
33453312 uiInfo.redBlue ^= 1;
33463313 return qtrue;
33473314 }
33483315 return qfalse;
33493316 }
33503317
3351 static qboolean UI_Crosshair_HandleKey( int flags, float *special, int key ) {
3352 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3353 if ( key == K_MOUSE2 ) {
3354 uiInfo.currentCrosshair--;
3318 static qboolean UI_Crosshair_HandleKey(int flags, float *special, int key) {
3319 int select = UI_SelectForKey(key);
3320 if (select != 0) {
3321 uiInfo.currentCrosshair += select;
3322
3323 if (uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
3324 uiInfo.currentCrosshair = 0;
3325 } else if (uiInfo.currentCrosshair < 0) {
3326 uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
3327 }
3328 trap_Cvar_SetValue("cg_drawCrosshair", uiInfo.currentCrosshair);
3329 return qtrue;
3330 }
3331 return qfalse;
3332 }
3333
3334
3335
3336 static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) {
3337 int select = UI_SelectForKey(key);
3338 if (select != 0) {
3339 int selected;
3340
3341 UI_BuildPlayerList();
3342 if (!uiInfo.teamLeader) {
3343 return qfalse;
3344 }
3345 selected = trap_Cvar_VariableValue("cg_selectedPlayer");
3346
3347 selected += select;
3348
3349 if (selected > uiInfo.myTeamCount) {
3350 selected = 0;
3351 } else if (selected < 0) {
3352 selected = uiInfo.myTeamCount;
3353 }
3354
3355 if (selected == uiInfo.myTeamCount) {
3356 trap_Cvar_Set( "cg_selectedPlayerName", "Everyone");
33553357 } else {
3356 uiInfo.currentCrosshair++;
3357 }
3358
3359 if ( uiInfo.currentCrosshair >= NUM_CROSSHAIRS ) {
3360 uiInfo.currentCrosshair = 0;
3361 } else if ( uiInfo.currentCrosshair < 0 ) {
3362 uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
3363 }
3364 trap_Cvar_Set( "cg_drawCrosshair", va( "%d", uiInfo.currentCrosshair ) );
3365 return qtrue;
3366 }
3367 return qfalse;
3368 }
3369
3370
3371
3372 static qboolean UI_SelectedPlayer_HandleKey( int flags, float *special, int key ) {
3373 if ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) {
3374 int selected;
3375
3376 UI_BuildPlayerList();
3377 if ( !uiInfo.teamLeader ) {
3378 return qfalse;
3379 }
3380 selected = trap_Cvar_VariableValue( "cg_selectedPlayer" );
3381
3382 if ( key == K_MOUSE2 ) {
3383 selected--;
3384 } else {
3385 selected++;
3386 }
3387
3388 if ( selected > uiInfo.myTeamCount ) {
3389 selected = 0;
3390 } else if ( selected < 0 ) {
3391 selected = uiInfo.myTeamCount;
3392 }
3393
3394 if ( selected == uiInfo.myTeamCount ) {
3395 trap_Cvar_Set( "cg_selectedPlayerName", "Everyone" );
3396 } else {
3397 trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected] );
3398 }
3399 trap_Cvar_Set( "cg_selectedPlayer", va( "%d", selected ) );
3358 trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]);
3359 }
3360 trap_Cvar_SetValue( "cg_selectedPlayer", selected);
34003361 }
34013362 return qfalse;
34023363 }
46654626 // trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n");
46664627 // trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n");
46674628 // Controls_SetDefaults();
4629 #ifdef CINEMATICS_INTRO
46684630 // trap_Cvar_Set("com_introPlayed", "1" );
4631 #endif
46694632 // trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
46704633
46714634 // from MP 11/12/01
46744637 trap_Cmd_ExecuteText( EXEC_NOW, "exec language.cfg\n" ); // NERVE - SMF
46754638 trap_Cmd_ExecuteText( EXEC_NOW, "setRecommended\n" ); // NERVE - SMF
46764639 Controls_SetDefaults();
4640 #ifdef CINEMATICS_INTRO
46774641 trap_Cvar_Set( "com_introPlayed", "1" );
4642 #endif
46784643 trap_Cvar_Set( "com_recommendedSet", "1" ); // NERVE - SMF
46794644 trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
46804645 // end from MP
56915656 } else {
56925657 // add a line that shows the number of servers found
56935658 if ( !uiInfo.numFoundPlayerServers ) {
5694 Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1], sizeof( uiInfo.foundPlayerServerAddresses[0] ), "no servers found" );
5659 Com_sprintf( uiInfo.foundPlayerServerNames[0], sizeof( uiInfo.foundPlayerServerNames[0] ), "no servers found" );
56955660 } else {
5696 Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1], sizeof( uiInfo.foundPlayerServerAddresses[0] ),
5697 "%d server%s found with player %s", uiInfo.numFoundPlayerServers - 1,
5698 uiInfo.numFoundPlayerServers == 2 ? "" : "s", uiInfo.findPlayerName );
5661 Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof( uiInfo.foundPlayerServerNames[0] ),
5662 "%d server%s found with player %s", uiInfo.numFoundPlayerServers - 1,
5663 uiInfo.numFoundPlayerServers == 2 ? "" : "s", uiInfo.findPlayerName );
56995664 }
57005665 uiInfo.nextFindPlayerRefresh = 0;
57015666 // show the server status info for the selected server
14321432 continue;
14331433 }
14341434
1435 if ( pages & ( 1 << ( newpage - 1 ) ) ) {
1435 if ( pages & ( 1 << ( abs( newpage - 1 ) ) ) ) {
14361436 dec++;
14371437 // if(dec == inc)
14381438 // break;
14501450 newpage = newpage + NOTEBOOK_MAX_PAGES;
14511451 }
14521452
1453 if ( pages & ( 1 << ( newpage - 1 ) ) ) {
1453 if ( pages & ( 1 << ( abs( newpage - 1 ) ) ) ) {
14541454 break;
14551455 }
14561456 }
23082308 }
23092309
23102310 qboolean Item_YesNo_HandleKey( itemDef_t *item, int key ) {
2311
2312 if ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) && item->window.flags & WINDOW_HASFOCUS && item->cvar ) {
2313 if ( key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3 ) {
2314 DC->setCVar( item->cvar, va( "%i", !DC->getCVarValue( item->cvar ) ) );
2311 if (item->cvar) {
2312 qboolean action = qfalse;
2313 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
2314 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
2315 action = qtrue;
2316 }
2317 } else if (UI_SelectForKey(key) != 0) {
2318 action = qtrue;
2319 }
2320 if (action) {
2321 DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
23152322 return qtrue;
23162323 }
23172324 }
23832390 qboolean Item_Multi_HandleKey( itemDef_t *item, int key ) {
23842391 multiDef_t *multiPtr = (multiDef_t*)item->typeData;
23852392 if ( multiPtr ) {
2386 if ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) && item->window.flags & WINDOW_HASFOCUS && item->cvar ) {
2387 if ( key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3 ) {
2388 int current = Item_Multi_FindCvarByValue( item ) + 1;
2393 if (item->cvar) {
2394 int select = 0;
2395 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
2396 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
2397 select = (key == K_MOUSE2) ? -1 : 1;
2398 }
2399 } else {
2400 select = UI_SelectForKey(key);
2401 }
2402 if (select != 0) {
2403 int current = Item_Multi_FindCvarByValue(item) + select;
23892404 int max = Item_Multi_CountSettings( item );
2390 if ( current < 0 || current >= max ) {
2405 if ( current < 0 ) {
2406 current = max-1;
2407 } else if ( current >= max ) {
23912408 current = 0;
23922409 }
23932410 if ( multiPtr->strDef ) {
27212738 float x, value, width, work;
27222739
27232740 //DC->Print("slider handle key\n");
2724 if ( item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) ) {
2725 if ( key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3 ) {
2741 if (item->cvar) {
2742 if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
27262743 editFieldDef_t *editDef = item->typeData;
2727 if ( editDef ) {
2744 if (editDef && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
27282745 rectDef_t testRect;
27292746 width = SLIDER_WIDTH;
27302747 if ( item->text ) {
27482765 // value = (((float)(DC->cursorx - x)/ SLIDER_WIDTH) * (editDef->maxVal - editDef->minVal));
27492766 value += editDef->minVal;
27502767 DC->setCVar( item->cvar, va( "%f", value ) );
2768 return qtrue;
2769 }
2770 }
2771 } else {
2772 int select = UI_SelectForKey(key);
2773 if (select != 0) {
2774 editFieldDef_t *editDef = item->typeData;
2775 if (editDef) {
2776 // 20 is number of steps
2777 value = DC->getCVarValue(item->cvar) + (((editDef->maxVal - editDef->minVal)/20) * select);
2778
2779 if (value < editDef->minVal)
2780 value = editDef->minVal;
2781 else if (value > editDef->maxVal)
2782 value = editDef->maxVal;
2783
2784 DC->setCVar(item->cvar, va("%f", value));
27512785 return qtrue;
27522786 }
27532787 }
29923026 return &rect;
29933027 }
29943028
3029 // menu item key horizontal action: -1 = previous value, 1 = next value, 0 = no change
3030 int UI_SelectForKey(int key)
3031 {
3032 switch (key) {
3033 case K_MOUSE1:
3034 case K_MOUSE3:
3035 case K_ENTER:
3036 case K_KP_ENTER:
3037 case K_RIGHTARROW:
3038 case K_KP_RIGHTARROW:
3039 case K_JOY1:
3040 case K_JOY2:
3041 case K_JOY3:
3042 case K_JOY4:
3043 return 1; // next
3044
3045 case K_MOUSE2:
3046 case K_LEFTARROW:
3047 case K_KP_LEFTARROW:
3048 return -1; // previous
3049 }
3050
3051 // no change
3052 return 0;
3053 }
3054
29953055 void Menu_HandleKey( menuDef_t *menu, int key, qboolean down ) {
29963056 int i;
29973057 itemDef_t *item = NULL;
31403200 case K_AUX14:
31413201 case K_AUX15:
31423202 case K_AUX16:
3143 break;
31443203 case K_KP_ENTER:
31453204 case K_ENTER:
31463205 case K_MOUSE3:
38853944 int id;
38863945 int i;
38873946
3888 if ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) && !g_waitingForKey ) {
3889 if ( down && ( key == K_MOUSE1 || key == K_ENTER ) ) {
3947 if (!g_waitingForKey)
3948 {
3949 if (down && ((key == K_MOUSE1 && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
3950 || key == K_ENTER || key == K_KP_ENTER || key == K_JOY1 || key == K_JOY2 || key == K_JOY3 || key == K_JOY4)) {
38903951 g_waitingForKey = qtrue;
38913952 g_bindItem = item;
38923953 }
38933954 return qtrue;
3894 } else
3955 }
3956 else
38953957 {
3896 if ( !g_waitingForKey || g_bindItem == NULL ) {
3958 if (g_bindItem == NULL) {
38973959 return qtrue;
38983960 }
38993961
473473 qboolean Menus_AnyFullScreenVisible( void );
474474 void Menus_Activate( menuDef_t *menu );
475475
476 int UI_SelectForKey(int key);
476477 displayContextDef_t *Display_GetContext( void );
477478 void *Display_CaptureItem( int x, int y );
478479 qboolean Display_MouseMove( void *p, int x, int y );
1313 #define _CRT_SECURE_NO_WARNINGS
1414 #endif
1515
16 #if defined(MACOS_X) || defined(IOAPI_NO_64)
16 #if defined(__APPLE__) || defined(IOAPI_NO_64)
1717 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
1818 #define FOPEN_FUNC(filename, mode) fopen(filename, mode)
1919 #define FTELLO_FUNC(stream) ftello(stream)
2020 #ifndef _ZLIBIOAPI64_H
2121 #define _ZLIBIOAPI64_H
2222
23 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(MACOS_X))
23 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
2424
2525 // Linux needs this to support file operation on files larger then 4+GB
2626 // But might need better if/def to select just the platforms that needs them.
5454 #define ftello64 ftell
5555 #define fseeko64 fseek
5656 #else
57 #ifdef __FreeBSD__
57 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
5858 #define fopen64 fopen
5959 #define ftello64 ftello
6060 #define fseeko64 fseeko
33
44 if [ "$ARCH" = "x86_64" ];
55 then
6 CMD_PREFIX="amd64-mingw32msvc x86_64-w64-mingw32"
6 CMD_PREFIX="x86_64-w64-mingw32 amd64-mingw32msvc"
77 else
8 CMD_PREFIX="i586-mingw32msvc i686-w64-mingw32"
8 CMD_PREFIX="i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32"
99 export ARCH=x86
1010 fi
1111
11
22 # Note: This works in Linux and cygwin
33
4 CMD_PREFIX="amd64-mingw32msvc x86_64-w64-mingw32";
4 CMD_PREFIX="x86_64-w64-mingw32 amd64-mingw32msvc";
55
66 if [ "X$CC" = "X" ]; then
77 for check in $CMD_PREFIX; do
0 # Rend2
1 <insert ascii art here>
2
3 Rend2 is an alternate renderer for iortcw. It aims to implement modern
4 features and technologies into the id tech 3 engine, but without sacrificing
5 compatibility with existing RTCW mods.
6
7
8 -------------------------------------------------------------------------------
9 FEATURES
10 -------------------------------------------------------------------------------
11
12 - Compatible with most vanilla RTCW mods.
13 - HDR Rendering, and support for HDR lightmaps
14 - Tone mapping and auto-exposure.
15 - Cascaded shadow maps.
16 - Multisample anti-aliasing.
17 - Texture upsampling.
18 - Advanced materials support.
19 - Advanced shading and specular methods.
20 - RGTC and BPTC texture compression support.
21 - Screen-space ambient occlusion.
22
23
24 -------------------------------------------------------------------------------
25 INSTALLATION
26 -------------------------------------------------------------------------------
27
28 For *nix:
29
30 1. This should be identical to installing iortcw. Check their README for more
31 details.
32
33
34 For Win32:
35
36 1. Have a RTCW install, fully patched.
37
38 2. Copy the following files into RTCW's install directory:
39
40 ioWolfSP.x86.exe
41 renderer_opengl1_x86.dll
42 renderer_rend2_x86.dll
43
44 These can be found in build/release-mingw32-x86 after compiling, or bug
45 someone to release binaries.
46
47
48 -------------------------------------------------------------------------------
49 RUNNING
50 -------------------------------------------------------------------------------
51
52 1. Start iowolfsp. (ioWolfSP.x86.exe on Win32)
53
54 2. Open the console (the default key is tilde ~) and type
55 `/cl_renderer rend2` and press enter
56 `/vid_restart` then press enter again.
57
58 3. Enjoy.
59
60
61 -------------------------------------------------------------------------------
62 CVARS
63 -------------------------------------------------------------------------------
64
65 Cvars for simple rendering features:
66
67 * `r_ext_compressed_textures` - Automatically compress textures.
68 0 - No texture compression. (default)
69 1 - DXT/RGTC texture compression if
70 supported.
71 2 - BPTC texture compression if supported.
72
73 * `r_ext_framebuffer_multisample` - Multisample Anti-aliasing.
74 0 - None. (default)
75 1-16 - Some.
76 17+ - Too much!
77
78 * `r_ssao` - Enable screen-space ambient occlusion.
79 Currently eats framerate and has some
80 visible artifacts.
81 0 - No. (default)
82 1 - Yes.
83
84 Cvars for HDR and tonemapping:
85
86 * `r_hdr` - Do scene rendering in a framebuffer with
87 high dynamic range. (Less banding, and
88 exposure changes look much better)
89 0 - No.
90 1 - Yes. (default)
91
92 * `r_cameraExposure` - Cheat. Alter brightness, in powers of two.
93 -2 - 4x as dark.
94 0 - Normal. (default)
95 0.5 - Sqrt(2)x as bright.
96 2 - 4x as bright.
97
98 * `r_postProcess` - Enable post-processing.
99 0 - No.
100 1 - Yes. (default)
101
102 * `r_toneMap` - Enable tone mapping. Requires
103 r_hdr and r_postProcess.
104 0 - No.
105 1 - Yes. (default)
106
107 * `r_forceToneMap` - Cheat. Override built-in and map tonemap settings and use cvars r_forceToneMapAvg, r_forceToneMapMin, and r_forceToneMapMax.
108 0 - No. (default)
109 1 - Yes.
110
111 * `r_forceToneMapAvg` - Cheat. Map average scene luminance to this
112 value, in powers of two. Requires
113 r_forceToneMap.
114 -2.0 - Dark.
115 -1.0 - Kinda dark. (default).
116 2.0 - Too bright.
117
118 * `r_forceToneMapMin` - Cheat. After mapping average, luminance
119 below this level is mapped to black.
120 Requires r_forceToneMap.
121 -5 - Not noticeable.
122 -3.25 - Normal. (default)
123 0.0 - Too dark.
124
125 * `r_forceToneMapMin` - Cheat. After mapping average, luminance
126 above this level is mapped to white.
127 Requires r_forceToneMap.
128 0.0 - Too bright.
129 1.0 - Normal. (default).
130 2.0 - Washed out.
131
132 * `r_autoExposure` - Do automatic exposure based on scene
133 brightness. Hardcoded to -2 to 2 on maps
134 that don't specify otherwise. Requires
135 r_hdr, r_postprocess, and r_toneMap.
136 0 - No.
137 1 - Yes. (default)
138
139 * `r_forceAutoExposure` - Cheat. Override built-in and map auto
140 exposure settings and use cvars
141 r_forceAutoExposureMin and
142 r_forceAutoExposureMax.
143 0 - No. (default)
144 1 - Yes.
145
146 * `r_forceAutoExposureMin` - Cheat. Set minimum exposure to this value,
147 in powers of two. Requires
148 r_forceAutoExpsure.
149 -3.0 - Dimmer.
150 -2.0 - Normal. (default)
151 -1.0 - Brighter.
152
153 * `r_forceAutoExposureMax` - Cheat. Set maximum exposure to this value,
154 in powers of two. Requires
155 r_forceAutoExpsure.
156 1.0 - Dimmer.
157 2.0 - Normal. (default)
158 3.0 - Brighter.
159
160 Cvars for advanced material usage:
161
162 * `r_normalMapping` - Enable normal maps for materials that
163 support it.
164 0 - No.
165 1 - Yes. (default)
166
167 * `r_specularMapping` - Enable specular maps for materials that
168 support it.
169 0 - No.
170 1 - Yes. (default)
171
172 * `r_deluxeMapping` - Enable deluxe mapping. (Map is compiled
173 with light directions.) Even if the map
174 doesn't have deluxe mapping compiled in,
175 an approximation based on the lightgrid
176 will be used.
177 0 - No.
178 1 - Yes. (default)
179
180 * `r_parallaxMapping` - Enable parallax mapping for materials that
181 support it.
182 0 - No. (default)
183 1 - Use parallax occlusion mapping.
184 2 - Use relief mapping. (slower)
185
186 * `r_baseSpecular` - Set the specular reflectance of materials
187 which don't include a specular map or
188 use the specularReflectance keyword.
189 0 - No.
190 0.04 - Realistic. (default)
191 1.0 - Ack.
192
193 * `r_baseGloss` - Set the glossiness of materials which don't
194 include a specular map or use the
195 specularExponent keyword.
196 0 - Rough.
197 0.3 - Default.
198 1.0 - Shiny.
199
200 * `r_baseNormalX` - Set the scale of the X values from normal
201 maps when the normalScale keyword is not
202 used.
203 -1 - Flip X.
204 0 - Ignore X.
205 1 - Normal X. (default)
206 2 - Double X.
207
208 * `r_baseNormalY` - Set the scale of the Y values from normal
209 maps when the normalScale keyword is not
210 used.
211 -1 - Flip Y.
212 0 - Ignore Y.
213 1 - Normal Y. (default)
214 2 - Double Y.
215
216 * `r_baseParallax` - Sets the scale of the parallax effect for
217 materials when the parallaxDepth keyword
218 is not used.
219 0 - No depth.
220 0.01 - Pretty smooth.
221 0.05 - Standard depth. (default)
222 0.1 - Looks broken.
223
224 * `r_pbr` - Enable physically based rendering.
225 Experimental, will not look correct without
226 assets meant for it.
227 0 - No. (default)
228 1 - Yes.
229
230 Cvars for image interpolation and generation:
231
232 * `r_imageUpsample` - Use interpolation to artifically increase
233 the resolution of all textures. Looks good
234 in certain circumstances.
235 0 - No. (default)
236 1 - 2x size.
237 2 - 4x size.
238 3 - 8x size, etc
239
240 * `r_imageUpsampleMaxSize` - Maximum texture size when upsampling
241 textures.
242 1024 - Default.
243 2048 - Really nice.
244 4096 - Really slow.
245 8192 - Crash.
246
247 * `r_imageUpsampleType` - Type of interpolation when upsampling
248 textures.
249 0 - None. (probably broken)
250 1 - Bad but fast (default,
251 FCBI without second derivatives)
252 2 - Okay but slow (normal FCBI)
253
254 * `r_genNormalMaps* - Naively generate normal maps for all
255 textures.
256 0 - Don't. (default)
257 1 - Do.
258
259 Cvars for the sunlight and cascaded shadow maps:
260
261 * `r_forceSun` - Force sunlight and shadows, using sun position from sky material.
262 0 - Don't. (default)
263 1 - Do.
264 2 - Sunrise, sunset.
265
266 * `r_forceSunLightScale` - Cheat. Scale sun brightness by this factor
267 when r_forceSun 1.
268 1.0 - Default
269
270 * `r_forceSunAmbientScale` - Cheat. Scale sun ambient brightness by this factor when r_forceSun 1. 0.5 - Default
271
272 * `r_sunShadows` - Enable sunlight and cascaded shadow maps for
273 it on maps that support it.
274 0 - No.
275 1 - Yes. (default)
276
277 * `r_sunlightMode` - Specify the method used to add sunlight to
278 the scene.
279 0 - No.
280 1 - Multiply lit areas by light scale, and
281 shadowed areas by ambient scale.
282 (default)
283 2 - Add light. Looks better, but is slower
284 and doesn't integrate well with existing
285 maps.
286
287 * `r_shadowFilter` - Enable filtering shadows for a smoother
288 look.
289 0 - No.
290 1 - Some. (default)
291 2 - Much.
292
293 * `r_shadowMapSize` - Size of each cascaded shadow map.
294 256 - 256x256, ugly, probably shouldn't
295 go below this.
296 512 - 512x512, passable.
297 1024 - 1024x1024, good. (default)
298 2048 - 2048x2048, extreme.
299 4096 - 4096x4096, indistinguishable from
300 2048.
301
302 Cvars that you probably don't care about or shouldn't mess with:
303
304 * `r_mergeMultidraws` - Optimize number of calls to
305 glMultiDrawElements().
306 0 - Don't.
307 1 - Do some. (default)
308 2 - Do more than necessary (eats CPU).
309
310 * `r_mergeLeafSurfaces` - Merge surfaces that share common materials
311 and a common leaf. Speeds up rendering.
312 0 - Don't.
313 1 - Do. (default)
314
315 * `r_recalcMD3Normals` - Recalculate the normals when loading an MD3.
316 Fixes normal maps in some cases but looks
317 ugly in others.
318 0 - Don't. (default)
319 1 - Do.
320
321 * `r_depthPrepass` - Do a depth-only pass before rendering.
322 Speeds up rendering in cases where advanced
323 features are used. Required for
324 r_sunShadows.
325 0 - No.
326 1 - Yes. (default)
327
328 * `r_mergeLightmaps` - Merge the small (128x128) lightmaps into
329 2 or fewer giant (4096x4096) lightmaps.
330 Easy speedup.
331 0 - Don't.
332 1 - Do. (default)
333
334 * `r_shadowCascadeZNear` - Near plane for shadow cascade frustums.
335 4 - Default.
336
337 * `r_shadowCascadeZFar` - Far plane for shadow cascade frustums.
338 3072 - Default.
339
340 * `r_shadowCascadeZBias` - Z-bias for shadow cascade frustums.
341 -256 - Default.
342
343 Cvars that have broken bits:
344
345 * `r_dlightMode` - Change how dynamic lights look.
346 0 - RTCW style dlights, fake
347 brightening. (default)
348 1 - Actual lighting, no shadows.
349 2 - Light and shadows. (broken)
350
351 * `r_pshadowDist` - Virtual camera distance when creating shadowmaps for projected shadows. Deprecated.
352
353 * `cg_shadows` - Old shadow code. Deprecated.
354
355
356 -------------------------------------------------------------------------------
357 MATERIALS
358 -------------------------------------------------------------------------------
359
360 Rend2 supports .mtr files, which are basically the same as .shader files, and
361 are located in the same place, but override existing .shader files if they
362 exist. This is to allow maps and mods to use the new material features without
363 breaking the map when using the old renderer.
364
365 Here's an example of a material stored in one, showing off some new features:
366
367 textures/abandon/grass
368 {
369 qer_editorimage textures/abandon/grass.jpg
370 {
371 map textures/abandon/grass3_256_d.jpg
372 rgbgen identity
373 }
374 {
375 stage normalparallaxmap
376 map textures/abandon/grass3_1024_n.png
377 normalScale 1 1
378 parallaxDepth 0.05
379 }
380 {
381 stage specularmap
382 map textures/abandon/grass3_256_s.png
383 specularReflectance 0.12
384 specularExponent 16
385 }
386 {
387 map $lightmap
388 blendfunc GL_DST_COLOR GL_ZERO
389 }
390 }
391
392 The first thing to notice is that this is basically the same as old RTCW
393 shader files. The next thing to notice are the new keywords. Here is what
394 they mean:
395
396 `stage <type>`
397 - State how this imagemap will be used by Rend2:
398 diffuseMap - Standard, same as no stage entry
399 normalMap - Image will be used as a normal map
400 normalParallaxMap - Image will be used as a normal map with
401 alpha treated as height for parallax mapping
402 specularMap - Image will be used as a specular map with
403 alpha treated as shininess.
404
405 `specularReflectance <value>`
406 - State how metallic this material is. Metals typically have a high
407 specular and a low diffuse, so this is typically high for them, and low
408 for other materials, such as plastic. For typical values for various
409 materials, see http://refractiveindex.info , pick a material, then scroll
410 down to the reflection calculator and look up its reflectance. Default
411 is 0.04, since most materials aren't metallic.
412
413 `specularExponent <value>`
414 - State how shiny this material is. Note that this is modulated by the
415 alpha channel of the specular map, so if it were set to 16, and the alpha
416 channel of the specular map was set to 0.5, then the shininess would be
417 set to 8. Default 256.
418
419 `normalScale <x> <y>`
420 - State the X and Y scales of the normal map. This is useful for increasing
421 or decreasing the "strength" of the normal map, or entering negative values
422 to flip the X and/or Y values. Default 1 1.
423
424 `parallaxDepth <value>`
425 - State the maximum depth of the parallax map. This is a fairly sensitive
426 value, and I recommend the default or lower. Default 0.05.
427
428 An important note is that normal and specular maps influence the diffuse map
429 declared before them, so materials like this are possible:
430
431 textures/terrain/grass
432 {
433 qer_editorimage textures/terrain/grass.jpg
434
435 {
436 map textures/terrain/rock.jpg
437 }
438 {
439 stage normalparallaxmap
440 map textures/terrain/rock_n.png
441 }
442 {
443 stage specularmap
444 map textures/terrain/rock_s.jpg
445 }
446 {
447 map textures/terrain/grass.jpg
448 blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
449 alphaGen vertex
450 }
451 {
452 stage normalparallaxmap
453 map textures/terrain/grass_n.png
454 }
455 {
456 stage specularmap
457 map textures/terrain/grass_s.png
458 specularReflectance 0.12
459 }
460 {
461 map $lightmap
462 blendfunc GL_DST_COLOR GL_ZERO
463 }
464 }
465
466 Though note due to the complexity of lighting, dynamic light (including
467 sunlight with cascaded shadow maps) currently only works 100% on materials like
468 this, where the second diffuse map doesn't have its own alpha, and only
469 uses vertex alpha. YMMV.
470
471 Another addition to materials is working normal/specular maps on vertex lit
472 surfaces. To enable this, make your material look like this:
473
474 textures/vehicles/car
475 {
476 qer_editorimage textures/vehicles/car.jpg
477
478 {
479 map textures/vehicles/car.jpg
480 rgbGen vertexLit
481 }
482 {
483 stage normalparallaxmap
484 map textures/vehicles/car_n.jpg
485 }
486 {
487 stage specularmap
488 map textures/vehicles/car_s.jpg
489 }
490 }
491
492 Note the new keyword, 'vertexLit' after rgbGen. This is analogous to
493 'rgbGen vertex', except a light direction will be determined from the lightgrid
494 and used with the normal and specular maps. 'exactVertexLit' exists as well,
495 and is the equivalent for 'exactVertex'.
496
497
498 -------------------------------------------------------------------------------
499 DYNAMIC SUNLIGHT AND CASCADED SHADOW MAPS
500 -------------------------------------------------------------------------------
501
502 This adds a new keyword to sky materials, q3gl2_sun. The syntax is:
503
504 q3gl2_sun <red> <green> <blue> <intensity> <degrees> <elevation> <ambientLightScale>
505
506 Note the first six parameters are the same as in q3map_sun or q3map_sunExt,
507 and the last two indicate scaling factors for the map brightness and an ambient
508 light of the same color as the sun.
509
510 There are currently two ways to use this in your own (and other people's) maps.
511
512 1. Create your map as normal, set r_sunlightMode to 1, and add a
513 'q3gl2_sun' line after your 'q3map_sun' line in your sky material, like
514 so:
515
516 textures/skies/bluesky
517 {
518 qer_editorimage textures/skies/bluesky.jpg
519
520 surfaceparm nomarks
521 surfaceparm noimpact
522 surfaceparm nolightmap
523 surfaceparm sky
524 q3map_sunExt 240 238 200 100 195 35 3 16
525 q3gl2_sun 240 238 200 50 195 35 0.2
526 q3map_skylight 50 16
527 q3map_lightimage $whiteimage
528
529 skyparms env/bluesky - -
530 }
531
532 The advantages with this method are that your map will continue to work
533 with the old renderer with the sunlight baked into the lightmap, and it
534 can be used with existing maps without recompilation. The downside is
535 artifacts like doubled shadows and uneven shadow edges.
536
537 2. Set r_sunlightMode to 2 and use 'q3gl2_sun' instead of 'q3map_sun' or
538 'q3map_sunExt', like so:
539
540 textures/skies/bluesky
541 {
542 qer_editorimage textures/skies/bluesky.jpg
543
544 surfaceparm nomarks
545 surfaceparm noimpact
546 surfaceparm nolightmap
547 surfaceparm sky
548 q3gl2_sun 240 238 200 50 195 35 0.2
549 q3map_skylight 50 16
550 q3map_lightimage $whiteimage
551
552 skyparms env/bluesky - -
553 }
554
555 The advantages with this method are that you don't get the artifacts that
556 characterize the other method, and your map compiles a lot faster without
557 the sunlight bouncing calculations. The downsides are that your map will
558 not display properly with the old renderer, and you lose the bounced light
559 that compiling the map with q3map_sun* in it would have.
560
561
562 -------------------------------------------------------------------------------
563 TONE MAPPING AND AUTO EXPOSURE
564 -------------------------------------------------------------------------------
565
566 This adds a new keyword to sky materials, q3gl2_tonemap. The syntax is:
567
568 q3gl2_tonemap <toneMapMin> <toneMapAvg> <toneMapMax> <autoExposureMin> <autoExposureMax>
569
570 Each of these settings corresponds to a matching cvar, so you can view and
571 adjust the effect before settling on fixed settings.
572
573
574 -------------------------------------------------------------------------------
575 THANKS
576 -------------------------------------------------------------------------------
577
578 I'd like to take this part of the readme to thank the numerous people who
579 contributed thoughts, ideas, and whole swaths of code to this project.
580
581 - Id Software, for creating RTCW and releasing its source code under a
582 GPL license, without which this project would not be possible.
583
584 - Zachary 'Zakk' Slater, Thilo Schulz, Tim Angus, and the rest of the
585 ioquake3 team and contributors, for improving massively upon the raw Quake
586 3 source, and accepting my and gimhael's modular renderer patch.
587
588 - Robert 'Tr3B' Beckebans and the other contributors to XReaL, for letting me
589 liberally copy code from you. :)
590
591 - Andrew 'Black Monk' Prosnik, Andrei 'Makro' Drexler, Tomi 'T.T.I.' Isoaho,
592 Richard 'JBravo' Allen, Walter 'Johnny Rocket' Somol, and the rest of the
593 Boomstick Studios, for contributing code, feature requests, and testing.
594
595 - Yoshiharu Gotanda, Tatsuya Shoji, and the rest of tri-Ace's R&D Department,
596 for creating the tri-Ace shading equations and posting their derivations in
597 simple English.
598
599 - Matthias 'gimhael' Bentrup, for random ideas and bits of code.
600
601 - Evan 'megatog615' Goers, for testing, ideas, and bugging me just enough
602 that I'd write documentation. :)
603
604 - The folks at #ioquake3, who don't seem to mind when I suddenly drop a
605 screenshot and insist on talking about it. :)
606
607 - And lots of various other random people, who posted on forums, blogs, and
608 Wikipedia, who helped in small but numerous ways.
609
610 If I missed you in this section, feel free to drop me a line and I'll add you.
611
612
613 -------------------------------------------------------------------------------
614 CONTACT
615 -------------------------------------------------------------------------------
616
617 My name is James Canete, and I wrote most of this readme. Also, a renderer.
618
619 If you wish to get in touch with me, try my GMail at use.less01 (you should be
620 able to solve this), or look for SmileTheory in #ioquake3 on irc.freenode.net.
+0
-634
SP/rend2-readme.txt less more
0 Rend2
1 <insert ascii art here>
2
3 Rend2 is an alternate renderer for iortcw. It aims to implement modern
4 features and technologies into the id tech 3 engine, but without sacrificing
5 compatibility with existing RTCW mods.
6
7
8 -------------------------------------------------------------------------------
9 FEATURES
10 -------------------------------------------------------------------------------
11
12 - Compatible with most vanilla RTCW mods.
13 - HDR Rendering, and support for HDR lightmaps
14 - Tone mapping and auto-exposure.
15 - Cascaded shadow maps.
16 - Multisample anti-aliasing.
17 - Texture upsampling.
18 - Advanced materials support.
19 - Advanced shading and specular methods.
20 - RGTC and BPTC texture compression support.
21 - Screen-space ambient occlusion.
22
23
24 -------------------------------------------------------------------------------
25 INSTALLATION
26 -------------------------------------------------------------------------------
27
28 For *nix:
29
30 1. This should be identical to installing iortcw. Check their README for more
31 details.
32
33
34 For Win32:
35
36 1. Have a RTCW install, fully patched.
37
38 2. Copy the following files into RTCW's install directory:
39
40 ioWolfSP.x86.exe
41 renderer_opengl1_x86.dll
42 renderer_rend2_x86.dll
43
44 These can be found in build/release-mingw32-x86 after compiling, or bug
45 someone to release binaries.
46
47
48 -------------------------------------------------------------------------------
49 RUNNING
50 -------------------------------------------------------------------------------
51
52 1. Start iowolfsp. (ioWolfSP.x86.exe on Win32)
53
54 2. Open the console (default key ~) and type '/cl_renderer rend2; vid_restart'
55
56 3. Enjoy.
57
58
59 -------------------------------------------------------------------------------
60 CVARS
61 -------------------------------------------------------------------------------
62
63 Cvars for simple rendering features:
64 r_ext_compressed_textures - Automatically compress textures.
65 0 - No texture compression. (default)
66 1 - DXT/RGTC texture compression if
67 supported.
68 2 - BPTC texture compression if supported.
69
70 r_ext_framebuffer_multisample - Multisample Anti-aliasing.
71 0 - None. (default)
72 1-16 - Some.
73 17+ - Too much!
74
75 r_ssao - Enable screen-space ambient occlusion.
76 Currently eats framerate and has some
77 visible artifacts.
78 0 - No. (default)
79 1 - Yes.
80
81 Cvars for HDR and tonemapping:
82 r_hdr - Do scene rendering in a framebuffer with
83 high dynamic range. (Less banding, and
84 exposure changes look much better)
85 0 - No.
86 1 - Yes. (default)
87
88 r_cameraExposure - Cheat. Alter brightness, in powers of two.
89 -2 - 4x as dark.
90 0 - Normal. (default)
91 0.5 - Sqrt(2)x as bright.
92 2 - 4x as bright.
93
94 r_postProcess - Enable post-processing.
95 0 - No.
96 1 - Yes. (default)
97
98 r_toneMap - Enable tone mapping. Requires
99 r_hdr and r_postProcess.
100 0 - No.
101 1 - Yes. (default)
102
103 r_forceToneMap - Cheat. Override built-in and map tonemap
104 settings and use cvars r_forceToneMapAvg,
105 r_forceToneMapMin, and r_forceToneMapMax.
106 0 - No. (default)
107 1 - Yes.
108
109 r_forceToneMapAvg - Cheat. Map average scene luminance to this
110 value, in powers of two. Requires
111 r_forceToneMap.
112 -2.0 - Dark.
113 -1.0 - Kinda dark. (default).
114 2.0 - Too bright.
115
116 r_forceToneMapMin - Cheat. After mapping average, luminance
117 below this level is mapped to black.
118 Requires r_forceToneMap.
119 -5 - Not noticeable.
120 -3.25 - Normal. (default)
121 0.0 - Too dark.
122
123 r_forceToneMapMin - Cheat. After mapping average, luminance
124 above this level is mapped to white.
125 Requires r_forceToneMap.
126 0.0 - Too bright.
127 1.0 - Normal. (default).
128 2.0 - Washed out.
129
130 r_autoExposure - Do automatic exposure based on scene
131 brightness. Hardcoded to -2 to 2 on maps
132 that don't specify otherwise. Requires
133 r_hdr, r_postprocess, and r_toneMap.
134 0 - No.
135 1 - Yes. (default)
136
137 r_forceAutoExposure - Cheat. Override built-in and map auto
138 exposure settings and use cvars
139 r_forceAutoExposureMin and
140 r_forceAutoExposureMax.
141 0 - No. (default)
142 1 - Yes.
143
144 r_forceAutoExposureMin - Cheat. Set minimum exposure to this value,
145 in powers of two. Requires
146 r_forceAutoExpsure.
147 -3.0 - Dimmer.
148 -2.0 - Normal. (default)
149 -1.0 - Brighter.
150
151 r_forceAutoExposureMax - Cheat. Set maximum exposure to this value,
152 in powers of two. Requires
153 r_forceAutoExpsure.
154 1.0 - Dimmer.
155 2.0 - Normal. (default)
156 3.0 - Brighter.
157
158 Cvars for advanced material usage:
159 r_normalMapping - Enable normal maps for materials that
160 support it.
161 0 - No.
162 1 - Yes. (default)
163
164 r_specularMapping - Enable specular maps for materials that
165 support it.
166 0 - No.
167 1 - Yes. (default)
168
169 r_deluxeMapping - Enable deluxe mapping. (Map is compiled
170 with light directions.) Even if the map
171 doesn't have deluxe mapping compiled in,
172 an approximation based on the lightgrid
173 will be used.
174 0 - No.
175 1 - Yes. (default)
176
177 r_parallaxMapping - Enable parallax mapping for materials that
178 support it.
179 0 - No. (default)
180 1 - Use parallax occlusion mapping.
181 2 - Use relief mapping. (slower)
182
183 r_baseSpecular - Set the specular reflectance of materials
184 which don't include a specular map or
185 use the specularReflectance keyword.
186 0 - No.
187 0.04 - Realistic. (default)
188 1.0 - Ack.
189
190 r_baseGloss - Set the glossiness of materials which don't
191 include a specular map or use the
192 specularExponent keyword.
193 0 - Rough.
194 0.3 - Default.
195 1.0 - Shiny.
196
197 r_baseNormalX - Set the scale of the X values from normal
198 maps when the normalScale keyword is not
199 used.
200 -1 - Flip X.
201 0 - Ignore X.
202 1 - Normal X. (default)
203 2 - Double X.
204
205 r_baseNormalY - Set the scale of the Y values from normal
206 maps when the normalScale keyword is not
207 used.
208 -1 - Flip Y.
209 0 - Ignore Y.
210 1 - Normal Y. (default)
211 2 - Double Y.
212
213 r_baseParallax - Sets the scale of the parallax effect for
214 materials when the parallaxDepth keyword
215 is not used.
216 0 - No depth.
217 0.01 - Pretty smooth.
218 0.05 - Standard depth. (default)
219 0.1 - Looks broken.
220
221 Cvars for image interpolation and generation:
222 r_imageUpsample - Use interpolation to artifically increase
223 the resolution of all textures. Looks good
224 in certain circumstances.
225 0 - No. (default)
226 1 - 2x size.
227 2 - 4x size.
228 3 - 8x size, etc
229
230 r_imageUpsampleMaxSize - Maximum texture size when upsampling
231 textures.
232 1024 - Default.
233 2048 - Really nice.
234 4096 - Really slow.
235 8192 - Crash.
236
237 r_imageUpsampleType - Type of interpolation when upsampling
238 textures.
239 0 - None. (probably broken)
240 1 - Bad but fast (default,
241 FCBI without second derivatives)
242 2 - Okay but slow (normal FCBI)
243
244 r_genNormalMaps - Naively generate normal maps for all
245 textures.
246 0 - Don't. (default)
247 1 - Do.
248
249 Cvars for the sunlight and cascaded shadow maps:
250 r_forceSun - Force sunlight and shadows, using sun
251 position from sky material.
252 0 - Don't. (default)
253 1 - Do.
254 2 - Sunrise, sunset.
255
256 r_forceSunMapLightScale - Cheat. Scale map brightness by this factor
257 when r_forceSun 1.
258 1.0 - Default
259
260 r_forceSunLightScale - Cheat. Scale sun brightness by this factor
261 when r_forceSun 1.
262 1.0 - Default
263
264 r_forceSunAmbientScale - Cheat. Scale sun ambient brightness by this
265 factor when r_forceSun 1.
266 0.5 - Default
267
268 r_sunShadows - Enable sunlight and cascaded shadow maps for
269 it on maps that support it.
270 0 - No.
271 1 - Yes. (default)
272
273 r_sunlightMode - Specify the method used to add sunlight to
274 the scene.
275 0 - No.
276 1 - Multiply lit areas by light scale, and
277 shadowed areas by ambient scale.
278 (default)
279 2 - Add light. Looks better, but is slower
280 and doesn't integrate well with existing
281 maps.
282
283 r_shadowFilter - Enable filtering shadows for a smoother
284 look.
285 0 - No.
286 1 - Some. (default)
287 2 - Much.
288
289 r_shadowMapSize - Size of each cascaded shadow map.
290 256 - 256x256, ugly, probably shouldn't
291 go below this.
292 512 - 512x512, passable.
293 1024 - 1024x1024, good. (default)
294 2048 - 2048x2048, extreme.
295 4096 - 4096x4096, indistinguishable from
296 2048.
297
298
299 Cvars that you probably don't care about or shouldn't mess with:
300 r_mergeMultidraws - Optimize number of calls to
301 glMultiDrawElements().
302 0 - Don't.
303 1 - Do some. (default)
304 2 - Do more than necessary (eats CPU).
305
306 r_mergeLeafSurfaces - Merge surfaces that share common materials
307 and a common leaf. Speeds up rendering.
308 0 - Don't.
309 1 - Do. (default)
310
311 r_recalcMD3Normals - Recalculate the normals when loading an MD3.
312 Fixes normal maps in some cases but looks
313 ugly in others.
314 0 - Don't. (default)
315 1 - Do.
316
317 r_depthPrepass - Do a depth-only pass before rendering.
318 Speeds up rendering in cases where advanced
319 features are used. Required for
320 r_sunShadows.
321 0 - No.
322 1 - Yes. (default)
323
324 r_mergeLightmaps - Merge the small (128x128) lightmaps into
325 2 or fewer giant (4096x4096) lightmaps.
326 Easy speedup.
327 0 - Don't.
328 1 - Do. (default)
329
330 r_shadowCascadeZNear - Near plane for shadow cascade frustums.
331 4 - Default.
332
333 r_shadowCascadeZFar - Far plane for shadow cascade frustums.
334 3072 - Default.
335
336 r_shadowCascadeZBias - Z-bias for shadow cascade frustums.
337 -256 - Default.
338
339 r_materialGamma - Gamma level for material textures.
340 (diffuse, specular)
341 1.0 - RTCW, fastest. (default)
342
343 r_lightGamma - Gamma level for light.
344 (lightmap, lightgrid, vertex lights)
345 1.0 - RTCW, fastest. (default)
346
347 r_framebufferGamma - Gamma level for framebuffers.
348 1.0 - RTCW, fastest. (default)
349
350 r_tonemapGamma - Gamma applied after tonemapping.
351 1.0 - RTCW, fastest. (default)
352
353
354 Cvars that have broken bits:
355 r_dlightMode - Change how dynamic lights look.
356 0 - RTCW style dlights, fake
357 brightening. (default)
358 1 - Actual lighting, no shadows.
359 2 - Light and shadows. (broken)
360
361 r_pshadowDist - Virtual camera distance when creating shadow
362 maps for projected shadows. Deprecated.
363
364 cg_shadows - Old shadow code. Deprecated.
365
366
367 -------------------------------------------------------------------------------
368 MATERIALS
369 -------------------------------------------------------------------------------
370
371 Rend2 supports .mtr files, which are basically the same as .shader files, and
372 are located in the same place, but override existing .shader files if they
373 exist. This is to allow maps and mods to use the new material features without
374 breaking the map when using the old renderer.
375
376 Here's an example of a material stored in one, showing off some new features:
377
378 textures/abandon/grass
379 {
380 qer_editorimage textures/abandon/grass.jpg
381 {
382 map textures/abandon/grass3_256_d.jpg
383 rgbgen identity
384 }
385 {
386 stage normalparallaxmap
387 map textures/abandon/grass3_1024_n.png
388 normalScale 1 1
389 parallaxDepth 0.05
390 }
391 {
392 stage specularmap
393 map textures/abandon/grass3_256_s.png
394 specularReflectance 0.12
395 specularExponent 16
396 }
397 {
398 map $lightmap
399 blendfunc GL_DST_COLOR GL_ZERO
400 }
401 }
402
403 The first thing to notice is that this is basically the same as old RTCW
404 shader files. The next thing to notice are the new keywords. Here is what
405 they mean:
406
407 stage <type>
408 - State how this imagemap will be used by Rend2:
409 diffuseMap - Standard, same as no stage entry
410 normalMap - Image will be used as a normal map
411 normalParallaxMap - Image will be used as a normal map with
412 alpha treated as height for parallax mapping
413 specularMap - Image will be used as a specular map with
414 alpha treated as shininess.
415
416 specularReflectance <value>
417 - State how metallic this material is. Metals typically have a high
418 specular and a low diffuse, so this is typically high for them, and low
419 for other materials, such as plastic. For typical values for various
420 materials, see http://refractiveindex.info , pick a material, then scroll
421 down to the reflection calculator and look up its reflectance. Default
422 is 0.04, since most materials aren't metallic.
423
424 specularExponent <value>
425 - State how shiny this material is. Note that this is modulated by the
426 alpha channel of the specular map, so if it were set to 16, and the alpha
427 channel of the specular map was set to 0.5, then the shininess would be
428 set to 8. Default 256.
429
430 normalScale <x> <y>
431 - State the X and Y scales of the normal map. This is useful for increasing
432 or decreasing the "strength" of the normal map, or entering negative values
433 to flip the X and/or Y values. Default 1 1.
434
435 parallaxDepth <value>
436 - State the maximum depth of the parallax map. This is a fairly sensitive
437 value, and I recommend the default or lower. Default 0.05.
438
439 An important note is that normal and specular maps influence the diffuse map
440 declared before them, so materials like this are possible:
441
442 textures/terrain/grass
443 {
444 qer_editorimage textures/terrain/grass.jpg
445
446 {
447 map textures/terrain/rock.jpg
448 }
449 {
450 stage normalparallaxmap
451 map textures/terrain/rock_n.png
452 }
453 {
454 stage specularmap
455 map textures/terrain/rock_s.jpg
456 }
457 {
458 map textures/terrain/grass.jpg
459 blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
460 alphaGen vertex
461 }
462 {
463 stage normalparallaxmap
464 map textures/terrain/grass_n.png
465 }
466 {
467 stage specularmap
468 map textures/terrain/grass_s.png
469 specularReflectance 0.12
470 }
471 {
472 map $lightmap
473 blendfunc GL_DST_COLOR GL_ZERO
474 }
475 }
476
477 Though note due to the complexity of lighting, dynamic light (including
478 sunlight with cascaded shadow maps) currently only works 100% on materials like
479 this, where the second diffuse map doesn't have its own alpha, and only
480 uses vertex alpha. YMMV.
481
482 Another addition to materials is working normal/specular maps on vertex lit
483 surfaces. To enable this, make your material look like this:
484
485 textures/vehicles/car
486 {
487 qer_editorimage textures/vehicles/car.jpg
488
489 {
490 map textures/vehicles/car.jpg
491 rgbGen vertexLit
492 }
493 {
494 stage normalparallaxmap
495 map textures/vehicles/car_n.jpg
496 }
497 {
498 stage specularmap
499 map textures/vehicles/car_s.jpg
500 }
501 }
502
503 Note the new keyword, 'vertexLit' after rgbGen. This is analogous to
504 'rgbGen vertex', except a light direction will be determined from the lightgrid
505 and used with the normal and specular maps. 'exactVertexLit' exists as well,
506 and is the equivalent for 'exactVertex'.
507
508
509 -------------------------------------------------------------------------------
510 DYNAMIC SUNLIGHT AND CASCADED SHADOW MAPS
511 -------------------------------------------------------------------------------
512
513 This adds a new keyword to sky materials, q3gl2_sun. The syntax is:
514
515 q3gl2_sun <red> <green> <blue> <intensity> <degrees> <elevation>
516 <mapLightScale> <ambientLightScale>
517
518 Note the first six parameters are the same as in q3map_sun or q3map_sunExt,
519 and the last two indicate scaling factors for the map brightness and an ambient
520 light of the same color as the sun.
521
522 There are currently two ways to use this in your own (and other people's) maps.
523
524 1. Create your map as normal, set r_sunlightMode to 1, and add a
525 'q3gl2_sun' line after your 'q3map_sun' line in your sky material, like
526 so:
527
528 textures/skies/bluesky
529 {
530 qer_editorimage textures/skies/bluesky.jpg
531
532 surfaceparm nomarks
533 surfaceparm noimpact
534 surfaceparm nolightmap
535 surfaceparm sky
536 q3map_sunExt 240 238 200 100 195 35 3 16
537 q3gl2_sun 240 238 200 50 195 35 1.0 0.2
538 q3map_skylight 50 16
539 q3map_lightimage $whiteimage
540
541 skyparms env/bluesky - -
542 }
543
544 The advantages with this method are that your map will continue to work
545 with the old renderer with the sunlight baked into the lightmap, and it
546 can be used with existing maps without recompilation. The downside is
547 artifacts like doubled shadows and uneven shadow edges.
548
549 2. Set r_sunlightMode to 2 and use 'q3gl2_sun' instead of 'q3map_sun' or
550 'q3map_sunExt', like so:
551
552 textures/skies/bluesky
553 {
554 qer_editorimage textures/skies/bluesky.jpg
555
556 surfaceparm nomarks
557 surfaceparm noimpact
558 surfaceparm nolightmap
559 surfaceparm sky
560 q3gl2_sun 240 238 200 50 195 35 0.5 0.2
561 q3map_skylight 50 16
562 q3map_lightimage $whiteimage
563
564 skyparms env/bluesky - -
565 }
566
567 The advantages with this method are that you don't get the artifacts that
568 characterize the other method, and your map compiles a lot faster without
569 the sunlight bouncing calculations. The downsides are that your map will
570 not display properly with the old renderer, and you lose the bounced light
571 that compiling the map with q3map_sun* in it would have.
572
573
574 -------------------------------------------------------------------------------
575 TONE MAPPING AND AUTO EXPOSURE
576 -------------------------------------------------------------------------------
577
578 This adds a new keyword to sky materials, q3gl2_tonemap. The syntax is:
579
580 q3gl2_tonemap <toneMapMin> <toneMapAvg> <toneMapMax <autoExposureMin>
581 <autoExposureMax>
582
583 Each of these settings corresponds to a matching cvar, so you can view and
584 adjust the effect before settling on fixed settings.
585
586
587 -------------------------------------------------------------------------------
588 THANKS
589 -------------------------------------------------------------------------------
590
591 I'd like to take this part of the readme to thank the numerous people who
592 contributed thoughts, ideas, and whole swaths of code to this project.
593
594 - Id Software, for creating RTCW and releasing its source code under a
595 GPL license, without which this project would not be possible.
596
597 - Zachary 'Zakk' Slater, Thilo Schulz, Tim Angus, and the rest of the
598 ioquake3 team and contributors, for improving massively upon the raw Quake
599 3 source, and accepting my and gimhael's modular renderer patch.
600
601 - Robert 'Tr3B' Beckebans and the other contributors to XReaL, for letting me
602 liberally copy code from you. :)
603
604 - Andrew 'Black Monk' Prosnik, Andrei 'Makro' Drexler, Tomi 'T.T.I.' Isoaho,
605 Richard 'JBravo' Allen, Walter 'Johnny Rocket' Somol, and the rest of the
606 Boomstick Studios, for contributing code, feature requests, and testing.
607
608 - Yoshiharu Gotanda, Tatsuya Shoji, and the rest of tri-Ace's R&D Department,
609 for creating the tri-Ace shading equations and posting their derivations in
610 simple English.
611
612 - Matthias 'gimhael' Bentrup, for random ideas and bits of code.
613
614 - Evan 'megatog615' Goers, for testing, ideas, and bugging me just enough
615 that I'd write documentation. :)
616
617 - The folks at #ioquake3, who don't seem to mind when I suddenly drop a
618 screenshot and insist on talking about it. :)
619
620 - And lots of various other random people, who posted on forums, blogs, and
621 Wikipedia, who helped in small but numerous ways.
622
623 If I missed you in this section, feel free to drop me a line and I'll add you.
624
625
626 -------------------------------------------------------------------------------
627 CONTACT
628 -------------------------------------------------------------------------------
629
630 My name is James Canete, and I wrote most of this readme. Also, a renderer.
631
632 If you wish to get in touch with me, try my GMail at use.less01 (you should be
633 able to solve this), or look for SmileTheory in #ioquake3 on irc.freenode.net.