diff options
| author | Miles Macklin <[email protected]> | 2017-03-10 14:51:31 +1300 |
|---|---|---|
| committer | Miles Macklin <[email protected]> | 2017-03-10 14:51:31 +1300 |
| commit | ad3d90fafe5ee79964bdfe1f1e0704c3ffcdfd5f (patch) | |
| tree | 4cc6f3288363889d7342f7f8407c0251e6904819 /demo/opengl/shader.cpp | |
| download | flex-ad3d90fafe5ee79964bdfe1f1e0704c3ffcdfd5f.tar.xz flex-ad3d90fafe5ee79964bdfe1f1e0704c3ffcdfd5f.zip | |
Initial 1.1.0 binary release
Diffstat (limited to 'demo/opengl/shader.cpp')
| -rw-r--r-- | demo/opengl/shader.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/demo/opengl/shader.cpp b/demo/opengl/shader.cpp new file mode 100644 index 0000000..3c7640f --- /dev/null +++ b/demo/opengl/shader.cpp @@ -0,0 +1,248 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 20132017 NVIDIA Corporation. All rights reserved. + +#include "shader.h" + +#include "../../core/types.h" +#include "../../core/maths.h" +#include "../../core/platform.h" +#include "../../core/tga.h" + +#include <stdarg.h> +#include <stdio.h> + +#define WITH_GLEW + +void GlslPrintShaderLog(GLuint obj) +{ +#if !PLATFORM_IOS + int infologLength = 0; + int charsWritten = 0; + char *infoLog; + + GLint result; + glGetShaderiv(obj, GL_COMPILE_STATUS, &result); + + // only print log if compile fails + if (result == GL_FALSE) + { + glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength); + + if (infologLength > 1) + { + infoLog = (char *)malloc(infologLength); + glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog); + printf("%s\n",infoLog); + free(infoLog); + } + } +#endif +} + +void glAssert(const char* msg, long line, const char* file) +{ + struct glError + { + GLenum code; + const char* name; + }; + + static const glError errors[] = { {GL_NO_ERROR, "No Error"}, + {GL_INVALID_ENUM, "Invalid Enum"}, + {GL_INVALID_VALUE, "Invalid Value"}, + {GL_INVALID_OPERATION, "Invalid Operation"} +#if OGL1 + ,{GL_STACK_OVERFLOW, "Stack Overflow"}, + {GL_STACK_UNDERFLOW, "Stack Underflow"}, + {GL_OUT_OF_MEMORY, "Out Of Memory"} +#endif + }; + + GLenum e = glGetError(); + + if (e == GL_NO_ERROR) + { + return; + } + else + { + const char* errorName = "Unknown error"; + + // find error message + for (uint32_t i=0; i < sizeof(errors)/sizeof(glError); i++) + { + if (errors[i].code == e) + { + errorName = errors[i].name; + } + } + + printf("OpenGL: %s - error %s in %s at line %d\n", msg, errorName, file, int(line)); + assert(0); + } +} + +void PreProcessShader(const char* filename, std::string& source) +{ + // load source + FILE* f = fopen(filename, "r"); + + if (!f) + { + printf("Could not open shader file for reading: %s\n", filename); + return; + } + + // add lines one at a time handling include files recursively + while (!feof(f)) + { + char buf[1024]; + + if (fgets(buf, 1024, f) != NULL) + { + // test for #include + if (strncmp(buf, "#include", 8) == 0) + { + const char* begin = strchr(buf, '\"'); + const char* end = strrchr(buf, '\"'); + + if (begin && end && (begin != end)) + { + // lookup file relative to current file + PreProcessShader((StripFilename(filename) + std::string(begin+1, end)).c_str(), source); + } + } + else + { + // add line to output + source += buf; + } + } + } + + fclose(f); +} + +GLuint CompileProgram(const char *vsource, const char *fsource, const char* gsource) +{ + GLuint vertexShader = GLuint(-1); + GLuint geometryShader = GLuint(-1); + GLuint fragmentShader = GLuint(-1); + + GLuint program = glCreateProgram(); + + if (vsource) + { + vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vsource, 0); + glCompileShader(vertexShader); + GlslPrintShaderLog(vertexShader); + glAttachShader(program, vertexShader); + } + + if (fsource) + { + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fsource, 0); + glCompileShader(fragmentShader); + GlslPrintShaderLog(fragmentShader); + glAttachShader(program, fragmentShader); + } + + if (gsource) + { + geometryShader = glCreateShader(GL_GEOMETRY_SHADER); + glShaderSource(geometryShader, 1, &gsource, 0); + glCompileShader(geometryShader); + GlslPrintShaderLog(geometryShader); + + // hack, force billboard gs mode + glAttachShader(program, geometryShader); + glProgramParameteriEXT ( program, GL_GEOMETRY_VERTICES_OUT_EXT, 4 ) ; + glProgramParameteriEXT ( program, GL_GEOMETRY_INPUT_TYPE_EXT, GL_POINTS ) ; + glProgramParameteriEXT ( program, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP ) ; + } + + glLinkProgram(program); + + // check if program linked + GLint success = 0; + glGetProgramiv(program, GL_LINK_STATUS, &success); + + if (!success) { + char temp[256]; + glGetProgramInfoLog(program, 256, 0, temp); + printf("Failed to link program:\n%s\n", temp); + glDeleteProgram(program); + program = 0; + } + + return program; +} + +void DrawPlane(const Vec4& p, bool color) +{ + Vec3 u, v; + BasisFromVector(Vec3(p.x, p.y, p.z), &u, &v); + + Vec3 c = Vec3(p.x, p.y, p.z)*-p.w; + + glBegin(GL_QUADS); + + if (color) + glColor3fv(p*0.5f + Vec4(0.5f, 0.5f, 0.5f, 0.5f)); + + float kSize = 200.0f; + + // draw a grid of quads, otherwise z precision suffers + for (int x = -3; x <= 3; ++x) + { + for (int y = -3; y <= 3; ++y) + { + Vec3 coff = c + u*float(x)*kSize*2.0f + v*float(y)*kSize*2.0f; + + glTexCoord2f(1.0f, 1.0f); + glNormal3f(p.x, p.y, p.z); + glVertex3fv(coff + u*kSize + v*kSize); + + glTexCoord2f(0.0f, 1.0f); + glNormal3f(p.x, p.y, p.z); + glVertex3fv(coff - u*kSize + v*kSize); + + glTexCoord2f(0.0f, 0.0f); + glNormal3f(p.x, p.y, p.z); + glVertex3fv(coff - u*kSize - v*kSize); + + glTexCoord2f(1.0f, 0.0f); + glNormal3f(p.x, p.y, p.z); + glVertex3fv(coff + u*kSize - v*kSize); + } + } + + glEnd(); +} + |