Help creating Static Polygons for fast drawing

support for the powerpc toolchain
DolphinG89
Posts: 28
Joined: Sat Apr 13, 2013 10:40 pm

Help creating Static Polygons for fast drawing

Post by DolphinG89 » Thu Jul 04, 2013 5:48 pm

The polygons created with GLBegin are not static. Static polygons would allow you to set the value and then have it stay constant for the program until it is deleted. I looking for a solution but haven't found any.

owen
Posts: 13
Joined: Mon Feb 07, 2011 2:05 pm
Contact:

Re: Help creating Static Polygons for fast drawing

Post by owen » Sun Jul 07, 2013 4:04 am

As far as I know you have to use either vertex arrays or displaylists. If you want to increase speed you will have to simply draw less on the screen.

DolphinG89
Posts: 28
Joined: Sat Apr 13, 2013 10:40 pm

Re: Help creating Static Polygons for fast drawing

Post by DolphinG89 » Sun Jul 21, 2013 2:33 am

Which one of those wouldn't cause a stack overflow at ~5000 polys since instructions have to fit in Cache and the Verticies alone would be 60KB which would be hard to fit in the Wii's L2 Cache.

antidote
Posts: 17
Joined: Wed Mar 23, 2011 2:54 am

Re: Help creating Static Polygons for fast drawing

Post by antidote » Sun Jul 28, 2013 8:30 pm

Vertex groups, split the model you wish to render into groups and each group can be a list.
Not the most elegant solution but it does get around your issue.

DolphinG89
Posts: 28
Joined: Sat Apr 13, 2013 10:40 pm

Re: Help creating Static Polygons for fast drawing

Post by DolphinG89 » Sat Aug 03, 2013 12:56 am

Can you give an example of how you would set up the makefile and the source code for vertex groups.

antidote
Posts: 17
Joined: Wed Mar 23, 2011 2:54 am

Re: Help creating Static Polygons for fast drawing

Post by antidote » Mon Aug 05, 2013 5:33 am

It can be done via a model editor, each group (called an object in blender) is part of the model, you just have to handle that in your loader code. Each "object" is loaded into a display list and called in the order specified by the model, the code is really dependent on the format and posting an example wouldn't do you any good since it may not work with the format you want.

But the basic flow is:
Load model storing the vertex group (probably using std::vector, or some custom linked list to handle parenting)
Load each group into a display list.
Iterate through and call each display list.

This this kind of setup you can hide certain parts of the model that aren't being used currently, Nintendo uses this extensively for things like hands.

DolphinG89
Posts: 28
Joined: Sat Apr 13, 2013 10:40 pm

Re: Help creating Static Polygons for fast drawing

Post by DolphinG89 » Mon Aug 12, 2013 11:06 am

The attached file is me trying to get display lists which are like vertex array with DevkitPPC. Do you see a mistake? Is that not vertex groups? I see it has a FIFO limit of 8192KB.

/*---------------------------------------------------------------------------------

nehe lesson 5 port to GX by WinterMute

---------------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#define DEFAULT_FIFO_SIZE (256*1024)

static void *frameBuffer[2] = { NULL, NULL};
GXRModeObj *rmode;

//---------------------------------------------------------------------------------
int main( int argc, char **argv ){
//---------------------------------------------------------------------------------
f32 yscale;

u32 xfbHeight;

Mtx view;
Mtx44 perspective;
Mtx model, modelview;

float rtri = 0.0f , rquad = 0.0f;

u32 fb = 0; // initial framebuffer index
GXColor background = {0, 0, 0, 0xff};


// init the vi.
VIDEO_Init();
WPAD_Init();

rmode = VIDEO_GetPreferredMode(NULL);

// allocate 2 framebuffers for double buffering
frameBuffer[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
frameBuffer[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));

VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(frameBuffer[fb]);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();

// setup the fifo and then init the flipper
void *gp_fifo = NULL;
gp_fifo = memalign(32,DEFAULT_FIFO_SIZE);
memset(gp_fifo,0,DEFAULT_FIFO_SIZE);

GX_Init(gp_fifo,DEFAULT_FIFO_SIZE);

// clears the bg to color and clears the z buffer
GX_SetCopyClear(background, 0x00ffffff);

// other gx setup
GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1);
yscale = GX_GetYScaleFactor(rmode->efbHeight,rmode->xfbHeight);
xfbHeight = GX_SetDispCopyYScale(yscale);
GX_SetScissor(0,0,rmode->fbWidth,rmode->efbHeight);
GX_SetDispCopySrc(0,0,rmode->fbWidth,rmode->efbHeight);
GX_SetDispCopyDst(rmode->fbWidth,xfbHeight);
GX_SetCopyFilter(rmode->aa,rmode->sample_pattern,GX_TRUE,rmode->vfilter);
GX_SetFieldMode(rmode->field_rendering,((rmode->viHeight==2*rmode->xfbHeight)?GX_ENABLE:GX_DISABLE));

GX_SetCullMode(GX_CULL_NONE);
GX_CopyDisp(frameBuffer[fb],GX_TRUE);
GX_SetDispCopyGamma(GX_GM_1_0);


// setup the vertex descriptor
// tells the flipper to expect direct data
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);

// setup the vertex attribute table
// describes the data
// args: vat location 0-7, type of data, data format, size, scale
// so for ex. in the first call we are sending position data with
// 3 values X,Y,Z of size F32. scale sets the number of fractional
// bits for non float data.
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGB8, 0);

GX_SetNumChans(1);
GX_SetNumTexGens(0);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);

// setup our camera at the origin
// looking down the -z axis with y up
guVector cam = {0.0F, 0.0F, 0.0F},
up = {0.0F, 1.0F, 0.0F},
look = {0.0F, 0.0F, -1.0F};
guLookAt(view, &cam, &up, &look);


// setup our projection matrix
// this creates a perspective matrix with a view angle of 90,
// and aspect ratio based on the display resolution
f32 w = rmode->viWidth;
f32 h = rmode->viHeight;
guPerspective(perspective, 45, (f32)w/h, 0.1F, 300.0F);
GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);

guVector triAxis = {0,1,0};
guVector cubeAxis = {1,1,1};

while(1) {

WPAD_ScanPads();

if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);

// do this before drawing
GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1);

guMtxIdentity(model);
guMtxRotAxisDeg(model, &triAxis, rtri);
guMtxTransApply(model, model, -4.5f,0.0f,-6.0f);
guMtxConcat(view,model,modelview);
// load the modelview matrix into matrix memory
GX_LoadPosMtxImm(modelview, GX_PNMTX0);

GX_Begin(GX_TRIANGLES, GX_VTXFMT0, 12); // Draw A Pyramid

GX_Position3f32( 0.0f, 1.0f, 0.0f); // Top of Triangle (front)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_Position3f32(-1.0f,-1.0f, 1.0f); // Left of Triangle (front)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green
GX_Position3f32( 1.0f,-1.0f, 1.0f); // Right of Triangle (front)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue

GX_Position3f32( 0.0f, 1.0f, 0.0f); // Top of Triangle (Right)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_Position3f32( 1.0f,-1.0f, 1.0f); // Left of Triangle (Right)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue
GX_Position3f32( 1.0f,-1.0f,-1.0f); // Right of Triangle (Right)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green

GX_Position3f32( 0.0f, 1.0f, 0.0f); // Top of Triangle (Back)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_Position3f32(-1.0f,-1.0f,-1.0f); // Left of Triangle (Back)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue
GX_Position3f32( 1.0f,-1.0f,-1.0f); // Right of Triangle (Back)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green

GX_Position3f32( 0.0f, 1.0f, 0.0f); // Top of Triangle (Left)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_Position3f32(-1.0f,-1.0f,-1.0f); // Left of Triangle (Left)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue
GX_Position3f32(-1.0f,-1.0f, 1.0f); // Right of Triangle (Left)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green

GX_End();

guMtxIdentity(model);
guMtxRotAxisDeg(model, &cubeAxis, rquad);
guMtxTransApply(model, model, 1.5f,0.0f,-7.0f);
guMtxConcat(view,model,modelview);
// load the modelview matrix into matrix memory
GX_LoadPosMtxImm(modelview, GX_PNMTX0);

....................................
ATTACHED disp list
....................................


// do this stuff after drawing
GX_DrawDone();

fb ^= 1; // flip framebuffer
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_CopyDisp(frameBuffer[fb],GX_TRUE);

VIDEO_SetNextFramebuffer(frameBuffer[fb]);

VIDEO_Flush();

VIDEO_WaitVSync();

rtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
rquad-=0; // Decrease The Rotation Variable For The Quad ( NEW )

}
return 0;
}
Attachments
Answers.zip
(64.42 KiB) Downloaded 892 times

DolphinG89
Posts: 28
Joined: Sat Apr 13, 2013 10:40 pm

Re: Help creating Static Polygons for fast drawing

Post by DolphinG89 » Mon Aug 19, 2013 6:34 am

I've figured out that its the size of the object file I'm compiling. It's probably to big for the wii's l2 cache so the linker hangs. Although is 32 bit aligned a cast to u32 u8 or u16 or something else this may also be an issue. Ultimately I want to know that and how to set up the makefile for multiple object files with a main file.

WinterMute
Site Admin
Posts: 1845
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: Help creating Static Polygons for fast drawing

Post by WinterMute » Thu Sep 05, 2013 12:39 am

The Wii L2 has no bearing on the linker.

Many of the examples we provide contain embedded data or arrays for the sake of simplicity but there are limits to how useful that approach is when it comes to more complex projects. Compiling large datasets as C arrays will eventually make the compiler or the linker fall over once you reach a certain size.

The Makefiles already handle multiple object files - all you have to do is create a new source file in the source directory & the Makefile does the rest. Ideally you should be using some kind of binary format for models and either embedding those or loading them from the filesystem at runtime.

Embedding datafiles is fairly easy. At the top of the Makefile is this section :-

Code: Select all

#---------------------------------------------------------------------------------
# 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
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET		:=	$(notdir $(CURDIR))
BUILD		:=	build
SOURCES		:=	source
DATA		:=
TEXTURES	:=	textures
INCLUDES	:=
You can either add a list of the directories containing binary files to the DATA variable or add a new variable (say MODELS := )

If you add a new variable then you'll need to modify the VPATH code

Code: Select all

export VPATH	:=	$(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
					$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
					$(foreach dir,$(TEXTURES),$(CURDIR)/$(dir))
add a \ to that last line and $(foreach dir,$(MODELS),$(CURDIR)/$(dir)) on the next line. Obviously change MODELS to whatever variable you used.

In the section to build object files you'll need to add code to pick up whatever extension you use

Code: Select all

#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES	:=	$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
SCFFILES	:=	$(foreach dir,$(TEXTURES),$(notdir $(wildcard $(dir)/*.scf)))
TPLFILES	:=	$(SCFFILES:.scf=.tpl)
so add something like MODELFILES := $(foreach dir,$(MODELS),$(notdir $(wildcard $(dir)/*.mdl))) unless you just chose to add them to the DATA variable which picks up everything regardless of extension.

If you're using your own variable and file extension then you'll need to modify OFILES

Code: Select all

export OFILES	:=	$(addsuffix .o,$(BINFILES)) \
					$(addsuffix .o,$(TPLFILES)) \
					$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
					$(sFILES:.s=.o) $(SFILES:.S=.o)[code]

add a \ to the end of the last line & $(addsuffix .o,$(MODELFILES)) on the next line.

Then add a rule for your extension like this

[code]#---------------------------------------------------------------------------------
# This rule links in binary data with the .mdl extension
#---------------------------------------------------------------------------------
%.mdl.o	:	%.mdl
#---------------------------------------------------------------------------------
	@echo $(notdir $<)
	$(bin2o)
In your C file you'll need to include the generated header so

Code: Select all

#include "<filename>_mdl_h"[code] where <filename> is the name of the binary file without the extension.

The header will define several variables as follows
[code]extern const u8 <filename>_mdl_end[];
extern const u8 <filename>_mdl[];
extern const u32 <filename>_mdl_size;
Again <filename> is the name of the file that was embedded as binary. <filename>_mdl will hold the address of the start of the data, <filename>_mdl_end is the end address & _size gives you the size in bytes. You'll probably need to cast the variables appropriately.
Help keep devkitPro toolchains free, Donate today

Personal Blog

DolphinG89
Posts: 28
Joined: Sat Apr 13, 2013 10:40 pm

Re: Help creating Static Polygons for fast drawing

Post by DolphinG89 » Sat Sep 28, 2013 6:43 pm

How would I store TEV calculations to be used as spherical unit vectors if i can't use arrays. If I have lots of TEV calculations wouldn't I need an array? Also linked list has O(n) traverse time so why wouldn't I use a binary array which stores by memory addresses?

Post Reply

Who is online

Users browsing this forum: No registered users and 11 guests