C is the new Assembler

As far back as I can tell, while I have used C, there was never a time when I didn’t have to write abstractions to make it easier to see that I am doing something in particular. Every knowledgeable C programmer would know that abstractions tend to make code easier to read, reducing the cost of maintenance, but it also incurs a performance penalty, as a result of data structure translations and additional function calls.

void ReadArray(Array arr, PopulateCallback cb, void* data)
{
	for (int i=0; i

This is because C was written to make assembler easier to write accurately for whatever machine it was compiled for. It was a method to allow UNIX to present the same face to the programmer no matter what machine it ran on, by abstracting commonly used concepts when dealing with hardware and operating systems. Thus the concept of pointers, packing, memory management and low-level optimizations are important in the language.

#define INITIALSIZE 32
Hashtable* CreateHashtable()
{
	Hashtable* h = malloc(sizeof(Hashtable));
	h->array = malloc(sizeof(INITIALSIZE));
	h->arraysize = INITIALSIZE;
	h->hashfun = &implePrimeHashFunc;
	return h;
}

void DeleteHashtable(Hashtable* h)
{
	free(h->array);
	free(h);
}

However, that is operating systems. Fast forward to the modern real world, which requires programs to
easily maintainable, and highly flexible when responding to code changes, layer after layer of abstraction is piled on top of each other to make the seemingly mundane tasks of sorting arrays and creating hashtables, or even responding to a user's keyboard possible. The reason for this is the low levelness of C. C does not have first class support for concepts that have arisen from real-world requirements and sensible programming techniques, such as closures, currying, lambdas and automated memory management.

class Program
{
	static void Main (string[] args)
	{
		Dictionary; mapOfEmployeeNumberToAge = new Dictionary();
		mapOfEmployeeNumberToAge.Add(5,6);
	}
}

This was because operating systems never had the luxury of being supported by a complete set of libraries. They have to stand on their own and can only depend on themselves. This meant that if one were to write an operating system for many machines, one needed an abstract form of assembler to be able to write for many platforms. Because C allowed OSes to present the same face across all platforms, it seemed the perfect choice at the time to write in C too, and it probably was.

FILE* fp = fopen("five.txt","w");
fprintf(fp, "%d", 5);
fclose(fp);

Looking at things this way, C is really just an abstract assembler, abstracting the single instructions into recognizable concepts such as pointers and associating them with types to reduce mistakes. In reality, nothing has changed in software development world ever since the 1970's when UNIX was conceived. People are still writing in assembler. There is nothing wrong with it, but the tediousness of having to abstract simple tasks has driven up the cost of writing software lately as complexity has increased tremendously.

short a = 0x1234;
short b = a;
   mov ax, 1234h
   mov bx, ax

However, mankind has probably learned the hard way that eventually there was need for better languages, and came up with many different languages such as Java, C++, C#, D, Processing, Python. All of which attempt to improve on C by introducing concepts absent in C that were highly desired by programmers. However, in an egoistic attempt to reach for the stars, they have all been made to compile directly to assembler, and thus end up still less portable than C and also perform slower as a result of those abstractions. In almost 40 years of development with C, it can be said that there is no other language more portable and no other language whose compilers are more capable of optimization than those for C.

error CS0006: cannot find metadata file `System.Windows.Forms.dll'Compilation failed:

One comes to wonder why, if there already are so many languages that can cover the shortcomings of C, they still cannot interoperate with C without an incredibly large amount of glue code and abstraction systems? All this makes for an extremely difficult situation which people have to bear with when they write for portability. Perhaps it is because the desires of proprietary lock ins done by companies such as Microsoft to promote this trend, to push their products such as COM/OLE and .NET which they preach as superior interop systems, yet fall short of achieving the very thing they are made to do, in order to prevent interop outside of Windows.

class NativeHashtable
{
	[DllImport("mydll")]
	static extern IntPtr CreateHashTable();

}

I propose that we leverage the existing codebase and toolchains that have made C so widely used and so well supported to make it simpler to write portable programs. This has many advantages: First, by targeting a subset of C that can be compiled by any existing C compiler at all, one effectively moves the repetitous task of writing abstractions and custom data structures to provide a code base from which programs can work on to the compiler specific to the language, and allowing the C compiler to provide the powerful optimization capabilites. Such a language that targets C will also find itself in a good position, since C already is compilable on many platforms, a language that targets C will be compilable too on many platforms.

	int NearestPow2(int n)
	{
		int x = 1;

		while(x < n) {
			x <<= 1;
		}

		return x;
	}

Also, compilers written for another language can perform their own optimizations in C code, which is what humans do, and maintain the rest of the program's data structures instead of having a human being do it, which is error prone and usually inconsistent. It also allows a program to write code effectively with one convention and allows one to automate the task of documenting hacks, tasks and tricks such as flag-reading, wrapping function pointers and checking datatypes, and maintaining structures and functions which use them, which is usually a choke point that requires extreme discipline from programmers and usually is tedious and takes up a lot of time.

// Populate an array.
// The PopulateCallback will be called as many times as there are elements in the array
// It will be given a pointer to a particular point in the array and it is cb's duty to modify
// the contents of each cell.
// data is any generic data that you can provide your cb for its use.
void PopulateArray(Array arr, PopulateCallback cb, void* data);

Writing such a compiler would also be easier than writing a compiler that targets assembler. There are more people who know C than people who know assembler, and it is an easy language to write automatically, since the same things are done over and over again when we write C code, in the form of maintaining declarations and definitions.

In order to target C for existing C compilers, one cannot realistically automate writing code for pure ANSI C. Instead, one must target a defined subset of C that resolves into machine code in a predictable way. There are many definitions out there such as C-- and CIL, however none of them have been put to significant practical use.

astrobunny@localhost$ ./program.cexe
C:\> cil program.cexe

If C were ever to be a target for modern languages, and used as an intermediate language for just-in-time compilation by compilers which have already abstracted system calls specific to a platform, one may finally be able to achieve the task that portability proponents have always longed for, with the performance to boot. C is the most portable language on Earth. Why not make the most of it?

Posted in Programming | 1 Comment

RBSP Tree for Lightmap packing

For fun, and for the purpose of making a batch texture that can store characters for fonts, I have created a little tree based off this tutorial by BlackPawn. Basically, the idea here is to partition the original rectangle in such a way to get the maximum area out of the texture to hold the subtextures.

The pseudocode provided in BlackPawn’s site is based off a simple concept. Basically, you partition an empty rectangle to store an image, and the other resulting empty rectangles are candidates for future partitioning. I call this structure a Rectangular Binary Space Partitioning Tree.

Continue reading

Posted in Graphics, Programming | Tagged , , , , , , , , | Leave a comment

2D in OpenGL

After some experimentation, I have finally come to a point where I have written some code that does scaling, rotation and alpha on images that I want to display on the screen. Although the concept of drawing 2D in OpenGL is fairly easy to grasp, in that everything is the same except you don’t deal with the z-dimension, most of the time when you deal with 2D, you want to deal in actual pixel coordinates on the screen, and you want to do some things differently. Despite the numerous tutorial in OpenGL you can find online, few actually provide much information about using OpenGL for 2D graphics.

Why OpenGL for 2D graphics?

Not too long ago I was working on a project to greatly simplify drawing an image on to screen and rotating and scaling it just as you could do in photoshop, but programatically, after a few months of working on it I started realizing how slow and heavy the process of actually doing that kind of transformation was. On a framebuffer, performing transforms like those and blitting it to the screen was something that was painfully slow, used 75% of the CPU time usually, and not suitable for any application that would be rich in graphic content.

This led me to attempting to try OpenGL. The main selling point OpenGL had was it enabled direct access to any graphics accelerator hardware available on the computer. Graphics cards have been purpose built to perform sampling on images, and were designed to reduce the amount of data transferred from the main memory for the purposes of drawing stuff on the screen. This enabled acceleration to the point where hundreds of images could be transformed on the fly without any drop in frame rate, and without burdening the CPU with having to process images at every frame.

OpenGL is now found almost everywhere a graphics card is installed, and most, if not all PCs and Macs now come with graphics card that supports OpenGL in one way or another. This means that an application written using OpenGL, will effectively, theoretically be usable on any computer at all. Also, its OS-neutral nature meant that any programs I write with it will be usable on any modern OS that supports a half-decent graphics subsystem.

Portability, ubiquity and performance. These were the key reasons I thought that it was time to give OpenGL a go, so I did.

So how do you do it?

OpenGL in 2D is nothing more than just OpenGL without using the Z-axis. There are tons of OpenGL tutorials out there *cough*NeHe*cough* that will teach you how to create a window and a rendering context for OpenGL. I recommend SDL for that purpose, because it has a set of libraries that work with it that simply does so much that you don’t have to find a library that does basic stuff like playing sounds and concentrate more on making your game. The only things you really need in addition to the standard 3D setup are to to map each pixel on the screen to OpenGL coordinates with gluOrtho2D and enabling alpha testing.

Some sample code stolen from somewhere below:

void glEnable2D()
{
	glEnable (GL_ALPHA_TEST); 

	int vPort[4];

	glGetIntegerv(GL_VIEWPORT, vPort);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	gluOrtho2D(0.0, vPort[2], vPort[3], 0.0);

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

}

So setting up OpenGL for 2D drawing is extremely simple. To draw something on the screen, simply go:

void drawFilledRectangle()
{
	glColor4f(255.0 , 0.0, 0.0, 255.0);

	glBindTexture( GL_TEXTURE_2D, 0 );

	glBegin( GL_QUADS );
	glVertex3i( 0, 0, 0 );
	glVertex3i( 100, 0, 0 );
	glVertex3i( 100, 100, 0 );
	glVertex3i( 0, 100, 0 );
	glEnd();
}

There we go, we have successfully drawn a rectangle on the screen. This may just become the start of a series of tutorials that I will write up as I learn more about using OpenGL for 2D drawings.

Posted in Graphics, Programming | Tagged , , | Leave a comment

Windows blues

After losing a few games of command and conquer and the computer blue screening when I’m just about to win, I am thoroughly convinced that contrary to their ads, Microsoft has never intended to make life easy for anyone. I swear by my keyboard I will make an OS that is actually reliable and usable by everyone someday. UURGH!

Posted in Random | Leave a comment

Different versions of MSVC have different versions of STL

Something that I have only recently noticed only after I have used MSVC for a while is that different versions of MSVC use different versions of the C++ standard template library. This isn’t a problem, unless you are linking libraries statically that were built with different versions of MSVC. For example, a static library that uses the STL built with MSVC 2003 would not be linkable with a program built with MSVC 2005 without a considerable amount of dicking around.

This is weird, because the STL is meant to be portable and make programs portable. It appears that Microsoft’s STL are not only a set of headers, but also a corresponding set of libraries that contain a set of functions that are used by the STL.

If you attempt to link a library built with a version of MSVC with a program built with another version of MSVC, the compiler will complain because it is unable to find references to the functions the library’s version of the STL calls.

The obvious way around this would be to link all the libraries the library depends on into itself, but that would cause problems with compiling with the same version of MSVC, and even more so when you are using static libraries that were all compiled with different versions of MSVC.

Usually you wouldn’t worry about this unless you are creating libraries to be used by other people, or using libraries written by other people. I wonder what Microsoft has against one STL to rule them all? So how do we get around this? Easy answer: You don’t use the STL.

Posted in Programming | Leave a comment

Shaders, where math meets art

Since playing with shaders is so much fun, lets have a little fun looking at what happens when you take an old game, and breathe some new life into it using a crazily reprogrammed pipeline:

Posted in Random | Leave a comment

Vertex Buffer Objects

In my last post I mentioned that if you wanted to draw a large number of things on a screen, you need VBOs. Well, honestly at the time, I only knew what it was but never touched it before. VBOs are Vertex Buffer Objects, in other words, boxes in the GPU to store vertices, their colors, normals and attributes. After a considerable amount of Googling, I was finally able to learn what VBOs are and relate them to the intermediate mode. This would probably help those who have started openGL by learning glBegin and glEnd learn about what VBOs truly are, and why they exist.

Continue reading

Posted in Graphics, Programming | Tagged , , , , , , , | Leave a comment

Playing with GLSL

After puzzling some time over the tutorials in Lighthouse3D, I finally learned how to prepare a GLSL shader and use it in an OpenGL render. In the beginning I thought a shader could be used on a particular set of vertices and fragments. However, it turned out that the shader was run every frame on every vertex and fragment you gave OpenGL to use. This meant that if you made a simple fragment shader that coloured the current fragment red, then everything you draw on the screen will be red. It turns out the shader replaces the so-called fixed-functionality in the rendering pipeline, which is basically a little assembly line where all the vertices and colours given to the video card gets processed. So instead of having the workers work their normal routine, a shader tells them what to do instead. To be honest I felt a little disappointed since I could not write something like actionscript would allow me to do, but I guess that is just because it isn’t meant to be actionscript.

Continue reading

Posted in Graphics, Programming | Tagged , , , , | Leave a comment

Reset

I never seem to be satisfied with any of the sites I made, so I made myself swear that this is the last time I’m going to replace the Labs site. The last one was a bit of a joke anyway. If you ever have a choice, Drupal 6 isn’t exactly a good CMS for building production sites, unless you have got plenty of in-house expertise. When you have to spend a whole day messing around with it to get it to let you post just one blog post, perhaps it just isn’t built to write posts.

So the difference is, yes I have moved down to the WordPress side to avoid the grief that comes with Drupal. I have decided that hacking something that works well is easier that hacking something that is borked. So I have decided that I will hack this. Woot. Now back to coding.

Posted in Random | Leave a comment