////////////////////////////////////////////////////////////
//                                                        //
//  PC MAGAZIN - PC Underground                           //
//                                                        //
//  OpenGL Extensions für die Vertex Shader	    	      //
//                                                        //
//  (w)(c)2002 Carsten Dachsbacher                        //
//                                                        //
////////////////////////////////////////////////////////////
#include <stdio.h>
#include "GLvertexprogram.h"

/*PFNGLBINDPROGRAMNVPROC glBindProgramNV;
PFNGLDELETEPROGRAMSNVPROC glDeleteProgramsNV;
PFNGLEXECUTEPROGRAMNVPROC glExecuteProgramNV;
PFNGLGENPROGRAMSNVPROC glGenProgramsNV;
PFNGLAREPROGRAMSRESIDENTNVPROC glAreProgramsResidentNV;
PFNGLREQUESTRESIDENTPROGRAMSNVPROC glRequestResidentProgramsNV;
PFNGLGETPROGRAMPARAMETERFVNVPROC glGetProgramParameterfvNV;
PFNGLGETPROGRAMPARAMETERDVNVPROC glGetProgramParameterdvNV;
PFNGLGETPROGRAMIVNVPROC glGetProgramivNV;
PFNGLGETPROGRAMSTRINGNVPROC glGetProgramStringNV;
PFNGLGETTRACKMATRIXIVNVPROC glGetTrackMatrixivNV;
PFNGLGETVERTEXATTRIBDVNVPROC glGetVertexAttribdvNV;
PFNGLGETVERTEXATTRIBFVNVPROC glGetVertexAttribfvNV;
PFNGLGETVERTEXATTRIBIVNVPROC glGetVertexAttribivNV;
PFNGLGETVERTEXATTRIBPOINTERVNVPROC glGetVertexAttribPointervNV;
PFNGLISPROGRAMNVPROC glIsProgramNV;
PFNGLLOADPROGRAMNVPROC glLoadProgramNV;
PFNGLPROGRAMPARAMETER4FNVPROC glProgramParameter4fNV;
PFNGLPROGRAMPARAMETER4DNVPROC glProgramParameter4dNV;
PFNGLPROGRAMPARAMETER4DVNVPROC glProgramParameter4dvNV;
PFNGLPROGRAMPARAMETER4FVNVPROC glProgramParameter4fvNV;
PFNGLPROGRAMPARAMETERS4DVNVPROC glProgramParameters4dvNV;
PFNGLPROGRAMPARAMETERS4FVNVPROC glProgramParameters4fvNV;
PFNGLTRACKMATRIXNVPROC glTrackMatrixNV;

PFNGLVERTEXATTRIBPOINTERNVPROC glVertexAttribPointerNV;
PFNGLVERTEXATTRIB1SNVPROC glVertexAttrib1sNV;
PFNGLVERTEXATTRIB1FNVPROC glVertexAttrib1fNV;
PFNGLVERTEXATTRIB1DNVPROC glVertexAttrib1dNV;
PFNGLVERTEXATTRIB2SNVPROC glVertexAttrib2sNV;
PFNGLVERTEXATTRIB2FNVPROC glVertexAttrib2fNV;
PFNGLVERTEXATTRIB2DNVPROC glVertexAttrib2dNV;
PFNGLVERTEXATTRIB3SNVPROC glVertexAttrib3sNV;
PFNGLVERTEXATTRIB3FNVPROC glVertexAttrib3fNV;
PFNGLVERTEXATTRIB3DNVPROC glVertexAttrib3dNV;
PFNGLVERTEXATTRIB4SNVPROC glVertexAttrib4sNV;
PFNGLVERTEXATTRIB4FNVPROC glVertexAttrib4fNV;
PFNGLVERTEXATTRIB4DNVPROC glVertexAttrib4dNV;
PFNGLVERTEXATTRIB4UBNVPROC glVertexAttrib4ubNV;
PFNGLVERTEXATTRIB1SVNVPROC glVertexAttrib1svNV;
PFNGLVERTEXATTRIB1FVNVPROC glVertexAttrib1fvNV;
PFNGLVERTEXATTRIB1DVNVPROC glVertexAttrib1dvNV;
PFNGLVERTEXATTRIB2SVNVPROC glVertexAttrib2svNV;
PFNGLVERTEXATTRIB2FVNVPROC glVertexAttrib2fvNV;
PFNGLVERTEXATTRIB2DVNVPROC glVertexAttrib2dvNV;
PFNGLVERTEXATTRIB3SVNVPROC glVertexAttrib3svNV;
PFNGLVERTEXATTRIB3FVNVPROC glVertexAttrib3fvNV;
PFNGLVERTEXATTRIB3DVNVPROC glVertexAttrib3dvNV;
PFNGLVERTEXATTRIB4SVNVPROC glVertexAttrib4svNV;
PFNGLVERTEXATTRIB4FVNVPROC glVertexAttrib4fvNV;
PFNGLVERTEXATTRIB4DVNVPROC glVertexAttrib4dvNV;
PFNGLVERTEXATTRIB4UBVNVPROC glVertexAttrib4ubvNV;
PFNGLVERTEXATTRIBS1SVNVPROC glVertexAttribs1svNV;
PFNGLVERTEXATTRIBS1FVNVPROC glVertexAttribs1fvNV;
PFNGLVERTEXATTRIBS1DVNVPROC glVertexAttribs1dvNV;
PFNGLVERTEXATTRIBS2SVNVPROC glVertexAttribs2svNV;
PFNGLVERTEXATTRIBS2FVNVPROC glVertexAttribs2fvNV;
PFNGLVERTEXATTRIBS2DVNVPROC glVertexAttribs2dvNV;
PFNGLVERTEXATTRIBS3SVNVPROC glVertexAttribs3svNV;
PFNGLVERTEXATTRIBS3FVNVPROC glVertexAttribs3fvNV;
PFNGLVERTEXATTRIBS3DVNVPROC glVertexAttribs3dvNV;
PFNGLVERTEXATTRIBS4SVNVPROC glVertexAttribs4svNV;
PFNGLVERTEXATTRIBS4FVNVPROC glVertexAttribs4fvNV;
PFNGLVERTEXATTRIBS4DVNVPROC glVertexAttribs4dvNV;
PFNGLVERTEXATTRIBS4UBVNVPROC glVertexAttribs4ubvNV;
*/

//PFNGLCOMBINERPARAMETERINVPROC glCombinerParameteriNV;

bool automipmap = false;

#define GETEXT( function, name ) \
	*(void**)&function = (void *)wglGetProcAddress( name ); \
	if ( function == NULL ) return false;

bool getVertexProgramExtensions()
{
	char *extensions;	
	extensions = strdup( (char*)glGetString( GL_EXTENSIONS ) );
	for ( unsigned int i = 0; i < strlen( extensions ); i ++ )
		if ( extensions[ i ] == ' ' ) extensions[ i ] = '\n';

/*
	FILE *f = fopen( "extensions.txt", "wt" );
	fprintf( f, "%s\n", extensions );
	fclose( f );
*/

	automipmap = false;
	if ( strstr( extensions, "GL_ARB_texture_cube_map" ) ||
		 strstr( extensions, "GL_NV_texgen_reflection" ) )
	{
		// benötigte extensions unterstützt

		// optionale extension
		if ( strstr( extensions, "GL_SGIS_generate_mipmap" ) )
			automipmap = true;
	} else
	{
		MessageBox( NULL, "Cube Mapping und/oder Reflection Mapping nicht unterstützt !", "Schade !", MB_OK );
		return false;
	}

	if ( strstr( extensions, "GL_ARB_multitexture" ) && 
		 strstr( extensions, "GL_NV_register_combiners" )
       )
	{	
		extern PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glCombinerStageParameterfvNV;
		extern PFNGLCOMBINEROUTPUTNVPROC glCombinerOutputNV;
		extern PFNGLCOMBINERINPUTNVPROC glCombinerInputNV;
		extern PFNGLFINALCOMBINERINPUTNVPROC glFinalCombinerInputNV;
		extern PFNGLCOMBINERPARAMETERINVPROC glCombinerParameteriNV;
		extern PFNGLCOMBINERPARAMETERFVNVPROC glCombinerParameterfvNV;

		//GETEXT( glCombinerStageParameterfvNV, "glCombinerStageParameterfvNV" );
		//GETEXT( glCombinerOutputNV, "glCombinerOutputNV" );
		//GETEXT( glCombinerInputNV, "glCombinerInputNV" );
		//GETEXT( glFinalCombinerInputNV, "glFinalCombinerInputNV" );
		//GETEXT( glCombinerParameterfvNV, "glCombinerParameterfvNV" );
		//GETEXT( glCombinerParameteriNV, "glCombinerParameteriNV" );
		
		extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;

		extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;

		glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress( "glClientActiveTextureARB" );	
		glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress( "glActiveTextureARB" );	

		glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)wglGetProcAddress( "glCombinerStageParameterfvNV" );
		glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)wglGetProcAddress( "glCombinerOutputNV" );
		glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)wglGetProcAddress( "glCombinerInputNV" );

		glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)wglGetProcAddress( "glFinalCombinerInputNV" );
		glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)wglGetProcAddress( "glCombinerParameteriNV" );

		glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)wglGetProcAddress( "glCombinerParameterfvNV" );
	} else
	{
		MessageBox( NULL, "Register Combiner werden nicht unterstützt !", "Schade !", MB_OK );
		return false;
	}


	if ( strstr( extensions, "NV_vertex_program" ) )
	{
		// benötigte extensions unterstützt
	} else
	{
		MessageBox( NULL, "Vertex Programs werden nicht von der aktuellen OpenGL Version unterstützt !", "Schade !", MB_OK );
		return false;
	}

	GETEXT( glBindProgramNV, "glBindProgramNV" );
	GETEXT( glDeleteProgramsNV, "glDeleteProgramsNV" );
	GETEXT( glExecuteProgramNV, "glExecuteProgramNV" );
	GETEXT( glGenProgramsNV, "glGenProgramsNV" );
	GETEXT( glAreProgramsResidentNV, "glAreProgramsResidentNV" );
	GETEXT( glRequestResidentProgramsNV, "glRequestResidentProgramsNV" );
	GETEXT( glGetProgramParameterfvNV, "glGetProgramParameterfvNV" );
	GETEXT( glGetProgramParameterdvNV, "glGetProgramParameterdvNV" );
	GETEXT( glGetProgramivNV, "glGetProgramivNV" );
	GETEXT( glGetProgramStringNV, "glGetProgramStringNV" );
	GETEXT( glGetTrackMatrixivNV, "glGetTrackMatrixivNV" );
	GETEXT( glGetVertexAttribdvNV, "glGetVertexAttribdvNV" );
	GETEXT( glGetVertexAttribfvNV, "glGetVertexAttribfvNV" );
	GETEXT( glGetVertexAttribivNV, "glGetVertexAttribivNV" );
	GETEXT( glGetVertexAttribPointervNV, "glGetVertexAttribPointervNV" );
	GETEXT( glIsProgramNV, "glIsProgramNV" );
	GETEXT( glLoadProgramNV, "glLoadProgramNV" );
	GETEXT( glProgramParameter4fNV, "glProgramParameter4fNV" );
	GETEXT( glProgramParameter4dNV, "glProgramParameter4dNV" );
	GETEXT( glProgramParameter4dvNV, "glProgramParameter4dvNV" );
	GETEXT( glProgramParameter4fvNV, "glProgramParameter4fvNV" );
	GETEXT( glProgramParameters4dvNV, "glProgramParameters4dvNV" );
	GETEXT( glProgramParameters4fvNV, "glProgramParameters4fvNV" );
	GETEXT( glTrackMatrixNV, "glTrackMatrixNV" );
	GETEXT( glVertexAttribPointerNV, "glVertexAttribPointerNV" );
	GETEXT( glVertexAttrib1sNV, "glVertexAttrib1sNV" );
	GETEXT( glVertexAttrib1fNV, "glVertexAttrib1fNV" );
	GETEXT( glVertexAttrib1dNV, "glVertexAttrib1dNV" );
	GETEXT( glVertexAttrib2sNV, "glVertexAttrib2sNV" );
	GETEXT( glVertexAttrib2fNV, "glVertexAttrib2fNV" );
	GETEXT( glVertexAttrib2dNV, "glVertexAttrib2dNV" );
	GETEXT( glVertexAttrib3sNV, "glVertexAttrib3sNV" );
	GETEXT( glVertexAttrib3fNV, "glVertexAttrib3fNV" );
	GETEXT( glVertexAttrib3dNV, "glVertexAttrib3dNV" );
	GETEXT( glVertexAttrib4sNV, "glVertexAttrib4sNV" );
	GETEXT( glVertexAttrib4fNV, "glVertexAttrib4fNV" );
	GETEXT( glVertexAttrib4dNV, "glVertexAttrib4dNV" );
	GETEXT( glVertexAttrib1svNV, "glVertexAttrib1svNV" );
	GETEXT( glVertexAttrib1fvNV, "glVertexAttrib1fvNV" );
	GETEXT( glVertexAttrib1dvNV, "glVertexAttrib1dvNV" );
	GETEXT( glVertexAttrib2svNV, "glVertexAttrib2svNV" );
	GETEXT( glVertexAttrib2fvNV, "glVertexAttrib2fvNV" );
	GETEXT( glVertexAttrib2dvNV, "glVertexAttrib2dvNV" );
	GETEXT( glVertexAttrib3svNV, "glVertexAttrib3svNV" );
	GETEXT( glVertexAttrib3fvNV, "glVertexAttrib3fvNV" );
	GETEXT( glVertexAttrib3dvNV, "glVertexAttrib3dvNV" );
	GETEXT( glVertexAttrib4svNV, "glVertexAttrib4svNV" );
	GETEXT( glVertexAttrib4fvNV, "glVertexAttrib4fvNV" );
	GETEXT( glVertexAttrib4dvNV, "glVertexAttrib4dvNV" );
	GETEXT( glVertexAttrib4ubvNV, "glVertexAttrib4ubvNV" );
	GETEXT( glVertexAttribs1svNV, "glVertexAttribs1svNV" );
	GETEXT( glVertexAttribs1fvNV, "glVertexAttribs1fvNV" );
	GETEXT( glVertexAttribs1dvNV, "glVertexAttribs1dvNV" );
	GETEXT( glVertexAttribs2svNV, "glVertexAttribs2svNV" );
	GETEXT( glVertexAttribs2fvNV, "glVertexAttribs2fvNV" );
	GETEXT( glVertexAttribs2dvNV, "glVertexAttribs2dvNV" );
	GETEXT( glVertexAttribs3svNV, "glVertexAttribs3svNV" );
	GETEXT( glVertexAttribs3fvNV, "glVertexAttribs3fvNV" );
	GETEXT( glVertexAttribs3dvNV, "glVertexAttribs3dvNV" );
	GETEXT( glVertexAttribs4svNV, "glVertexAttribs4svNV" );
	GETEXT( glVertexAttribs4fvNV, "glVertexAttribs4fvNV" );
	GETEXT( glVertexAttribs4dvNV, "glVertexAttribs4dvNV" );
	GETEXT( glVertexAttribs4ubvNV, "glVertexAttribs4ubvNV" );

	return true;
}