opengl - GLSL - Binding Attributes to Semantics -


i've seen number of questions , answers here on stack overflow topic. these answers, i've come possible solution binding glsl attributes user-defined semantics. wanted input , discussion going it, , check if valid idea.

to start, let's assume have list of user-defined semantics:

enum vertexelementsemantic {   position, normal, ambient, diffuse, specular,   tex_coord0, tex_coord1, tex_coord2, tex_coord3,   indices }; 

and structure encapsulates data required set vertex attribute pointer.

struct vertexelement {   unsigned int m_source;   unsigned int m_offset;   unsigned int m_stride; } 

now, renderoperation class contain map of vertexelementsemantics vertexelements. format, size, , whether vertexelement normalized can determined semantic.

the last bit of information require in order set pointer attribute location itself. here's want bind our vertexelementsemantic specific location.

from the first answer question, learn can explicitly state desired location of each attribute so:

layout(location = 0) in vec3 position; 

so could map our semantics these hard coded locations, require location hard coded in each shader. changes these locations require go through , edit every shader.

however, value not have provided shader source @ all. the answer question, learn can externally add #defines our shaders so:

char *sources[2] = { "#define foo\n", sourcefromfile }; glshadersourcearb(shader, 2, sources, null); 

using this, build string #defines variables desired locations of each semantic. example, build string end inserting following beginning of each of our shaders:

#define position_location 0 #define normal_location 1 #define ambient_location 2 ... 

going explicitly stating our attribute locations, should able state them such now:

layout(location = position_location) in vec3 position; layout(location = normal_location) in vec3 normal; layout(location = ambient_location) in vec4 ambient; 

this method allow set desired attribute location of each semantic in code. provides sort of semantic binding feel shaders themselves. system step in right direction solving issue of providing meaning attribute locations?

let's consider consequences of idea.

we build string #defines variables desired locations of each semantic. example, build string end inserting following beginning of each of our shaders:

well, bad on 2 counts. first, there's #version issue. if want use any glsl version other 1.10, must provide #version declaration. , declaration must first thing in shader, outside of comments , whitespace.

by putting these #defines shader source (whether string concatenation, or using multiple strings do), have accept consequences. usually, each individual shader file have own #version declaration, specifying glsl version uses. can't if want use besides glsl 1.10. have have c++ source code generate #version, before #defines.

this means shader source decoupled version compiles under. doable, means shader source unclear without knowing version is. communicate version in other way, such filename (for example, lit_transform_330.vert use version 3.30). you'll have devise such system.

now version issue sorted out, on next problem: doing redundant.

you use terms "semantic", have no meaning opengl. appears you're trying assign form of name particular vertex attribute, can see uses of name in shader , c++ code, , therefore know attribute for.

that is, want define mapping between "name" , "attribute index". want defined in 1 place, such automagically propagated every shader , used consistently throughout c++ source code.

well have mapping between name , attribute index. it's called "the mapping between attribute's name , attribute's index". every shader must provide name it's attributes. that's string name see in definitions in vec4 position; attribute's name position. that's glsl calls variable when uses it.

as stated in answer linked to, can associate particular attribute name attribute index c++ code before program linked. done via the glbindattriblocation function. can set number of mappings like. when program linked, attributes match specified location assigned location.

all need list of "semantics" (aka: attribute indices) , string names require shaders use attributes.

you might say, "well, want shaders have freedom call variable whatever want." response be... what's difference? suggested scheme requires user adhere specific naming convention. it's name must use isn't variable's name; it's name of tag associate variable @ declaration time.

so difference? writer of shader has adhere set naming scheme vertex attribute variable name? isn't consistent name same concept across shaders good thing?

the 1 difference that, if mistype "semantic" under scheme, shader compilation error (since mistyped "semantic" name won't match actual #defines). whereas if mistype name of attribute, compiler error if don't mistype name when use attribute.

there ways catch that. requires using program introspection walk list of active attributes , checking them against expect names of attributes.

you can boil down simple set of conventions. using "semantic" definition:

enum vertexelementsemantic {   position, normal, ambient, diffuse, specular,   tex_coord0, tex_coord1, tex_coord2, tex_coord3,   indices, num_semantics };  //in c++ file use link shaders const char *attributenames[] = {   "position", "normal", "ambient", "diffuse", "specular",    "tex_coord0", "tex_coord1", "tex_coord2", "tex_coord3",    "indices", }  static_assert(array_count(attributenames) == num_semantics); //where `array_count` macro computes number of elements in static array.  gluint createprogram(gluint vertexshader, gluint fragmentshader) {   gluint prog = glcreateprogram();   //attach shaders   for(int attrib = 0; attrib < num_semantics; ++attrib)   {     glbindattriblocation(prog, attrib, attributenames[attrib]);   }    gllinkprogram(prog);    //detach shaders   //check linking errors    //verify attribute locations expected.   //left exercise reader.    return prog; } 

personally speaking, use number. no matter use, person writing shader going have adhere convention. means when go write vertex shader takes position, they're going have how "this position". they're going have something in table somewhere no matter what.

at point, comes down problem is. issues either thinks know answer wrong (ie: didn't up), , mistyped answer. it's hard mistype number (though can happen), while it's easier mistype position_location. former problem happen either 1 in more or less equal numbers.

so seems me you're more fewer convention mis-match problems if convention based on numbers rather words.


Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -