mirror of
https://github.com/switchbrew/switch-examples.git
synced 2025-06-20 21:12:38 +02:00
Add basic deko3d C example (rendering a triangle)
This commit is contained in:
parent
a34aba3b72
commit
554d75d499
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,4 +8,5 @@ build
|
||||
*.nsp
|
||||
*.npdm
|
||||
*.bz2
|
||||
*.dksh
|
||||
*~
|
||||
|
271
graphics/deko3d/deko_basic/Makefile
Normal file
271
graphics/deko3d/deko_basic/Makefile
Normal file
@ -0,0 +1,271 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_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
|
||||
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
||||
#
|
||||
# NO_ICON: if set to anything, do not use icon.
|
||||
# NO_NACP: if set to anything, no .nacp file is generated.
|
||||
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
|
||||
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
|
||||
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
|
||||
# ICON is the filename of the icon (.jpg), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.jpg
|
||||
# - icon.jpg
|
||||
# - <libnx folder>/default_icon.jpg
|
||||
#
|
||||
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.json
|
||||
# - config.json
|
||||
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
|
||||
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
|
||||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
ROMFS := romfs
|
||||
|
||||
# Output folders for autogenerated files in romfs
|
||||
OUT_SHADERS := shaders
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++17 -fno-exceptions -fno-rtti
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -ldeko3dd -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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)))
|
||||
GLSLFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.glsl)))
|
||||
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_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
ifneq ($(strip $(ROMFS)),)
|
||||
ROMFS_TARGETS :=
|
||||
ROMFS_FOLDERS :=
|
||||
ifneq ($(strip $(OUT_SHADERS)),)
|
||||
ROMFS_SHADERS := $(ROMFS)/$(OUT_SHADERS)
|
||||
ROMFS_TARGETS += $(patsubst %.glsl, $(ROMFS_SHADERS)/%.dksh, $(GLSLFILES))
|
||||
ROMFS_FOLDERS += $(ROMFS_SHADERS)
|
||||
endif
|
||||
|
||||
export ROMFS_DEPS := $(foreach file,$(ROMFS_TARGETS),$(CURDIR)/$(file))
|
||||
endif
|
||||
|
||||
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 $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
||||
else
|
||||
ifneq (,$(findstring config.json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/config.json
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ICON)),)
|
||||
icons := $(wildcard *.jpg)
|
||||
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
|
||||
else
|
||||
ifneq (,$(findstring icon.jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/icon.jpg
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_ICON := $(TOPDIR)/$(ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_ICON)),)
|
||||
export NROFLAGS += --icon=$(APP_ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_NACP)),)
|
||||
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
|
||||
endif
|
||||
|
||||
ifneq ($(APP_TITLEID),)
|
||||
export NACPFLAGS += --titleid=$(APP_TITLEID)
|
||||
endif
|
||||
|
||||
ifneq ($(ROMFS),)
|
||||
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
|
||||
endif
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(ROMFS_TARGETS) | $(BUILD)
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
$(BUILD):
|
||||
@mkdir -p $@
|
||||
|
||||
ifneq ($(strip $(ROMFS_TARGETS)),)
|
||||
|
||||
$(ROMFS_TARGETS): | $(ROMFS_FOLDERS)
|
||||
|
||||
$(ROMFS_FOLDERS):
|
||||
@mkdir -p $@
|
||||
|
||||
$(ROMFS_SHADERS)/%_vsh.dksh: %_vsh.glsl
|
||||
@echo {vert} $(notdir $<)
|
||||
@uam -s vert -o $@ $<
|
||||
|
||||
$(ROMFS_SHADERS)/%_tcsh.dksh: %_tcsh.glsl
|
||||
@echo {tess_ctrl} $(notdir $<)
|
||||
@uam -s tess_ctrl -o $@ $<
|
||||
|
||||
$(ROMFS_SHADERS)/%_tesh.dksh: %_tesh.glsl
|
||||
@echo {tess_eval} $(notdir $<)
|
||||
@uam -s tess_eval -o $@ $<
|
||||
|
||||
$(ROMFS_SHADERS)/%_gsh.dksh: %_gsh.glsl
|
||||
@echo {geom} $(notdir $<)
|
||||
@uam -s geom -o $@ $<
|
||||
|
||||
$(ROMFS_SHADERS)/%_fsh.dksh: %_fsh.glsl
|
||||
@echo {frag} $(notdir $<)
|
||||
@uam -s frag -o $@ $<
|
||||
|
||||
$(ROMFS_SHADERS)/%.dksh: %.glsl
|
||||
@echo {comp} $(notdir $<)
|
||||
@uam -s comp -o $@ $<
|
||||
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
@rm -fr $(BUILD) $(ROMFS_FOLDERS) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
|
||||
else
|
||||
@rm -fr $(BUILD) $(ROMFS_FOLDERS) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
|
||||
endif
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
|
||||
all : $(OUTPUT).nro
|
||||
|
||||
ifeq ($(strip $(NO_NACP)),)
|
||||
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp $(ROMFS_DEPS)
|
||||
else
|
||||
$(OUTPUT).nro : $(OUTPUT).elf $(ROMFS_DEPS)
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
all : $(OUTPUT).nsp
|
||||
|
||||
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
|
||||
|
||||
$(OUTPUT).nso : $(OUTPUT).elf
|
||||
|
||||
endif
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
9
graphics/deko3d/deko_basic/source/color_fsh.glsl
Normal file
9
graphics/deko3d/deko_basic/source/color_fsh.glsl
Normal file
@ -0,0 +1,9 @@
|
||||
#version 460
|
||||
|
||||
layout (location = 0) in vec4 inColor;
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = inColor;
|
||||
}
|
226
graphics/deko3d/deko_basic/source/main.c
Normal file
226
graphics/deko3d/deko_basic/source/main.c
Normal file
@ -0,0 +1,226 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <switch.h>
|
||||
#include <deko3d.h>
|
||||
|
||||
// Define the desired number of framebuffers
|
||||
#define FB_NUM 2
|
||||
|
||||
// Define the desired framebuffer resolution (here we set it to 720p).
|
||||
#define FB_WIDTH 1280
|
||||
#define FB_HEIGHT 720
|
||||
|
||||
// Remove above and uncomment below for 1080p
|
||||
//#define FB_WIDTH 1920
|
||||
//#define FB_HEIGHT 1080
|
||||
|
||||
// Define the size of the memory block that will hold code
|
||||
#define CODEMEMSIZE (64*1024)
|
||||
|
||||
// Define the size of the memory block that will hold command lists
|
||||
#define CMDMEMSIZE (16*1024)
|
||||
|
||||
static DkDevice g_device;
|
||||
static DkMemBlock g_framebufferMemBlock;
|
||||
static DkImage g_framebuffers[FB_NUM];
|
||||
static DkSwapchain g_swapchain;
|
||||
|
||||
static DkMemBlock g_codeMemBlock;
|
||||
static uint32_t g_codeMemOffset;
|
||||
static DkShader g_vertexShader;
|
||||
static DkShader g_fragmentShader;
|
||||
|
||||
static DkMemBlock g_cmdbufMemBlock;
|
||||
static DkCmdBuf g_cmdbuf;
|
||||
static DkCmdList g_cmdsBindFramebuffer[FB_NUM];
|
||||
static DkCmdList g_cmdsRender;
|
||||
|
||||
static DkQueue g_renderQueue;
|
||||
|
||||
// Simple function for loading a shader from the filesystem
|
||||
static void loadShader(DkShader* pShader, const char* path)
|
||||
{
|
||||
// Open the file, and retrieve its size
|
||||
FILE* f = fopen(path, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
uint32_t size = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
// Look for a spot in the code memory block for loading this shader. Note that
|
||||
// we are just using a simple incremental offset; this isn't a general purpose
|
||||
// allocation algorithm.
|
||||
uint32_t codeOffset = g_codeMemOffset;
|
||||
g_codeMemOffset += (size + DK_SHADER_CODE_ALIGNMENT - 1) &~ (DK_SHADER_CODE_ALIGNMENT - 1);
|
||||
|
||||
// Read the file into memory, and close the file
|
||||
fread((uint8_t*)dkMemBlockGetCpuAddr(g_codeMemBlock) + codeOffset, size, 1, f);
|
||||
fclose(f);
|
||||
|
||||
// Initialize the user provided shader object with the code we've just loaded
|
||||
DkShaderMaker shaderMaker;
|
||||
dkShaderMakerDefaults(&shaderMaker, g_codeMemBlock, codeOffset);
|
||||
dkShaderInitialize(pShader, &shaderMaker);
|
||||
}
|
||||
|
||||
// This function creates all the necessary graphical resources.
|
||||
static void graphicsInitialize(void)
|
||||
{
|
||||
// Create the device, which is the root object
|
||||
DkDeviceMaker deviceMaker;
|
||||
dkDeviceMakerDefaults(&deviceMaker);
|
||||
g_device = dkDeviceCreate(&deviceMaker);
|
||||
|
||||
// Calculate layout for the framebuffers
|
||||
DkImageLayoutMaker imageLayoutMaker;
|
||||
dkImageLayoutMakerDefaults(&imageLayoutMaker, g_device);
|
||||
imageLayoutMaker.flags = DkImageFlags_UsageRender | DkImageFlags_UsagePresent | DkImageFlags_HwCompression;
|
||||
imageLayoutMaker.format = DkImageFormat_RGBA8_Unorm;
|
||||
imageLayoutMaker.dimensions[0] = FB_WIDTH;
|
||||
imageLayoutMaker.dimensions[1] = FB_HEIGHT;
|
||||
|
||||
// Calculate layout for the framebuffers
|
||||
DkImageLayout framebufferLayout;
|
||||
dkImageLayoutInitialize(&framebufferLayout, &imageLayoutMaker);
|
||||
|
||||
// Retrieve necessary size and alignment for the framebuffers
|
||||
uint32_t framebufferSize = dkImageLayoutGetSize(&framebufferLayout);
|
||||
uint32_t framebufferAlign = dkImageLayoutGetAlignment(&framebufferLayout);
|
||||
framebufferSize = (framebufferSize + framebufferAlign - 1) &~ (framebufferAlign - 1);
|
||||
|
||||
// Create a memory block that will host the framebuffers
|
||||
DkMemBlockMaker memBlockMaker;
|
||||
dkMemBlockMakerDefaults(&memBlockMaker, g_device, FB_NUM*framebufferSize);
|
||||
memBlockMaker.flags = DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image;
|
||||
g_framebufferMemBlock = dkMemBlockCreate(&memBlockMaker);
|
||||
|
||||
// Initialize the framebuffers with the layout and backing memory we've just created
|
||||
DkImage const* swapchainImages[FB_NUM];
|
||||
for (unsigned i = 0; i < FB_NUM; i ++)
|
||||
{
|
||||
swapchainImages[i] = &g_framebuffers[i];
|
||||
dkImageInitialize(&g_framebuffers[i], &framebufferLayout, g_framebufferMemBlock, i*framebufferSize);
|
||||
}
|
||||
|
||||
// Create a swapchain out of the framebuffers we've just initialized
|
||||
DkSwapchainMaker swapchainMaker;
|
||||
dkSwapchainMakerDefaults(&swapchainMaker, g_device, nwindowGetDefault(), swapchainImages, FB_NUM);
|
||||
g_swapchain = dkSwapchainCreate(&swapchainMaker);
|
||||
|
||||
// Create a memory block onto which we will load shader code
|
||||
dkMemBlockMakerDefaults(&memBlockMaker, g_device, CODEMEMSIZE);
|
||||
memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached | DkMemBlockFlags_Code;
|
||||
g_codeMemBlock = dkMemBlockCreate(&memBlockMaker);
|
||||
g_codeMemOffset = 0;
|
||||
|
||||
// Load our shaders (both vertex and fragment)
|
||||
loadShader(&g_vertexShader, "romfs:/shaders/triangle_vsh.dksh");
|
||||
loadShader(&g_fragmentShader, "romfs:/shaders/color_fsh.dksh");
|
||||
|
||||
// Create a memory block which will be used for recording command lists using a command buffer
|
||||
dkMemBlockMakerDefaults(&memBlockMaker, g_device, CMDMEMSIZE);
|
||||
memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached;
|
||||
g_cmdbufMemBlock = dkMemBlockCreate(&memBlockMaker);
|
||||
|
||||
// Create a command buffer object
|
||||
DkCmdBufMaker cmdbufMaker;
|
||||
dkCmdBufMakerDefaults(&cmdbufMaker, g_device);
|
||||
g_cmdbuf = dkCmdBufCreate(&cmdbufMaker);
|
||||
|
||||
// Feed our memory to the command buffer so that we can start recording commands
|
||||
dkCmdBufAddMemory(g_cmdbuf, g_cmdbufMemBlock, 0, CMDMEMSIZE);
|
||||
|
||||
// Generate a command list for each framebuffer, which will bind each of them as a render target
|
||||
for (unsigned i = 0; i < FB_NUM; i ++)
|
||||
{
|
||||
DkImageView imageView;
|
||||
dkImageViewDefaults(&imageView, &g_framebuffers[i]);
|
||||
dkCmdBufBindRenderTarget(g_cmdbuf, &imageView, NULL);
|
||||
g_cmdsBindFramebuffer[i] = dkCmdBufFinishList(g_cmdbuf);
|
||||
}
|
||||
|
||||
// Declare structs that will be used for binding state
|
||||
DkViewport viewport = { 0.0f, 0.0f, (float)FB_WIDTH, (float)FB_HEIGHT, 0.0f, 1.0f };
|
||||
DkScissor scissor = { 0, 0, FB_WIDTH, FB_HEIGHT };
|
||||
DkShader const* shaders[] = { &g_vertexShader, &g_fragmentShader };
|
||||
DkRasterizerState rasterizerState;
|
||||
DkColorState colorState;
|
||||
DkColorWriteState colorWriteState;
|
||||
|
||||
// Initialize state structs with the deko3d defaults
|
||||
dkRasterizerStateDefaults(&rasterizerState);
|
||||
dkColorStateDefaults(&colorState);
|
||||
dkColorWriteStateDefaults(&colorWriteState);
|
||||
|
||||
// Generate the main rendering command list
|
||||
dkCmdBufSetViewports(g_cmdbuf, 0, &viewport, 1);
|
||||
dkCmdBufSetScissors(g_cmdbuf, 0, &scissor, 1);
|
||||
dkCmdBufClearColorFloat(g_cmdbuf, 0, DkColorMask_RGBA, 0.125f, 0.294f, 0.478f, 1.0f);
|
||||
dkCmdBufBindShaders(g_cmdbuf, DkStageFlag_GraphicsMask, shaders, sizeof(shaders)/sizeof(shaders[0]));
|
||||
dkCmdBufBindRasterizerState(g_cmdbuf, &rasterizerState);
|
||||
dkCmdBufBindColorState(g_cmdbuf, &colorState);
|
||||
dkCmdBufBindColorWriteState(g_cmdbuf, &colorWriteState);
|
||||
dkCmdBufDraw(g_cmdbuf, DkPrimitive_Triangles, 3, 1, 0, 0);
|
||||
g_cmdsRender = dkCmdBufFinishList(g_cmdbuf);
|
||||
|
||||
// Create a queue, to which we will submit our command lists
|
||||
DkQueueMaker queueMaker;
|
||||
dkQueueMakerDefaults(&queueMaker, g_device);
|
||||
queueMaker.flags = DkQueueFlags_Graphics;
|
||||
g_renderQueue = dkQueueCreate(&queueMaker);
|
||||
}
|
||||
|
||||
// This function is to be called at each frame, and it is in charge of rendering.
|
||||
static void graphicsUpdate(void)
|
||||
{
|
||||
// Acquire a framebuffer from the swapchain (and wait for it to be available)
|
||||
int slot = dkQueueAcquireImage(g_renderQueue, g_swapchain);
|
||||
|
||||
// Run the command list that binds said framebuffer as a render target
|
||||
dkQueueSubmitCommands(g_renderQueue, g_cmdsBindFramebuffer[slot]);
|
||||
|
||||
// Run the main rendering command list
|
||||
dkQueueSubmitCommands(g_renderQueue, g_cmdsRender);
|
||||
|
||||
// Now that we are done rendering, present it to the screen
|
||||
dkQueuePresentImage(g_renderQueue, g_swapchain, slot);
|
||||
}
|
||||
|
||||
// This function destroys the graphical resources created by graphicsInitialize.
|
||||
static void graphicsExit(void)
|
||||
{
|
||||
// Make sure the rendering queue is idle before destroying anything
|
||||
dkQueueWaitIdle(g_renderQueue);
|
||||
|
||||
// Destroy all the resources we've created
|
||||
dkQueueDestroy(g_renderQueue);
|
||||
dkCmdBufDestroy(g_cmdbuf);
|
||||
dkMemBlockDestroy(g_cmdbufMemBlock);
|
||||
dkMemBlockDestroy(g_codeMemBlock);
|
||||
dkSwapchainDestroy(g_swapchain);
|
||||
dkMemBlockDestroy(g_framebufferMemBlock);
|
||||
dkDeviceDestroy(g_device);
|
||||
}
|
||||
|
||||
// Main entrypoint
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
romfsInit();
|
||||
graphicsInitialize();
|
||||
|
||||
while (appletMainLoop())
|
||||
{
|
||||
hidScanInput();
|
||||
|
||||
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
if (kDown & KEY_PLUS)
|
||||
break; // break in order to return to hbmenu
|
||||
|
||||
graphicsUpdate();
|
||||
}
|
||||
|
||||
graphicsExit();
|
||||
romfsExit();
|
||||
return 0;
|
||||
}
|
23
graphics/deko3d/deko_basic/source/triangle_vsh.glsl
Normal file
23
graphics/deko3d/deko_basic/source/triangle_vsh.glsl
Normal file
@ -0,0 +1,23 @@
|
||||
#version 460
|
||||
|
||||
// Hardcoded array of vertex positions for our triangle
|
||||
const vec4 positions[3] = vec4[](
|
||||
vec4( 0.0, +1.0, 0.0, 1.0),
|
||||
vec4(-1.0, -1.0, 0.0, 1.0),
|
||||
vec4(+1.0, -1.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
// Hardcoded array of vertex colors for our triangle
|
||||
const vec4 colors[3] = vec4[](
|
||||
vec4(1.0, 0.0, 0.0, 1.0),
|
||||
vec4(0.0, 1.0, 0.0, 1.0),
|
||||
vec4(0.0, 0.0, 1.0, 1.0)
|
||||
);
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = positions[gl_VertexID];
|
||||
outColor = colors[gl_VertexID];
|
||||
}
|
Loading…
Reference in New Issue
Block a user