celestia/src/celengine/fragmentprog.cpp

230 lines
5.9 KiB
C++

// fragmentprog.cpp
//
// Copyright (C) 2003 Chris Laurel <claurel@shatters.net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#include <iostream>
#include <fstream>
#include <string>
#include <celutil/util.h>
#include <GL/glew.h>
#include "fragmentprog.h"
using namespace std;
unsigned int fp::sphereShadowOnRings = 0;
unsigned int fp::eclipseShadow1 = 0;
unsigned int fp::eclipseShadow2 = 0;
unsigned int fp::texDiffuse = 0;
unsigned int fp::texDiffuseBump = 0;
unsigned int fp::texSpecular = 0;
unsigned int fp::texSpecularAlpha = 0;
class FragmentProcessorNV : public FragmentProcessor
{
public:
FragmentProcessorNV() = default;
~FragmentProcessorNV() override = default;
void enable() override;
void disable() override;
void use(unsigned int /*prog*/) override;
void parameter(fp::Parameter /*param*/, float /*x*/, float /*y*/, float /*z*/, float /*w*/) override;
void parameter(fp::Parameter /*param*/, const float* /*fv*/) override;
};
class FragmentProcessorARB : public FragmentProcessor
{
public:
FragmentProcessorARB() = default;
~FragmentProcessorARB() override = default;
void enable() override;
void disable() override;
void use(unsigned int /*unused*/) override;
void parameter(fp::Parameter /*unused*/, float /*unused*/, float /*unused*/, float /*unused*/, float /*unused*/) override;
void parameter(fp::Parameter /*unused*/, const float* /*unused*/) override;
};
static string* ReadTextFromFile(const string& filename)
{
ifstream textFile(filename, ios::in);
if (!textFile.good())
return nullptr;
auto* s = new string();
char c;
while (textFile.get(c))
*s += c;
return s;
}
#if 0
static int findLineNumber(const string& s, unsigned int index)
{
if (index >= s.length())
return -1;
int lineno = 1;
for (unsigned int i = 0; i < index; i++)
{
if (s[i] == '\n')
lineno++;
}
return lineno;
}
#endif
static bool LoadNvFragmentProgram(const string& filename, unsigned int& id)
{
cout << _("Loading NV fragment program: ") << filename << '\n';
string* source = ReadTextFromFile(filename);
if (source == nullptr)
{
cout << _("Error loading NV fragment program: ") << filename << '\n';
return false;
}
glGenProgramsNV(1, (GLuint*) &id);
glLoadProgramNV(GL_FRAGMENT_PROGRAM_NV,
id,
source->length(),
reinterpret_cast<const GLubyte*>(source->c_str()));
delete source;
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
GLint errPos = 0;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errPos);
cout << _("Error in fragment program ") << filename << ' ' <<
glGetString(GL_PROGRAM_ERROR_STRING_NV) << '\n';
return false;
}
return true;
}
FragmentProcessor* fp::initNV()
{
cout << _("Initializing NV fragment programs . . .\n");
if (!LoadNvFragmentProgram("shaders/shadow_on_rings_nv.fp", sphereShadowOnRings))
return nullptr;
if (!LoadNvFragmentProgram("shaders/eclipse1_nv.fp", eclipseShadow1))
return nullptr;
if (!LoadNvFragmentProgram("shaders/eclipse2_nv.fp", eclipseShadow2))
return nullptr;
if (!LoadNvFragmentProgram("shaders/diffuse_nv.fp", texDiffuse))
return nullptr;
if (!LoadNvFragmentProgram("shaders/bumpdiffuse_nv.fp", texDiffuseBump))
return nullptr;
if (!LoadNvFragmentProgram("shaders/texphong_nv.fp", texSpecular))
return nullptr;
if (!LoadNvFragmentProgram("shaders/texphong_alpha_nv.fp", texSpecularAlpha))
return nullptr;
cout << _("All NV fragment programs loaded successfully.\n");
return new FragmentProcessorNV();
}
FragmentProcessor* fp::initARB()
{
cout << _("Initializing ARB fragment programs . . .\n");
return new FragmentProcessorARB();
}
void FragmentProcessor::parameter(fp::Parameter param, const Eigen::Vector3f& v)
{
parameter(param, v.x(), v.y(), v.z(), 0.0f);
}
void FragmentProcessor::parameter(fp::Parameter param, const Eigen::Vector4f& v)
{
parameter(param, v.x(), v.y(), v.z(), v.w());
}
void FragmentProcessor::parameter(fp::Parameter param, const Color& c)
{
parameter(param, c.red(), c.green(), c.blue(), c.alpha());
}
// FragmentProcessorNV implementation
void FragmentProcessorNV::enable()
{
glEnable(GL_FRAGMENT_PROGRAM_NV);
}
void FragmentProcessorNV::disable()
{
glDisable(GL_FRAGMENT_PROGRAM_NV);
}
void FragmentProcessorNV::use(unsigned int prog)
{
glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, prog);
}
void FragmentProcessorNV::parameter(fp::Parameter param,
float x, float y, float z, float w)
{
glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_NV,
param, x, y, z, w);
}
void FragmentProcessorNV::parameter(fp::Parameter param, const float* fv)
{
glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, param, fv);
}
// FragmentProcessorARB implementation
void FragmentProcessorARB::enable()
{
//glEnable(GL_FRAGMENT_PROGRAM_ARB);
}
void FragmentProcessorARB::disable()
{
//glDisable(GL_FRAGMENT_PROGRAM_ARB);
}
void FragmentProcessorARB::use(unsigned int /*prog*/)
{
//glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog);
}
void FragmentProcessorARB::parameter(fp::Parameter /*param*/,
float /*x*/, float /*y*/,
float /*z*/, float /*w*/)
{
//glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, param, x, y, z, w);
}
void FragmentProcessorARB::parameter(fp::Parameter /*param*/, const float* /*fv*/)
{
//glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, param, fv);
}