c# - How exactly do we bind an attribute name to a location in OpenGL? -


i using opentk, wrapper .net. version of opengl used 4.5 implemented nvidia. using windows 10 pro.

issue

my issue simple. want address vertex attributes names, instead of hard coding location in shader source.

i have vertex shader called basictexturedvert.glsl

#version 450 core  in vec4 position; in vec2 normal;  uniform mat4 modelmatrix; uniform mat4 viewmatrix; uniform mat4 projectionmatrix;  out vec2 vs_uv;  void main(void) {     vs_uv = normal;     gl_position = projectionmatrix * viewmatrix * modelmatrix * position; } 

things have tried

now that, have gl.getattriblocation name of attribute in program , return location of it. tried returns location of in vec4 position , not of in vec2 normal. , mean:

  • when hard code location of both attributes, gl.getattriblocation("position") returns correct location, same normal returns -1.
  • i thought had name of normal, maybe reserved word opengl, changed random word abcdef still gives same result.
  • now thinking maybe has order of declaration of shader attributes in shader source, move normal before position, still same results.
  • about going insane trying figure why opengl giving right location position. thought maybe vec2 (which here differentiator between two) not accepted type, check online, damn accepted.

as can see tried many things before trying one. read can programmatically bind attributes names , assign location choose. here in following code.

first create shader objects this:

var basictexturedvertexshader = new shader("basic textured vertex shader",                 shadertype.vertexshader,                 file.readalltext(@"components\shaders\vertex\basictexturedvert.glsl"),                 new[] { "position", "normal" }                 ); var basictexturedfragmentshader = new shader("basic textured fragment shader",                 shadertype.fragmentshader,                 file.readalltext(@"components\shaders\fragment\basictexturedfrag.glsl")                 ); 

as can see, each shader gets assigned: - name can understand shader working on (during debug) - type of shader (vertexshader or fragmentshader) - shader source code - , optionally array containing names of shader attributes first 1 new[] { "position", "normal" } assigned location during program linking

i create program , link them it:

_texturedprogram = new shaderprogram(basictexturedvertexshader, basictexturedfragmentshader); _texturedprogram.link(); 

now inside _texturedprogram.link:

int location = 0; // location index starts 0 goes         foreach (var shader in _shaders) {             debugutil.info($"attaching shader {shader.name} of handle {shader.handle} of type {shader.type} program {_handle}");             gl.attachshader(_handle, shader.handle);             // if shader attached has attribute names             // means need give them location             if (shader.attributenames != null)             {                 foreach (var shaderattributename in shader.attributenames)                 {                     _attributelocation[shaderattributename] = location;                     gl.bindattriblocation(_handle, location, shaderattributename);                      // check if wrong happened , output                     errorcode error;                     bool errorhappened = false;                     while ((error = gl.geterror()) != errorcode.noerror) {                         debugutil.warning($"problem during binding attrib location of {shaderattributename} of {shader.name} {location} in program {_handle}. error: {error}");                         errorhappened = true;                     }                     if (!errorhappened) {                         debugutil.info($"shader attribute \"{shaderattributename}\" of {shader.name} of program {handle} should have been bound location {location}");                     }                     location++;                 }              }           }            // link program           gl.linkprogram(_handle);            // make sure linking happened no problem           var info = gl.getprograminfolog(_handle);           if (!string.isnullorwhitespace(info)) {              debugutil.warning($"info log during linking of shaders program {_handle}: {info}");           }           else {              debugutil.info($"program {_handle} linked successfully");           }            // compare locations think have been assigned vertex attributes           // 1 stored in opengl           foreach (var attribute in _attributelocation) {                 debugutil.info($"[program:{_handle}] according opengl, {attribute.key} located in {gl.getattriblocation(_handle, attribute.key)} when supposed in {attribute.value}");           }            // clean :)           foreach (var shader in _shaders) {               gl.detachshader(_handle, shader.handle);               gl.deleteshader(shader.handle);           }            // no need shaders anymore           _shaders.clear(); 

and here console output:

consoleoutput location=0

lets position's default position have been 0 , coincidence. let's set location starting index @ 5.

consoleoutput location=5

as can see, code works position not normal...

it appears that, because normal vertex attribute leads no use in subsequent stage (= fragment shader), opengl optimizes shader program getting rid of unused variables.

thanks @ripi2 pointing out.


Comments

Popular posts from this blog

What is happening when Matlab is starting a "parallel pool"? -

angular - DownloadURL return null in below code -

php - Cannot override Laravel Spark authentication with own implementation -