[Bf-committers] Proposed changes re: procedural textures

Robin Allen r.a3 at ntlworld.com
Tue Nov 21 17:39:48 CET 2006


Tell me if this isn't the place to discuss this, I'll be happy to post 
it elsewhere.

Anyway, this is a list of all the places code must currently be added to 
add a new procedural texture:

-- DNA_texture_types.h: --
add new TEX_ constant to list

-- buttons_shading.c: --
Add texture_panel_xxx function
Add new case to huge switch in texture_panels()
Modify texture type menu string

-- render/intern/source/texture.c: --
Add texture render function
Add case to huge switch in multitex()

Proposed Changes:

I'm proposing an array of structs to hold data about the procedural 
textures, requiring a simple list of function calls to register all the 
textures at startup. This can later be extended to hold plugin textures 
as well, as a first step to making the difference between builtins and 
plugins transparent to the user.

In the new header file (procedural.h?) would go something like:

typedef   int(*TexUIFunc)     (Tex*);
typedef float(*TexRenderFunc) (Tex*,float*,TexResult*);

typedef struct ProcTex {
    TexUIFunc ui_func;                /* Function to draw this texture's 
UI */
    TexRenderFunc render_func;        /* Function to render this texture */
    const char* name;                 /* Name of this texture in the menu */
} ProcTex;
    
void register_textures();             /* Called at startup to populate 
array */

extern ProcTex textypes[];            /* The list of all procedurals */

Texture drawing and texture UI drawing functions to be moved out of 
texture.c and the already huge buttons_shading.c and put together in a 
new .c file (procedural.c?) which would look something like:

ProcTex textypes[500];

/* Function called by register_textures for each texture */
static void regtex( int id, const char* name, TexUIFunc uif, 
TexRenderFunc rf)
{
    ProcTex* pt = textypes[id];
    pt.ui_func = uif;
    pt.render_func = rf;
    pt.name = name;
}

/* Functions to draw textures and UI go here */
void clouds_ui() {...
void clouds_r() {...

void tiles_ui() {...
void tiles_r() {...

void image_ui() {...
void image_r() {...

/* A neat list of function calls to register all the textures */
void register_textures()
{
    regtex( TEX_TILES,   "Tiles", &tiles_ui, &tiles_r );
    regtex( TEX_IMAGE,   "Image", &image_ui, &image_r );
    regtex( TEX_SOMETEX, "MyTexture", &sometex_ui, &sometex_r );
}

This system would greatly clean up the code in several other files, namely:

-- buttons_shading.c: --
Remove giant switch/case in texture_panels
Instead of:

switch(tex->type) { case ...
    ... huge list ...

Replace with: (2 lines!)

TexUIFunc uif = textypes[tex->type].ui_func;
if(uif) uif(tex);

In the function texture_panel_texture(), replace the awful:

sprintf(textypes, "Texture Type %%t|None %%x%d|Image %%x%d|EnvMap 
%%x%d|Clouds %%x%d|Marble %%x%d|Stucci %%x%d|Wood %%x%d|Magic 
%%x%d|Blend %%x%d|Noise %%x%d|Plugin %%x%d|Musgrave %%x%d|Voronoi 
%%x%d|DistortedNoise %%x%d|Tiles %%x%d|Cloth %%x%d", 0, TEX_IMAGE, 
TEX_ENVMAP, TEX_CLOUDS, TEX_MARBLE, TEX_STUCCI, TEX_WOOD, TEX_MAGIC, 
TEX_BLEND, TEX_NOISE, TEX_PLUGIN, TEX_MUSGRAVE, TEX_VORONOI, 
TEX_DISTNOISE, TEX_TILES, TEX_CLOTH);
uiDefBut(block, LABEL, 0, "Texture Type",        160, 150, 140, 20, 0, 
0.0, 0.0, 0, 0, "");
uiDefButS(block, MENU, B_TEXTYPE, textypes,    160, 125, 140, 25, 
&tex->type, 0,0,0,0, "Select texture type");

... with code that generates the list automatically from the textypes 
array (shouldn't be too difficult).

-- render\...\texture.c: --

In multitex(), replace:

switch(tex->type) { ...
    ... huge switch list ...

with:

if(tex->type)
    retval = textypes[tex->type].render_func(tex,texvec,texres);

(I know some of the cases here are more than a function call, but this 
code should be put into a function.)

So instead of the 6 scattered insertion points required before to add a 
texture, you now just need to:
* Add TEX_ constant to DNA_texturetypes.h
* Write UI and Render functions (same file, one after the other) and add 
the regtex() line, also in the same file.

With a few modifications to the struct, it should be easy to generalise 
to plugin textures as well.

Thoughts?


More information about the Bf-committers mailing list