CS计算机代考程序代写 compiler c++ c/c++ GPU This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License
Computer Graphics
The GLSL API
Mike Bailey mjb@cs.oregonstate.edu
glslapi.pptx
mjb – December 15, 2020
1

Computer Graphics
The GLSL Shader-Creation Process
2
mjb – December 15, 2020

Computer Graphics
#include “glew.h“ …
GLenum err = glewInit(); if( err != GLEW_OK )
{
Do this immediately after opening the window
}
Initializing the GL Extension Wrangler (GLEW)
3
fprintf( stderr, “glewInit Error\n” ); exit( 1 );
fprintf( stderr, “GLEW initialized OK\n” );
fprintf( stderr, “Status: Using GLEW %s\n”, glewGetString(GLEW_VERSION) );
GLEW cannot be initialized until a graphics window is open. Like OpenGL itself, GLEW’s calls will not work unless it can see a graphics context (i.e., a graphics state).
http://glew.sourceforge.net
mjb – December 15, 2020

Computer Graphics
Reading a Shader source file into a character array
4
#include
FILE *fp = fopen( filename, “r” ); if(fp==NULL) {…}
fseek( fp, 0, SEEK_END );
int numBytes = ftell( fp ); // length of file
GLchar * buffer = new GLchar [numBytes+1];
rewind( fp ); // same as: “fseek( in, 0, SEEK_SET )”
fread( buffer, 1, numBytes, fp );
fclose( fp );
buffer[numBytes] = ‘\0‘; // the entire file is now in a byte string
mjb – December 15, 2020

Creating and Compiling a Vertex Shader from that character buffer (Geometry and Fragment files work the same way)
5
Computer Graphics
int status;
int logLength;
This is the only part of this process that is specific to the type of shader it is
GLuint vertShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertShader, 1, (const GLchar **)&buffer, NULL );
delete [ ] buffer;
glCompileShader( vertShader ); CheckGlErrors( “Vertex Shader 1” );
An array of strings
glGetShaderiv( vertShader, GL_COMPILE_STATUS, &status ); if( status == GL_FALSE )
{
fprintf( stderr, “Vertex shader compilation failed.\n” );
glGetShaderiv( vertShader, GL_INFO_LOG_LENGTH, &logLength ); GLchar *log = new GLchar [logLength];
glGetShaderInfoLog( vertShader, logLength, NULL, log );
fprintf( stderr, “\n%s\n”, log );
delete [ ] log;
exit( 1 );
}
CheckGlErrors( “Vertex Shader 2” );
mjb – December 15, 2020

Creating Different Shader Types
6
GLuint shader = glCreateShader( GL_VERTEX_SHADER );
GLuint shader = glCreateShader( GL_GEOMETRY_SHADER );
GLuint shader = glCreateShader( GL_TESS_CONTROL_SHADER ); GLuint shader = glCreateShader( GL_TESS_EVALUATION_SHADER ); GLuint shader = glCreateShader( GL_FRAGMENT_SHADER );
GLuint shader = glCreateShader( GL_COMPUTE_SHADER );
Other than this, the rest of the create, compile, link process is the same for each shader type.
Computer Graphics
mjb – December 15, 2020

How does that array-of-strings thing work?
7
GLchar *ArrayOfStrings[3];
ArrayOfStrings[0] = “#define SMOOTH_SHADING”; ArrayofStrings[1] = “ . . . a commonly-used procedure . . . “; ArrayofStrings[2] = “ . . . the real vertex shader code . .. “; glShaderSource( vertShader, 3, ArrayofStrings, NULL );
These are two ways to provide a single buffer:
GLchar *buffer[1];
buffer[0] = “ . . . the entire shader code . . . “; glShaderSource( vertShader, 1, buffer, NULL );
GLchar *buffer = “ . . . the entire shader code . . . “; glShaderSource( vertShader, 1, (const GLchar **)&buffer, NULL );
Computer Graphics
mjb – December 15, 2020

1.
You can use the same shader source and insert the appropriate “#defines” at the beginning
2. 3.
You can insert a common header file (≈ a .h file)
You can simulate a “#include” to re-use common pieces of code
Why use an array of strings as the shader input, instead of just a single string?
8
if( Mode == SmoothShading ) {…}
else if( Mode == PhongShading ) {…}
#ifdef SMOOTH_SHADING {…}
#endif
Computer Graphics
if-tests vs. preprocessing
#ifdef PHONG_SHADING {…}
#endif
mjb – December 15, 2020

Computer Graphics
Creating the Program and Attaching the Shaders to It
9
GLuint program = glCreateProgram( ); glAttachShader( program, vertShader ); glAttachShader( program, fragShader ); glAttachShader( program, geomShader );
mjb – December 15, 2020

Computer Graphics
Linking the Program and Checking its Validity
10
glLinkProgram( program );
CheckGlErrors( “Shader Program 1” );
glGetProgramiv( program, GL_LINK_STATUS, &status ); if( status == GL_FALSE )
{
fprintf( stderr, “Link failed.\n” );
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLength ); log = new GLchar [logLength];
glGetProgramInfoLog( program, logLength, NULL, log );
fprintf( stderr, “\n%s\n”, log );
delete [ ] log;
exit( 1 );
}
CheckGlErrors( “Shader Program 2” );
glValidateProgram( program );
glGetProgramiv( program, GL_VALIDATE_STATUS, &status );
fprintf( stderr, “Program is %s.\n”, status == GL_FALSE ? “invalid” : “valid” );
mjb – December 15, 2020

Computer Graphics
Making the Program Active
11
glUseProgram( program );
Making the Program Inactive
(use the fixed function pipeline instead)
glUseProgram( 0 );
mjb – December 15, 2020

Computer Graphics
Using Multiple Shader Programs
12
glUseProgram( program0 );
glUseProgram( program1 );
glUseProgram( program2 );
glUseProgram( program3 );
glUseProgram( program4 );
glUseProgram( program5 );
A specified shader program is an “attribute” – it stays in effect until you change it
mjb – December 15, 2020

Computer Graphics
Passing in Uniform Variables
You first need to find the variable’s location in the shader program’s symbol table.
float lightLoc[3] = { 0., 100., 0. };
GLint location = glGetUniformLocation( program, “uLightLocation” );
if( location < 0 ) fprintf( stderr, “Cannot find Uniform variable ‘uLightLocation’\n” ); else glUniform3fv( location, 1, lightLoc ); Then you need to fill it. mjb – December 15, 2020 13 Computer Graphics else { Passing in Attribute Variables You first need to find the variable’s location in the shader program’s symbol table. GLint location = glGetAttribLocation( program, “aArray” ); if( location < 0 ) { fprintf( stderr, “Cannot find Attribute variable ‘aArray’\n” ); } glBegin( GL_TRIANGLES ); glVertexAttrib2f( location, a0, b0 ); glEnd(); } Then you need to fill it per-vertex. glVertex3f( x0, y0, z0 ); glVertexAttrib2f( location, a1, b1 ); glVertex3f( x1, y1, z1 ); glVertexAttrib2f( location, a2, b2 ); glVertex3f( x2, y2, z2 ); mjb – December 15, 2020 14 void CheckGlErrors( const char* caller ) { } } Computer Graphics It’s not a bad idea to do this in all your OpenGL programs, even without shaders! unsigned int glerr = glGetError(); if( glerr == GL_NO_ERROR ) return; fprintf( stderr, "GL Error discovered from caller ‘%s‘: ", caller ); switch( glerr ) { break; case GL_INVALID_VALUE: break; default: Checking for Errors 15 case GL_INVALID_ENUM: fprintf( stderr, "Invalid enum.\n" ); fprintf( stderr, "Invalid value.\n" ); break; case GL_INVALID_OPERATION: fprintf( stderr, "Invalid Operation.\n" ); break; case GL_STACK_OVERFLOW: fprintf( stderr, "Stack overflow.\n" ); break; case GL_STACK_UNDERFLOW: fprintf(stderr, "Stack underflow.\n" ); break; case GL_OUT_OF_MEMORY: fprintf( stderr, "Out of memory.\n" ); fprintf( stderr, “Unknown OpenGL error: %d (0x%0x)\n”, glerr, glerr ); mjb – December 15, 2020 Setup: Writing a C++ Class to Handle Everything is Fairly Straightforward 16 int Polar; float K; GLSLProgram *Hyper = new GLSLProgram( ); bool valid = Hyper->Create( “hyper.vert”, “hyper.geom”, “hyper.frag” ); if( ! valid ) { . . . }
This loads, compiles, and links the shader. It prints error messages if something went wrong.
Using the GPU program:
Hyper->Use( );
Hyper->SetUniformVariable( “uPolar”, Polar ); Hyper->SetUniformVariable( “uK”, K ); glBegin( GL_TRIANGLES );
glEnd( );
Hyper->SetAttributeVariable( “aTemperature”, T0 ); glVertex3f( x0, y0, z0 ); Hyper->SetAttributeVariable( “aTemperature”, T1 ); glVertex3f( x1, y1, z1 ); Hyper->SetAttributeVariable( “aTemperature”, T2 ); glVertex3f( x2, y2, z2 );
Reverting to the fixed-function pipeline during display:
Hyper->Use( 0 );
Computer Graphics
mjb – December 15, 2020

SPIR-V
17
SPIR-V is a file format that can be used to hold shader code that has been pre-compiled, but has not yet been turned into machine code. It was created as a way for software developers to pre-compile their code and then allow the vendor-specific driver to produce the final binary representation. There are four major advantages in doing things this way:
1. A software developer can more easily wring compiler errors from the code by having an external compiler that can be run independently from the application.
2. Vendors can still apply their optimization-magic in their device-specific drivers.
3. SPIR-V files can be read at the start of a program and be turned into machine code faster than the original GLSL files could have been turned into machine code.
4. Software developers can distribute their code without having to reveal the shaders’ source code.
GLSL Source GLSL Compiler
SPIR-V
Computer Graphics
External
Compiler in driver
Vendor-specific code
mjb – December 15, 2020

18 The new glShaderBinary( ) call replaces both glCreateShader( ) and glCompilerShader( )
Reading SPIR-V-compiled Shaders
FILE *fp = fopen( filename, “r” );
if(fp==NULL) {…}
fseek( fp, 0, SEEK_END );
int numBytes = ftell( fp ); // length of file – guaranteed to be a multiple of 4 GLchar * buffer = new GLchar [numBytes];
rewind( fp ); // same as: “fseek( in, 0, SEEK_SET )” fread( buffer, 1, numBytes, fp );
fclose( fp );
GLuint shaders[2]
glShaderBinary( 2, shaders, GL_SHADER_BINARY_FORMAT_SPIR_V, buffer, numbytes ); GLuint program = glCreateProgram( );
glAttachShader( program, shaders[0] );
glAttachShader( program, shaders[1] );
Computer Graphics
mjb – December 15, 2020

Computer Graphics
SPIR-V:
Standard Portable Intermediate Representation for Vulkan
19
glslangValidator shaderFile -G [-H] [-I

] [-S ] -o shaderBinaryFile.spv
Shaderfile extensions:
.vert Vertex
.tesc Tessellation Control .tese Tessellation Evaluation .geom Geometry
.frag Fragment
.comp Compute
(Can be overridden by the –S option)
-V Compile for Vulkan
-G Compile for OpenGL
-I Directory(ies) to look in for #includes
-S Specify stage rather than get it from shaderfile extension -c Print out the maximum sizes of various properties
Windows: glslangValidator.exe
Linux: setenv LD_LIBRARY_PATH /usr/local/common/gcc-6.3.0/lib64/
mjb – December 15, 2020

Computer Graphics
How do you know if SPIR-V compiled successfully?
20
Same as C/C++ — the compiler gives you no nasty messages.
Also, if you care, legal .spv files have a magic number of 0x07230203
So, if you do an od –x on the .spv file, the magic number looks like this:
0203 0723 . . .
mjb – December 15, 2020