You need the following Simdify® modules to complete this exercise: Simdify® Free Edition, Microsoft® Visual Studio® 2017 or newer (to export).
In this exercise you'll learn to create an application layout that renders geometry with a vertex and fragment shader. After creating the application, you'll learn how to export it to Windows® and compile it with Microsoft Visual Studio®. You can follow this exercise, even if you don't intend to export it at the end.
The application displays a splash screen and then the application desktop appears. The main menu is composed of three items since this is an empty document. More interface options become available when you create a new file or load a file from disk.
The software displays a wizard that allows you to specify the parameters of your new shader. The Profile shown below is 460 core, but you will see the highest GLSL version available on your machine.
NOTE: You will not see video or compute shader options in the wizard dialog if you do have not purchased the compute or video add-on modules.
User Basic Shader
The application creates a new application layout document and the main menu options change. You can see the hierarchy on the left, the rendered shader with geometry in the middle, and the property sheet on the right. GLSL compiler messages are shown in the output window below. The shader sets the fragment color to red and does no other work.
If the shader compiled successfully, you should see a red square in the center of the worksheet.
This expands the graph so that you can see all the nodes. As you can see, this application is made from a set of nodes. Nodes are atomic types because there is no smaller element that can be used in the layout.
In this simple example, program and mesh resources are declared inside invisible sections of the document. Then in the visible sections, the shader is activated and uniform values are set. Finally, the mesh is rendered. This is the most important pattern in any layout.
Notice that you can see the GLSL version, profile, and source code locations. Many nodes, but not all of them, display useful information if you hover over them.
This displays a dialog that allows you to select GLSL shader source code (and any include files). The file path of the source item you select will be copied to the Windows® clipboard so you can open it in a text editor.
This copies the absolute path to the fragment shader source code to the Windows® clipboard. For example, a file path like the following: C:\Users\MyUserName\MyDocuments\Scenomics\Shader\Simple Application Layout\460\visual_fragment_shader.glsl is copied to the clipboard.
This is the fragment shader. Note that your #version 460 declaration might be different, depending on the highest GLSL version on your machine. You can still follow this exercise even if the shader code is different. Just follow the steps below and make the same changes in the same locations.
// #version 460
// The version number is automatically injected by the application.
// It is included above for reference purposes only.
#include <SPA_Version.glsl>
#include <SPA_Constants.glsl>
#include <Modules/SPA_EditStateFragmentColorOverride.glsl>
#include "visual_attributes.glsl"
in Data { vertexData attributes; } DataIn;
out vec4 fragColor;
void main(void)
{
fragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
SPA_EditStateFragmentColorOverride( fragColor );
}
Simdify supports #include for GLSL. This makes life a lot easier when you're writing shader code. You can dump the fully assembled translation unit at any time if you need to see all your shader code, or when you are ready to take the shader code and use it in your own applications.
Notice that there is a line #include <Modules/SPA_EditStateFragmentColorOverride.glsl> and a corresponding line SPA_EditStateFragmentColorOverride( fragColor ); at the end of the shader. This is necessary for the Magnifier draw mode to work. The Magnifier draw mode powers the compute shader and texture debugging tools. If you're using these shaders for other purposes, or if you don't need to debug, you can remove the include statement and the call to SPA_EditStateFragmentColorOverride( fragColor ). Removing this code won't affect how your shader works.
fragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
fragColor = vec4( DataIn.attributes.texcoord, 1.0, 1.0 );
Note that if you're using an older version of GLSL in this exercise, the replacement code might be something like this:
fragColor = vec4( fs_texcoord, 1.0, 1.0 );
Leave the fragment shader open in the text editor.
uniform vec4 tint_color;
Your fragment shader code looks like this:
// #version 460
// The version number is automatically injected by the application.
// It is included above for reference purposes only.
#include <SPA_Version.glsl>
#include <SPA_Constants.glsl>
#include <Modules/SPA_EditStateFragmentColorOverride.glsl>
#include "user_basic_attributes.glsl"
in Data { vertexData attributes; } DataIn;
uniform vec4 tint_color;
out vec4 fragColor;
void main(void)
{
fragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
SPA_EditStateFragmentColorOverride( fragColor );
}
fragColor = tint_color;
Your fragment shader main function looks like this:
void main(void)
{
fragColor = tint_color;
SPA_EditStateFragmentColorOverride( fragColor );
}
Leave the fragment shader open in the text editor.
The rendered geometry is going to turn black when you return to the application. Depending on the behavior of your graphics driver you may see other colors as well. This is because we have not yet set a value for uniform vec4 tint_color. We're going to create a resource for this uniform next.
This binds the program to the rendering device and activates it. Once the program is in an active state, we can set uniforms and do other things.
The software presents a dialog that allows you to add resources that have been declared in your GLSL code.
The software adds a <Float32VectorNode> named uniform vec4 tint_color to the layout.
This displays the <Float32VectorNode> property editor.
The worksheet looks like this:
This is generally how you set uniform values. You declare them in the shader and then add then to the document. In versions of GLSL higher than 120, you can also initialize uniforms when you declare them. If initialized in GLSL, the values of the <VariableNode> in the Layout app will match the initializer values you typed in the shader code. You can then configure the values of the new nodes to suit your purpose. Many uniform values are set by the user, as we just did, but later you'll learn about using <DataCapture> objects to capture values from the document and use them as uniform values. The other way to create uniforms, uniform buffers, is discussed in a subsequent exercise (but it requires the Simdify Compute+ Module).
uniform sampler2D diffuse_texture;
Your fragment shader code looks like this:
// #version 460
// The version number is automatically injected by the application.
// It is included above for reference purposes only.
#include <SPA_Version.glsl>
#include <SPA_Constants.glsl>
#include <Modules/SPA_EditStateFragmentColorOverride.glsl>
#include "user_basic_attributes.glsl"
in Data { vertexData attributes; } DataIn;
uniform vec4 tint_color;
uniform sampler2D diffuse_texture;
out vec4 fragColor;
void main(void)
{
fragColor = tint_color;
SPA_EditStateFragmentColorOverride( fragColor );
}
vec4 diffuse_color = texture( diffuse_texture, DataIn.attributes.texcoord );
Your fragment shader main function looks like this:
void main(void)
{
vec4 diffuse_color = texture( diffuse_texture, DataIn.attributes.texcoord );
fragColor = tint_color;
SPA_EditStateFragmentColorOverride( fragColor );
}
This code samples a texture using the texture coordinates computed by the vertex shader.
fragColor = diffuse_color * tint_color;
Your fragment shader main function looks like this:
void main(void)
{
vec4 diffuse_color = texture( diffuse_texture, DataIn.attributes.texcoord );
fragColor = diffuse_color * tint_color;
SPA_EditStateFragmentColorOverride( fragColor );
}
Leave the fragment shader open in the text editor.
The software presents a dialog that allows you to add resources that have been declared in your GLSL code.
The software adds a <SamplerNode> to the layout.
This displays the file open dialog, which allows you to choose a 2D texture from the hard disk. There is a list of folders that organize textures by pixel format.
IPF_8888_ARGB
IPF_8888_ARGB.png
The software adds a <Texture> node named IPF_8888_ARGB to the document and connects the <SamplerNode> to the new texture.
You can see the texture modified by the tint color. If you change the tint color uniform, then the results on screen will change.
The software displays a dialog that allows you to export the application layout as a standalone Windows graphics application.
By default, the export is configured to generate the exported document in a sub-directory of the folder containing the .BOX document that implements the shader.
The software exports the document. The export process generates the C++, GLSL, and Visual Studio solution files required to run the shader as a stand-alone graphics application.