diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /KaplaDemo/samples/sampleViewer3/Shader.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/Shader.cpp')
| -rw-r--r-- | KaplaDemo/samples/sampleViewer3/Shader.cpp | 750 |
1 files changed, 750 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/Shader.cpp b/KaplaDemo/samples/sampleViewer3/Shader.cpp new file mode 100644 index 00000000..b1d4a41f --- /dev/null +++ b/KaplaDemo/samples/sampleViewer3/Shader.cpp @@ -0,0 +1,750 @@ +#include "Shader.h" +#include <assert.h> +//#define NOMINMAX +#include <windows.h> + +#include "foundation/PxMat44.h" + +// -------------------------------------------------------------------------------------------- +Shader::Shader() +{ + mVertexShaderSource = NULL; + mVertexShaderSourceLength = 0; + + mGeometryShaderSource = NULL; + mGeometryShaderSourceLength = 0; + + mFragmentShaderSource = NULL; + mFragmentShaderSourceLength = 0; + + mShaderProgram = 0; + mVertexShader = 0; + mGeometryShader = 0; + mFragmentShader = 0; + + mErrorMessage = ""; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::loadShaders(const char* vertexShaderFile, const char* fragmentShaderFile) +{ + mErrorMessage = ""; + + if (vertexShaderFile == NULL || fragmentShaderFile == NULL) + return false; + + if (!GLEW_VERSION_2_0) + return false; + + if (!loadFile(vertexShaderFile, mVertexShaderSource, mVertexShaderSourceLength)) { + printf("Can't load vertex shader\n"); + return false; + } + + if (mGeometryShaderSource) { + free(mGeometryShaderSource); + mGeometryShaderSource = NULL; + mGeometryShaderSourceLength = 0; + } + + if (!loadFile(fragmentShaderFile, mFragmentShaderSource, mFragmentShaderSourceLength)) { + printf("Can't load fragment shader\n"); + return false; + } + + if (!compileShaders()) { + printf("Can't compile shaders\n"); + return false; + } + + findVariables(); + + return true; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::loadShaders(const char* vertexShaderFile, const char* geometryShaderFile, const char* fragmentShaderFile) +{ + mErrorMessage = ""; + + if (vertexShaderFile == NULL || geometryShaderFile == NULL || fragmentShaderFile == NULL) + return false; + + if (!GLEW_VERSION_2_0) + return false; + + if (!loadFile(vertexShaderFile, mVertexShaderSource, mVertexShaderSourceLength)) + return false; + + if (!loadFile(geometryShaderFile, mGeometryShaderSource, mGeometryShaderSourceLength)) + return false; + + if (!loadFile(fragmentShaderFile, mFragmentShaderSource, mFragmentShaderSourceLength)) + return false; + + if (!compileShaders()) + return false; + + findVariables(); + + return true; +} + + + + +// -------------------------------------------------------------------------------------------- +bool Shader::loadShaderCode(const char* vertexShaderCode, const char* fragmentShaderCode) +{ +/* + mErrorMessage = ""; + + if (!GLEW_VERSION_2_0) + return false; + + size_t size; + + if (mVertexShaderSource != NULL) + free(mVertexShaderSource); + + size = strlen(vertexShaderCode)+1; + mVertexShaderSourceLength = size-1; + mVertexShaderSource = (char*)malloc(size * sizeof(char)); + strcpy_s(mVertexShaderSource, size, vertexShaderCode); + + if (mFragmentShaderSource != NULL) + free(mFragmentShaderSource); + + size = strlen(fragmentShaderCode)+1; + mFragmentShaderSourceLength = size-1; + mFragmentShaderSource = (char*)malloc(size * sizeof(char)); + strcpy_s(mFragmentShaderSource, size, fragmentShaderCode); + + if (!compileShaders()) + return false; + + findVariables(); + + return true; + */ + return loadShaderCode(vertexShaderCode, NULL, fragmentShaderCode); +} + +// -------------------------------------------------------------------------------------------- +bool Shader::loadShaderCode(const char* vertexShaderCode, const char* geometryShaderCode, const char* fragmentShaderCode) +{ + mErrorMessage = ""; + + if (!GLEW_VERSION_2_0) + return false; + + size_t size; + + if (mVertexShaderSource != NULL) + free(mVertexShaderSource); + + size = strlen(vertexShaderCode)+1; + mVertexShaderSourceLength = size-1; + mVertexShaderSource = (char*)malloc(size * sizeof(char)); + strcpy_s(mVertexShaderSource, size, vertexShaderCode); + + if (mFragmentShaderSource != NULL) + free(mFragmentShaderSource); + + if (mGeometryShaderSource != NULL) { + free(mGeometryShaderSource); + mGeometryShaderSource = NULL; + } + + if (geometryShaderCode) { + size = strlen(geometryShaderCode)+1; + mGeometryShaderSourceLength = size-1; + mGeometryShaderSource = (char*)malloc(size * sizeof(char)); + strcpy_s(mGeometryShaderSource, size, geometryShaderCode); + + } + + if (mFragmentShaderSource != NULL) + free(mFragmentShaderSource); + + size = strlen(fragmentShaderCode)+1; + mFragmentShaderSourceLength = size-1; + mFragmentShaderSource = (char*)malloc(size * sizeof(char)); + strcpy_s(mFragmentShaderSource, size, fragmentShaderCode); + + if (!compileShaders()) + return false; + + findVariables(); + + return true; +} + + +// -------------------------------------------------------------------------------------------- +Shader::~Shader() +{ + deleteShaders(); +} + +// -------------------------------------------------------------------------------------------- +void Shader::deleteShaders() +{ + glDetachShader(mShaderProgram, mVertexShader); + glDeleteShader(mVertexShader); + + glDetachShader(mShaderProgram, mFragmentShader); + glDeleteShader(mFragmentShader); + + + glDeleteProgram(mShaderProgram); + + mVertexShader = 0; + mFragmentShader = 0; + mShaderProgram = 0; + + free(mVertexShaderSource); + free(mFragmentShaderSource); + + mVertexShaderSource = NULL; + mFragmentShaderSource = NULL; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::compileShaders() +{ + if (mShaderProgram != 0) { + glDetachShader(mShaderProgram, mVertexShader); + glDeleteShader(mVertexShader); + + + glDetachShader(mShaderProgram, mGeometryShader); + glDeleteShader(mGeometryShader); + + glDetachShader(mShaderProgram, mFragmentShader); + glDeleteShader(mFragmentShader); + + glDeleteProgram(mShaderProgram); + + mVertexShader = 0; + mGeometryShader = 0; + mFragmentShader = 0; + mShaderProgram = 0; + } + + bool ok = true; + + mShaderProgram = glCreateProgram(); + mVertexShader = glCreateShader(GL_VERTEX_SHADER); + if (mGeometryShaderSource) { + mGeometryShader = glCreateShader(GL_GEOMETRY_SHADER_ARB); + } + mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + mGlShaderAttributes = 0; + + const GLchar* sources[3]; + GLint lengths[3]; + + char header[128]; + sprintf_s(header, 128, "\n"); + sources[0] = header; + lengths[0] = strlen(header); + + char footer[2] = "\n"; + sources[2] = footer; + lengths[2] = strlen(footer); + + sources[1] = mVertexShaderSource; + lengths[1] = mVertexShaderSourceLength; + + glShaderSource(mVertexShader, 3, sources, lengths); + glCompileShader(mVertexShader); + + sources[1] = mFragmentShaderSource; + lengths[1] = mFragmentShaderSourceLength; + + glShaderSource(mFragmentShader, 3, sources, lengths); + glCompileShader(mFragmentShader); + + + if (mGeometryShaderSource) { + sources[1] = mGeometryShaderSource; + lengths[1] = mGeometryShaderSourceLength; + + glShaderSource(mGeometryShader, 3, sources, lengths); + glCompileShader(mGeometryShader); + + } + + // error checking + int param; + + glGetShaderiv(mVertexShader, GL_COMPILE_STATUS, ¶m); + if (param != GL_TRUE) { + getCompileError(mVertexShader); + deleteShaders(); + return false; + } + + if (mGeometryShader) { + glGetShaderiv(mGeometryShader, GL_COMPILE_STATUS, ¶m); + if (param != GL_TRUE) { + getCompileError(mGeometryShader); + deleteShaders(); + return false; + } + } + + glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, ¶m); + if (param != GL_TRUE) { + getCompileError(mFragmentShader); + deleteShaders(); + return false; + } + + + // link + glAttachShader(mShaderProgram, mVertexShader); + if (mGeometryShader) { + GLenum gsInput = GL_POINTS; + GLenum gsOutput = GL_TRIANGLE_STRIP; + GLuint maxGSVOut = 4; + glAttachShader(mShaderProgram, mGeometryShader); + + glProgramParameteriEXT(mShaderProgram, GL_GEOMETRY_INPUT_TYPE_EXT, gsInput); + glProgramParameteriEXT(mShaderProgram, GL_GEOMETRY_OUTPUT_TYPE_EXT, gsOutput); + glProgramParameteriEXT(mShaderProgram, GL_GEOMETRY_VERTICES_OUT_EXT, maxGSVOut); + } + glAttachShader(mShaderProgram, mFragmentShader); + + + glLinkProgram(mShaderProgram); + glGetProgramiv(mShaderProgram, GL_LINK_STATUS, ¶m); + + // check if program linked + + if (!param) { + char temp[4096]; + glGetProgramInfoLog(mShaderProgram, 4096, 0, temp); + fprintf(stderr, "Failed to link program:\n%s\n", temp); + //printf("..\n"); + getLinkError(mShaderProgram); + printf(mErrorMessage.c_str()); + return false; + } + + return true; +} + +// -------------------------------------------------------------------------------------------- +void Shader::findVariables() +{ + // Find uniforms + GLint numUniforms, maxLength; + mUniforms.clear(); + mAttributes.clear(); + glGetProgramiv(mShaderProgram, GL_ACTIVE_UNIFORMS, &numUniforms); + glGetProgramiv(mShaderProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); + assert(maxLength < 256); + char buf[256]; + + for (GLint i = 0; i < numUniforms; i++) + { + GLint length; + UniformVariable u; + glGetActiveUniform(mShaderProgram, i, 256, &length, &u.size, &u.type, buf); + assert(length < 256); + if (strncmp("gl_", buf, 3) != 0) + { + u.index = glGetUniformLocation(mShaderProgram, buf); + mUniforms[buf] = u; + } + } + + // Find attribs + GLint numAttribs; + glGetProgramiv(mShaderProgram, GL_ACTIVE_ATTRIBUTES, &numAttribs); + glGetProgramiv(mShaderProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength); + assert(maxLength < 256); + + for (GLint i = 0; i < numAttribs; i++) + { + GLint length; + AttributeVariable a; + glGetActiveAttrib(mShaderProgram, i, 256, &length, &a.size, &a.type, buf); + if (strncmp("gl_", buf, 3) != 0) + { + a.index = glGetAttribLocation(mShaderProgram, buf); + mAttributes[buf] = a; + } + else + { + if (strncmp("gl_Vertex", buf, 9) == 0) + mGlShaderAttributes |= gl_VERTEX; + else if (strncmp("gl_Normal", buf, 9) == 0) + mGlShaderAttributes |= gl_NORMAL; + else if (strncmp("gl_Color", buf, 8) == 0) + mGlShaderAttributes |= gl_COLOR; + else if (strncmp("gl_MultiTexCoord0", buf, 17) == 0) + mGlShaderAttributes |= gl_TEXTURE; + else if (strncmp("gl_MultiTexCoord1", buf, 17) == 0) + mGlShaderAttributes |= gl_TEXTURE; + else if (strncmp("gl_MultiTexCoord2", buf, 17) == 0) + mGlShaderAttributes |= gl_TEXTURE; + else if (strncmp("gl_MultiTexCoord3", buf, 17) == 0) + mGlShaderAttributes |= gl_TEXTURE; + else if (strncmp("gl_MultiTexCoord4", buf, 17) == 0) + mGlShaderAttributes |= gl_TEXTURE; + else if (strncmp("gl_MultiTexCoord5", buf, 17) == 0) + mGlShaderAttributes |= gl_TEXTURE; + else + printf("Unknown gl attribute: %s\n", buf); + } + } +} + +// -------------------------------------------------------------------------------------------- +void Shader::getCompileError(GLuint shader) +{ + int infoLogLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + + if (infoLogLength > 1) + { + char* log = (char*)malloc(sizeof(char) * infoLogLength); + int slen; + glGetShaderInfoLog(shader, infoLogLength, &slen, log); + + const GLubyte* vendor = glGetString(GL_VENDOR); + const GLubyte* renderer = glGetString(GL_RENDERER); + const GLubyte* version = glGetString(GL_VERSION); + + printf("Compiler error\nVendor: %s\nRenderer: %s\nVersion: %s\nError: %s\n", + vendor, renderer, version, log); + + mErrorMessage = "compile error: "; + mErrorMessage += std::string(log); + free(log); + } +} + +// -------------------------------------------------------------------------------------------- +void Shader::getLinkError(GLuint shader) +{ + int infoLogLength; + glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + + if (infoLogLength > 1) + { + char* log = (char*)malloc(sizeof(char) * infoLogLength); + int slen; + glGetProgramInfoLog(shader, infoLogLength, &slen, log); + + //const GLubyte* vendor = glGetString(GL_VENDOR); + //const GLubyte* renderer = glGetString(GL_RENDERER); + //const GLubyte* version = glGetString(GL_VERSION); + + //printf("Link Error:\nVendor: %s\nRenderer: %s\nVersion: %s\nError:\n%s\n", + // vendor, renderer, version, log); + + mErrorMessage = "link error: "; + mErrorMessage += std::string(log); + + free(log); + } +} + +// -------------------------------------------------------------------------------------------- +void Shader::activate(const ShaderMaterial &mat) +{ + if (mShaderProgram == 0) + return; + + glUseProgram(mShaderProgram); +} + + +// -------------------------------------------------------------------------------------------- +void Shader::activate() +{ + if (mShaderProgram == 0) + return; + + glUseProgram(mShaderProgram); +} + +// -------------------------------------------------------------------------------------------- +void Shader::deactivate() +{ + if (mShaderProgram == 0) + return; + + GLint curProg; + glGetIntegerv(GL_CURRENT_PROGRAM, &curProg); + assert(curProg == mShaderProgram); + + //for (tAttributes::iterator it = mAttributes.begin(); it != mAttributes.end(); ++it) + //{ + // glDisableVertexAttribArray(it->second.index); + //} + //if (mGlShaderAttributes & gl_VERTEX) + // glDisableClientState(GL_VERTEX_ARRAY); + + //if (mGlShaderAttributes & gl_NORMAL) + // glDisableClientState(GL_NORMAL_ARRAY); + + //if (mGlShaderAttributes & gl_COLOR) + // glDisableClientState(GL_COLOR_ARRAY); + + //if (mGlShaderAttributes & gl_TEXTURE) + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glUseProgram(0); +} + +// -------------------------------------------------------------------------------------------- +bool Shader::isValid() +{ + return mShaderProgram != 0; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform(const char *name, const PxMat33& value) +{ + GLint uniform = getUniformCommon(name); + if (uniform != -1) + { + float v[9]; + v[0] = value.column0.x; v[3] = value.column0.y; v[6] = value.column0.z; + v[1] = value.column1.x; v[4] = value.column1.y; v[7] = value.column1.z; + v[2] = value.column2.x; v[5] = value.column2.y; v[8] = value.column2.z; + glUniformMatrix3fv(uniform, 1, false, v); + + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform(const char *name, const PxTransform& value) +{ + GLint uniform = getUniformCommon(name); + if (uniform != -1) + { + float v[16]; + PxMat44 v44 = value; + v[0] = v44.column0.x; v[4] = v44.column0.y; v[8] = v44.column0.z; v[12] = v44.column0.w; + v[1] = v44.column1.x; v[5] = v44.column1.y; v[9] = v44.column1.z; v[13] = v44.column1.w; + v[2] = v44.column2.x; v[6] = v44.column2.y; v[10] = v44.column2.z; v[14] = v44.column2.w; + v[3] = v44.column3.x; v[7] = v44.column3.y; v[11] = v44.column3.z; v[15] = v44.column3.w; + glUniformMatrix4fv(uniform, 1, false, v); + + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform(const char *name, PxU32 size, const PxVec3* value) +{ + GLint uniform = getUniformCommon(name); + if (uniform != -1) + { + glUniform3fv(uniform, size, (const GLfloat*)value); + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform1(const char* name, const float value) +{ + GLint loc = glGetUniformLocation(mShaderProgram, name); + if (loc >= 0) { + glUniform1f(loc, value); + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform2(const char* name, float val0, float val1) +{ + GLint loc = glGetUniformLocation(mShaderProgram, name); + if (loc >= 0) { + glUniform2f(loc, val0, val1); + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform3(const char* name, float val0, float val1, float val2) +{ + GLint loc = glGetUniformLocation(mShaderProgram, name); + if (loc >= 0) { + glUniform3f(loc, val0, val1, val2); + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform4(const char* name, float val0, float val1, float val2, float val3) +{ + GLint loc = glGetUniformLocation(mShaderProgram, name); + if (loc >= 0) { + glUniform4f(loc, val0, val1, val2, val3); + return true; + } + return false; +} + + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform(const char* name, float value) +{ + GLint uniform = getUniformCommon(name); + if (uniform != -1) + { + glUniform1f(uniform, value); + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setUniform(const char* name, int value) +{ + GLint uniform = getUniformCommon(name); + if (uniform != -1) + { + glUniform1i(uniform, value); + return true; + } + return false; +} + + +bool +Shader::setUniformfv(const GLchar *name, GLfloat *v, int elementSize, int count) +{ + GLint loc = glGetUniformLocation(mShaderProgram, name);//getUniformCommon( name); + if (loc == -1) { + return false; + } + switch (elementSize) { + case 1: + glUniform1fv(loc, count, v); + break; + case 2: + glUniform2fv(loc, count, v); + break; + case 3: + glUniform3fv(loc, count, v); + break; + case 4: + glUniform4fv(loc, count, v); + break; + } + return true; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::setAttribute(const char* name, PxU32 size, PxU32 stride, GLenum type, void* data) +{ + GLint activeProgram; + glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram); + tAttributes::iterator it = mAttributes.find(name); + if (it != mAttributes.end()) + { + PxI32 index = it->second.index; + glEnableVertexAttribArray(index); + glVertexAttribPointer(index, size, type, GL_FALSE, stride, data); + + return true; + } + return false; +} + +// -------------------------------------------------------------------------------------------- +GLint Shader::getUniformCommon(const char* name) +{ + GLint activeProgram; + glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram); + if (activeProgram == 0) return -1; + tUniforms::iterator it = mUniforms.find(name); + if (it != mUniforms.end()) + { + assert(it->second.index != -1); + return it->second.index; + } + return -1; +} + +// -------------------------------------------------------------------------------------------- +bool Shader::loadFile(const char* filename, char*& destination, int& destinationLength) +{ + if (destination != NULL) + { + assert(destinationLength != 0); + free(destination); + destination = NULL; + destinationLength = 0; + } + assert(destinationLength == 0); + + FILE* file = NULL; + file = fopen(filename, "rb"); + if (file == NULL) + { + mErrorMessage = "Shader file " + std::string(filename) + "not found\n"; + return false; + } + // find length + fseek(file, 0, SEEK_END); + destinationLength = ftell(file); + fseek(file, 0, SEEK_SET); + + if (destinationLength > 0) + { + destination = (char*)malloc(destinationLength * sizeof(char) + 1); + + fread(destination, 1, destinationLength, file); + destination[destinationLength] = 0; + } + fclose(file); + return true; +} + +void +Shader::bindTexture(const char *name, GLuint tex, GLenum target, GLint unit) +{ + GLint loc = getUniformCommon(name); + if (loc >= 0) { + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(target, tex); + glUseProgram(mShaderProgram); + glUniform1i(loc, unit); + glActiveTexture(GL_TEXTURE0); + } else { +#if _DEBUG + fprintf(stderr, "Error binding texture '%s'\n", name); +#endif + } +} + +bool +Shader::setUniformMatrix4fv(const GLchar *name, const GLfloat *m, bool transpose) +{ + GLint loc = getUniformCommon(name); + if (loc >= 0) { + glUniformMatrix4fv(loc, 1, transpose, m); + } else { + return false; + } + + return true; +} + + |