mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-10-05 13:51:04 +00:00
Merge branch 'experimental'
Conflicts: BBGE/Shader.cpp
This commit is contained in:
commit
93abd03c27
67 changed files with 2061 additions and 1000 deletions
|
@ -32,9 +32,9 @@ Effect::Effect()
|
|||
AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
|
||||
{
|
||||
active = false;
|
||||
activeShader = AS_NONE;
|
||||
numEffects = 0;
|
||||
bRenderGridPoints = true;
|
||||
shaderPipeline.resize(10, 0);
|
||||
|
||||
screenWidth = core->getWindowWidth();
|
||||
screenHeight = core->getWindowHeight();
|
||||
|
@ -43,46 +43,11 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
|
|||
this->yDivs = 0;
|
||||
|
||||
drawGrid = 0;
|
||||
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
|
||||
|
||||
this->xDivs = xDivs;
|
||||
this->yDivs = yDivs;
|
||||
//cameraPointer = nCameraPointer;
|
||||
|
||||
//Asssuming the resolutions values are > 256 and < 2048
|
||||
//Set the texture heights and widths
|
||||
if (core->frameBuffer.isInited())
|
||||
{
|
||||
textureWidth = core->frameBuffer.getWidth();
|
||||
textureHeight = core->frameBuffer.getHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (screenWidth <= 512)
|
||||
textureWidth = 512;
|
||||
else if (screenWidth <= 1024)
|
||||
textureWidth = 1024;
|
||||
else
|
||||
textureWidth = 2048;
|
||||
if (screenHeight <= 512)
|
||||
textureHeight = 512;
|
||||
else if (screenHeight <= 1024)
|
||||
textureHeight = 1024;
|
||||
else
|
||||
textureHeight = 2048;
|
||||
}
|
||||
|
||||
//create our texture
|
||||
glGenTextures(1,&texture);
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
#endif
|
||||
//BuildMip();
|
||||
reloadDevice();
|
||||
|
||||
if (xDivs != 0 && yDivs != 0)
|
||||
{
|
||||
|
@ -98,14 +63,9 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
|
|||
|
||||
void AfterEffectManager::loadShaders()
|
||||
{
|
||||
/*
|
||||
blurShader.load("data/shaders/stan.vert", "data/shaders/blur.frag");
|
||||
bwShader.load("data/shaders/stan.vert", "data/shaders/bw.frag");
|
||||
washoutShader.load("data/shaders/stan.vert", "data/shaders/washout.frag");
|
||||
//motionBlurShader.load("data/shaders/stan.vert", "data/shaders/hoblur.frag");
|
||||
motionBlurShader.load("data/shaders/stan.vert", "data/shaders/blur.frag");
|
||||
glowShader.load("data/shaders/stan.vert", "data/shaders/glow.frag");
|
||||
*/
|
||||
deleteShaders();
|
||||
|
||||
// ...Load shaders here...
|
||||
}
|
||||
|
||||
AfterEffectManager::~AfterEffectManager()
|
||||
|
@ -120,6 +80,7 @@ AfterEffectManager::~AfterEffectManager()
|
|||
delete[] drawGrid;
|
||||
}
|
||||
deleteEffects();
|
||||
deleteShaders();
|
||||
}
|
||||
|
||||
void AfterEffectManager::deleteEffects()
|
||||
|
@ -137,6 +98,21 @@ void AfterEffectManager::deleteEffects()
|
|||
openSpots.pop();
|
||||
}
|
||||
|
||||
void AfterEffectManager::deleteShaders()
|
||||
{
|
||||
for(size_t i = 0; i < shaderPipeline.size(); ++i)
|
||||
shaderPipeline[i] = 0;
|
||||
|
||||
for(size_t i = 0; i < loadedShaders.size(); ++i)
|
||||
{
|
||||
if(loadedShaders[i])
|
||||
{
|
||||
delete loadedShaders[i];
|
||||
loadedShaders[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AfterEffectManager::clear()
|
||||
{
|
||||
deleteEffects();
|
||||
|
@ -190,49 +166,20 @@ void AfterEffectManager::destroyEffect(int id)
|
|||
openSpots.push(id);
|
||||
}
|
||||
|
||||
void AfterEffectManager::capture()
|
||||
{
|
||||
/*
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenWidth, screenHeight);
|
||||
#endif
|
||||
*/
|
||||
if (core->frameBuffer.isInited())
|
||||
{
|
||||
core->frameBuffer.endCapture();
|
||||
//core->enable2D(core->pixelScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenWidth, screenHeight);
|
||||
#endif
|
||||
}
|
||||
//glDisable(GL_TEXTURE_2D);
|
||||
|
||||
}
|
||||
void AfterEffectManager::render()
|
||||
{
|
||||
assert(core->frameBuffer.isInited());
|
||||
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
glPushMatrix();
|
||||
//glDisable(GL_BLEND);
|
||||
//glEnable(GL_BLEND);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
capture();
|
||||
core->frameBuffer.endCapture();
|
||||
glTranslatef(core->cameraPos.x, core->cameraPos.y, 0);
|
||||
glScalef(core->invGlobalScale, core->invGlobalScale,0);
|
||||
/*
|
||||
static float angle;
|
||||
angle += 0.03f;
|
||||
*/
|
||||
//glRotatef(angle, 0, 0, 1);
|
||||
//glColor4f(1,1,1,0.75);
|
||||
|
||||
glColor4f(1,1,1,1);
|
||||
renderGrid();
|
||||
//renderGridPoints();
|
||||
|
@ -240,86 +187,49 @@ void AfterEffectManager::render()
|
|||
#endif
|
||||
}
|
||||
|
||||
void AfterEffectManager::setActiveShader(ActiveShader as)
|
||||
{
|
||||
activeShader = as;
|
||||
}
|
||||
|
||||
void AfterEffectManager::renderGrid()
|
||||
{
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
//glBindTexture(GL_TEXTURE_2D, texture);
|
||||
if (core->frameBuffer.isInited())
|
||||
core->frameBuffer.bindTexture();
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
|
||||
|
||||
//bwShader.bind();
|
||||
Shader *activeShader=0;
|
||||
if (core->frameBuffer.isInited())
|
||||
int firstShader = -1;
|
||||
int lastShader = -1;
|
||||
Shader *activeShader = 0;
|
||||
for (size_t i = 0; i < shaderPipeline.size(); ++i)
|
||||
{
|
||||
switch(this->activeShader)
|
||||
if(shaderPipeline[i])
|
||||
{
|
||||
case AS_BLUR:
|
||||
activeShader = &blurShader;
|
||||
break;
|
||||
case AS_BW:
|
||||
activeShader = &bwShader;
|
||||
break;
|
||||
case AS_WASHOUT:
|
||||
activeShader = &washoutShader;
|
||||
break;
|
||||
case AS_MOTIONBLUR:
|
||||
activeShader = &motionBlurShader;
|
||||
break;
|
||||
case AS_GLOW:
|
||||
activeShader = &glowShader;
|
||||
break;
|
||||
if(firstShader < 0)
|
||||
{
|
||||
firstShader = i;
|
||||
activeShader = shaderPipeline[i];
|
||||
}
|
||||
lastShader = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeShader)
|
||||
activeShader->bind();
|
||||
|
||||
screenWidth = core->getWindowWidth();
|
||||
screenHeight = core->getWindowHeight();
|
||||
|
||||
/*
|
||||
float percentX, percentY;
|
||||
percentX = 1;
|
||||
percentY = 0.5;
|
||||
*/
|
||||
|
||||
/*
|
||||
percentX = (float)textureWidth/(float)screenWidth;
|
||||
percentY = (float)textureHeight/(float)screenHeight;
|
||||
*/
|
||||
|
||||
float percentX, percentY;
|
||||
percentX = (float)screenWidth/(float)textureWidth;
|
||||
percentY = (float)screenHeight/(float)textureHeight;
|
||||
|
||||
|
||||
/*
|
||||
if (screenWidth <= textureWidth)
|
||||
{
|
||||
percentX = (float)screenWidth/(float)textureWidth;
|
||||
percentY = (float)screenHeight/(float)textureHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
percentY = 10;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
int vw = core->getVirtualWidth();
|
||||
int vh = core->getVirtualHeight();
|
||||
int offx = -core->getVirtualOffX();
|
||||
int offy = -core->getVirtualOffY();
|
||||
|
||||
core->frameBuffer.bindTexture();
|
||||
|
||||
if(activeShader)
|
||||
{
|
||||
activeShader->bind();
|
||||
activeShader->setInt("tex", 0);
|
||||
|
||||
if(firstShader != lastShader)
|
||||
backupBuffer.startCapture();
|
||||
}
|
||||
|
||||
//float div = xDivs;
|
||||
for (int i = 0; i < (xDivs-1); i++)
|
||||
{
|
||||
|
@ -347,6 +257,56 @@ void AfterEffectManager::renderGrid()
|
|||
}
|
||||
}
|
||||
|
||||
if (activeShader)
|
||||
activeShader->unbind();
|
||||
|
||||
float width2 = float(vw)/2;
|
||||
float height2 = float(vh)/2;
|
||||
|
||||
|
||||
if(firstShader != lastShader)
|
||||
{
|
||||
// From here on: secondary shader passes.
|
||||
// We just outputted to the backup buffer...
|
||||
FrameBuffer *fbIn = &core->frameBuffer;
|
||||
FrameBuffer *fbOut = &backupBuffer;
|
||||
|
||||
|
||||
for(int i = firstShader + 1; i <= lastShader; ++i)
|
||||
{
|
||||
activeShader = shaderPipeline[i];
|
||||
if(!activeShader)
|
||||
continue;
|
||||
|
||||
// Swap and exchange framebuffers. The old output buffer serves as texture input for the other one
|
||||
fbOut->endCapture();
|
||||
std::swap(fbIn, fbOut);
|
||||
fbIn->bindTexture();
|
||||
|
||||
// If this is the last pass, do not render to a frame buffer again
|
||||
if(i != lastShader)
|
||||
fbOut->startCapture();
|
||||
|
||||
activeShader->bind();
|
||||
activeShader->setInt("tex", 0);
|
||||
|
||||
// note that offx, offy are negative here!
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0.0f, 0.0f);
|
||||
glVertex3f(offx, vh+offy, 0.0f);
|
||||
glTexCoord2d(percentX, 0.0f);
|
||||
glVertex3f( vw+offx, vh+offy, 0.0f);
|
||||
glTexCoord2d(percentX, percentY);
|
||||
glVertex3f( vw+offx, offy, 0.0f);
|
||||
glTexCoord2d(0.0f, percentY);
|
||||
glVertex3f(offx, offy, 0.0f);
|
||||
glEnd();
|
||||
|
||||
activeShader->unbind();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// uncomment to render grid points
|
||||
/*
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
@ -382,9 +342,6 @@ void AfterEffectManager::renderGrid()
|
|||
//glDisable(GL_TEXTURE_2D);
|
||||
RenderObject::lastTextureApplied = 0;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (activeShader)
|
||||
activeShader->unbind();
|
||||
|
||||
//bwShader.unbind();
|
||||
//glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
@ -415,8 +372,8 @@ void AfterEffectManager::renderGridPoints()
|
|||
|
||||
void AfterEffectManager::unloadDevice()
|
||||
{
|
||||
if (texture)
|
||||
glDeleteTextures(1,&texture);
|
||||
backupBuffer.unloadDevice();
|
||||
deleteShaders();
|
||||
}
|
||||
|
||||
void AfterEffectManager::reloadDevice()
|
||||
|
@ -431,22 +388,18 @@ void AfterEffectManager::reloadDevice()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (screenWidth <= 1024)
|
||||
textureWidth = 1024;
|
||||
else
|
||||
textureWidth = 2048;
|
||||
if (screenHeight <= 1024)
|
||||
textureHeight = 1024;
|
||||
else
|
||||
textureHeight = 2048;
|
||||
textureWidth = screenWidth;
|
||||
sizePowerOf2Texture(textureWidth);
|
||||
textureHeight = screenHeight;
|
||||
sizePowerOf2Texture(textureHeight);
|
||||
}
|
||||
|
||||
//create our texture
|
||||
glGenTextures(1,&texture);
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
if(backupBuffer.isInited())
|
||||
backupBuffer.reloadDevice();
|
||||
else
|
||||
backupBuffer.init(-1, -1, true);
|
||||
|
||||
loadShaders();
|
||||
}
|
||||
|
||||
void AfterEffectManager::addEffect(Effect *e)
|
||||
|
@ -598,3 +551,79 @@ void RippleEffect::update(float dt, Vector ** drawGrid, int xDivs, int yDivs)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int AfterEffectManager::loadShaderFile(const char *vert, const char *frag)
|
||||
{
|
||||
Shader *sh = new Shader();
|
||||
sh->load(vert, frag);
|
||||
if(!sh->isLoaded())
|
||||
{
|
||||
delete sh;
|
||||
return 0;
|
||||
}
|
||||
return _insertShader(sh);
|
||||
}
|
||||
|
||||
int AfterEffectManager::loadShaderSrc(const char *vert, const char *frag)
|
||||
{
|
||||
Shader *sh = new Shader();
|
||||
sh->loadSrc(vert, frag);
|
||||
if(!sh->isLoaded())
|
||||
{
|
||||
delete sh;
|
||||
return 0;
|
||||
}
|
||||
return _insertShader(sh);
|
||||
}
|
||||
|
||||
Shader *AfterEffectManager::getShaderPtr(int handle)
|
||||
{
|
||||
size_t idx = handle - 1;
|
||||
return idx < loadedShaders.size() ? loadedShaders[idx] : 0;
|
||||
}
|
||||
|
||||
void AfterEffectManager::setShaderPipelineSize(size_t size)
|
||||
{
|
||||
shaderPipeline.resize(size, 0);
|
||||
}
|
||||
|
||||
bool AfterEffectManager::setShaderPipelinePos(int handle, size_t pos)
|
||||
{
|
||||
if(pos < shaderPipeline.size())
|
||||
{
|
||||
shaderPipeline[pos] = getShaderPtr(handle);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns handle (= index + 1)
|
||||
int AfterEffectManager::_insertShader(Shader *sh)
|
||||
{
|
||||
for(size_t i = 0; i < loadedShaders.size(); ++i)
|
||||
{
|
||||
if(!loadedShaders[i])
|
||||
{
|
||||
loadedShaders[i] = sh;
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
loadedShaders.push_back(sh);
|
||||
return loadedShaders.size();
|
||||
}
|
||||
|
||||
void AfterEffectManager::unloadShader(int handle)
|
||||
{
|
||||
Shader *sh = getShaderPtr(handle);
|
||||
if(!sh)
|
||||
return;
|
||||
|
||||
for(size_t i = 0; i < shaderPipeline.size(); ++i)
|
||||
if(shaderPipeline[i] == sh)
|
||||
shaderPipeline[i] = 0;
|
||||
|
||||
size_t idx = handle - 1;
|
||||
loadedShaders[idx] = 0;
|
||||
delete sh;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,16 +72,6 @@ public:
|
|||
float time;
|
||||
};
|
||||
|
||||
enum ActiveShader
|
||||
{
|
||||
AS_NONE = 0,
|
||||
AS_BLUR ,
|
||||
AS_BW ,
|
||||
AS_WASHOUT ,
|
||||
AS_MOTIONBLUR ,
|
||||
AS_GLOW
|
||||
};
|
||||
|
||||
class AfterEffectManager
|
||||
{
|
||||
public:
|
||||
|
@ -96,12 +86,12 @@ public:
|
|||
|
||||
void resetGrid();
|
||||
|
||||
void capture();
|
||||
void render();
|
||||
void renderGrid();
|
||||
void renderGridPoints();
|
||||
|
||||
void loadShaders();
|
||||
void deleteShaders();
|
||||
|
||||
void unloadDevice();
|
||||
void reloadDevice();
|
||||
|
@ -111,12 +101,6 @@ public:
|
|||
|
||||
bool active;
|
||||
|
||||
void setActiveShader(ActiveShader as);
|
||||
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
GLuint texture;
|
||||
#endif
|
||||
|
||||
bool bRenderGridPoints;
|
||||
|
||||
int numEffects;
|
||||
|
@ -124,11 +108,23 @@ public:
|
|||
int screenWidth, screenHeight;
|
||||
int textureWidth, textureHeight;
|
||||
|
||||
Shader blurShader, bwShader, washoutShader, motionBlurShader, glowShader;
|
||||
Vector ** drawGrid;
|
||||
|
||||
Vector ** drawGrid;
|
||||
// returns handle > 0 on success
|
||||
int loadShaderFile(const char *vert, const char *frag);
|
||||
int loadShaderSrc(const char *vert, const char *frag);
|
||||
Shader *getShaderPtr(int handle);
|
||||
void setShaderPipelineSize(size_t size);
|
||||
bool setShaderPipelinePos(int handle, size_t pos);
|
||||
void unloadShader(int handle);
|
||||
|
||||
protected:
|
||||
int _insertShader(Shader *sh);
|
||||
|
||||
std::vector<Shader*> shaderPipeline; // Shaders are applied in this order. Can contain the same pointer more than once.
|
||||
std::vector<Shader*> loadedShaders;
|
||||
FrameBuffer backupBuffer;
|
||||
|
||||
ActiveShader activeShader;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#define BBGE_BUILD_SDL 1
|
||||
#define BBGE_BUILD_FRAMEBUFFER 1
|
||||
//#define BBGE_BUILD_SHADERS 1
|
||||
#define BBGE_BUILD_SHADERS 1
|
||||
#define BBGE_BUILD_OPENGL 1
|
||||
#define BBGE_BUILD_OPENGL_DYNAMIC 1
|
||||
#define BBGE_BUILD_FMOD_OPENAL_BRIDGE 1
|
||||
|
|
|
@ -291,8 +291,7 @@ bool exists(const std::string &f, bool makeFatal, bool skipVFS)
|
|||
|
||||
if (makeFatal && !e)
|
||||
{
|
||||
errorLog(std::string("Could not open [" + f + "]"));
|
||||
exit(0);
|
||||
exit_error("Could not open [" + f + "]");
|
||||
}
|
||||
|
||||
return e;
|
||||
|
@ -301,7 +300,7 @@ bool exists(const std::string &f, bool makeFatal, bool skipVFS)
|
|||
void drawCircle(float radius, int stepSize)
|
||||
{
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
{
|
||||
|
@ -312,14 +311,14 @@ void drawCircle(float radius, int stepSize)
|
|||
}
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
//glEnable(GL_CULL_FACE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void fatalError(const std::string &message)
|
||||
void exit_error(const std::string &message)
|
||||
{
|
||||
msg(message);
|
||||
exit(0);
|
||||
errorLog(message);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::string parseCommand(const std::string &line, const std::string &command)
|
||||
|
@ -424,8 +423,7 @@ void errorLog(const std::string &s)
|
|||
}
|
||||
else
|
||||
{
|
||||
//msg("Core Not Initialized");
|
||||
//MessageBox(0, s.c_str(), "ErrorLog (Core Not Initalized)", MB_OK);
|
||||
messageBox("Error!", s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,17 +773,18 @@ std::vector<std::string> getFileList(std::string path, std::string type, int par
|
|||
return list;
|
||||
}
|
||||
|
||||
std::string msg(const std::string &message)
|
||||
void messageBox(const std::string& title, const std::string &msg)
|
||||
{
|
||||
core->msg(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
void msgVector(const std::string &name, const Vector &vec)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << name << ": (" << vec.x <<", " << vec.y << ", " << vec.z << ")";
|
||||
msg (os.str());
|
||||
#ifdef BBGE_BUILD_WINDOWS
|
||||
MessageBox (0,msg.c_str(),title.c_str(),MB_OK);
|
||||
#elif defined(BBGE_BUILD_MACOSX)
|
||||
cocoaMessageBox(title, msg);
|
||||
#elif defined(BBGE_BUILD_UNIX)
|
||||
// !!! FIXME: probably don't want the whole GTK+ dependency in here...
|
||||
fprintf(stderr, "%s: %s\n", title.c_str(), msg.c_str());
|
||||
#else
|
||||
#error Please define your platform.
|
||||
#endif
|
||||
}
|
||||
|
||||
Vector getNearestPointOnLine(Vector a, Vector b, Vector c)
|
||||
|
|
|
@ -257,11 +257,9 @@ bool isVectorInRect(const Vector &vec, const Vector &coord1, const Vector &coord
|
|||
|
||||
std::string parseCommand(const std::string &line, const std::string &command);
|
||||
|
||||
std::string msg(const std::string &message);
|
||||
void messageBox(const std::string &title, const std::string& msg);
|
||||
|
||||
void msgVector(const std::string &name, const Vector &vec);
|
||||
|
||||
void fatalError(const std::string &message);
|
||||
void exit_error(const std::string &message);
|
||||
|
||||
unsigned hash(const std::string &string);
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ void BitmapText::onRender()
|
|||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
*/
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
|
||||
//glScalef(1, -1, 0);
|
||||
|
||||
|
@ -374,7 +374,7 @@ void BitmapText::onRender()
|
|||
}
|
||||
}
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
//glEnable(GL_CULL_FACE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -818,7 +818,7 @@ bool Core::getMetaState()
|
|||
|
||||
void Core::errorLog(const std::string &s)
|
||||
{
|
||||
messageBox("Message", s);
|
||||
messageBox("Error!", s);
|
||||
debugLog(s);
|
||||
}
|
||||
|
||||
|
@ -828,16 +828,7 @@ void cocoaMessageBox(const std::string &title, const std::string &msg);
|
|||
|
||||
void Core::messageBox(const std::string &title, const std::string &msg)
|
||||
{
|
||||
#ifdef BBGE_BUILD_WINDOWS
|
||||
MessageBox (0,msg.c_str(),title.c_str(),MB_OK);
|
||||
#elif defined(BBGE_BUILD_MACOSX)
|
||||
cocoaMessageBox(title, msg);
|
||||
#elif defined(BBGE_BUILD_UNIX)
|
||||
// !!! FIXME: probably don't want the whole GTK+ dependency in here...
|
||||
fprintf(stderr, "%s: %s\n", title.c_str(), msg.c_str());
|
||||
#else
|
||||
#error Please define your platform.
|
||||
#endif
|
||||
::messageBox(title, msg);
|
||||
}
|
||||
|
||||
void Core::debugLog(const std::string &s)
|
||||
|
@ -1276,7 +1267,7 @@ void Core::init()
|
|||
|
||||
if((SDL_Init(0))==-1)
|
||||
{
|
||||
exit(0);
|
||||
exit_error("Failed to init SDL");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1849,11 +1840,13 @@ void Core::setSDLGLAttributes()
|
|||
#define GLAPIENTRY
|
||||
#endif
|
||||
|
||||
unsigned int Core::dbg_numRenderCalls = 0;
|
||||
|
||||
#ifdef BBGE_BUILD_OPENGL_DYNAMIC
|
||||
#define GL_FUNC(ret,fn,params,call,rt) \
|
||||
extern "C" { \
|
||||
static ret (GLAPIENTRY *p##fn) params = NULL; \
|
||||
ret GLAPIENTRY fn params { rt p##fn call; } \
|
||||
ret GLAPIENTRY fn params { ++Core::dbg_numRenderCalls; rt p##fn call; } \
|
||||
}
|
||||
#include "OpenGLStubs.h"
|
||||
#undef GL_FUNC
|
||||
|
@ -1917,16 +1910,15 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync
|
|||
{
|
||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
||||
{
|
||||
errorLog(std::string("SDL Error: ") + std::string(SDL_GetError()));
|
||||
exit(0);
|
||||
exit_error(std::string("SDL Error: ") + std::string(SDL_GetError()));
|
||||
}
|
||||
|
||||
#if BBGE_BUILD_OPENGL_DYNAMIC
|
||||
if (SDL_GL_LoadLibrary(NULL) == -1)
|
||||
{
|
||||
errorLog(std::string("SDL_GL_LoadLibrary Error: ") + std::string(SDL_GetError()));
|
||||
std::string err = std::string("SDL_GL_LoadLibrary Error: ") + std::string(SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
exit_error(err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1950,9 +1942,8 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync
|
|||
{
|
||||
std::ostringstream os;
|
||||
os << "Couldn't set resolution [" << width << "x" << height << "]\n" << SDL_GetError();
|
||||
errorLog(os.str());
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
exit_error(os.str());
|
||||
}
|
||||
|
||||
#if BBGE_BUILD_OPENGL_DYNAMIC
|
||||
|
@ -1960,9 +1951,8 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync
|
|||
{
|
||||
std::ostringstream os;
|
||||
os << "Couldn't load OpenGL symbols we need\n";
|
||||
errorLog(os.str());
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
exit_error(os.str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2632,13 +2622,6 @@ void Core::setDockIcon(const std::string &ident)
|
|||
{
|
||||
}
|
||||
|
||||
void Core::msg(const std::string &message)
|
||||
{
|
||||
#ifdef BBGE_BUILD_WINDOWS
|
||||
MessageBox(0, message.c_str(), "Message", MB_OK);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Core::setMousePosition(const Vector &p)
|
||||
{
|
||||
Vector lp = core->mouse.position;
|
||||
|
@ -3015,6 +2998,8 @@ void Core::main(float runTime)
|
|||
|
||||
updateCullData();
|
||||
|
||||
dbg_numRenderCalls = 0;
|
||||
|
||||
if (settings.renderOn)
|
||||
{
|
||||
if (verbose) debugLog("dark layer prerender");
|
||||
|
@ -3857,10 +3842,6 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail)
|
|||
int i = renderObjectLayerOrder[c];
|
||||
if (i == -1) continue;
|
||||
if ((startLayer != -1 && endLayer != -1) && (i < startLayer || i > endLayer)) continue;
|
||||
if (afterEffectManager && afterEffectManager->active && i == afterEffectManagerLayer)
|
||||
{
|
||||
afterEffectManager->render();
|
||||
}
|
||||
|
||||
if (i == postProcessingFx.layer)
|
||||
{
|
||||
|
@ -3890,6 +3871,11 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail)
|
|||
}
|
||||
}
|
||||
|
||||
if (afterEffectManager && afterEffectManager->active && i == afterEffectManagerLayer)
|
||||
{
|
||||
afterEffectManager->render();
|
||||
}
|
||||
|
||||
RenderObjectLayer *r = &renderObjectLayers[i];
|
||||
RenderObject::rlayer = r;
|
||||
if (r->visible)
|
||||
|
@ -4844,14 +4830,13 @@ void Core::setupFileAccess()
|
|||
debugLog("Init VFS...");
|
||||
|
||||
if(!ttvfs::checkCompat())
|
||||
exit(1);
|
||||
exit_error("ttvfs not compatible");
|
||||
|
||||
vfs.AddArchiveLoader(new ttvfs::VFSZipArchiveLoader);
|
||||
|
||||
if(!vfs.LoadFileSysRoot(false))
|
||||
{
|
||||
errorLog("Failed to setup file access");
|
||||
exit(1);
|
||||
exit_error("Failed to setup file access");
|
||||
}
|
||||
|
||||
vfs.Prepare();
|
||||
|
|
|
@ -1175,8 +1175,6 @@ public:
|
|||
void saveSizedScreenshotTGA(const std::string &filename, int sz, int crop34);
|
||||
void saveCenteredScreenshotTGA(const std::string &filename, int sz);
|
||||
|
||||
virtual void msg(const std::string &message);
|
||||
|
||||
bool minimized;
|
||||
std::string getEnqueuedJumpState();
|
||||
int cullRadius;
|
||||
|
@ -1310,6 +1308,7 @@ public:
|
|||
int zgaSave(const char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData);
|
||||
|
||||
volatile int dbg_numThreadDecoders;
|
||||
static unsigned int dbg_numRenderCalls;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ void Emitter::onRender()
|
|||
|
||||
if (data.flipH || (data.copyParentFlip && (pe->isfh() || (pe->getParent() && pe->getParent()->isfh()))))
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
glRotatef(180, 0, 1, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@ Precacher::~Precacher()
|
|||
errorLog ("Precacher shutdown unclean");
|
||||
}
|
||||
|
||||
void Precacher::setBaseDir(const std::string& dir)
|
||||
{
|
||||
basedirOverride = dir;
|
||||
}
|
||||
|
||||
void Precacher::clean()
|
||||
{
|
||||
for (unsigned int i = 0; i < renderObjects.size(); i++)
|
||||
|
@ -88,6 +93,8 @@ void Precacher::precacheTex(const std::string &tex)
|
|||
}
|
||||
if (tex.empty()) return;
|
||||
|
||||
std::string basedir = basedirOverride.empty() ? core->getBaseTextureDirectory() : basedirOverride;
|
||||
|
||||
if (core->debugLogTextures)
|
||||
debugLog("PRECACHING: " + tex);
|
||||
|
||||
|
@ -99,7 +106,7 @@ void Precacher::precacheTex(const std::string &tex)
|
|||
int loc = tex.find('*');
|
||||
std::string path = tex.substr(0, loc);
|
||||
std::string type = tex.substr(loc+1, tex.size());
|
||||
path = core->getBaseTextureDirectory() + path;
|
||||
path = basedir + path;
|
||||
forEachFile(path, type, precacherCallback, (intptr_t)this);
|
||||
return;
|
||||
}
|
||||
|
@ -108,9 +115,9 @@ void Precacher::precacheTex(const std::string &tex)
|
|||
if (loadProgressCallback)
|
||||
loadProgressCallback();
|
||||
std::string t = tex;
|
||||
if (tex.find(core->getBaseTextureDirectory()) != std::string::npos)
|
||||
if (tex.find(basedir) != std::string::npos)
|
||||
{
|
||||
t = tex.substr(core->getBaseTextureDirectory().size(), tex.size());
|
||||
t = tex.substr(basedir.size(), tex.size());
|
||||
}
|
||||
Quad *q = new Quad;
|
||||
q->setTexture(t);
|
||||
|
|
|
@ -32,11 +32,13 @@ public:
|
|||
void precacheList(const std::string &list, void progressCallback() = NULL);
|
||||
void clean();
|
||||
void loadTextureRange(const std::string &file, const std::string &type, int start, int end);
|
||||
void setBaseDir(const std::string& dir);
|
||||
|
||||
std::vector<RenderObject*> renderObjects;
|
||||
private:
|
||||
bool cleaned;
|
||||
void (*loadProgressCallback)();
|
||||
std::string basedirOverride;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -499,7 +499,7 @@ void Quad::onRender()
|
|||
if (!strip.empty())
|
||||
{
|
||||
//glDisable(GL_BLEND);gggg
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
|
||||
const float texBits = 1.0f / (strip.size()-1);
|
||||
|
||||
|
@ -517,7 +517,7 @@ void Quad::onRender()
|
|||
}
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
//glEnable(GL_CULL_FACE);
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
glColor4f(1,0,0,1);
|
||||
glPointSize(64);
|
||||
|
@ -802,6 +802,7 @@ void Quad::onSetTexture()
|
|||
|
||||
PauseQuad::PauseQuad() : Quad(), pauseLevel(0)
|
||||
{
|
||||
addType(SCO_PAUSEQUAD);
|
||||
}
|
||||
|
||||
void PauseQuad::onUpdate(float dt)
|
||||
|
|
|
@ -59,7 +59,7 @@ void QuadTrail::onRender()
|
|||
if (numPoints < 2) return;
|
||||
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
int c = 0;
|
||||
Vector p, diff, dl, dr;
|
||||
Vector lastPoint;
|
||||
|
|
|
@ -629,7 +629,7 @@ void RenderObject::renderCall()
|
|||
glTranslatef(position.x, position.y, position.z);
|
||||
if (isfh())
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
glRotatef(180, 0, 1, 0);
|
||||
}
|
||||
|
||||
|
@ -655,7 +655,7 @@ void RenderObject::renderCall()
|
|||
glTranslatef(pos.x, pos.y, pos.z);
|
||||
if (isfh())
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
glRotatef(180, 0, 1, 0);
|
||||
}
|
||||
glRotatef(rotation.z+rotationOffset.z, 0, 0, 1);
|
||||
|
@ -714,7 +714,7 @@ void RenderObject::renderCall()
|
|||
glRotatef(rotation.z+rotationOffset.z, 0, 0, 1);
|
||||
if (isfh())
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
glRotatef(180, 0, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -105,7 +105,7 @@ void RoundedRect::onRender()
|
|||
//glBindTexture(GL_TEXTURE_2D, 0);
|
||||
int w2 = width/2;
|
||||
int h2 = height/2;
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
float iter = 0.1f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
@ -167,7 +167,7 @@ void RoundedRect::onRender()
|
|||
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
//glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void RoundedRect::show()
|
||||
|
|
|
@ -37,6 +37,8 @@ static const char *scriptObjTypeNames[] =
|
|||
/* (1 << 9) */ "Path/Node",
|
||||
/* (1 <<10) */ "Quad",
|
||||
/* (1 <<11) */ "Text",
|
||||
/* (1 <<12) */ "PauseQuad",
|
||||
/* (1 <<13) */ "Shader",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ enum ScriptObjectType
|
|||
SCO_PATH = 0x0200,
|
||||
SCO_QUAD = 0x0400,
|
||||
SCO_TEXT = 0x0800,
|
||||
SCO_PAUSEQUAD = 0x1000,
|
||||
SCO_SHADER = 0x2000,
|
||||
|
||||
SCO_FORCE_32BIT = 0xFFFFFFFF
|
||||
};
|
||||
|
|
424
BBGE/Shader.cpp
424
BBGE/Shader.cpp
|
@ -18,10 +18,9 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "Shader.h"
|
||||
#ifdef BBGE_BUILD_WINDOWS
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include "algorithmx.h"
|
||||
|
||||
#ifdef BBGE_BUILD_SHADERS
|
||||
// GL_ARB_shader_objects
|
||||
|
@ -36,8 +35,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
|
||||
PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
|
||||
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
|
||||
PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;
|
||||
PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
|
||||
PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
|
||||
PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL;
|
||||
PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL;
|
||||
PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
|
||||
PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;
|
||||
PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL;
|
||||
PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL;
|
||||
PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL;
|
||||
PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
bool Shader::_wasInited = false;
|
||||
|
@ -73,22 +80,6 @@ void Shader::staticInit()
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef BBGE_BUILD_GLFW
|
||||
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glCreateProgramObjectARB");
|
||||
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glfwGetProcAddress("glDeleteObjectARB");
|
||||
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glUseProgramObjectARB");
|
||||
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glfwGetProcAddress("glCreateShaderObjectARB");
|
||||
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glfwGetProcAddress("glShaderSourceARB");
|
||||
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glfwGetProcAddress("glCompileShaderARB");
|
||||
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glfwGetProcAddress("glGetObjectParameterivARB");
|
||||
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glfwGetProcAddress("glAttachObjectARB");
|
||||
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glfwGetProcAddress("glGetInfoLogARB");
|
||||
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glfwGetProcAddress("glLinkProgramARB");
|
||||
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glfwGetProcAddress("glGetUniformLocationARB");
|
||||
glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glfwGetProcAddress("glUniform4fARB");
|
||||
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glfwGetProcAddress("glUniform1iARB");
|
||||
#endif
|
||||
|
||||
#ifdef BBGE_BUILD_SDL
|
||||
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB");
|
||||
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)SDL_GL_GetProcAddress("glDeleteObjectARB");
|
||||
|
@ -101,15 +92,23 @@ void Shader::staticInit()
|
|||
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB");
|
||||
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB");
|
||||
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB");
|
||||
glUniform4fARB = (PFNGLUNIFORM4FARBPROC)SDL_GL_GetProcAddress("glUniform4fARB");
|
||||
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");
|
||||
glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)SDL_GL_GetProcAddress("glGetActiveUniformARB");
|
||||
glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)SDL_GL_GetProcAddress("glUniform1fvARB");
|
||||
glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)SDL_GL_GetProcAddress("glUniform2fvARB");
|
||||
glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)SDL_GL_GetProcAddress("glUniform3fvARB");
|
||||
glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)SDL_GL_GetProcAddress("glUniform4fvARB");
|
||||
glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)SDL_GL_GetProcAddress("glUniform1ivARB");
|
||||
glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)SDL_GL_GetProcAddress("glUniform2ivARB");
|
||||
glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)SDL_GL_GetProcAddress("glUniform3ivARB");
|
||||
glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)SDL_GL_GetProcAddress("glUniform4ivARB");
|
||||
#endif
|
||||
|
||||
if( !glCreateProgramObjectARB || !glDeleteObjectARB || !glUseProgramObjectARB ||
|
||||
!glCreateShaderObjectARB || !glCreateShaderObjectARB || !glCompileShaderARB ||
|
||||
!glGetObjectParameterivARB || !glAttachObjectARB || !glGetInfoLogARB ||
|
||||
!glLinkProgramARB || !glGetUniformLocationARB || !glUniform4fARB ||
|
||||
!glUniform1iARB )
|
||||
!glLinkProgramARB || !glGetUniformLocationARB || !glGetActiveUniformARB ||
|
||||
!glUniform1fvARB || !glUniform2fvARB || !glUniform3fvARB || !glUniform4fvARB ||
|
||||
!glUniform1ivARB || !glUniform2ivARB || !glUniform3ivARB || !glUniform4ivARB)
|
||||
{
|
||||
glCreateProgramObjectARB = 0;
|
||||
debugLog("One or more GL_ARB_shader_objects functions were not found");
|
||||
|
@ -132,88 +131,35 @@ end:
|
|||
|
||||
Shader::Shader()
|
||||
{
|
||||
loaded = false;
|
||||
mode = 0;
|
||||
numUniforms = -1;
|
||||
uniformsDirty = false;
|
||||
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
g_vertexShader = 0;
|
||||
g_fragmentShader = 0;
|
||||
g_programObj = 0;
|
||||
vx = vy = vz = vw = 0;
|
||||
g_location_texture = 0;
|
||||
g_location_mode = 0;
|
||||
g_location_value = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
|
||||
void Shader::unload()
|
||||
{
|
||||
#ifdef BBGE_BUILD_SHADERS
|
||||
if (!_useShaders)
|
||||
return;
|
||||
if (g_vertexShader)
|
||||
glDeleteObjectARB( g_vertexShader );
|
||||
if (g_fragmentShader)
|
||||
glDeleteObjectARB( g_fragmentShader );
|
||||
if (g_programObj)
|
||||
{
|
||||
glDeleteObjectARB( g_programObj );
|
||||
g_programObj = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Shader::isLoaded()
|
||||
bool Shader::isLoaded() const
|
||||
{
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void Shader::setMode(int mode)
|
||||
{
|
||||
this->mode = mode;
|
||||
}
|
||||
|
||||
void Shader::setValue(float x, float y, float z, float w)
|
||||
{
|
||||
vx = x;
|
||||
vy = y;
|
||||
vz = z;
|
||||
vw = w;
|
||||
}
|
||||
|
||||
unsigned char *readShaderFile( const char *fileName )
|
||||
{
|
||||
debugLog("readShaderFile()");
|
||||
#ifdef BBGE_BUILD_WINDOWS
|
||||
FILE *file = fopen( fileName, "r" ); // FIXME: should this code ever be re-activated, adjust to VFS! -- fg
|
||||
|
||||
if( file == NULL )
|
||||
{
|
||||
errorLog("Cannot open shader file!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct _stat fileStats;
|
||||
|
||||
if( _stat( fileName, &fileStats ) != 0 )
|
||||
{
|
||||
errorLog("Cannot get file stats for shader file!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned char *buffer = new unsigned char[fileStats.st_size];
|
||||
|
||||
int bytes = fread( buffer, 1, fileStats.st_size, file );
|
||||
|
||||
buffer[bytes] = 0;
|
||||
|
||||
fclose( file );
|
||||
|
||||
debugLog("End readShaderFile()");
|
||||
|
||||
return buffer;
|
||||
|
||||
#else
|
||||
debugLog("End readShaderFile()");
|
||||
return 0;
|
||||
#endif
|
||||
return g_programObj != 0;
|
||||
}
|
||||
|
||||
void Shader::reload()
|
||||
|
@ -226,13 +172,8 @@ void Shader::bind()
|
|||
#ifdef BBGE_BUILD_SHADERS
|
||||
if (!_useShaders)
|
||||
return;
|
||||
glUseProgramObjectARB( g_programObj );
|
||||
if( g_location_texture != -1 )
|
||||
glUniform1iARB( g_location_texture, 0 );
|
||||
if ( g_location_mode )
|
||||
glUniform1iARB( g_location_mode, mode);
|
||||
if ( g_location_value )
|
||||
glUniform4fARB( g_location_value, vx, vy, vz, vw);
|
||||
glUseProgramObjectARB(g_programObj);
|
||||
_flushUniforms();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -241,142 +182,273 @@ void Shader::unbind()
|
|||
#ifdef BBGE_BUILD_SHADERS
|
||||
if (!_useShaders)
|
||||
return;
|
||||
glUseProgramObjectARB( NULL );
|
||||
glUseProgramObjectARB(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int Shader::_compileShader(int type, const char *src, char *errbuf, size_t errbufsize)
|
||||
{
|
||||
#ifdef BBGE_BUILD_SHADERS
|
||||
GLint compiled = 0;
|
||||
GLhandleARB handle = glCreateShaderObjectARB(type);
|
||||
if(!handle)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to create shader object of type " << type;
|
||||
debugLog(os.str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
glShaderSourceARB( handle, 1, &src, NULL );
|
||||
glCompileShaderARB( handle);
|
||||
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
|
||||
glGetInfoLogARB(handle, errbufsize, NULL, errbuf);
|
||||
if(!compiled)
|
||||
{
|
||||
glDeleteObjectARB(handle);
|
||||
handle = 0;
|
||||
}
|
||||
GLint err = glGetError();
|
||||
if(err != GL_NO_ERROR)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Shader::_compileShader: Unexpected error " << err;
|
||||
errorLog(os.str());
|
||||
}
|
||||
return handle;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Shader::load(const std::string &file, const std::string &fragFile)
|
||||
{
|
||||
staticInit();
|
||||
loaded = false;
|
||||
|
||||
#ifdef BBGE_BUILD_SHADERS
|
||||
if(!_useShaders)
|
||||
return;
|
||||
|
||||
debugLog("Shader::load("+file+", "+fragFile+")");
|
||||
|
||||
g_location_texture = 0;
|
||||
g_location_mode = 0;
|
||||
g_location_value = 0;
|
||||
|
||||
debugLog("Shader::load 1");
|
||||
this->vertFile = file;
|
||||
this->fragFile = fragFile;
|
||||
//
|
||||
// If the required extension is present, get the addresses of its
|
||||
// functions that we wish to use...
|
||||
//
|
||||
|
||||
const char *vertexShaderStrings[1];
|
||||
const char *fragmentShaderStrings[1];
|
||||
GLint bVertCompiled;
|
||||
GLint bFragCompiled;
|
||||
GLint bLinked;
|
||||
char *vertCode = file.length() ? readFile(file) : NULL;
|
||||
char *fragCode = fragFile.length() ? readFile(fragFile) : NULL;
|
||||
|
||||
loadSrc(vertCode, fragCode);
|
||||
|
||||
delete [] vertCode;
|
||||
delete [] fragCode;
|
||||
}
|
||||
|
||||
void Shader::loadSrc(const char *vertCode, const char *fragCode)
|
||||
{
|
||||
staticInit();
|
||||
unload();
|
||||
|
||||
if(!_useShaders)
|
||||
return;
|
||||
|
||||
#ifdef BBGE_BUILD_SHADERS
|
||||
|
||||
char str[4096];
|
||||
|
||||
GLhandleARB vertexShader = 0;
|
||||
GLhandleARB fragmentShader = 0;
|
||||
|
||||
//
|
||||
// Create the vertex shader...
|
||||
//
|
||||
|
||||
debugLog("Shader::load 2");
|
||||
|
||||
g_vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
|
||||
|
||||
unsigned char *vertexShaderAssembly = readShaderFile( file.c_str() );
|
||||
vertexShaderStrings[0] = (char*)vertexShaderAssembly;
|
||||
glShaderSourceARB( g_vertexShader, 1, vertexShaderStrings, NULL );
|
||||
glCompileShaderARB( g_vertexShader);
|
||||
delete[] vertexShaderAssembly;
|
||||
|
||||
glGetObjectParameterivARB( g_vertexShader, GL_OBJECT_COMPILE_STATUS_ARB,
|
||||
&bVertCompiled );
|
||||
if( bVertCompiled == false )
|
||||
//if (true)
|
||||
if(vertCode && *vertCode && !(vertexShader = _compileShader(GL_VERTEX_SHADER_ARB, vertCode, str, sizeof(str))))
|
||||
{
|
||||
glGetInfoLogARB(g_vertexShader, sizeof(str), NULL, str);
|
||||
std::ostringstream os;
|
||||
os << "Vertex Shader Compile Error: " << str;
|
||||
debugLog(os.str());
|
||||
os << "Vertex Shader Compile Error [" << vertFile << "]:\n" << str;
|
||||
errorLog(os.str());
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the fragment shader...
|
||||
//
|
||||
|
||||
debugLog("Shader::load 3");
|
||||
|
||||
g_fragmentShader = glCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB );
|
||||
|
||||
unsigned char *fragmentShaderAssembly = readShaderFile( fragFile.c_str() );
|
||||
fragmentShaderStrings[0] = (char*)fragmentShaderAssembly;
|
||||
glShaderSourceARB( g_fragmentShader, 1, fragmentShaderStrings, NULL );
|
||||
glCompileShaderARB( g_fragmentShader );
|
||||
delete[] fragmentShaderAssembly;
|
||||
|
||||
glGetObjectParameterivARB( g_fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB,
|
||||
&bFragCompiled );
|
||||
if( bFragCompiled == false )
|
||||
if(fragCode && *fragCode && !(fragmentShader = _compileShader(GL_FRAGMENT_SHADER_ARB, fragCode, str, sizeof(str))))
|
||||
{
|
||||
glGetInfoLogARB( g_fragmentShader, sizeof(str), NULL, str );
|
||||
std::ostringstream os;
|
||||
os << "Fragment Shader Compile Error: " << str;
|
||||
debugLog(os.str());
|
||||
os << "Fragment Shader Compile Error [" << fragFile << "]:\n" << str;
|
||||
errorLog(os.str());
|
||||
return;
|
||||
}
|
||||
|
||||
debugLog("Shader::load 4");
|
||||
|
||||
//
|
||||
// Create a program object and attach the two compiled shaders...
|
||||
//
|
||||
|
||||
|
||||
g_programObj = glCreateProgramObjectARB();
|
||||
|
||||
if (!g_programObj || !g_vertexShader || !g_fragmentShader)
|
||||
if (!(g_programObj && (vertexShader || fragmentShader)))
|
||||
{
|
||||
debugLog("programObj / vertexShader / fragmentShader problem");
|
||||
errorLog("programObj / vertexShader / fragmentShader problem");
|
||||
unload();
|
||||
return;
|
||||
}
|
||||
|
||||
glAttachObjectARB( g_programObj, g_vertexShader );
|
||||
glAttachObjectARB( g_programObj, g_fragmentShader );
|
||||
|
||||
//
|
||||
// Link the program object and print out the info log...
|
||||
//
|
||||
if(vertexShader)
|
||||
glAttachObjectARB( g_programObj, vertexShader );
|
||||
if(fragmentShader)
|
||||
glAttachObjectARB( g_programObj, fragmentShader );
|
||||
|
||||
glLinkProgramARB( g_programObj );
|
||||
|
||||
// Shader objects will be deleted as soon as the program object is deleted
|
||||
if(vertexShader)
|
||||
glDeleteObjectARB(vertexShader);
|
||||
if(fragmentShader)
|
||||
glDeleteObjectARB(fragmentShader);
|
||||
|
||||
GLint bLinked;
|
||||
glGetObjectParameterivARB( g_programObj, GL_OBJECT_LINK_STATUS_ARB, &bLinked );
|
||||
|
||||
debugLog("Shader::load 5");
|
||||
|
||||
if( bLinked == false )
|
||||
if(!bLinked)
|
||||
{
|
||||
glGetInfoLogARB( g_programObj, sizeof(str), NULL, str );
|
||||
std::ostringstream os;
|
||||
os << "Shader Linking Error: " << str;
|
||||
debugLog(os.str());
|
||||
errorLog(os.str());
|
||||
unload();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Locate some parameters by name so we can set them later...
|
||||
//
|
||||
|
||||
debugLog("Shader::load 6");
|
||||
|
||||
g_location_texture = glGetUniformLocationARB( g_programObj, "tex" );
|
||||
g_location_mode = glGetUniformLocationARB( g_programObj, "mode" );
|
||||
g_location_value = glGetUniformLocationARB( g_programObj, "value" );
|
||||
|
||||
debugLog("Shader::load 7");
|
||||
|
||||
loaded = true;
|
||||
_queryUniforms();
|
||||
|
||||
#endif
|
||||
debugLog("End Shader::load()");
|
||||
}
|
||||
|
||||
void Shader::_setUniform(Uniform *u)
|
||||
{
|
||||
/*if(u->location == -1)
|
||||
{
|
||||
u->location = glGetUniformLocationARB(g_programObj, u->name);
|
||||
if(u->location == -1)
|
||||
{
|
||||
u->dirty = false;
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
switch(u->type)
|
||||
{
|
||||
case GL_FLOAT: glUniform1fvARB(u->location, 1, u->data.f); break;
|
||||
case GL_FLOAT_VEC2_ARB: glUniform2fvARB(u->location, 1, u->data.f); break;
|
||||
case GL_FLOAT_VEC3_ARB: glUniform3fvARB(u->location, 1, u->data.f); break;
|
||||
case GL_FLOAT_VEC4_ARB: glUniform4fvARB(u->location, 1, u->data.f); break;
|
||||
case GL_INT: glUniform1ivARB(u->location, 1, u->data.i); break;
|
||||
case GL_INT_VEC2_ARB: glUniform2ivARB(u->location, 1, u->data.i); break;
|
||||
case GL_INT_VEC3_ARB: glUniform3ivARB(u->location, 1, u->data.i); break;
|
||||
case GL_INT_VEC4_ARB: glUniform4ivARB(u->location, 1, u->data.i); break;
|
||||
}
|
||||
u->dirty = false;
|
||||
}
|
||||
|
||||
void Shader::_flushUniforms()
|
||||
{
|
||||
if(!uniformsDirty)
|
||||
return;
|
||||
uniformsDirty = false;
|
||||
|
||||
for(size_t i = 0; i < uniforms.size(); ++i)
|
||||
{
|
||||
Uniform &u = uniforms[i];
|
||||
if(u.dirty)
|
||||
_setUniform(&u);
|
||||
}
|
||||
}
|
||||
|
||||
// for sorting
|
||||
bool Shader::_sortUniform(const Uniform& a, const char *bname)
|
||||
{
|
||||
return strcmp(a.name, bname) < 0;
|
||||
}
|
||||
|
||||
bool Shader::Uniform::operator< (const Uniform& b) const
|
||||
{
|
||||
return Shader::_sortUniform(*this, &b.name[0]);
|
||||
}
|
||||
|
||||
void Shader::_queryUniforms()
|
||||
{
|
||||
glGetObjectParameterivARB(g_programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB , &numUniforms);
|
||||
|
||||
if (numUniforms <= 0)
|
||||
return;
|
||||
|
||||
uniforms.reserve(numUniforms);
|
||||
|
||||
for (unsigned int i = 0; i < numUniforms; ++i)
|
||||
{
|
||||
Uniform u;
|
||||
GLint size = 0;
|
||||
GLenum type = 0;
|
||||
glGetActiveUniformARB(g_programObj, i, sizeof(u.name), NULL, &size, &type, &u.name[0]);
|
||||
if(!type || !size)
|
||||
continue;
|
||||
u.location = glGetUniformLocationARB(g_programObj, u.name);
|
||||
if(u.location == -1)
|
||||
continue;
|
||||
u.dirty = false;
|
||||
u.type = type;
|
||||
memset(&u.data, 0, sizeof(u.data));
|
||||
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
// sort to be able to do binary search later
|
||||
std::sort(uniforms.begin(), uniforms.end());
|
||||
}
|
||||
|
||||
int Shader::_getUniformIndex(const char *name)
|
||||
{
|
||||
// binary search
|
||||
UniformVec::iterator it = stdx_fg::lower_bound(uniforms.begin(), uniforms.end(), name, _sortUniform);
|
||||
// because lower_bound returns the first element that compares less, it might not be the correct one
|
||||
if(it != uniforms.end() && strcmp(it->name, name))
|
||||
return -1;
|
||||
return int(it - uniforms.begin());
|
||||
}
|
||||
|
||||
void Shader::setInt(const char *name, int x, int y /* = 0 */, int z /* = 0 */, int w /* = 0 */)
|
||||
{
|
||||
#if BBGE_BUILD_SHADERS
|
||||
if(!g_programObj || numUniforms <= 0)
|
||||
return;
|
||||
int idx = _getUniformIndex(name);
|
||||
if(unsigned(idx) >= uniforms.size())
|
||||
return;
|
||||
Uniform& u = uniforms[idx];
|
||||
u.data.i[0] = x;
|
||||
u.data.i[1] = y;
|
||||
u.data.i[2] = z;
|
||||
u.data.i[3] = w;
|
||||
u.dirty = true;
|
||||
uniformsDirty = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Shader::setFloat(const char *name, float x, float y /* = 0 */, float z /* = 0 */, float w /* = 0 */)
|
||||
{
|
||||
#if BBGE_BUILD_SHADERS
|
||||
if(!g_programObj || numUniforms <= 0)
|
||||
return;
|
||||
int idx = _getUniformIndex(name);
|
||||
if(unsigned(idx) >= uniforms.size())
|
||||
return;
|
||||
Uniform& u = uniforms[idx];
|
||||
u.data.f[0] = x;
|
||||
u.data.f[1] = y;
|
||||
u.data.f[2] = z;
|
||||
u.data.f[3] = w;
|
||||
u.dirty = true;
|
||||
uniformsDirty = true;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -22,36 +22,74 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define BBGE_SHADER_H
|
||||
|
||||
#include "Base.h"
|
||||
#include "ScriptObject.h"
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader();
|
||||
~Shader();
|
||||
bool isLoaded();
|
||||
bool isLoaded() const;
|
||||
void load(const std::string &file, const std::string &fragFile);
|
||||
void loadSrc(const char *vertCode, const char *fragCode);
|
||||
void reload();
|
||||
void unload();
|
||||
void bind();
|
||||
void unbind();
|
||||
void setMode(int mode);
|
||||
void setValue(float x, float y, float z, float w);
|
||||
std::string vertFile, fragFile;
|
||||
|
||||
void setInt(const char *name, int x, int y = 0, int z = 0, int w = 0);
|
||||
void setFloat(const char *name, float x, float y = 0, float z = 0, float w = 0);
|
||||
// TODO: other setters needed?
|
||||
|
||||
|
||||
protected:
|
||||
std::string vertFile, fragFile;
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
GLuint g_programObj;
|
||||
GLuint g_vertexShader;
|
||||
GLuint g_fragmentShader;
|
||||
GLuint g_location_texture;
|
||||
GLuint g_location_mode;
|
||||
GLuint g_location_value;
|
||||
int numUniforms;
|
||||
#endif
|
||||
int mode;
|
||||
float vx, vy, vz, vw;
|
||||
bool loaded;
|
||||
|
||||
private:
|
||||
static void staticInit();
|
||||
static bool _wasInited;
|
||||
static bool _useShaders;
|
||||
|
||||
static unsigned int _compileShader(int type, const char *src, char *errbuf, size_t errbufsize);
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
int location; // GL location variable
|
||||
int type;
|
||||
bool dirty; // need to flush if true
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int i[4];
|
||||
};
|
||||
struct
|
||||
{
|
||||
float f[4];
|
||||
};
|
||||
} data;
|
||||
char name[32];
|
||||
|
||||
bool operator< (const Uniform&) const;
|
||||
};
|
||||
|
||||
static bool _sortUniform(const Uniform& a, const char *bname);
|
||||
|
||||
void _queryUniforms();
|
||||
void _flushUniforms();
|
||||
void _registerUniform();
|
||||
|
||||
void _setUniform(Uniform *u);
|
||||
int _getUniformIndex(const char *name);
|
||||
|
||||
typedef std::vector<Uniform> UniformVec;
|
||||
UniformVec uniforms;
|
||||
|
||||
bool uniformsDirty;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -507,8 +507,7 @@ Animation* AnimationLayer::getCurrentAnimation()
|
|||
{
|
||||
std::ostringstream os;
|
||||
os << "skel: " << s->filenameLoaded << " currentAnimation: " << currentAnimation << " is out of range\n error in anim file?";
|
||||
errorLog(os.str());
|
||||
exit(-1);
|
||||
exit_error(os.str());
|
||||
return 0;
|
||||
}
|
||||
return &s->animations[currentAnimation];
|
||||
|
|
|
@ -279,7 +279,7 @@ void StateManager::registerStateObject(StateObject *stateObject, const std::stri
|
|||
//getNameFromDerivedClassTypeName(c);
|
||||
if (stateObject->name.empty())
|
||||
{
|
||||
fatalError("StateManager::registerStateObject - Empty name.");
|
||||
exit_error("StateManager::registerStateObject - Empty name.");
|
||||
}
|
||||
|
||||
if (!stateObjects[stateObject->name])
|
||||
|
|
|
@ -446,7 +446,6 @@ void Texture::loadPNG(const std::string &file)
|
|||
width = 64;
|
||||
height = 64;
|
||||
Texture::textureError = TEXERR_FILENOTFOUND;
|
||||
//exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -483,7 +482,6 @@ void Texture::loadPNG(const std::string &file)
|
|||
width = 64;
|
||||
height = 64;
|
||||
Texture::textureError = TEXERR_FILENOTFOUND;
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -306,12 +306,12 @@ Vector VectorPath::getValue(float usePercent)
|
|||
|
||||
if (!from && !target)
|
||||
{
|
||||
msg ("returning first value");
|
||||
errorLog("returning first value");
|
||||
return pathNodes[0].value;
|
||||
}
|
||||
else if (!from && target)
|
||||
{
|
||||
msg("Unexpected Path node result (UPDATE: Could use current value as from?)");
|
||||
errorLog("Unexpected Path node result (UPDATE: Could use current value as from?)");
|
||||
}
|
||||
else if (from && !target)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue