⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aglsl.cpp

📁 GLSL tutorial with sourcecode
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/********************************************************************
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 + -