[2798] | 1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
---|
[3502] | 2 | /* |
---|
| 3 | * Copyright (c) 2004-2013 HUBzero Foundation, LLC |
---|
| 4 | * |
---|
| 5 | */ |
---|
[1111] | 6 | #include <stdio.h> |
---|
[2833] | 7 | |
---|
[2870] | 8 | #include <GL/glew.h> |
---|
| 9 | #include <Cg/cg.h> |
---|
| 10 | #include <Cg/cgGL.h> |
---|
| 11 | |
---|
[3465] | 12 | #include <util/FilePath.h> |
---|
[2870] | 13 | |
---|
[3612] | 14 | #include "Shader.h" |
---|
[2870] | 15 | #include "Trace.h" |
---|
[580] | 16 | |
---|
[3611] | 17 | using namespace nv; |
---|
[3463] | 18 | using namespace nv::util; |
---|
| 19 | |
---|
[3612] | 20 | CGprofile Shader::_defaultVertexProfile = CG_PROFILE_VP40; |
---|
| 21 | CGprofile Shader::_defaultFragmentProfile = CG_PROFILE_FP40; |
---|
| 22 | CGcontext Shader::_cgContext = NULL; |
---|
[580] | 23 | |
---|
[4904] | 24 | void Shader::init() |
---|
[580] | 25 | { |
---|
[2870] | 26 | _cgContext = cgCreateContext(); |
---|
[580] | 27 | } |
---|
| 28 | |
---|
[4904] | 29 | void Shader::exit() |
---|
[2870] | 30 | { |
---|
| 31 | setErrorCallback(NULL); |
---|
| 32 | printErrorInfo(); |
---|
| 33 | if (_cgContext != NULL) { |
---|
[2911] | 34 | TRACE("Before DestroyContext"); |
---|
[2870] | 35 | cgDestroyContext(_cgContext); |
---|
[2911] | 36 | TRACE("After DestroyContext"); |
---|
[2870] | 37 | _cgContext = NULL; |
---|
| 38 | } |
---|
| 39 | } |
---|
| 40 | |
---|
[3612] | 41 | bool Shader::printErrorInfo() |
---|
[2870] | 42 | { |
---|
| 43 | CGerror lastError = cgGetError(); |
---|
| 44 | |
---|
| 45 | if (lastError) { |
---|
[3452] | 46 | TRACE("Cg Error: %s", cgGetErrorString(lastError)); |
---|
[2870] | 47 | if (getCgContext()) |
---|
[3452] | 48 | TRACE("%s", cgGetLastListing(getCgContext())); |
---|
[2870] | 49 | return false; |
---|
| 50 | } |
---|
| 51 | return true; |
---|
| 52 | } |
---|
| 53 | |
---|
| 54 | CGprogram |
---|
[3612] | 55 | Shader::loadCgSourceProgram(CGcontext context, const char *fileName, |
---|
| 56 | CGprofile profile, const char *entryPoint) |
---|
[2911] | 57 | { |
---|
[3463] | 58 | std::string path = FilePath::getInstance()->getPath(fileName); |
---|
[2972] | 59 | if (path.empty()) { |
---|
[3452] | 60 | ERROR("can't find program \"%s\"", fileName); |
---|
[2870] | 61 | } |
---|
[3452] | 62 | TRACE("cg program compiling: %s", path.c_str()); |
---|
[2870] | 63 | CGprogram program; |
---|
[2972] | 64 | program = cgCreateProgramFromFile(context, CG_SOURCE, path.c_str(), profile, |
---|
[2870] | 65 | entryPoint, NULL); |
---|
| 66 | cgGLLoadProgram(program); |
---|
| 67 | CGerror LastError = cgGetError(); |
---|
| 68 | if (LastError) { |
---|
[3452] | 69 | ERROR("Error message: %s", cgGetLastListing(context)); |
---|
[2870] | 70 | } |
---|
[3452] | 71 | TRACE("successfully compiled program: %s", path.c_str()); |
---|
[2870] | 72 | return program; |
---|
| 73 | } |
---|
| 74 | |
---|
[3612] | 75 | Shader::Shader(): |
---|
[2911] | 76 | _vertexProfile(_defaultVertexProfile), |
---|
| 77 | _fragmentProfile(_defaultFragmentProfile), |
---|
[2870] | 78 | _cgVP(NULL), |
---|
| 79 | _cgFP(NULL) |
---|
[580] | 80 | { |
---|
| 81 | } |
---|
| 82 | |
---|
[3612] | 83 | Shader::~Shader() |
---|
[580] | 84 | { |
---|
[3612] | 85 | TRACE("Enter"); |
---|
[2911] | 86 | if (_cgContext == NULL) { |
---|
[2954] | 87 | TRACE("Lost Cg context: vp: %s, fp: %s", _vpFile.c_str(), _fpFile.c_str()); |
---|
[2911] | 88 | } else { |
---|
| 89 | resetPrograms(); |
---|
| 90 | } |
---|
[580] | 91 | } |
---|
| 92 | |
---|
[4904] | 93 | void Shader::loadVertexProgram(const char *fileName) |
---|
[776] | 94 | { |
---|
[2911] | 95 | if (_cgVP != NULL) { |
---|
| 96 | cgDestroyProgram(_cgVP); |
---|
| 97 | } |
---|
| 98 | _cgVP = loadCgSourceProgram(_cgContext, fileName, |
---|
[4904] | 99 | _vertexProfile, "main"); |
---|
[2954] | 100 | _vpFile = fileName; |
---|
[776] | 101 | } |
---|
| 102 | |
---|
[4904] | 103 | void Shader::loadFragmentProgram(const char *fileName) |
---|
[776] | 104 | { |
---|
[2911] | 105 | if (_cgFP != NULL) { |
---|
| 106 | cgDestroyProgram(_cgFP); |
---|
| 107 | } |
---|
| 108 | _cgFP = loadCgSourceProgram(_cgContext, fileName, |
---|
[4904] | 109 | _fragmentProfile, "main"); |
---|
[2954] | 110 | _fpFile = fileName; |
---|
[776] | 111 | } |
---|
| 112 | |
---|
[3612] | 113 | void Shader::resetPrograms() |
---|
[776] | 114 | { |
---|
[2870] | 115 | if (_cgVP != NULL) { |
---|
[3452] | 116 | TRACE("Destroying vertex program: %s", _vpFile.c_str()); |
---|
[776] | 117 | cgDestroyProgram(_cgVP); |
---|
| 118 | } |
---|
| 119 | |
---|
[2870] | 120 | if (_cgFP != NULL) { |
---|
[3452] | 121 | TRACE("Destroying fragment program: %s", _fpFile.c_str()); |
---|
[776] | 122 | cgDestroyProgram(_cgFP); |
---|
| 123 | } |
---|
| 124 | } |
---|
[851] | 125 | |
---|
[4904] | 126 | void Shader::setErrorCallback(ShaderCallbackFunction callback) |
---|
[851] | 127 | { |
---|
[3612] | 128 | TRACE("Shader setting error callback to: %p", callback); |
---|
[851] | 129 | cgSetErrorCallback(callback); |
---|
| 130 | } |
---|