Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLSL Struct Support #12

Closed
wants to merge 1 commit into from
Closed

GLSL Struct Support #12

wants to merge 1 commit into from

Conversation

mbolt35
Copy link

@mbolt35 mbolt35 commented Jun 3, 2017

Update Shader parsing such that it's capable of handling custom glsl struct definitions. ProgramParams are now created for the inner struct locations.

Here's an example fragment shader that was failing:

#version 330 core

// Material definition
struct Material {
    vec3 color;
};

// Light definition
struct Light {
    vec3 position;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

uniform Light light;
uniform Material material;

in vec3 FragPosition;
in vec3 FragNormal;

out vec4 FragColor;

void main(void)
{
    vec3 lightDelta = light.position - FragPosition;

    vec3 n = normalize(FragNormal);
    vec3 l = normalize(lightDelta);

    float cosTheta = clamp(dot(n, l), 0.0f, 1.0f);

    vec3 ambient = light.ambient;
    vec3 diffuse = light.diffuse * cosTheta;

    vec3 fragColor = (ambient + diffuse) * material.color;
    FragColor = vec4(fragColor, 1);
}

Before this change, ShaderProgram would throw an error trying to parse the types for each ProgramParam, specifically when looking at: uniform Light light (exception was "Unsupported Type").

The named location lookup would use the format <uniform name>.<inner_property>, so the attached pull request provides a little extra assistance in creating those additional ProgramParam instances by looking for the struct token, then collecting each inner struct property (name + type), then storing in a Dictionary using the struct type name as a key.

When processing the uniforms, we first check to see if our type is in the struct Dictionary, and if so, loop through each inner property and apply the . format for the location lookups.

For instance, using the fragment shader above, the following would set the appropriate values in C#:

    _shader["light.position"].SetValue(_lightPosition);
    _shader["light.ambient"].SetValue(new Vector3(0.3f, 0.3f, 0.3f));
    _shader["light.diffuse"].SetValue(Vector3.One);
    _shader["light.specular"].SetValue(Vector3.One);

    // set the color to blue
    _shader["material.color"].SetValue(new Vector3(0.3, 0.3, 1.0));

There are a few things that I wasn't quite sure about:

  • Do the struct definitions have to be defined before using the type with uniform (I assume so!)
    -- If no, the parsing function may have to become a two pass parse.
  • I'm not sure whether you can set default values for struct types (The parsing of inner property types uses the same = token check as uniform token processing (might be unnecessary).

I've been using your library for a C#/OpenGL live stream every week, and it's been an enormous help. Thank you for opening it up to the community. Hope this helps!

…struct definitions. ProgramParams are now created for the inner struct locations.
@giawa
Copy link
Owner

giawa commented Jun 8, 2017

Awesome, thanks for the pull request! I'll try to find some time tomorrow to check this out. I'm glad you have found the library helpful.

@giawa
Copy link
Owner

giawa commented Jun 8, 2017

As a completely random aside, the fact you are using this for voxel development is really awesome! I actually made a blog series about my own voxel engine using the same library here: https://www.giawa.com I look forward to checking out what you make

@giawa
Copy link
Owner

giawa commented Jun 10, 2017

After thinking this over (and wondering why I went with parsing the GLSL back in the day) I decided to re-write this functionality by querying OpenGL directly for the uniform and attribute names. Since the OpenGL names are compatible with what you have done you should see no difference, and that way the code will now support future extensions to GLSL and any other parsing issues that we haven't foreseen.

Thanks again for submitting the pull request :D and hopefully you continue to find the library useful!

Commit that added this new functionality: 2050865

@giawa giawa closed this Jun 10, 2017
@mbolt35
Copy link
Author

mbolt35 commented Jun 11, 2017

Excellent! Thanks for the update!

When I was poking around for GL bindings, I came across your blog, and it made the decision very easy. We haven't made it that far into development since it's only a few hours 2-3 times a week. It's mainly been a linear algebra refresher (I'm still struggling to remember rotation transforms and quaternions, yikes), but we are getting into some of the data structures, terrain generation, etc... so hopefully it won't be much longer until we get into the core voxel stuff. I'm going to let viewers drive a lot of the "what we do" after we establish the basics. We'll see where that goes :)

Thanks again for dropping and line, and the library update!

@mbolt35
Copy link
Author

mbolt35 commented Jun 11, 2017

Oh, these are all unedit cuts, so they can be super lengthy. It's mostly me struggling, which can be somewhat entertaining: https://www.youtube.com/playlist?list=PLxLT4bny07yRB_kIDMYFeSpq2W7iNiDEu

@giawa
Copy link
Owner

giawa commented Jun 12, 2017

Very cool! I'll definitely be checking it out! Let me know if you run into any pain points with the bindings, and I'll see what I can do to help out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants