Add simple example

This commit is contained in:
fincs 2015-03-05 18:31:10 +01:00
parent 2863ed36c1
commit 57c98d4291
5 changed files with 541 additions and 0 deletions

175
examples/gputest/Makefile Normal file
View File

@ -0,0 +1,175 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>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):
# - <Project name>.png
# - icon.png
# - <libctru folder>/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
#---------------------------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,220 @@
#include <string.h>
#include <3ds.h>
#include <citro3d.h>
#ifdef DEBUG
#include <stdio.h>
#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;
}

View File

@ -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

View File

@ -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