//
 // Destructor
 //
 CShadingProgram::~CShadingProgram()
 {
     glClearErrors();
     glDeleteProgram( m_Program ); 
     if (glGetError() != GL_NO_ERROR)
         Print( Sys::CLog::PT_ERROR, "::~CShadingProgram() : Failed to delete GLSL program." );
 }
    //
    // SetFeedbackVaryings
    // Called after program linking!
    //
    void CShadingProgram::SetFeedbackVaryings( 
                                              const vector<string>& Varyings, 
                                              GLenum Mode 
                                              )
    {
        if (!m_Extensions->NV_transform_feedback)
            throw CExtensionException( this, "::SetFeedbackVaryings()", "GL_NV_transform_feedback." );
        
        if (Varyings.empty())
            throw Sys::CDeveloperException( this, "::SetFeedbackVaryings() : Invalid <Varyings> parameter." );
        if (Mode != GL_INTERLEAVED_ATTRIBS_NV && Mode != GL_SEPARATE_ATTRIBS_NV)
            throw Sys::CDeveloperException( this, "::SetFeedbackVaryings() : Invalid <Mode> parameter." );

        vector<GLint> Locations;

        glClearErrors();
        for (int i = 0; i < static_cast<int>( Varyings.size() ); ++i) 
        {
            GLint Location = glGetVaryingLocationNV( m_Program, Varyings[ i ].c_str() );
            if (Location == -1)
                throw Sys::CException( this, "::SetFeedbackVaryings() : Failed to determine location of varying \"%s\".", Varyings[ i ].c_str() );
                       
            Locations.push_back( Location );
        }
        glTransformFeedbackVaryingsNV( m_Program, static_cast<GLsizei>( Locations.size() ), &Locations[ 0 ], Mode );
        GLenum Error = glGetError();
        if (Error != GL_NO_ERROR)
            throw CException( this, Error, "::SetFeedbackVaryings() : An OpenGL error has occured.." );
    }
    //
    // GetInfoLog
    //
    string CShadingProgram::GetInfoLog() const
    {
        vector<GLchar> InfoLog;
        GLint InfoLogLength;

        glClearErrors();
        glGetProgramiv( m_Program, GL_INFO_LOG_LENGTH, &InfoLogLength );
        if (InfoLogLength > 1)
			InfoLog.resize( InfoLogLength, '\0' );
		else
			return "";

        glGetProgramInfoLog( m_Program, InfoLogLength, NULL, &InfoLog[0] );
        GLenum Error = glGetError();
        if (Error != GL_NO_ERROR)
            throw CException( this, Error, "::GetInfoLog() : An OpenGL error has occured." );
		
		if (InfoLogLength > 2)
		{
			if (InfoLog[ InfoLogLength - 2 ] == '\n') // ATI.
				InfoLog[ InfoLogLength - 2 ] = '\0';
		}

        return &InfoLog[ 0 ];
    }
    //
    // GetNumUniforms
    //
    GLuint CShadingProgram::GetNumUniforms() const
    {
        glClearErrors();
        GLint NumUniforms;
        glGetProgramiv( m_Program, GL_ACTIVE_UNIFORMS, &NumUniforms );
        GLenum Error = glGetError();
        if (Error != GL_NO_ERROR)
            throw CException( this, Error, "::GetNumUniforms() : An OpenGL error has occured." );

        return NumUniforms;
    }
 //
 // BindAttribLocation
 //
 void CShadingProgram::BindAttribLocation( 
                                          const string& Name, 
                                          GLuint Index 
                                          )
 {
     glClearErrors();
     glBindAttribLocation( m_Program, Index, Name.c_str() );
     GLenum Error = glGetError();
     if (Error != GL_NO_ERROR)
         throw CException( this, Error, "::BindAttribLocation() : Failed to bind \"%s\" to generic vertex attribute %d.", Name.c_str(), Index );
 }
    //
    // SetActiveVarying
    //
    void CShadingProgram::SetActiveVarying( 
                                           const string& Name 
                                           )
    {
        if (!m_Extensions->NV_transform_feedback)
            throw CExtensionException( this, "::SetActiveVarying()", "GL_NV_transform_feedback." );

        glClearErrors();
        glActiveVaryingNV( m_Program, Name.c_str() );
        GLenum Error = glGetError();
        if (Error != GL_NO_ERROR)
            throw CException( this, Error, "::SetActiveVarying() : Failed to force the linker to mark a varying variable \"%s\" as active.", Name.c_str() );
    }
Example #7
0
bool ProgramStringIsNative(GLenum target, const char* filename)
{
	// clear any current GL errors so that the following check is valid
	glClearErrors();

	const GLuint tempProg = LoadProgram(target, filename, (target == GL_VERTEX_PROGRAM_ARB? "vertex": "fragment"));

	if (tempProg == 0) {
		return false;
	}

	glSafeDeleteProgram(tempProg);
	return true;
}
    //
    // GetUniformDesc
    //
    void CShadingProgram::GetUniformDesc( 
                                         GLuint Index, 
                                         TVariableDesc *Desc 
                                         ) const
    {
        GLint MaxLength;
        glGetProgramiv( m_Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &MaxLength );

        vector<GLchar> Name( MaxLength, '\0' );

        glClearErrors();
        glGetActiveUniform( m_Program, Index, MaxLength, NULL, &Desc->Size, &Desc->Type, &Name[ 0 ] );
        GLenum Error = glGetError();
        if (Error != GL_NO_ERROR)
            throw CException( this, Error, "::GetUniformDesc() : An OpenGL error has occured." );

        Desc->Index = Index;
        Desc->Name = &Name[ 0 ];
    }
    //
    // Constructor
    //
    CShadingProgram::CShadingProgram():
        m_Program( 0 )
    {
        if (!m_Extensions->OpenGL_2_0)
        {
            throw CExtensionException( this, "::CShadingProgram()", 2, 0 );
        }

        glClearErrors();
        m_Program = glCreateProgram();
        if (!m_Program)
        {
            GLenum Error = glGetError();
            if (Error != GL_NO_ERROR)
                throw CException( this, Error, "::CShadingProgram() : Failed to create GLSL program." );
            else
                throw Sys::CException( this, "::CShadingProgram() : Failed to create GLSL program." ); 
        }
    }
Example #10
0
    //
    // AttachShader
    //
    void CShadingProgram::AttachShader( 
                                       Ptr<const CShader> Shader
                                       )
    {
        glClearErrors();
        glAttachShader( m_Program, Shader->m_Shader );
        
        if (Shader->m_Target == GL_GEOMETRY_SHADER_EXT)
        {
            Ptr<const CGeometryShader> GeometryShader = Shader.CastTo<const CGeometryShader>();

            glProgramParameteriEXT( m_Program, GL_GEOMETRY_VERTICES_OUT_EXT, GeometryShader->m_VerticesOut );
            glProgramParameteriEXT( m_Program, GL_GEOMETRY_INPUT_TYPE_EXT, GeometryShader->m_InputTopology );
            glProgramParameteriEXT( m_Program, GL_GEOMETRY_OUTPUT_TYPE_EXT, GeometryShader->m_OutputTopology );
        }
        
		GLenum Error = glGetError();
        if (Error != GL_NO_ERROR)
            throw CException( this, Error, "::AttachShader() : An OpenGL error has occured." ); 
    }
 //
 // Set
 //
 void CCgShadingProgram::Set() const
 {
     cgGLBindProgram( m_Program );
 #ifdef _DEBUG
     CGerror Error = cgGetError();
     if (Error != CG_NO_ERROR)
         throw CCgException( this, Error, "::Set() : A Cg error has occured." );
 #endif
     
     if (!m_FeedbackAttribs.empty())
     {
 #ifdef _DEBUG
         glClearErrors();
 #endif
         glTransformFeedbackAttribsNV( static_cast<GLsizei>( m_FeedbackAttribs.size() / 3 ), &m_FeedbackAttribs[ 0 ], m_FeedbackMode );
 #ifdef _DEBUG
         GLenum Error = glGetError();
         if (Error != GL_NO_ERROR)
             throw CException( this, Error, "::Set() : An OpenGL error has occured." );
 #endif
     }
 }
Example #12
0
void CMapGenerator::GenerateSMT(CVirtualArchive* archive)
{
	CVirtualFile* fileSMT = archive->AddFile("maps/generated.smt");

	const int tileSize = 32;

	//--- Make TileFileHeader ---
	TileFileHeader smtHeader;
	strcpy(smtHeader.magic, "spring tilefile");
	smtHeader.version = 1;
	smtHeader.numTiles = 1; //32 * 32 * (generator->GetMapSize().x * 32) * (generator->GetMapSize().y * 32);
	smtHeader.tileSize = tileSize;
	smtHeader.compressionType = 1;

	const int bpp = 3;
	int tilePos = 0;
	unsigned char tileData[tileSize * tileSize * bpp];
	for(int x = 0; x < tileSize; x++)
	{
		for(int y = 0; y < tileSize; y++)
		{
			tileData[tilePos] = 0;
			tileData[tilePos + 1] = 0xFF;
			tileData[tilePos + 2] = 0;
			tilePos += bpp;
		}
	}
	glClearErrors();
	GLuint tileTex;
	glGenTextures(1, &tileTex);
	glBindTexture(GL_TEXTURE_2D, tileTex);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, tileSize, tileSize, 0, GL_RGB, GL_UNSIGNED_BYTE, tileData);
	glGenerateMipmapEXT(GL_TEXTURE_2D);
	char tileDataDXT[SMALL_TILE_SIZE];

	int dxtImageOffset = 0;
	int dxtImageSize = 512;
	for(int x = 0; x < 4; x++)
	{
		glGetCompressedTexImage(GL_TEXTURE_2D, x, tileDataDXT + dxtImageOffset);
		dxtImageOffset += dxtImageSize;
		dxtImageSize /= 4;
	}

	glDeleteTextures(1, &tileTex);

	GLenum errorcode = glGetError();
	if(errorcode != GL_NO_ERROR)
	{
		throw content_error("Error generating map - texture generation not supported");
	}

	size_t totalSize = sizeof(TileFileHeader);
	fileSMT->buffer.resize(totalSize);

	int writePosition = 0;
	memcpy(&(fileSMT->buffer[writePosition]), &smtHeader, sizeof(smtHeader));
	writePosition += sizeof(smtHeader);

	fileSMT->buffer.resize(fileSMT->buffer.size() + smtHeader.numTiles * SMALL_TILE_SIZE);
	for(int x = 0; x < smtHeader.numTiles; x++)
	{
		memcpy(&(fileSMT->buffer[writePosition]), tileDataDXT, SMALL_TILE_SIZE);
		writePosition += SMALL_TILE_SIZE;
	}
}
Example #13
0
string LuaTextures::Create(const Texture& tex)
{	
	GLint currentBinding;
	glGetIntegerv(GL_TEXTURE_BINDING_2D, &currentBinding);

	GLuint texID;
	glGenTextures(1, &texID);
	glBindTexture(tex.target, texID);

	GLenum dataFormat = GL_RGBA;
	GLenum dataType   = GL_UNSIGNED_BYTE;
	if ((tex.format == GL_DEPTH_COMPONENT) ||
	    (tex.format == GL_DEPTH_COMPONENT16) ||
	    (tex.format == GL_DEPTH_COMPONENT24) ||
	    (tex.format == GL_DEPTH_COMPONENT32)) {
		dataFormat = GL_DEPTH_COMPONENT;
		dataType = GL_FLOAT;
	}

	glClearErrors();
	glTexImage2D(tex.target, 0, tex.format,
	             tex.xsize, tex.ysize, tex.border,
	             dataFormat, dataType, NULL);
	const GLenum err = glGetError();
	if (err != GL_NO_ERROR) {
		glDeleteTextures(1, &texID);
		glBindTexture(GL_TEXTURE_2D, currentBinding);
		return string("");
	}

	glTexParameteri(tex.target, GL_TEXTURE_WRAP_S, tex.wrap_s);
	glTexParameteri(tex.target, GL_TEXTURE_WRAP_T, tex.wrap_t);
	glTexParameteri(tex.target, GL_TEXTURE_WRAP_R, tex.wrap_r);
	glTexParameteri(tex.target, GL_TEXTURE_MIN_FILTER, tex.min_filter);
	glTexParameteri(tex.target, GL_TEXTURE_MAG_FILTER, tex.mag_filter);
	glTexParameteri(tex.target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);

	if ((tex.aniso != 0.0f) && GLEW_EXT_texture_filter_anisotropic) {
		static GLfloat maxAniso = -1.0f;
		if (maxAniso == -1.0f) {
			glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
		}
		const GLfloat aniso = std::max(1.0f, std::min(maxAniso, tex.aniso));
		glTexParameterf(tex.target, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
	}

	glBindTexture(GL_TEXTURE_2D, currentBinding); // revert the current binding

	GLuint fbo = 0;
	GLuint fboDepth = 0;

	if (tex.fbo != 0) {
		if (!GLEW_EXT_framebuffer_object) {
			glDeleteTextures(1, &texID);
			return string("");
		}
		GLint currentFBO;
		glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &currentFBO);

		glGenFramebuffersEXT(1, &fbo);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

		if (tex.fboDepth != 0) {
			glGenRenderbuffersEXT(1, &fboDepth);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepth);
			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,
			                         tex.xsize, tex.ysize);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
			                             GL_RENDERBUFFER_EXT, fboDepth);
		}

		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
		                          tex.target, texID, 0);

		const GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
		if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
			glDeleteTextures(1, &texID);
			glDeleteFramebuffersEXT(1, &fbo);
			glDeleteRenderbuffersEXT(1, &fboDepth);
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, currentFBO);
			return string("");
		}

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, currentFBO);
	}

	lastCode++;
	char buf[64];
	SNPRINTF(buf, sizeof(buf), "%c%i", prefix, lastCode);
	Texture newTex = tex;
	newTex.id = texID;
	newTex.name = buf;
	newTex.fbo = fbo;
	newTex.fboDepth = fboDepth;
	textures[newTex.name] = newTex;

	return newTex.name;
}