1 // fragmentprog.cpp
2 //
3 // Copyright (C) 2003 Chris Laurel <claurel@shatters.net>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 
10 #include <iostream>
11 #include <fstream>
12 #include <string>
13 #include <celutil/util.h>
14 #include "gl.h"
15 #include "glext.h"
16 #include "fragmentprog.h"
17 
18 using namespace std;
19 
20 
21 unsigned int fp::sphereShadowOnRings = 0;
22 unsigned int fp::eclipseShadow1      = 0;
23 unsigned int fp::eclipseShadow2      = 0;
24 unsigned int fp::texDiffuse          = 0;
25 unsigned int fp::texDiffuseBump      = 0;
26 unsigned int fp::texSpecular         = 0;
27 unsigned int fp::texSpecularAlpha    = 0;
28 
29 
30 class FragmentProcessorNV : public FragmentProcessor
31 {
32  public:
33     FragmentProcessorNV();
34     virtual ~FragmentProcessorNV();
35 
36     virtual void enable();
37     virtual void disable();
38     virtual void use(unsigned int);
39     virtual void parameter(fp::Parameter, float, float, float, float);
40     virtual void parameter(fp::Parameter, const float*);
41 };
42 
43 class FragmentProcessorARB : public FragmentProcessor
44 {
45  public:
46     FragmentProcessorARB();
47     virtual ~FragmentProcessorARB();
48 
49     virtual void enable();
50     virtual void disable();
51     virtual void use(unsigned int);
52     virtual void parameter(fp::Parameter, float, float, float, float);
53     virtual void parameter(fp::Parameter, const float*);
54 };
55 
56 
57 
ReadTextFromFile(const string & filename)58 static string* ReadTextFromFile(const string& filename)
59 {
60     ifstream textFile(filename.c_str(), ios::in);
61     if (!textFile.good())
62         return NULL;
63 
64     string* s = new string();
65 
66     char c;
67     while (textFile.get(c))
68         *s += c;
69 
70     return s;
71 }
72 
73 #if 0
74 static int findLineNumber(const string& s, unsigned int index)
75 {
76     if (index >= s.length())
77         return -1;
78 
79     int lineno = 1;
80     for (unsigned int i = 0; i < index; i++)
81     {
82         if (s[i] == '\n')
83             lineno++;
84     }
85 
86     return lineno;
87 }
88 #endif
89 
90 
LoadNvFragmentProgram(const string & filename,unsigned int & id)91 static bool LoadNvFragmentProgram(const string& filename, unsigned int& id)
92 {
93     cout << _("Loading NV fragment program: ") << filename << '\n';
94 
95     string* source = ReadTextFromFile(filename);
96     if (source == NULL)
97     {
98         cout << _("Error loading NV fragment program: ") << filename << '\n';
99         return false;
100     }
101 
102     glx::glGenProgramsNV(1, (GLuint*) &id);
103     glx::glLoadProgramNV(GL_FRAGMENT_PROGRAM_NV,
104                          id,
105                          source->length(),
106                          reinterpret_cast<const GLubyte*>(source->c_str()));
107 
108     delete source;
109 
110     GLenum err = glGetError();
111     if (err != GL_NO_ERROR)
112     {
113         GLint errPos = 0;
114         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errPos);
115         cout << _("Error in fragment program ") << filename << ' ' <<
116             glGetString(GL_PROGRAM_ERROR_STRING_NV) << '\n';
117         return false;
118     }
119 
120     return true;
121 }
122 
123 
initNV()124 FragmentProcessor* fp::initNV()
125 {
126     cout << _("Initializing NV fragment programs . . .\n");
127     if (!LoadNvFragmentProgram("shaders/shadow_on_rings_nv.fp", sphereShadowOnRings))
128         return NULL;
129     if (!LoadNvFragmentProgram("shaders/eclipse1_nv.fp", eclipseShadow1))
130         return NULL;
131     if (!LoadNvFragmentProgram("shaders/eclipse2_nv.fp", eclipseShadow2))
132         return NULL;
133     if (!LoadNvFragmentProgram("shaders/diffuse_nv.fp", texDiffuse))
134         return NULL;
135     if (!LoadNvFragmentProgram("shaders/bumpdiffuse_nv.fp", texDiffuseBump))
136         return NULL;
137     if (!LoadNvFragmentProgram("shaders/texphong_nv.fp", texSpecular))
138         return NULL;
139     if (!LoadNvFragmentProgram("shaders/texphong_alpha_nv.fp", texSpecularAlpha))
140         return NULL;
141 
142     cout << _("All NV fragment programs loaded successfully.\n");
143 
144     return new FragmentProcessorNV();
145 }
146 
147 
initARB()148 FragmentProcessor* fp::initARB()
149 {
150     cout << _("Initializing ARB fragment programs . . .\n");
151 
152     return new FragmentProcessorARB();
153 }
154 
155 
FragmentProcessor()156 FragmentProcessor::FragmentProcessor()
157 {
158 }
159 
~FragmentProcessor()160 FragmentProcessor::~FragmentProcessor()
161 {
162 }
163 
parameter(fp::Parameter param,const Vec3f & v)164 void FragmentProcessor::parameter(fp::Parameter param, const Vec3f& v)
165 {
166     parameter(param, v.x, v.y, v.z, 0.0f);
167 }
168 
parameter(fp::Parameter param,const Point3f & p)169 void FragmentProcessor::parameter(fp::Parameter param, const Point3f& p)
170 {
171     parameter(param, p.x, p.y, p.z, 0.0f);
172 }
173 
parameter(fp::Parameter param,const Color & c)174 void FragmentProcessor::parameter(fp::Parameter param, const Color& c)
175 {
176     parameter(param, c.red(), c.green(), c.blue(), c.alpha());
177 }
178 
179 
180 
181 // FragmentProcessorNV implementation
182 
FragmentProcessorNV()183 FragmentProcessorNV::FragmentProcessorNV()
184 {
185 }
186 
~FragmentProcessorNV()187 FragmentProcessorNV::~FragmentProcessorNV()
188 {
189 }
190 
enable()191 void FragmentProcessorNV::enable()
192 {
193     glEnable(GL_FRAGMENT_PROGRAM_NV);
194 }
195 
disable()196 void FragmentProcessorNV::disable()
197 {
198     glDisable(GL_FRAGMENT_PROGRAM_NV);
199 }
200 
use(unsigned int prog)201 void FragmentProcessorNV::use(unsigned int prog)
202 {
203     glx::glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, prog);
204 }
205 
parameter(fp::Parameter param,float x,float y,float z,float w)206 void FragmentProcessorNV::parameter(fp::Parameter param,
207                                     float x, float y, float z, float w)
208 {
209     glx::glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_NV,
210                                       param, x, y, z, w);
211 }
212 
parameter(fp::Parameter param,const float * fv)213 void FragmentProcessorNV::parameter(fp::Parameter param, const float* fv)
214 {
215     glx::glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, param, fv);
216 }
217 
218 
219 // FragmentProcessorARB implementation
220 
FragmentProcessorARB()221 FragmentProcessorARB::FragmentProcessorARB()
222 {
223 }
224 
~FragmentProcessorARB()225 FragmentProcessorARB::~FragmentProcessorARB()
226 {
227 }
228 
enable()229 void FragmentProcessorARB::enable()
230 {
231     //glEnable(GL_FRAGMENT_PROGRAM_ARB);
232 }
233 
disable()234 void FragmentProcessorARB::disable()
235 {
236     //glDisable(GL_FRAGMENT_PROGRAM_ARB);
237 }
238 
use(unsigned int)239 void FragmentProcessorARB::use(unsigned int /*prog*/)
240 {
241     //glx::glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog);
242 }
243 
parameter(fp::Parameter,float,float,float,float)244 void FragmentProcessorARB::parameter(fp::Parameter /*param*/,
245                                      float /*x*/, float /*y*/,
246                                      float /*z*/, float /*w*/)
247 {
248     //glx::glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, param, x, y, z, w);
249 }
250 
parameter(fp::Parameter,const float *)251 void FragmentProcessorARB::parameter(fp::Parameter /*param*/, const float* /*fv*/)
252 {
253     //glx::glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, param, fv);
254 }
255