Commit c7897734 authored by Eric Bruneton's avatar Eric Bruneton
Browse files

added support for binary programs


git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/ork/trunk@6 28599a00-4e59-401b-b2d8-d34d4661a6c9
parent 463273b8
......@@ -340,9 +340,9 @@ a ork::Texture object is no longer referenced it is deleted,
which deletes the corresponding OpenGL texture in GPU memory).
The rendering API fully covers the OpenGL 3.3 core profile, and
partially covers the OpenGL 4.0 and 4.1 core profile APIs (tesselation
shaders are supported, but uniform subroutines, binary shaders and
programs, pipeline objects, separable shaders, and multiple viewports
partially covers the OpenGL 4.0 and 4.1 core profile APIs (tessellation
shaders and binary programs are supported, but uniform subroutines,
pipeline objects, separable shaders, and multiple viewports
are currently not supported).
\subsection sec_meshes Meshes
......
......@@ -59,6 +59,21 @@ Program::Program(ptr<Module> module) : Object("Program")
init(modules);
}
Program::Program(GLenum format, GLsizei length, unsigned char *binary) : Object("Program")
{
init(format, length, binary);
}
void Program::init(GLenum format, GLsizei length, unsigned char *binary)
{
programId = glCreateProgram();
assert(programId > 0);
glProgramBinary(programId, format, binary, length);
initUniforms();
}
void Program::init(const vector< ptr<Module> > &modules)
{
this->modules = modules;
......@@ -117,8 +132,14 @@ void Program::init(const vector< ptr<Module> > &modules)
}
// link everything together
GLint linked;
glLinkProgram(programId);
initUniforms();
}
void Program::initUniforms()
{
GLint linked;
glGetProgramiv(programId, GL_LINK_STATUS, &linked);
if (linked == GL_FALSE) {
// if a link error occured ...
......@@ -462,6 +483,7 @@ void Program::init(const vector< ptr<Module> > &modules)
}
// sets the initial values of the uniforms
vector< ptr<Module> >::iterator i;
for (i = this->modules.begin(); i != this->modules.end(); ++i) {
ptr<Module> module = *i;
map<string, ptr<Value> >::iterator j = module->initialValues.begin();
......@@ -544,6 +566,15 @@ ptr<UniformBlock> Program::getUniformBlock(const string &name)
return i->second;
}
unsigned char *Program::getBinary(GLsizei &length, GLenum &format)
{
GLsizei len = 0;
glGetProgramiv(programId, GL_PROGRAM_BINARY_LENGTH, &len);
unsigned char *binary = new unsigned char[len];
glGetProgramBinary(programId, len, &length, &format, binary);
return binary;
}
void Program::swap(ptr<Program> p)
{
updateTextureUsers(false);
......@@ -799,6 +830,17 @@ public:
e = e == NULL ? desc->descriptor : e;
vector< ptr<Module> > modules;
checkParameters(desc, e, "name,");
if (desc->getData() != NULL) {
try {
init(*((int*) desc->getData()), desc->getSize() - 4, desc->getData() + 4);
desc->clearData();
} catch (...) {
desc->clearData();
}
return;
}
const TiXmlNode *n = e->FirstChild();
while (n != NULL) {
const TiXmlElement *f = n->ToElement();
......
......@@ -58,6 +58,15 @@ public:
*/
Program(ptr<Module> module);
/**
* Creates a new program from a compiled representation.
*
* @param format the format of the compiled reprensentation.
* @param length the length of the 'binary' array.
* @param binary the compiled program code.
*/
Program(GLenum format, GLsizei length, unsigned char *binary);
/**
* Deletes this program.
*/
......@@ -447,6 +456,15 @@ public:
*/
ptr<UniformBlock> getUniformBlock(const string &name);
/**
* Returns a compiled version of this program.
*
* @param[out] length the length of the returned array.
* @param[out] format the format of the returned array.
* @return a compiled version of this program.
*/
unsigned char *getBinary(GLsizei &length, GLenum &format);
protected:
/**
* The modules of this program.
......@@ -465,6 +483,20 @@ protected:
*/
void init(const vector< ptr<Module> > &modules);
/**
* Initializes this program from a compiled representation.
*
* @param format the format of the compiled reprensentation.
* @param length the length of the 'binary' array.
* @param binary the compiled program code.
*/
void init(GLenum format, GLsizei length, unsigned char *binary);
/**
* Initializes the uniforms of this program.
*/
void initUniforms();
/**
* Swaps this program with the given one.
*/
......
......@@ -33,12 +33,12 @@
#else
#include <sys/stat.h>
#include <sys/fcntl.h>
#endif
#include "ork/resource/ResourceManager.h"
#include "stbi/stb_image.h"
#include "ork/resource/ResourceManager.h"
namespace ork
{
......@@ -544,7 +544,8 @@ ptr<ResourceDescriptor> XMLResourceLoader::loadResource(const string &name)
// resource names of the form "module1;module;module3;..." describe
// program resources that may not be described by any file, either for the
// XML part or for the binary part. The XML part is generated from the
// resource name, and the binary part is NULL
// resource name, and the binary part is NULL (unless a compiled program
// exists for this program)
desc = findDescriptor(name, stamp, false);
if (desc == NULL) {
desc = buildProgramDescriptor(name);
......@@ -772,11 +773,28 @@ unsigned char* XMLResourceLoader::loadData(TiXmlElement *desc, unsigned int &siz
strcmp(desc->Value(), "textureCubeArray") == 0 ||
strcmp(desc->Value(), "textureRectangle") == 0 ||
strcmp(desc->Value(), "module") == 0 ||
strcmp(desc->Value(), "mesh") == 0)
strcmp(desc->Value(), "mesh") == 0 ||
strcmp(desc->Value(), "program") == 0)
{
// we first get the name of the file containing this ASCII or binary part
string str;
const char* file = desc->Attribute("source");
if (file == NULL) {
if (file == NULL && strcmp(desc->Value(), "program") == 0) {
str = string(desc->Attribute("name")) + ".bin";
for (unsigned int i = 0; i < paths.size(); ++i) {
string path = paths[i] + '/' + str;
FILE *f;
fopen(&f, path.c_str(), "rb");
if (f != NULL) {
fclose(f);
file = str.c_str();
break;
}
}
if (file == NULL) {
return NULL;
}
} else if (file == NULL) {
if (strcmp(desc->Value(), "module") != 0 &&
strcmp(desc->Value(), "mesh") != 0 &&
desc->Attribute("width") != NULL)
......@@ -909,8 +927,10 @@ unsigned char* XMLResourceLoader::loadData(TiXmlElement *desc, unsigned int &siz
// via #include directives; we need to load them and to substitute
// their content
return loadShaderData(desc, paths, path, data, size, stamps);
} else if (strcmp(desc->Value(), "mesh") == 0) {
// for a mesh resource, no processing is needed
} else if (strcmp(desc->Value(), "mesh") == 0 ||
strcmp(desc->Value(), "program") == 0)
{
// for a mesh or compiled program resource, no processing is needed
time_t t;
getTimeStamp(path, t);
stamps.push_back(make_pair(path, t));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment