Last Ray of Hope Home of Kaluriel Hargrove

2Nov/11Off

SprintfCat

On the train to Cardiff yesterday, I was creating a fixed function shader generator for the Athena engine. I kept using strcat() with if statements, and in a lot of places I kept using sprintf() then copying that in with strcat().

So I decided to make SprintfCat(), all the wonderful joy of sprintf, with the ability to concatenate with a already existant string like strcat.

//
//
size_t ath::SprintfCat( char * inoutBuffer, const size_t inBufferSize, const char * inFormat, ... )
{
	const size_t offset = StrLen( inoutBuffer );
	size_t ret = 0;
	va_list arg;
 
	//
	va_start( arg, inFormat );
	{
		ret = VSprintf( inoutBuffer + offset, inBufferSize - offset, inFormat, arg );
	}
	va_end( arg );
 
	//
	return offset + ret;
}

I had already created my own wrappers around strlen() and vsprintf(), the reason being the fault of Microsoft. With their implementation of the standard library, they decided to deprecate non-safe versions complain at you until you either used their own _s variants, or defined a certain preprocessor.

//
//
size_t ath::VSprintf( char * outBuffer, const size_t inBufferSize, const char * inFormat, va_list inArgs )
{
#ifndef ATH_PLATFORM_WINDOWS
	return vsnprintf( outBuffer, inBufferSize, inFormat, inArgs );
#else
	return vsprintf_s( outBuffer, inBufferSize, inFormat, inArgs );
#endif
}
 
//
//
size_t ath::StrLen( const char * inString )
{
	return strlen( inString );
}

While I do prefer to have safe versions, their _s variants are not present in the standard and so it makes the code not portable.

I'm still not quite sure about my naming convention for a variable that is an input and an output. While I do like the in or out prefix, I don't think inout looks right, being slightly too long. I wasn't a fan of io either. I have however grown to like the truncation of Athena namespace to ath.

28Oct/11Off

OpenGL Shader Debugging

One thing that always annoys me with using glGetShaderInfoLog(), is that when compiling OpenGL shaders multiple sources can be used. Because of this, the line numbers get shifted, and trying to find line 123 where a syntax error exists is a length process.

So I made a function that will take the sources list and output the lines with line numbers.

void OutputWithLineNumbers( const char ** inSources, const unsigned int inCount )
{
	bool unendedLineNo = false;
	int lineNumber = 1;
 
	for( unsigned int i = 0; i < inCount; ++i )
	{
		const char * cur = inSources[i];
		const char * next = NULL;
 
		do
		{
			//
			if( !unendedLineNo )
			{
				printf( "%04d: ", lineNumber );
			}
 
			//
			next = strchr( cur, '\r' );
 
			//
			if( next )
			{
				size_t len = ( next - cur );
				char * lineText = (char *)alloca( len );
				memcpy( lineText, cur, len );
				lineText[len] = 0;
 
				printf( "%s\n", lineText );
 
				unendedLineNo = false;
				++lineNumber;
			}
			else
			{
				printf( "%s", cur );
				unendedLineNo = true;
			}
 
			//
			cur = next + 2;
		} while( next );
	}
 
	if( unendedLineNo )
	{
		printf( "\n" );
	}
}

This code requires the source files to have a carriage return as well as a new line character.

26Aug/11Off

XCode4 Build Rules for iOS

For a while now I have been manually compiling files since my asset conversion pipeline tool is not quite finished yet.

So I took at look into Build Rules in XCode. My main trouble within using them was finding the environment variables, even googling them doesn't turn up much information.

I think the output files act as an error check, if the output file fails to appear then the tool failed.

One other thing I had an issue with was the source files list. I tried comma and semi colon delimiters, and spaces, but the TGA file kept giving the warning on Tree1.tga. I have yet t0 find the a way to do this without multiple entries. And I'm thinking a separate tool for building files may be easier.

 

Tagged as: , No Comments
25Aug/11Off

iPhone Orientation

Earlier I wanted to test my engine with autorotation for when an iOS device's orientation changes. I spent a fair bit of time trying to work out why, sure that I had written some code somewhere to stop it from triggering.

After creating another app and still haven't the same problem, I was about to report it as a bug when the answer dawned on me, I had the orientation lock on.

It would be nice if you could do it on an application basis as well as a global one, since I only turn it on because photos get orientated incorrectly.

The contents of my "Useless" app folder: Stocks, Weather, Contacts, Calculator, Voice Memos, Compass, Reminders. If only you could turn off the default apps as well.

On another note, I've added a page next to website for iOS specific links.

Tagged as: No Comments
18Aug/11Off

iOS: Using Separate Shaders

One of the lovely additions to iOS5 is there is now the ability to use separate vertex and fragment shaders (GL_EXT_separate_shader_objects).

The first step in using separate shaders is to create an object to bind them onto that will be our overall shader program, known as a pipeline object.

GLuint gProgramPipeline = 0;
GLuint gVertexProgram = 0;
GLuint gFragmentProgram = 0;
 
//
//
int main()
{
	//
	CreatePipeline();
	CreateShaders();
 
	//
	BindShadersToPipeline();
 
	//
	do
	{
		//
		UpdateUniforms();
 
		//
		BindPipeline();
		DrawSomething();
		UnbindPipeline();
	}
	while( true );
 
	//
	DestroyShaders();
	DestroyPipeline();
}
 
//
//
void CreatePipeline()
{
	glGenProgramPipelinesEXT( 1, &gProgramPipeline );
}
 
//
//
void DestroyPipeline()
{
	if( gProgramPipeline )
	{
		glDeleteProgramPipelinesEXT( 1, &gProgramPipeline );
		gProgramPipeline = 0;
	}
}

This pipeline object acts similar to vertex array object (VAO) only with shader programs, however instead of using glUseProgram, a separate function glUseProgramStagesEXT() must be used to bind the shader program to the pipeline, specifying the role of the shader program.

//
//
void BindShadersToPipeline()
{
	glUseProgramStagesEXT( gProgramPipeline, GL_VERTEX_SHADER_BIT_EXT, gVertexProgram );
	glUseProgramStagesEXT( gProgramPipeline, GL_FRAGMENT_SHADER_BIT_EXT, gFragmentProgram );
}

Updating uniforms is slightly different as well.

//
//
void UpdateUniforms()
{
	//
	GLint uniformLoc = glGetUniformLocation( gVertexProgram, "myVertUniform" );
	glProgramUniform1fEXT( gVertexProgram,
			       uniformLoc,
			       1.248f );
 
	uniformLoc = glGetUniformLocation( gFragmentProgram, "myFragUniform" );
	glProgramUniform1fEXT( gFragmentProgram,
			       uniformLoc,
			       6.1218f );
 
	//
	uniformLoc = glGetUniformLocation( gVertexProgram, "myCommonUniform" );
	float commonValue = 2.0f;
 
	glProgramUniform1fEXT( gVertexProgram,
			       uniformLoc,
			       commonValue );
 
	uniformLoc = glGetUniformLocation( gFragmentProgram, "myCommonUniform" );
	glProgramUniform1fEXT( gVertexProgram,
			       uniformLoc,
			       commonValue );
}

Finally to use the program pipeline, we just need to bind it.

//
//
void BindPipeline()
{
	glBindProgramPipelineEXT( gProgramPipeline );
}
 
//
//
void UnbindPipeline()
{
	glBindProgramPipelineEXT( 0 );
}

fef

18Aug/11Off

Bootstrap Server and thread yielding

One annoying this about iOS development is when the device crashes and you get the following message.

"Couldn't register com.yourcompany.youapp with the bootstrap server. Error: unknown error code.
This generally means that another instance of this process was already running or is hung in the debugger."

It usually means a restart of a few minutes. I kept getting these when using an iterative formula to calculate something. I have made a mistake of subtracting instead of adding, and I ended up getting into an infinite loop (I really should have put an attempt timeout in the while condition).

This happened about 5-6 times before I was able to track it down, and when working on the main thread, I couldn't seem to put a breakpoint in to debug it.

However I found that calling sched_yield() on the main thread within my loop, did stop (or at least drastically reduce) the number of bootstrap failures.

"Internet Explorer, the Number One browser for downloading a better browser."