source: nanovis/trunk/Shader.cpp @ 4887

Last change on this file since 4887 was 3875, checked in by ldelgass, 11 years ago

Add config.h option USE_ARB_PROGRAMS, which will use ARB_vertex/fragment_program
extensions as the Cg compile target instead of NV_vertex_program3 and
NV_fragment_program2. Note that glyph texture style rendering in flows will not
work if this define is set (however, the default style is line arrows which will
work).

  • Property svn:eol-style set to native
File size: 3.6 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (c) 2004-2013  HUBzero Foundation, LLC
4 *
5 */
6#include <stdio.h>
7
8#include <GL/glew.h>
9#include <Cg/cg.h>
10#include <Cg/cgGL.h>
11
12#include <util/FilePath.h>
13
14#include "config.h"
15#include "Shader.h"
16#include "Trace.h"
17
18using namespace nv;
19using namespace nv::util;
20
21/**
22 * These correspond to NV_vertex_program3 and NV_fragment_program2:
23 * CG_PROFILE_VP40
24 * CG_PROFILE_FP40
25 *
26 * These correspond to ARB_vertex_program and ARB_fragment_program:
27 * CG_PROFILE_ARBVP1
28 * CG_PROFILE_ARBFP1
29 *
30 * Generic GLSL targets:
31 * CG_PROFILE_GLSLV
32 * CG_PROFILE_GLSLF
33 */
34#ifdef USE_ARB_PROGRAMS
35CGprofile Shader::_defaultVertexProfile = CG_PROFILE_ARBVP1;
36CGprofile Shader::_defaultFragmentProfile = CG_PROFILE_ARBFP1;
37#else
38CGprofile Shader::_defaultVertexProfile = CG_PROFILE_VP40;
39CGprofile Shader::_defaultFragmentProfile = CG_PROFILE_FP40;
40#endif
41CGcontext Shader::_cgContext = NULL;
42
43void Shader::init()
44{
45    _cgContext = cgCreateContext();
46}
47
48void Shader::exit()
49{
50    setErrorCallback(NULL);
51    printErrorInfo();
52    if (_cgContext != NULL) {
53        TRACE("Before DestroyContext");
54        cgDestroyContext(_cgContext);
55        TRACE("After DestroyContext");
56        _cgContext = NULL;
57    }
58}
59
60bool Shader::printErrorInfo()
61{
62    CGerror lastError = cgGetError();
63
64    if (lastError) {
65        TRACE("Cg Error: %s", cgGetErrorString(lastError));
66        if (getCgContext())
67            TRACE("%s", cgGetLastListing(getCgContext()));
68        return false;
69    }
70    return true;
71}
72
73CGprogram
74Shader::loadCgSourceProgram(CGcontext context, const char *fileName,
75                            CGprofile profile, const char *entryPoint)
76{
77    std::string path = FilePath::getInstance()->getPath(fileName);
78    if (path.empty()) {
79        ERROR("can't find program \"%s\"", fileName);
80    }
81    TRACE("cg program compiling: %s", path.c_str());
82    CGprogram program;
83    program = cgCreateProgramFromFile(context, CG_SOURCE, path.c_str(), profile,
84                                      entryPoint, NULL);
85    cgGLLoadProgram(program);
86    CGerror LastError = cgGetError();
87    if (LastError) {
88        ERROR("Error message: %s", cgGetLastListing(context));
89    }
90    TRACE("successfully compiled program: %s", path.c_str());
91    return program;
92}
93
94Shader::Shader():
95    _vertexProfile(_defaultVertexProfile),
96    _fragmentProfile(_defaultFragmentProfile),
97    _cgVP(NULL),
98    _cgFP(NULL)
99{
100}
101
102Shader::~Shader()
103{
104    TRACE("Enter");
105    if (_cgContext == NULL) {
106        TRACE("Lost Cg context: vp: %s, fp: %s", _vpFile.c_str(), _fpFile.c_str());
107    } else {
108        resetPrograms();
109    }
110}
111
112void Shader::loadVertexProgram(const char *fileName)
113{
114    if (_cgVP != NULL) {
115        cgDestroyProgram(_cgVP);
116    }
117    _cgVP = loadCgSourceProgram(_cgContext, fileName,
118                                _vertexProfile, "main");
119    _vpFile = fileName;
120}
121
122void Shader::loadFragmentProgram(const char *fileName)
123{
124    if (_cgFP != NULL) {
125        cgDestroyProgram(_cgFP);
126    }
127    _cgFP = loadCgSourceProgram(_cgContext, fileName,
128                                _fragmentProfile, "main");
129    _fpFile = fileName;
130}
131
132void Shader::resetPrograms()
133{
134    if (_cgVP != NULL) {
135        TRACE("Destroying vertex program: %s", _vpFile.c_str());
136        cgDestroyProgram(_cgVP);
137    }
138
139    if (_cgFP != NULL) {
140        TRACE("Destroying fragment program: %s", _fpFile.c_str());
141        cgDestroyProgram(_cgFP);
142    }
143}
144
145void Shader::setErrorCallback(ShaderCallbackFunction callback)
146{
147    TRACE("Shader setting error callback to: %p", callback);
148    cgSetErrorCallback(callback);
149}
Note: See TracBrowser for help on using the repository browser.