int test_outputfunc()
{
	LOG		*g = NULL ;
	
	g = CreateLogHandle() ;
	if( g == NULL )
	{
		printf( "创建日志句柄失败errno[%d]\n" , errno );
		return -1;
	}
	else
	{
		printf( "创建日志句柄成功\n" );
	}
	
	SetLogOutput( g , LOG_OUTPUT_CALLBACK , "127.0.0.1:514" , & MyOpenLogFirst , NULL , & MyWriteLog , NULL , NULL , & MyCloseLogFinally );
	SetLogLevel( g , LOG_LEVEL_INFO );
	SetLogStyles( g , LOG_STYLES_LOG , LOG_NO_STYLEFUNC );
	
	WriteDebugLog( g , __FILE__ , __LINE__ , "hello iLOG3\n" );
	WriteInfoLog( g , __FILE__ , __LINE__ , "hello iLOG3\n" );
	WriteWarnLog( g , __FILE__ , __LINE__ , "hello iLOG3\n" );
	WriteErrorLog( g , __FILE__ , __LINE__ , "hello iLOG3\n" );
	WriteFatalLog( g , __FILE__ , __LINE__ , "hello iLOG3\n" );
	
	DestroyLogHandle( g );
	printf( "销毁日志句柄\n" );
	
	return 0;
}
/**
 * Loads a vertex or fragment shader.
 * Loads either a vertex or fragment shader and tries to compile it.
 * \param ShaderDesc - name of the file containing the shader
 * \param Type - either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
 * \param src - defines the source of the shader. Can be either GLSLPROGRAM_DISK or GLSLPROGRAM_STRING.
 * \return a handle to the compiled shader if successful, 0 otherwise
 * \warning uses glGetError()
 * \author <a href="mailto:[email protected]">Jens Schneider</a>
 * \date Mar.2005
 * \see GLSLPROGRAM_SOURCE
 */
GLuint GLSLProgram::LoadShader(const char *ShaderDesc, GLenum Type, GLSLPROGRAM_SOURCE src) {
  // assert right type
  assert(Type==GL_VERTEX_SHADER || Type==GL_FRAGMENT_SHADER);

  CheckGLError();

  unsigned long lFileSize;
  char *pcShader;
  FILE *fptr;

  // Load and compile vertex shader
  switch(src) {
    case GLSLPROGRAM_DISK:
      fptr=fopen(ShaderDesc,"rb");
      if (!fptr) {
        T_ERROR("File %s not found!",ShaderDesc);
        return 0;
      }
      if (fseek(fptr,0,SEEK_END)) {
        fclose(fptr);
        T_ERROR("Error reading file %s.",ShaderDesc);
        return 0;
      }
      lFileSize=ftell(fptr)/sizeof(char);
      fseek(fptr,0,SEEK_SET);
      pcShader=new char[lFileSize+1];
      pcShader[lFileSize]='\0';
      if (lFileSize!=fread(pcShader,sizeof(char),lFileSize,fptr)) {
        fclose(fptr);
        delete[] pcShader;
        T_ERROR("Error reading file %s.",ShaderDesc);
        return 0;
      }
      fclose(fptr);
      break;
    case GLSLPROGRAM_STRING:
      pcShader=(char*)ShaderDesc;
      lFileSize=long(strlen(pcShader));
      break;
    default:
      T_ERROR("Unknown source");
      return 0;
      break;
  }

  GLuint hShader = 0;
  bool bError=false;
  if (m_bGLUseARB) {
    hShader = glCreateShaderObjectARB(Type);
    glShaderSourceARB(hShader,1,(const GLchar**)&pcShader,NULL); // upload null-terminated shader
    glCompileShaderARB(hShader);

    // Check for errors
    if (CheckGLError("LoadProgram()")) {
      glDeleteObjectARB(hShader);
      bError =true;
    }
  } else {
    hShader = glCreateShader(Type);
    glShaderSource(hShader,1,(const char**)&pcShader,NULL);  // upload null-terminated shader
    glCompileShader(hShader);

    // Check for compile status
    GLint iCompiled;
    glGetShaderiv(hShader,GL_COMPILE_STATUS,&iCompiled);

    // Check for errors
    if (WriteInfoLog(ShaderDesc, hShader,false)) {
      glDeleteShader(hShader);
      bError=true;
    }

    if (CheckGLError("LoadProgram()") || iCompiled!=GLint(GL_TRUE)) {
      glDeleteShader(hShader);
      bError=true;
    }
  }

  if (pcShader!=ShaderDesc) delete[] pcShader;

  if (bError) return 0;
  return hShader;
}
/**
 * Loads vertex and fragment shader from disk/memory.
 * Loads any combination of vertex and fragment shader from disk or from a memory position.
 * Generates error/information messages to stdout during loading.
 * If nor successful the handle of the shader will be set to 0.
 * \param VSFile - name of the file containing the vertex shader
 * \param FSFile - name of the file containing the fragment shader
 * \param src - selects the source of vertex and fragment shader. Can be either GLSLPROGRAM_DISK or GLSLPROGRAM_STRING
 * \return void
 * \warning Uses glGetError()
 * \author <a href="mailto:[email protected]">Jens Schneider</a>
 * \date Aug.2004
 * \see GLSLPROGRAM_SOURCE
 */
void GLSLProgram::Load(const char *VSFile, const char *FSFile, GLSLPROGRAM_SOURCE src) {
  CheckGLError();

  // load
  GLuint hVS=0;
  GLuint hFS=0;
  bool bVSSuccess=true;  // fixed function pipeline is always working
  if (VSFile!=NULL) {
    hVS=LoadShader(VSFile,GL_VERTEX_SHADER,src);
    if(hVS != 0) {
      m_sVS = std::string(VSFile); // record program source
    } else {
      bVSSuccess=false;
      if (src==GLSLPROGRAM_DISK) {
        T_ERROR("ERROR IN: %s", VSFile);
      }
      else {
        T_ERROR("---------- ERROR -----------");
        int iPos=0;
        int iLine=1;
        char chLine[32];
        char *chVerbose=new char[strlen(VSFile)+1];
        memcpy(chVerbose,VSFile,strlen(VSFile)+1);
        for (unsigned int i=0; i<strlen(VSFile); i++) {
          if (chVerbose[i]=='\n') {
            chVerbose[i]='\0';
            sprintf(chLine,"(%.4i) ",iLine++);
            T_ERROR("Load %s %s", chLine, &chVerbose[iPos]);
            iPos=i+1;
          }
        }
        delete[] chVerbose;
      }
    }
  }
  bool bFSSuccess=true;  // fixed function pipeline is always working
  if (FSFile!=NULL) {
    hFS=LoadShader(FSFile,GL_FRAGMENT_SHADER,src);
    if(hVS != 0) {
      m_sFS = std::string(FSFile); // record program source
    } else {
      bFSSuccess=false;
      if (src==GLSLPROGRAM_DISK) {
        T_ERROR( "Error in fragment shader: %s", FSFile);
      }
      else {
        T_ERROR("---------- ERROR -----------");
        int iPos=0;
        int iLine=1;
        char chLine[32];
        char *chVerbose=new char[strlen(FSFile)+1];
        memcpy(chVerbose,FSFile,strlen(FSFile)+1);
        for (unsigned int i=0; i<strlen(FSFile); i++) {
          if (chVerbose[i]=='\n') {
            chVerbose[i]='\0';
            sprintf(chLine,"(%.4i) ",iLine++);
            T_ERROR( "Load %s %s",chLine, &chVerbose[iPos]);
            iPos=i+1;
          }
        }
        delete[] chVerbose;
      }
    }
  }

  if (m_bGLUseARB) {
    // attach to shader program
    m_hProgram=glCreateProgramObjectARB();
    if (hVS) glAttachObjectARB(m_hProgram,hVS);
    if (hFS) glAttachObjectARB(m_hProgram,hFS);

    // link the program together
    if (bVSSuccess && bFSSuccess) {
      glLinkProgramARB(m_hProgram);

      // check for errors
      GLint iLinked;
      glGetObjectParameterivARB(m_hProgram,GL_OBJECT_LINK_STATUS_ARB,&iLinked);
      WriteError(m_hProgram);

      // delete temporary objects
      if (hVS) glDeleteObjectARB(hVS);
      if (hFS) glDeleteObjectARB(hFS);

      if (CheckGLError("Load()") || !iLinked) {
        glDeleteObjectARB(m_hProgram);
        m_bInitialized=false;
        return;
      } else {
        m_bInitialized=true;
      }
    } else {
      if (hVS) glDeleteObjectARB(hVS);
      if (hFS) glDeleteObjectARB(hFS);
      glDeleteObjectARB(m_hProgram);
      m_hProgram=0;
      m_bInitialized=false;
      if (!bVSSuccess && !bFSSuccess) T_ERROR("Error in vertex and fragment shaders");
      else if (!bVSSuccess) T_ERROR("Error in vertex shader");
      else if (!bFSSuccess) T_ERROR("Error in fragment shader");
    }
  } else {
    // attach to program object
    m_hProgram=glCreateProgram();
    if (hVS) glAttachShader(m_hProgram,hVS);
    if (hFS) glAttachShader(m_hProgram,hFS);

    // link the program together
    if (bVSSuccess && bFSSuccess) {
      glLinkProgram(m_hProgram);

      // check for errors
      GLint iLinked;
      glGetProgramiv(m_hProgram,GL_LINK_STATUS,&iLinked);

      std::string fileDesc = std::string("VS: ") + std::string(VSFile) +
                             std::string(", FS:") + std::string(FSFile);
      WriteInfoLog(fileDesc.c_str(), m_hProgram, true);

      // flag shaders such that they can be deleted when they get detached
      if (hVS) glDeleteShader(hVS);
      if (hFS) glDeleteShader(hFS);
      if (CheckGLError("Load()") || iLinked!=GLint(GL_TRUE)) {
        glDeleteProgram(m_hProgram);
        m_hProgram=0;
        m_bInitialized=false;
        return;
      }
      else {
        m_bInitialized=true;
      }
    }
    else {
      if (hVS) glDeleteShader(hVS);
      if (hFS) glDeleteShader(hFS);
      glDeleteProgram(m_hProgram);
      m_hProgram=0;
      m_bInitialized=false;
      if (!bVSSuccess && !bFSSuccess) T_ERROR("Error in vertex and fragment shaders");
      else if (!bVSSuccess) T_ERROR("Error in vertex shader");
      else if (!bFSSuccess) T_ERROR("Error in fragment shader");
    }
  }
}