📄 aglsl.cpp
字号:
/********************************************************************
aGLSL.cpp
Version: 0.7.0 beta
(c) 2003-2004 by Martin Christen. All Rights reserved.
christen@clockworkcoders.com
*********************************************************************/
#include "aGLSL.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <GL/glu.h>
#include <math.h>
#include "aGL_Extensions.cpp"
using namespace std;
bool useGLSL = false;
//-----------------------------------------------------------------------------
// Error Strings
char* aGLSLErrorString[] = {
"(e0000) GLSL not enabled",
"(e0001) not a valid program object",
"(e0002) not a valid object",
"(e0003) out of memory",
"(e0004) unknown compiler error"};
//-----------------------------------------------------------------------------
// GL ERROR CHECK
int CheckGLError(char *file, int line)
{
GLenum glErr;
int retCode = 0;
glErr = glGetError();
while (glErr != GL_NO_ERROR) {
cout << "GL Error #" << glErr << "(" << gluErrorString(glErr) << ") " << " in File " << file << " at line: " << line << endl;
retCode = 1;
glErr = glGetError();
}
return retCode;
}
#define CHECK_GL_ERROR() CheckGLError(__FILE__, __LINE__)
//-----------------------------------------------------------------------------
bool initGLSL(void)
{
int error = 0;
if (useGLSL) return true; // already initialized
if (!init_ARB_fragment_shader()) error = -1;
if (!init_ARB_vertex_shader()) error = -1;;
if (!init_ARB_shader_objects()) error = -1;;
if (error)
{
useGLSL = false;
}
else
{
useGLSL = true;
}
return useGLSL;
}
//-----------------------------------------------------------------------------
// Test if a certain Extension exists, returns true if it exists
// example: mcTextExtension("ARB_vertex_shader");
bool mcTestExtension(const char* extension_name)
{
const GLubyte *str;
str = glGetString(GL_EXTENSIONS);
if (strstr((const char *)str, extension_name) != 0) return true;
#ifdef GLSL_WINDOWS
#ifdef USE_WGLEXT
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
if(wglGetExtensionsStringARB == NULL)
{
return false;
}
str = (const GLubyte*) wglGetExtensionsStringARB(wglGetCurrentDC());
if (strstr((const char *)str, extension_name) != 0) return true;
#endif
#else
// ignore additional platform extensions
#endif
return false;
}
// ************************************************************************
// GLExtensions : Create a STL Vector with all available GLExtensions names
// ************************************************************************
GLExtensions::GLExtensions()
{
const GLubyte *str;
str = glGetString(GL_EXTENSIONS);
GLString_Convert((char*)str);
#ifdef GLSL_WINDOWS
#ifdef USE_WGLEXT
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
if(wglGetExtensionsStringARB == NULL)
{
return;
}
str = (const GLubyte*) wglGetExtensionsStringARB(wglGetCurrentDC());
GLString_Convert((char*)str);
#endif
#else
// ignore additional extensions....
#endif
}
//-----------------------------------------------------------------------------
GLExtensions::~GLExtensions()
{
for (unsigned int i=0;i<ExtensionList.size();i++)
{
delete[] ExtensionList[i]; // free string
}
}
//-----------------------------------------------------------------------------
void GLExtensions::GLString_Convert(char* str)
{
#define ELaAX_BUF_SIZE 80
char buf[ELaAX_BUF_SIZE];
int i=0;
char* d = (char*) str;
while (*d!=0)
{
if (*d==' ')
{
buf[i] = 0;
i=0;
addElement(buf);
}
else
{
buf[i++]= *d;
if (i>ELaAX_BUF_SIZE-1) i=ELaAX_BUF_SIZE-1;
}
d++;
}
}
//-----------------------------------------------------------------------------
void GLExtensions::addElement(char* str)
{
char* s = new char[strlen(str)+1];
strcpy(s, str);
ExtensionList.push_back(s);
}
//-----------------------------------------------------------------------------
void GLExtensions::print(ostream& out)
{
out << "OpenGL Vendor: " << (char*) glGetString(GL_VENDOR) << "\n";
out << "OpenGL Renderer: " << (char*) glGetString(GL_RENDERER) << "\n";
out << "OpenGL Version: " << (char*) glGetString(GL_VERSION) << "\n\n";
for (unsigned int i=0;i<ExtensionList.size();i++)
{
out << ExtensionList[i] << endl;
}
}
//-----------------------------------------------------------------------------
bool GLExtensions::check(char* extension_name)
{
for (unsigned int i=0;i<ExtensionList.size();i++)
{
if (strstr((const char *)ExtensionList[i], extension_name) != 0)
{
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
bool GLExtensions::init(void)
{
init_ARB_extensions();
return true;
}
//-----------------------------------------------------------------------------
// Bubble Sort to sort extension names.
void GLExtensions::sort(void)
{
char* tmp;
for (unsigned int i = 0; i < ExtensionList.size(); i++)
{
for (unsigned int j = (unsigned int) ExtensionList.size()-1; j>i; j--)
{
if (strcmp(ExtensionList[j-1],ExtensionList[j]) > 0)
{
tmp = ExtensionList[j-1];
ExtensionList[j-1] = ExtensionList[j];
ExtensionList[j] = tmp;
}
}
}
}
// ************************************************************************
// Implementation der Klasse aShaderObject
// ************************************************************************
aShaderObject::aShaderObject()
{
ShaderObject = 0;
linker_log = 0;
_mM = false;
if (!initGLSL())
{
cout << "Error initializing OpenGL Shading Language function pointers" << endl;
}
if (!mcTestExtension("GL_ARB_shader_objects"))
cout << "**warning** GL_ARB_shader_objects not defined!!\n";
if (!mcTestExtension("GL_ARB_vertex_shader"))
cout << "**warning** GL_ARB_vertex_shader not defined!!\n";
if (!mcTestExtension("GL_ARB_fragment_shader"))
cout << "**warning** GL_ARB_fragment_shader not defined!!\n";
if (!mcTestExtension("GL_ARB_shading_language_100"))
cout << "**warning** GL_ARB_shading_language_100 not defined!!\n";
if (initGLSL())
{
ShaderObject = glCreateProgramObjectARB();
}
is_linked = false;
}
//-----------------------------------------------------------------------------
aShaderObject::~aShaderObject()
{
if (linker_log!=0) free(linker_log);
if (useGLSL)
{
for (unsigned int i=0;i<ShaderList.size();i++)
{
glDetachObjectARB(ShaderObject, ShaderList[i]->ProgramObject);
CHECK_GL_ERROR(); // if you get an error here, you deleted the Program object first and then
// the ShaderObject! Always delete ShaderObjects last!
if (_mM) delete ShaderList[i];
}
glDeleteObjectARB(ShaderObject);
CHECK_GL_ERROR();
}
}
//-----------------------------------------------------------------------------
bool aShaderObject::oglslEnabled(void)
{
return useGLSL;
}
//-----------------------------------------------------------------------------
void aShaderObject::addShader(aShaderProgram* ShaderProgram)
{
if (!useGLSL) return;
if (ShaderProgram==0) return;
if (!ShaderProgram->is_compiled)
{
cout << "**warning** please compile program before adding object! trying to compile now...\n";
if (!ShaderProgram->compile())
{
cout << "...compile ERROR!\n";
return;
}
else
{
cout << "...ok!\n";
}
}
ShaderList.push_back(ShaderProgram);
}
//-----------------------------------------------------------------------------
bool aShaderObject::link(void)
{
if (!useGLSL) return false;
unsigned int i;
if (is_linked) // already linked, detach everything first
{
cout << "**warning** Object is already linked, trying to link again" << endl;
for (i=0;i<ShaderList.size();i++)
{
glDetachObjectARB(ShaderObject, ShaderList[i]->ProgramObject);
CHECK_GL_ERROR();
}
}
for (i=0;i<ShaderList.size();i++)
{
glAttachObjectARB(ShaderObject, ShaderList[i]->ProgramObject);
CHECK_GL_ERROR();
//cout << "attaching ProgramObj [" << i << "] @ 0x" << hex << ShaderList[i]->ProgramObject << " in ShaderObj @ 0x" << ShaderObject << endl;
}
int linked;
glLinkProgramARB(ShaderObject);
CHECK_GL_ERROR();
glGetObjectParameterivARB(ShaderObject, GL_OBJECT_LINK_STATUS_ARB, &linked);
CHECK_GL_ERROR();
if (linked)
{
is_linked = true;
return true;
}
else
{
cout << "**linker error**\n";
}
return false;
}
//-----------------------------------------------------------------------------
// Compiler Log: Ausgabe der Compiler Meldungen in String
char* aShaderObject::getLinkerLog(void)
{
if (!useGLSL) return aGLSLErrorString[0];
int blen = 0;
int slen = 0;
if (ShaderObject==0) return aGLSLErrorString[2];
glGetObjectParameterivARB(ShaderObject, GL_OBJECT_INFO_LOG_LENGTH_ARB , &blen);
CHECK_GL_ERROR();
if (blen > 1)
{
if (linker_log!=0)
{
free(linker_log);
linker_log =0;
}
if ((linker_log = (GLcharARB*)malloc(blen)) == NULL)
{
printf("ERROR: Could not allocate compiler_log buffer\n");
return aGLSLErrorString[3];
}
glGetInfoLogARB(ShaderObject, blen, &slen, linker_log);
CHECK_GL_ERROR();
}
if (linker_log!=0)
return (char*) linker_log;
return aGLSLErrorString[4];
}
void aShaderObject::begin(void)
{
if (!useGLSL) return;
if (ShaderObject == 0) return;
if (!_noshader) return;
if (is_linked)
{
glUseProgramObjectARB(ShaderObject);
CHECK_GL_ERROR();
}
}
//-----------------------------------------------------------------------------
void aShaderObject::end(void)
{
if (!useGLSL) return;
if (!_noshader) return;
glUseProgramObjectARB(0);
CHECK_GL_ERROR();
}
//-----------------------------------------------------------------------------
bool aShaderObject::sendUniform1f(char* varname, GLfloat v0)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform1fARB(loc, v0);
return true;
}
//-----------------------------------------------------------------------------
bool aShaderObject::sendUniform2f(char* varname, GLfloat v0, GLfloat v1)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform2fARB(loc, v0, v1);
return true;
}
//-----------------------------------------------------------------------------
bool aShaderObject::sendUniform3f(char* varname, GLfloat v0, GLfloat v1, GLfloat v2)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform3fARB(loc, v0, v1, v2);
return true;
}
//-----------------------------------------------------------------------------
bool aShaderObject::sendUniform4f(char* varname, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform4fARB(loc, v0, v1, v2, v3);
return true;
}
//-----------------------------------------------------------------------------
bool aShaderObject::sendUniform1i(char* varname, GLint v0)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform1iARB(loc, v0);
return true;
}
bool aShaderObject::sendUniform2i(char* varname, GLint v0, GLint v1)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform2iARB(loc, v0, v1);
return true;
}
//-----------------------------------------------------------------------------
bool aShaderObject::sendUniform3i(char* varname, GLint v0, GLint v1, GLint v2)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform3iARB(loc, v0, v1, v2);
return true;
}
bool aShaderObject::sendUniform4i(char* varname, GLint v0, GLint v1, GLint v2, GLint v3)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform4iARB(loc, v0, v1, v2, v3);
return true;
}
//-----------------------------------------------------------------------------
bool aShaderObject::sendUniform1fv(char* varname, GLsizei count, GLfloat *value)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform1fvARB(loc, count, value);
return true;
}
bool aShaderObject::sendUniform2fv(char* varname, GLsizei count, GLfloat *value)
{
if (!useGLSL) return false; // GLSL not available
if (!_noshader) return true;
GLint loc = GetUniLoc(varname);
if (loc==-1) return false; // can't find variable
glUniform2fvARB(loc, count, value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -