diff --git a/examples/gputest/Makefile b/examples/gputest/Makefile new file mode 100644 index 0000000..c38d65c --- /dev/null +++ b/examples/gputest/Makefile @@ -0,0 +1,175 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +TOPDIR ?= $(CURDIR) +include $(DEVKITARM)/3ds_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +# +# NO_SMDH: if set to anything, no SMDH file is generated. +# APP_TITLE is the name of the app stored in the SMDH file (Optional) +# APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) +# APP_AUTHOR is the author of the app stored in the SMDH file (Optional) +# ICON is the filename of the icon (.png), relative to the project folder. +# If not set, it attempts to use one of the following (in this order): +# - .png +# - icon.png +# - /default_icon.png +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard + +CFLAGS := -g -Wall -O2 -mword-relocations \ + -fomit-frame-pointer -ffast-math \ + $(ARCH) + +CFLAGS += $(INCLUDE) -DARM11 -D_3DS + +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +LIBS := -lcitro3d -lctru -lm + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CTRULIB) $(CURDIR)/../.. + + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SHADERFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shader))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) $(SHADERFILES:.shader=.shbin.o) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +ifeq ($(strip $(ICON)),) + icons := $(wildcard *.png) + ifneq (,$(findstring $(TARGET).png,$(icons))) + export APP_ICON := $(TOPDIR)/$(TARGET).png + else + ifneq (,$(findstring icon.png,$(icons))) + export APP_ICON := $(TOPDIR)/icon.png + endif + endif +else + export APP_ICON := $(TOPDIR)/$(ICON) +endif + +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +ifeq ($(strip $(NO_SMDH)),) +$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh +else +$(OUTPUT).3dsx : $(OUTPUT).elf +endif + +$(OUTPUT).elf : $(OFILES) + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +#--------------------------------------------------------------------------------- +%.shbin.o: %.shader + @echo $(notdir $<) + $(eval CURBIN := $(patsubst %.shader,%.shbin,$(notdir $<))) + $(eval CURH := $(patsubst %.shader,%.shader.h,$(notdir $<))) + @picasso $(CURBIN) $< $(CURH) + @bin2s $(CURBIN) | $(AS) -o $@ + @echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h + @echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h + @echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/gputest/data/grass.bin b/examples/gputest/data/grass.bin new file mode 100644 index 0000000..0bbf96e --- /dev/null +++ b/examples/gputest/data/grass.bin @@ -0,0 +1 @@ +۞ިؔ۞ި{qؔqߟިߟި{ߟިިߟ۞۞ՆݖqՆхߟؔԍި۞ԍި۞{ިqߟ۞ߟԍؔߟ{ިхߟؔߟؔ۞ڕؔؔԍިؔхؔ{ؔ۞ݖ{qߟх۞qԍ{؍۞؍ؔхڕؔԍߟߟ۞хؔݖؔިި۞ިݖߟިߟڕި۞۞۞q{х{ߟqߟ{ԍڕԍߟ۞Ն۞Նߟ{Նqؔߟхڕ{qqqхՆ؍qڕߟՆڕؔԍڕԍ{хqqݖхݖ{ݖՆڕ؍Ն{؍Նؔߟԍؔݖ۞ڕ؍{Ն{ՆߟՆؔ{Ն{ݖ؍ԍ؍ԍԍԍߟؔؔхԍхߟՆߟхԍߟؔԍ؍ߟՆх؍Նڕߟхߟڕ{ݖ{ڕؔؔߟؔިԍިؔߟڕ۞ڕ۞ؔؔڕՆؔݖԍؔ۞ߟݖڕ؍ݖ۞ߟؔߟؔ؍хՆ؍؍ՆՆ{{Ն{{{ߟх؍؍ՆՆ؍ؔՆ؍Ն{{؍{Նq{؍ؔڕؔؔ۞ڕ۞ڕߟߟхߟхިؔ۞ڕؔިڕިݖ؍ՆԍߟިڕؔؔߟԍԍߟՆՆڕхߟ{хߟԍ{ڕqߟԍхх{{х{{ԍؔ{ݖؔݖިߟߟߟߟި۞ިԍؔ۞ԍ۞ߟߟ۞ڕ۞хڕߟߟԍڕԍ۞ڕؔިؔؔԍххߟިިިިި۞۞۞ިި۞ިިՆިިި۞۞ި۞ߟ{Նԍхڕхߟхؔԍڕؔߟԍ۞ؔި{ߟхߟԍߟؔ۞ؔؔؔ۞۞ؔ؍ԍՆх۞۞ߟ۞{ԍqؔߟхިхؔؔхԍԍ۞х۞{хՆڕڕؔхڕߟ۞ؔ{ߟх۞ԍؔؔߟި۞{۞qՆߟqڕ؍q{qqՆqqߟڕԍިؔ۞ڕިхڕԍߟݖߟؔq{{ߟݖqؔqؔިхq{qхq۞qݖ{Ն؍qߟ{{ߟ{qq{q؍{{{{q{q{qqqԍݖхߟ{ߟި{۞{ؔхԍqߟ{qq{{ؔߟؔڕ{ڕڕؔՆؔՆԍڕ؍{Ն{ڕх{{qqԍߟڕߟхڕߟ۞ݖؔڕ۞ߟߟؔߟڕڕ{qՆqх۞{ڕ؍Նڕ؍ڕݖ۞ؔݖؔ؍ԍݖԍިިڕхߟؔݖߟڕؔߟ۞ؔхߟԍ{ߟՆߟх{хߟڕߟԍؔߟؔߟ؍ڕި{ؔՆߟх{{۞хؔхؔިؔި۞ިިߟхިԍڕ۞؍۞ؔؔؔؔؔߟߟؔި۞ި۞ؔ۞ڕؔԍԍх۞۞хڕިԍިԍؔߟؔߟՆ؍{Նߟؔߟؔ{ݖ؍ԍڕԍԍڕؔިߟؔݖڕݖިߟ۞ؔ۞ԍިԍؔؔ۞ؔ۞ڕؔؔ۞ڕڕՆڕ{х؍х{q{{{qхqߟ{؍хххх{qqхؔ{qqqq۞ڕ۞{ؔ{؍ިՆ۞ؔՆ؍ߟިݖ۞ߟߟߟݖ۞؍ؔߟߟڕڕхؔхՆؔ۞{ߟ{ߟххххڕؔхՆԍՆߟхԍՆߟՆqݖԍݖ۞хި؍ڕՆ{ؔ{ххߟ۞۞{ؔݖިިިх؍ߟՆڕ؍ԍݖՆԍՆххՆՆ{{{Ն{ި۞۞ؔ۞хؔ{۞۞Նؔх۞۞ި۞хؔхՆި۞۞qq{qިڕ۞х{Նхߟ؍{х{ިިߟ۞{ՆхՆхߟ{ڕ۞хؔ{؍ؔݖхԍ{ՆՆՆ{{{ԍڕхڕԍ۞ؔߟ؍؍ххؔڕԍ؍۞۞ؔ۞ԍ؍ԍՆԍ۞{ؔؔڕߟх{{{{ߟхߟՆ{{qՆхՆхԍՆڕ؍х؍ݖݖڕхх{؍{؍Ն؍۞х۞х؍ڕԍؔؔх؍Նݖؔݖؔ۞۞ؔؔ؍ؔԍߟؔхڕՆؔؔݖхՆ{{{ݖх؍{{{qՆх۞ՆؔڕՆߟх؍х؍{ххߟؔߟߟ{۞ԍ۞ڕؔՆؔڕ۞ߟؔ۞۞۞ؔިި۞۞ؔڕؔݖؔؔԍؔՆх{х۞ؔߟԍ{х{؍ߟхߟ{ؔԍ۞ؔؔ۞ߟ۞ؔؔؔؔхԍߟި۞۞۞ؔߟؔߟؔڕؔݖؔՆؔߟؔ۞۞ߟхߟ{ؔؔؔԍߟ{ߟ{Ն؍{؍Ն؍х{Ն؍؍{х{ԍ{хх{хݖхՆؔq{qՆ{ڕqՆՆqݖх۞ݖؔՆߟ{۞ߟ۞؍qި{ߟ{ՆхؔՆߟڕ۞۞ߟߟؔ{ؔ{ڕߟԍڕԍՆߟхڕхԍՆؔڕߟ؍ԍхԍݖؔՆؔх؍ԍՆݖхԍؔхߟ{ݖިؔхؔ؍ݖߟؔڕިߟ۞ߟՆ؍ؔݖх؍ԍՆؔؔؔԍߟхԍх؍Նх۞ߟ۞ߟՆ؍Ն؍ݖݖՆՆՆՆՆ؍ՆԍхՆՆ؍ՆхݖؔՆؔؔިؔިؔݖх؍Նߟ۞ߟؔ۞ԍߟ۞ߟؔ۞ި۞ԍ{Նq{{ݖ{q{{Նх{х{Նх؍{{ՆхՆՆ{{Ն{ՆՆՆq{q{ݖ{ݖqqqqqՆՆՆՆ{؍{Ն{{q{хݖߟߟՆq{qqqqqՆqqqqqq{ݖ{؍q{؍q؍{qq{{Ն{{ڕххՆ{Ն{q{ՆՆ{qqq{qՆqq{{؍{qqqqڕ؍ؔڕ؍{؍{{Ն{ՆՆх؍х؍хߟ{{ՆՆ؍{ڕхڕՆ؍ՆՆ؍ؔՆԍԍ{؍Նؔߟؔ؍Նߟхԍ۞хߟՆՆՆԍххххݖԍߟڕ؍х؍ڕߟхߟԍхߟߟ۞ߟ۞ި۞ިх؍ڕڕݖqՆ{ؔԍԍх{Ն{ؔڕݖڕхՆх{{ڕ{ԍ{q{{Ն{{{q{ݖ{{х؍ߟؔߟԍ{؍хߟ{Ն{qݖ۞ߟؔqqqՆՆ{qqݖ{ݖڕqqqqхՆqՆqԍ{{ؔqqؔ{ڕިqqՆqݖ{{ިqߟؔؔ{ߟqՆ{{{ݖ{ڕqؔqڕؔߟххՆڕ؍х{ؔ{۞{qqх۞Նڕ{хؔԍ۞ި{{ڕ{ި{ԍ۞ިؔߟިߟԍ۞۞۞ڕߟڕڕިި۞ؔިؔިިؔ۞ԍߟԍߟԍؔި۞ԍ؍хڕ۞ؔިՆڕхڕިڕި؍хߟ۞ߟ۞؍۞ڕԍڕԍڕؔިؔԍؔԍߟ۞ި۞۞ި۞۞ؔؔߟڕߟިؔިߟݖؔ؍ڕڕؔՆԍިިՆՆ{Ն۞Նqq{ݖ{Ն{ххݖхިؔՆՆݖՆؔިؔ۞ڕݖ۞ݖԍؔ؍ؔ؍ݖڕߟިߟި۞ڕ۞ڕ۞ؔ{ؔؔ{۞qިިхq{qqqqq{؍ݖԍqх{ߟߟ{ڕ{ިߟ۞ߟ{q{Ն۞ݖڕڕ؍؍ڕ؍ݖߟߟ۞хՆх؍ڕؔڕхՆݖ؍ڕqqq{ިؔިؔqх{хߟ؍ߟԍݖԍԍؔڕхڕڕԍؔԍڕݖх؍{{х{ԍ۞ԍߟݖхؔؔڕڕڕڕڕݖ؍ԍڕՆqݖ{ؔߟ۞ߟڕхؔߟݖڕԍؔڕڕ؍ڕхх{؍؍ڕхՆؔؔԍՆؔՆߟՆڕ{؍хؔ{ԍ{؍Նݖ{ՆхՆݖԍߟхڕхڕڕ{хՆхՆхݖԍڕڕؔݖؔڕؔڕؔڕڕԍߟؔݖؔڕؔ؍ڕߟؔؔ؍ڕݖԍՆq؍q؍х{Ն{{Նq{؍ݖڕڕх؍хՆؔڕؔڕڕՆڕڕ{{Ն{qqqq؍{ՆՆ{{ՆՆqڕq{؍{؍{qqqq{qq{؍qqqݖߟڕؔqqqq؍{Նqqq{qq{q{{Նхݖ{{Ն{qqՆqqqq{؍qݖqq؍qߟ؍х{ՆߟݖؔՆqՆ{Նх؍{Նؔ۞ԍڕݖ{Ն{х{{qqՆqՆ{{{qq{qq{qqqqqqqqqqq{х؍ԍqqqq{ߟqݖԍߟڕ۞ؔ۞ؔؔؔؔڕڕԍ۞ԍؔؔхՆߟ؍ߟ{хݖ۞ݖߟՆߟ{ڕхՆԍՆ{ԍؔхݖ{ݖхؔߟؔՆݖՆ؍ڕؔڕؔххݖх۞ݖՆߟхԍхՆхߟԍߟԍхߟؔߟ۞ިؔ۞Ն۞хިхߟؔߟхިߟިؔ{ڕ{ڕިڕ۞ިިؔި۞ߟڕڕި۞۞ؔݖؔڕ۞ؔԍ۞ؔؔؔхх؍ՆڕՆ؍۞Ն۞ݖՆߟхԍڕިؔި۞۞ؔؔߟߟߟڕߟԍߟ۞ߟߟ۞ߟߟ۞ߟ۞ڕߟߟڕ؍؍Նިߟ۞ߟՆхх؍ߟڕڕԍхߟڕݖڕԍ؍х؍؍ՆՆؔڕؔؔԍݖݖՆؔؔڕߟڕ{ڕqՆ{{{Ն{{{qqqqqqqqߟх؍Ն؍ݖՆՆՆՆՆՆՆՆՆ{ؔ؍ڕՆؔ؍ՆݖՆՆՆ؍хԍ{ԍ{{{{{{{qqq{qqqq{Ն؍؍؍ххݖххߟ{ߟхؔхߟ؍ՆڕՆߟؔߟхݖхߟхߟхߟхԍ؍ՆՆՆՆՆՆՆՆՆՆ{ՆՆ{ߟхߟؔߟхх۞۞۞ިԍߟݖхڕхՆхՆڕԍߟڕߟхߟхڕԍؔԍؔ؍{ݖхԍхݖ{ݖхՆݖݖqݖх{ߟݖՆڕՆххߟ{ݖ{ݖqڕqх؍ߟ{ߟqڕ{ߟڕݖߟݖԍڕ؍{хх{хިߟххqqqՆqq{qq؍{ڕݖqхqՆqؔqхՆqqڕ{ՆߟхߟިՆ{ݖq۞ԍ؍ݖхххՆqߟq۞ؔԍ۞ߟߟިх۞ݖхх۞ިхߟڕؔՆݖؔߟԍؔؔ۞ߟߟؔڕߟԍިߟԍߟ۞ިߟ۞ި۞۞ߟԍߟߟ۞ި۞ިߟ۞ڕ؍Նхݖ؍ՆՆՆ{{{{{q{ڕԍՆхڕ؍؍{{{qqՆqqq{{Ն{qqqqݖ{ߟ{Ն{ݖ{qqqqqqqqqqq{qqqqхх{Նڕڕ؍ڕ{{q{Ն؍؍Նڕڕ؍؍ؔؔԍԍՆՆՆ{Նх{{qqqq؍Ն؍{q{{{؍{؍{{{{q{{{qqq{{q{{Նؔڕԍ؍؍qՆqхՆՆՆՆ{Ն{qqqqՆq{qqq{qqqqq{{q{{{{qq{{{{qՆqՆ{ՆՆq{q{хՆԍ؍q{qq{{{х{ՆՆՆqх{{؍{ݖՆqՆqՆԍՆڕՆqՆ{Նڕ؍ݖх{{؍q{ߟq؍ߟ{ڕݖq{qqԍх{؍х؍хڕߟިՆݖԍݖؔߟхݖؔߟڕԍ{Ն{{ԍхؔڕԍߟхݖхՆՆ؍ՆՆՆ{{Նqqq{q؍ххq{ڕՆԍՆՆq{qqqqq{q{ՆqqqqՆхՆ؍ڕ۞ڕ۞ՆхqՆڕؔх؍ؔ۞ڕڕ۞۞ؔ۞؍؍ՆՆڕؔՆԍq{qq{Նq{{q{{qqqq{{{q؍хՆхqqqq{ݖqڕؔߟڕڕڕ۞ڕؔԍؔхݖؔؔԍԍ۞۞ߟؔި۞۞۞ߟ؍ߟՆڕؔՆՆ{хqqߟхݖԍqq{qՆݖ{ݖݖՆхՆ{Նq{{؍хՆq{qՆߟ۞۞ߟ۞ߟؔؔؔԍߟߟڕؔ؍ߟڕؔ؍ؔݖؔݖхх{Ն؍ՆݖՆݖߟݖؔؔхؔ؍ݖߟݖؔ؍ؔ؍{{q{ݖ{ݖՆ{ՆՆԍڕхڕؔؔԍԍߟݖqՆ{۞ߟߟх؍ԍߟ{{Նqqqq{Նq{q{{{{ިިߟڕхިިхՆ{q{Նq{{qqՆq{۞q{{Ն{ՆՆ{ՆՆ{Ն{{ՆՆ{Ն{{Ն؍ՆՆڕхՆڕхߟ۞ؔ۞ߟՆqՆ{q{qqՆڕؔߟq{q؍ԍߟߟߟ۞ިߟިިՆ{؍х؍Նڕؔݖڕߟߟԍߟؔߟԍݖх؍{{{ՆхՆх{{Ն{{ިިިިߟߟߟߟިިިިިߟՆ{؍{qqqqՆՆхՆqq{qхݖ{ՆՆq؍{q{qqՆ{{{ߟ۞ڕؔؔݖؔڕՆԍ{{ԍՆՆՆqqqqqqqq{qՆqqqqqq{qq{{Ն{qqqqՆ{ՆՆՆߟ؍ڕхՆх؍Ն؍{Ն{؍Ն{Ն{Նq{{Ն{ՆqՆ{ՆՆ{Ն{{ՆՆՆqՆqՆڕхڕڕ{ߟՆ{{{؍q{{{{ݖ{ڕхՆߟՆq{qq{{Ն{qq{{{{{qqqq{qՆ{qqՆ{Ն{qqqՆ؍{ߟ{q{qՆߟՆ۞؍{ߟՆ{Ն؍Նq{qՆߟԍԍqݖqߟՆՆՆݖ{Նq{х؍ݖ{q{qqڕ{؍{qՆ{Ն{{q{qݖqՆݖq؍qՆqՆqхՆхݖԍqݖqՆqх{{хq{ԍ؍ؔߟqqؔߟԍߟؔڕ۞ߟх۞ڕިި۞ިިڕؔ۞ߟިިߟި؍ިިՆ{ިިިިިިިި \ No newline at end of file diff --git a/examples/gputest/source/main.c b/examples/gputest/source/main.c new file mode 100644 index 0000000..142dd39 --- /dev/null +++ b/examples/gputest/source/main.c @@ -0,0 +1,220 @@ +#include +#include <3ds.h> +#include +#ifdef DEBUG +#include +#endif +#include "test_vsh_shbin.h" +#include "test_vsh.shader.h" +#include "test_gsh_shbin.h" +#include "test_gsh.shader.h" +#include "grass_bin.h" + +#define VAR_3D_SLIDERSTATE (*(volatile float*)0x1FF81080) +#define EXTENDED_TOPSCR_RESOLUTION + +#ifndef EXTENDED_TOPSCR_RESOLUTION +#define TOPSCR_WIDTH 240 +#define TOPSCR_COPYFLAG 0x00001000 +#else +#define TOPSCR_WIDTH (240*2) +#define TOPSCR_COPYFLAG 0x01001000 +#endif + +u32* gpuDepthBuf; +u32* gpuColorBuf; + +static DVLB_s *pVsh, *pGsh; +static shaderProgram_s shader; + +C3D_MtxStack projMtx, mdlvMtx; + +typedef struct +{ + float position[3]; + float texCoord[2]; + float color[3]; +} vertex_t; + +static const vertex_t vertices[] = +{ + // First triangle + {{-0.5f, +0.5f, -4.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, + {{-0.5f, -0.5f, -4.0f}, {0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}}, + {{+0.5f, -0.5f, -4.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}, + + // Second triangle + {{+0.5f, -0.5f, -4.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}, + {{+0.5f, +0.5f, -4.0f}, {1.0f, 1.0f}, {1.0f, 1.0f, 0.0f}}, + {{-0.5f, +0.5f, -4.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, +}; + +//#define BG_COLOR 0x68B0D8FF +#define BG_COLOR 0x80FF80FF + +#define FOVY (2.0f/15) + +static inline void clearGpuBuffers(u32 color) +{ + GX_SetMemoryFill(NULL, gpuColorBuf, color, gpuColorBuf+0x2EE00, 0x201, gpuDepthBuf, 0x00000000, gpuDepthBuf+0x2EE00, 0x201); + gspWaitForPSC0(); +} + +static C3D_VBO myVbo; +static C3D_Tex myTex; + +static void drawScene(float trX, float trY) +{ + GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDepthBuf), (u32*)osConvertVirtToPhys((u32)gpuColorBuf), 0, 0, TOPSCR_WIDTH, 400); + + C3D_TexBind(0, &myTex); + + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_TEXTURE0, 0); + C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + + Mtx_PerspTilt(MtxStack_Cur(&projMtx), C3D_Angle(FOVY), C3D_AspectRatioTop, 0.01f, 1000.0f); + Mtx_Identity(MtxStack_Cur(&mdlvMtx)); + Mtx_Translate(MtxStack_Cur(&mdlvMtx), trX, trY, 0.0f); + + MtxStack_Update(&projMtx); + MtxStack_Update(&mdlvMtx); + + C3D_DrawArray(&myVbo, GPU_TRIANGLES); + + C3D_Flush(); +} + +static void drawSceneBottom(float trX, float trY) +{ + GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDepthBuf), (u32*)osConvertVirtToPhys((u32)gpuColorBuf), 0, 0, 240/**2*/, 320); + + C3D_TexBind(0, NULL); + + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, 0); + C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + + Mtx_PerspTilt(MtxStack_Cur(&projMtx), C3D_Angle(FOVY), C3D_AspectRatioBot, 0.01f, 1000.0f); + Mtx_Identity(MtxStack_Cur(&mdlvMtx)); + Mtx_Translate(MtxStack_Cur(&mdlvMtx), trX, trY, 0.0f); + + MtxStack_Update(&projMtx); + MtxStack_Update(&mdlvMtx); + + C3D_DrawArray(&myVbo, GPU_TRIANGLES); + + C3D_Flush(); +} + +int main() +{ + gfxInitDefault(); + gfxSet3D(true); // uncomment if using stereoscopic 3D + +#ifdef DEBUG + consoleInit(GFX_BOTTOM, NULL); + printf("Testing...\n"); +#endif + + gpuDepthBuf = (u32*)vramAlloc(400*240*2*sizeof(float)); + gpuColorBuf = (u32*)vramAlloc(400*240*2*sizeof(u32)); + + C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + + MtxStack_Init(&projMtx); + MtxStack_Bind(&projMtx, VSH_FVEC_projMtx, VSH_ULEN_projMtx); + MtxStack_Init(&mdlvMtx); + MtxStack_Bind(&mdlvMtx, VSH_FVEC_mdlvMtx, VSH_ULEN_mdlvMtx); + + C3D_TexInit(&myTex, 64, 64, GPU_RGBA8); + C3D_TexUpload(&myTex, grass_bin); + //C3D_TexFlush(&myTex) + // ^ Not needed! FlushAndRun() already does it + + // Load shaders + pVsh = DVLB_ParseFile((u32*)test_vsh_shbin, test_vsh_shbin_size); + pGsh = DVLB_ParseFile((u32*)test_gsh_shbin, test_gsh_shbin_size); + shaderProgramInit(&shader); + shaderProgramSetVsh(&shader, &pVsh->DVLE[0]); + shaderProgramSetGsh(&shader, &pGsh->DVLE[0], 3*5); // Comment this out to disable the geoshader + shaderProgramUse(&shader); + + // Configure attributes + C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); + AttrInfo_Init(attrInfo); + AttrInfo_AddParam(attrInfo, GPU_FLOAT, 3); // position + AttrInfo_AddParam(attrInfo, GPU_FLOAT, 2); // texcoord + AttrInfo_AddParam(attrInfo, GPU_FLOAT, 3); // vertex color + AttrInfo_AddBuffer(attrInfo, 0, sizeof(vertex_t), 3, 0x210); + + // Configure VBO + C3D_VBOInit(&myVbo, sizeof(vertices)); + C3D_VBOAddData(&myVbo, vertices, sizeof(vertices), sizeof(vertices)/sizeof(vertex_t)); + + clearGpuBuffers(BG_COLOR); + + float trX = 0, trY = 0; + float zDist = 0.1f; + + // Main loop + while (aptMainLoop()) + { + gspWaitForVBlank(); + gfxSwapBuffersGpu(); + hidScanInput(); + + u32 kDown = hidKeysDown(); + u32 kHeld = hidKeysHeld(); + if (kDown & KEY_START) + break; // break in order to return to hbmenu + + if (kHeld & KEY_UP) + trY += 0.05f; + if (kHeld & KEY_DOWN) + trY -= 0.05f; + if (kHeld & KEY_LEFT) + trX -= 0.05f; + if (kHeld & KEY_RIGHT) + trX += 0.05f; + if (kHeld & KEY_L) + zDist -= 0.005f; + if (kHeld & KEY_R) + zDist += 0.005f; + + float slider = VAR_3D_SLIDERSTATE; + float czDist = zDist*slider/2; + + drawScene(trX-czDist, trY); + + GX_SetDisplayTransfer(NULL, gpuColorBuf, GX_BUFFER_DIM(TOPSCR_WIDTH,400), (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(TOPSCR_WIDTH,400), TOPSCR_COPYFLAG); + gspWaitForPPF(); + + if (slider > 0.0f) + { + clearGpuBuffers(BG_COLOR); + + drawScene(trX+czDist, trY); + + GX_SetDisplayTransfer(NULL, gpuColorBuf, GX_BUFFER_DIM(TOPSCR_WIDTH,400), (u32*)gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), GX_BUFFER_DIM(TOPSCR_WIDTH,400), TOPSCR_COPYFLAG); + gspWaitForPPF(); + } + +#ifndef DEBUG + clearGpuBuffers(BG_COLOR); + + drawSceneBottom(trX, trY); + + GX_SetDisplayTransfer(NULL, gpuColorBuf, GX_BUFFER_DIM(240,320), (u32*)gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(240,320), 0x1000); + gspWaitForPPF(); +#endif + + clearGpuBuffers(BG_COLOR); + } + + C3D_Fini(); + gfxExit(); + return 0; +} diff --git a/examples/gputest/source/test_gsh.shader b/examples/gputest/source/test_gsh.shader new file mode 100644 index 0000000..7971bf0 --- /dev/null +++ b/examples/gputest/source/test_gsh.shader @@ -0,0 +1,93 @@ +; This is a geometry Shader + +; Constants +.constf myconst(0.0, 1.0, 2.0, 3.0) +.alias zeros myconst.xxxx +.alias ones myconst.yyyy + +; Outputs +.out outpos position +.out outtc0 texcoord0 +.out outtc1 texcoord1 +.out outtc2 texcoord2 +.out outclr color + +.proc main + ; === EMIT THE FIRST TRIANGLE - passed through as-is === + + ; Emit the first vertex of the triangle + setemit 0 + mov outpos, v0 + mov outtc0, v1 + mov outtc1, v2 + mov outtc2, v3 + mov outclr, v4 + emit + + ; Emit the second vertex of the triangle + setemit 1 + mov outpos, v5 + mov outtc0, v6 + mov outtc1, v7 + mov outtc2, v8 + mov outclr, v9 + emit + + ; Emit the third and final vertex of the triangle + setemit 2, prim + mov outpos, v10 + mov outtc0, v11 + mov outtc1, v12 + mov outtc2, v13 + mov outclr, v14 + emit + + ; === EMIT THE SECOND TRIANGLE - translated and its color inverted === + + ; Adjust the coordinates of the first vertex & invert its color + add r0, -myconst.xzxx, v0 + mul r0, myconst.zzyy, r0 + add r4.xyz, ones, -v4 + mov r4.w, v4 + + ; Adjust the coordinates of the second vertex & invert its color + add r5, -myconst.xzxx, v5 + mul r5, myconst.zzyy, r5 + add r9.xyz, ones, -v9 + mov r9.w, v9 + + ; Adjust the coordinates of the third vertex & invert its color + add r10, -myconst.xzxx, v10 + mul r10, myconst.zzyy, r10 + add r14.xyz, ones, -v14 + mov r14.w, v14 + + ; Emit the first vertex of the triangle + setemit 0 + mov outpos, r0 + mov outtc0, v1 + mov outtc1, v2 + mov outtc2, v3 + mov outclr, r4 + emit + + ; Emit the second vertex of the triangle + setemit 1 + mov outpos, r5 + mov outtc0, v6 + mov outtc1, v7 + mov outtc2, v8 + mov outclr, r9 + emit + + ; Emit the third and final vertex of the triangle + setemit 2, prim + mov outpos, r10 + mov outtc0, v11 + mov outtc1, v12 + mov outtc2, v13 + mov outclr, r14 + emit + + end +.end diff --git a/examples/gputest/source/test_vsh.shader b/examples/gputest/source/test_vsh.shader new file mode 100644 index 0000000..3ea4445 --- /dev/null +++ b/examples/gputest/source/test_vsh.shader @@ -0,0 +1,52 @@ +; This is a vertex shader + +; Uniforms +.fvec projMtx[4], mdlvMtx[4] + +; Constants +.constf myconst(0.0, 1.0, -1.0, 0.0) +.alias zeros myconst.xxxx +.alias ones myconst.yyyy +.alias negones myconst.zzzz +.alias dummytcoord myconst.xxxy ; (0,0,0,1) + +; Outputs +.out outpos position +.out outtc0 texcoord0 +.out outtc1 texcoord1 +.out outtc2 texcoord2 +.out outclr color + +; Inputs +.alias inpos v0 +.alias intex v1 +.alias inarg v2 + +.proc main + ; r0 = (inpos.x, inpos.y, inpos.z, 1.0) + mov r0.xyz, inpos + mov r0.w, ones + + ; r1 = mdlvMtx * r0 + dp4 r1.x, mdlvMtx[0], r0 + dp4 r1.y, mdlvMtx[1], r0 + dp4 r1.z, mdlvMtx[2], r0 + dp4 r1.w, mdlvMtx[3], r0 + + ; outpos = projMtx * r1 + dp4 outpos.x, projMtx[0], r1 + dp4 outpos.y, projMtx[1], r1 + dp4 outpos.z, projMtx[2], r1 + dp4 outpos.w, projMtx[3], r1 + + ; Set texcoords + mov outtc0, intex + mov outtc1, ones + mov outtc2, ones + + ; Set vertex color + mov outclr.xyz, inarg + mov outclr.w, ones + + end +.end