TWO small questions

Thanks for taking time to view these two small questions:

  1. Can a subroutine call another subroutine in a single shader?

  2. I have to use GL_FLOAT if I pass integers into vertex shader when calling glVertexAttribPointer. It’s somewhat weird.

Any ideas? Thanks in advance.

  1. If by subroutine you mean a regular function, yes. If by “subroutine”, you mean the GL 4.0 feature shader subroutines, also yes :wink:

However, they can never participate in recursion. If you call a function that calls another function that eventually calls you, badness ensues.

I have to use GL_FLOAT if I pass integers into vertex shader when calling glVertexAttribPointer. It’s somewhat weird.

It’s hard to say what’s going on without seeing some code.

If you want to use pure integer attributes, read about glVertexAttribIPointer.

Thanks for the answer. For question 2, thing goes well by using :

glVertexAttribIPointer( (GLuint)2, 1, GL_INT, 0, NULL );

I experimented and got the result that subroutine can not call another subroutine in a single shader. Take the example I posted below.
In phong mode, the following instruction failed the program linking.

vec3 diffuse = diffuseOnly(position, norm);

===
#version 400

subroutine vec3 shadeModelType( vec4 position, vec3 normal);
subroutine uniform shadeModelType shadeModel;

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in int VertexColorIndex;

out vec3 LightIntensity;

struct LightInfo {
vec4 Position; // Light position in eye coords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
vec3 Ls; // Specular light intensity
};
uniform LightInfo Light;

struct MaterialInfo {
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivity
vec3 Ks; // Specular reflectivity
float Shininess; // Specular shininess factor
};
uniform MaterialInfo Material;

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;

void getEyeSpace( out vec3 norm, out vec4 position )
{
norm = normalize( NormalMatrix * VertexNormal);
position = ModelViewMatrix * vec4(VertexPosition,1.0);
}

subroutine( shadeModelType )
vec3 phongModel( vec4 position, vec3 norm )
{
vec3 s = normalize(vec3(Light.Position - position));
vec3 v = normalize(-position.xyz);
vec3 r = reflect( -s, norm );
vec3 ambient = Light.La * Material.Ka;
float sDotN = max( dot(s,norm), 0.0 );
vec3 diffuse = Light.Ld * Material.Kd * sDotN;//does work.
//vec3 diffuse = diffuseOnly(position, norm); //does not work.
vec3 spec = vec3(0.0);
if( sDotN > 0.0 )
spec = Light.Ls * Material.Ks *
pow( max( dot(r,v), 0.0 ), Material.Shininess );

return ambient + diffuse + spec;

}

subroutine( shadeModelType )
vec3 diffuseOnly( vec4 position, vec3 norm )
{
vec3 s = normalize( vec3(Light.Position - position) );

vec3 materialCatelogue;

switch(int(mod(VertexColorIndex, 9)))
{
	case 0:
	default:
	materialCatelogue = Material.Kd;
	break;
	case 1:
	materialCatelogue = vec3(1.0, 0.0, 0.0);
	break;
	case 2:
	materialCatelogue = vec3(0.0, 1.0, 0.0);
	break;
	case 3:
	materialCatelogue = vec3(0.0, 0.0, 1.0);
	break;
	case 4:
	materialCatelogue = vec3(1.0, 1.0, 0.0);
	break;
	case 5:
	materialCatelogue = vec3(1.0, 0.0, 1.0);
	break;
	case 6:
	materialCatelogue = vec3(0.0, 1.0, 1.0);
	break;
	case 7:
	materialCatelogue = vec3(1.0, 1.0, 1.0);
	break;
	case 8:
	materialCatelogue = vec3(0.0, 0.0, 0.0);
	break;
}

return Light.Ld * materialCatelogue * max( dot(s, norm), 0.0 );

}

subroutine( shadeModelType )
vec3 ambientOnly( vec4 position, vec3 norm )
{
return Material.Ka;
}

void main()
{
vec3 eyeNorm;
vec4 eyePosition;

// Get the position and normal in eye space
getEyeSpace(eyeNorm, eyePosition);

// Evaluate the shading equation.  This will call one of
// the functions: diffuseOnly or phongModel.
LightIntensity = shadeModel( eyePosition, eyeNorm );

gl_Position = MVP * vec4(VertexPosition,1.0);

}

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.