Category Archives: Personal Rantings - Page 2

What I (don't) like about C#

I've been using C# personally quite a bit lately and want to share with you a list of the things I like or don't about it.

First the things I like about it (compared to C++ and Java sometimes):

  • The out and ref keywords are awesome
    You actually need to use them both when declaring out and reference parameters and in the actual function calls.
    This really avoids confusion and makes the code clearer compared to the way references are transparently handled in C++.
  • a class's definition and declaration is kept in just one file
    Avid C++ coders will probably disagree with me here, but I really like this way of coding things. It allows me to code faster and also reduces one source of compiler errors. To be honest I would probably go insane when coding in C++ if it wasn't for Visual Assist's nifty "Move Implementation to Source File" and "Create Declaration/Implementation" refactorings.
    Likewise one could say that C#'s (or .NET's) notion of assemblies is better and less messy than C/C++'s compilation units.
  • Properties are simply awesome
    Properties look like normal member variables but you can write your own getter and setter functions and also give both different access levels, so e.g. you can have a property that is public for reading but protected for writing.
    Moreover, you can have C# create the code automatically, so you just end up with a way to specify separate access levels.
  • Read-only variables can be set anywhere in the constructor
    If you know C++'s initialization lists, you will thank god for this feature, because this feature gives you a lot more freedom and again results in more readable code (at least in my opinion).
  • The override and new keywords are really handy
    Again this is a feature to avoid unnecessary bugs because you get warnings as soon as you "override" a method that doesn't exist.

What I don't like:

  • No typedefs
    This really bugs me, because the concept of typedefs is a good way to add abstraction to your code and the using keyword in C# only marginally improves the situation, because it only affects the current module.
  • No default/optional parameters
    You have to overload methods instead, which is kind of annoying. I hope this gets fixed sooner or later.
  • No inner classes like in Java
    Passing on references to constructors is annoying and inner classes in Java really help it quite often.
  • No synchronized keyword like in Java
    Again this is a nice-to-have feature because it would  clean up some code.

How to make WordPress display Full Text in RSS Feeds

... and why WordPress Moderators are obviously idiots

Today I got an email asking me to enable full text RSS feeds - so far so good, only when I activated the "Full Text" option nothing changed - neither in FireFox, nor in Google Reader, nor anywhere else. Only in Feed Proxy I saw a <content:encoded> tag appear that contained the full text (including html tags), but the description still only contained the excerpt (without html tags).

Before I link you to the thread that made me conclude the statement in the post title, let me quote from the RSS 2.0 specs:

A channel may contain any number of <item>s. An item may represent a "story" -- much like a story in a newspaper or magazine; if so its description is a synopsis of the story, and the link points to the full story. An item may also be complete in itself, if so, the description contains the text (entity-encoded HTML is allowed; see examples), and the link and title may be omitted. All elements of an item are optional, however at least one of title or description must be present.

That said take a look at http://wordpress.org/support/topic/190901 - having the problem described above and reading the replies, it just left me with one question:

If Otto42 is a moderator, where does WordPress get its trolls from?

The RSS Specs are pretty unspecific and blurry when it comes to the issue, one can at most point to http://www.feedvalidator.org/docs/warning/DuplicateDescriptionSemantics.html, but the main issue I have is that the rants of this "moderator" don't help me fix my problem, because Google Reader and FireFox still don't display the full entries.

A fix for it

If you want to fix it, you can do the following (in WP 2.7):

Open up wp-includes/feed-rss2.php and change

<?php if (get_option('rss_use_excerpt')) : ?>
<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
<?php else : ?>
<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
<?php if ( strlen( $post->post_content ) > 0 ) : ?>
<content:encoded><![CDATA[<?php the_content() ?>]]></content:encoded>
<?php else : ?>
<content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
<?php endif; ?>
<?php endif; ?>

to

<?php if (get_option('rss_use_excerpt')) : ?>
<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
<?php else : ?>
<description><![CDATA[<?php the_content() ?>]]></description>
<?php endif; ?>

Similarly, if you want to fix your comments, too, open wp-includes/feed-rss2-comments.php and change

<?php if ( post_password_required($comment_post) ) : ?>
<description><?php echo ent2ncr(__('Protected Comments: Please enter your password to view comments.')); ?></description>
<content:encoded><![CDATA[<?php echo get_the_password_form() ?>]]></content:encoded>
<?php else : // post pass ?>
<description><?php comment_text_rss() ?></description>
<content:encoded><![CDATA[<?php comment_text() ?>]]></content:encoded>
<?php endif; // post pass

to

<?php if ( post_password_required($comment_post) ) : ?>
<description><![CDATA[<?php echo get_the_password_form() ?>]]></description>
<?php else : // post pass ?>
<description><![CDATA[<?php comment_text() ?>]]></description>
<?php endif; // post pass

Cheers,
Andreas

Partial Integration and the Substitution Rule

I only want to write this down to have a place to look it up:

If we want to integrate \displaystyle{ \int_{a}^{b}{f'\left(x \right) g\left( x\right)} } , we can use:


  \displaystyle { (f \cdot g)'\left( x \right) & = f'\left(x \right)g\left(x \right) +  f\left(x \right)g'\left(x \right) } \\
 \displaystyle { \Leftrightarrow f\left(x \right)g\left(x \right) \big |_{a=x}^b } & = \displaystyle { \int_{a}^{b}{ f'\left(x \right)g\left(x \right) +  f\left(x \right)g' \left(x \right) } \, dx  } \\
\displaystyle { \Leftrightarrow \int_{a}^{b}{ f'\left(x \right)g\left(x \right) }\, dx } & \displaystyle { = f\left(x \right)g\left(x \right) |_{a=x}^b - \int_{a}^{b}{ f\left(x \right)g' \left(x \right) } \, dx }

And if we want to substitute a function in an integral:

 
{  \int_{g\left(a \right)}^{g\left(b \right)}{ f\left( x  \right) } \, dx = F \left ( g \left ( b \right ) \right ) - F \left ( g \left ( a \right ) \right ) = \left (F \circ g \right ) \left ( b \right ) - \left (F \circ g \right ) \left ( a \right ) = } \\ 
= \int_{a}^{b}{ \left (F \circ g \right ) ' \left ( x \right )  } \, dx = \int_{a}^{b}{ f \left ( g  \left ( x \right ) \right )  } \, g' \left ( x \right ) \, dx

(with  F \left ( x \right ) = \int^{x}{ f \left ( x \right )} \, dx)
or using a trick:

\int_{a}^{b}{f \left ( g \left ( x \right ) \right ) } \, dx = F \left ( b \right ) - F \left ( a \right ) = \left ( F \circ g \circ g^{-1} \right ) \left ( b \right ) - \left ( F \circ g \circ g^{-1} \right ) \left ( a \right ) = \\
= \left ( F \circ g^{-1} \right ) \left( g \left ( b \right ) \right ) - \left ( F \circ g^{-1} \right ) \left( g \left ( a \right ) \right ) =
\int_{g \left ( a \right )}^{g \left ( b \right )}{ \left ( F \circ g^{-1} \right ) ' \left ( x \right ) } \, dx = \\
= \int_{g \left ( a \right )}^{g \left ( b \right )}{ F' \left ( g^{-1} \left ( x \right ) \right ) \, g^{-1} ' \left ( x \right ) } \, dx =
 \int_{g \left ( a \right )}^{g \left ( b \right )}{ f \left ( g \left ( g^{-1} \left ( x \right ) \right ) \right ) \, g^{-1} ' \left ( x \right ) } \, dx = \\
= \int_{g \left ( a \right )}^{g \left ( b \right )}{ f \left ( x \right ) \, \frac{1}{g' \left ( g^{-1} \left ( x \right ) \right} } \, dx

(with  F \left ( x \right ) = \int^{x}{ f \left ( g \left ( x \right ) \right )} \, dx)

Microsoft PowerPoint Rant

I have to do a presentation at university and it needs to be done in PowerPoint - OpenOffice and LaTeX are explicity not allowed.
Usually I'm all for Microsoft, but PowerPoint really lacks quite a few things that one would expect to be common in modern presentation software:

  • ability to insert document properties
  • working document properties - somehow I get an error message every time I try to open the document property viewer...
  • changing the language of a presentation (for all slides, etc.) - it's just a huge W-T-F that you have to use macros or add-ins to do that
  • table of contents slides - it's incredible that there is no way to automate this in PowerPoint.

LaTeX is a 1000x more user-friendly in that regard to be honest. You can download some packages for free that automate everything that is worth automating and you won't be bothered with updating all possible things manually everytime. It also usually supports more powerful slides with advanced navigation, etc.

Nonetheless if PowerPoint sucks, then Visual Basic for Applications for PowerPoint is one big brainfuck. The level of stupidity and general suckiness of VBA as language and the fact that you somehow don't find up-to-date documentation about it online (no language specs?) and some braindead decisions in the PowerPoint macro API make it a real PITA to work with..

Anyway, I've written a macro to create a Table of Contents slide automatically for a PowerPoint presentation - it also allows for updating it later on and for customizing its title without overwriting it on update:

' create a Table of Contents slide as second slide (but you can move it around afterwards)
' you can use the macro to update an already generated one without it resetting the title or the slide's position
Const TOCTag = "TOC?Level"
Const TOCSlideName = "TOC?Slide"

Sub CreateTOCSlide()
    Dim contentSlide As Slide
    On Error Resume Next
    Set contentSlide = ActivePresentation.Slides(TOCSlideName)

    If contentSlide Is Nothing Then
        Set contentSlide = ActivePresentation.Slides.AddSlide(2, ActivePresentation.Slides(1).CustomLayout)
        contentSlide.Name = TOCSlideName
        contentSlide.Layout = ppLayoutText
        contentSlide.Shapes.title.TextFrame.TextRange.Text = "Table of Contents"
    End If

    UpdateTOCSlide
End Sub

Private Function FindTOCSlideWithTitle(title As String) As Slide
    Dim cSlide As Slide
    For Each cSlide In ActivePresentation.Slides
        If cSlide.Tags(TOCTag) <> "" Then
            If cSlide.Shapes.title.TextFrame.TextRange.Text = title Then
                Set FindTOCSlideWithTitle = cSlide
                Exit Function
            End If
        End If
    Next cSlide
    Set FindTOCSlideWithTitle = Nothing
End Function

Sub UpdateIndentationFromTOC()
    Dim contentSlide As Slide
    On Error Resume Next
    Set contentSlide = ActivePresentation.Slides(TOCSlideName)

    If contentSlide Is Nothing Then
        Exit Sub
    End If

    Dim contentTextRange As TextRange2
    Set contentTextRange = contentSlide.Shapes.Placeholders(2).TextFrame2.TextRange

    Dim p As TextRange2
    For Each p In contentTextRange.Paragraphs()
        Dim cSlide As Slide
        Set cSlide = FindTOCSlideWithTitle(Left(p.Text, Len(p.Text) - 1))
        If Not cSlide Is Nothing Then
            cSlide.Tags.Add TOCTag, p.ParagraphFormat.indentLevel
        End If
    Next p
End Sub

Private Sub UpdateTOCSlide()
    Dim contentSlide As Slide
    On Error Resume Next
    Set contentSlide = ActivePresentation.Slides(TOCSlideName)

    If contentSlide Is Nothing Then
        Exit Sub
    End If

    Dim contentTextRange As TextRange2
    Set contentTextRange = contentSlide.Shapes.Placeholders(2).TextFrame2.TextRange

    contentSlide.Shapes.Placeholders(2).TextFrame2.DeleteText
    contentTextRange.ParagraphFormat.Bullet.Type = ppBulletNumbered

    Dim index As Integer
    index = 1

    For Each pSlide In ActivePresentation.Slides
        Dim tagValue As Integer
        tagValue = Val(pSlide.Tags(TOCTag))
        If tagValue > 0 Then
            contentTextRange.InsertAfter pSlide.Shapes.title.TextFrame.TextRange.Text &amp; vbCrLf
            contentTextRange.Lines(index, 1).ParagraphFormat.indentLevel = tagValue
            contentTextRange.Lines(index, 1).ParagraphFormat.LeftIndent = 40 * tagValue
            'contentTextRange.Lines(index).ParagraphFormat.Bullet.Type = ppBulletNumbered
            index = index + 1
        End If
    Next pSlide

End Sub

Sub ToggleTOCEntrySlide()
    Dim currentSlide As Slide
    Set currentSlide = ActiveWindow.View.Slide

    Dim newValue As String
    If currentSlide.Tags(TOCTag) <> "" Then
        newValue = ""
    Else
        newValue = "1"
    End If
    currentSlide.Tags.Add TOCTag, newValue

    UpdateTOCSlide
End Sub

Private Function ClampIndentLevel(level As Integer) As Integer
    If level < 1 Then
        ClampIndentLevel = 1
    ElseIf level > 5 Then
        ClampIndentLevel = 5
    Else
        ClampIndentLevel = level
    End If
End Function

Sub IndentTOCEntrySlide()
    Dim currentSlide As Slide
    Set currentSlide = ActiveWindow.View.Slide

    currentSlide.Tags.Add TOCTag, ClampIndentLevel(1 + Val(currentSlide.Tags(TOCTag)))

    UpdateTOCSlide
End Sub

Sub UnindentTOCEntrySlide()
    Dim currentSlide As Slide
    Set currentSlide = ActiveWindow.View.Slide

    currentSlide.Tags.Add TOCTag, ClampIndentLevel(Val(currentSlide.Tags(TOCTag)) - 1)
    UpdateTOCSlide
End Sub

The most recent version can be found in this .zip file here (TOC.bas).

Some remarks:

  • "On Error Resume Next" - it's crazy that VBA uses this to control its error handler (this construct dates back to QuickBasic..)
  • VBA doesn't support normal exception handling it seems
  • what does the set statement do and why is it necessary to use it when dealing with object references - I've experienced strange error messages before I started using it
  • VBA doesn't seem to support a Continue statement (continue as the counterpart to break)
  • The VBA documentation is inside the Access documentation (in case you look for it)

Hopefully this is useful for other poor souls who have to or try to work with PowerPoint's macro facilities.

Cheers,
Andreas

Crysis notes - random

Last week I had the joy of playing and beating Crysis (you'll find out later why I emphasize that I beat it). While playing I took some notes, which I want to share with you (some might be funny facts, others might show why Crysis sucks and others could be proof for some awesomeness that you can - still? - find in the game).

First off though, this is going to contain lots and lots of spoilers, so just lemme put up a

SPOILER ALERT

sign before continuing.

Read more »

VSTorqueScript #5

It took me quite long to make progess in the last days. Partially this is due me being in Munich again and working in my uni job part-time again - and I'm stunned each time how tired I am when I come home.

It also is due to me experimenting with my TelnetDebuggerClient implementation that connects my debug engine to Torque's Telnet Debugger. I've tried quite a few different approaches for synchronous and asynchronous communication before I could settle for the simplest and the more advanced ones reside in the repository's history. I'll probably have to switch to them sooner or later because I only implement asynchronous communication at the moment which is fine for most things except when you need more advanced debugging info like for displaying objects properly in the debug window for example.

I've also had to read the "Definitive ANTLR Reference" in one night because I had to return it to uni's library the next day, so I was busy for 7 hours reading 350 pages of a parser reference. It was interesting though and tonight I'll try to write a QuakeC grammar - that's the plan at least.

However yesterday, I had time to work on the debug engine some more and here's a picture that tells it all:

VSTorqueScript now supports displaying the callstack, too

VSTorqueScript now supports displaying the callstack, too

As you see you can now break a program and it will retrieve the callstack from Torque and update the callstack window automatically and open the right file and jump to the correct file position, too - or rather as I've just noticed one-line off because VS line indicies have base 0 and TorqueScript uses base 1 >_>...

A few implementation notes as always:

  • I t seems, if your Debug Engine doesn't implement IDebugEngineLaunch2, your Program Provider has to implement IDebugProgramProvider2.WatchForProviderEvents
  • Moreover, if you don't implement IDebugEngineLaunch2, which in turn forces you to implement IDebugProcess2 (and maybe IDebugProcess3, too), suddenly some "deprecated" methods in your Program class (your IDebugProgram2 implementation) will be called, which, if you follow MSDN and the debug engine sampe, will result in failed asserts and the nice fail message "This function is not called by the debugger." :-)
    It's kind of logical that IDebugProgram2.Execute() is going to be called because the debugger has no IDebugProcess2 interface to call Execute on..
  • What is enum_FRAMEINFO_FLAGS_VALUES? It's undocumented and I suspect it's used for the undocumented m_dwFlags field in FRAMEINFO...
  • I'm totally stunned by how stable Visual Studio is. Most the interfaces I implement are only half implemented and return E_NOTIMPL on most calls and Visual Studio runs and runs well and only displays the information it can in a clean way.
    I guess this is one of the advantages of the COM programming/design paradigma and I think it's great. Being able to implement interfaces bit by bit and add functionality slowly makes debugging easier and also helps you understand things better - which is good because even though a lot is documented, you still need some practice and trial & error to get things right eventually.

Enough is enough though for now, and I'll head to uni in a bit.

Only one last remark: I've started reading the book "The Pragmatic Programmer" and so far it's really entertaining and, I guess, good.
I'll write more on it, when I've finished it and can actually assess its qualities..

Cheers,
Andreas

Weird Things Happen

Today I was at work for the first time since August and nobody seems to have logged into my shared workstation since then since my account name was still in the login field.
The first weird thing that happened was that suddenly the application I've been working on didn't run correctly anymore.
First let me tell you a bit about the app:
It renders a volume texture with some custom raytracing shaders in one window and allows editing of the transfer function - this is a function/texture that maps a scalar value in the volume texture to a color in another window. The transfer function is made up of primitives/shapes that you can colorize and stretch or deform the way you want to allow for easy editing. Look at this picture to see what a transfer function (editor) could look like - this isn't ours though.
The TF editor uses an FBO to render the transfer function into the transfer texture.

While the rest of the app was running mostly fine (that is AntTweakBar rendered fine and the background of the transfer function editor which is a histogram of the volume texture, too), the actual transfer function rendering was corrupted.
On my workstation you could move the primitive around and while you did so it would either totally disappear, invert its color or show small light green or purple blocks that stayed stationary inside the window as you moved the primitive around - the whole look liked corrupted memory that stayed corrupted and was only visible when the primitive rendered over it.

It's a pity I didn't take any screenshots but I didn't think of that back then.

I was totally at a loss with this behavior, so I rebooted which didn't fix it. Somehow I was hoping that the gfx card broke in the last month and it wasn't my code which caused this totally inexplicable behavior.
To determine this I logged into another workstation in our lab, checked out my code and run the program. To my horror it had similar problems... now quite the same but still strangely colored sprinkles all over the editor window when the primitive was rendered there. Both workstations are using graphics cards from Nvidia (8800 GTX if I recall correctly).

I tried to determine the revision which broke rendering with a binary search like trial & error through our revision history at work and found out that it broke when I changed the way the primitives were rendered to the texture.

It used to simply iterate through all primitives and render them once to the FBO and it was done.

The paper I'm implementing at the moment required  a special solution for overlapping primitives though, so I switched to a more complicated 2.5 pass rendering.

If $latex c_i $ is the color value of the ith primitive and $latex \alpha _ i $ its alpha value, then the resulting color and alpha are calculated as follows: $latex \left< c, \alpha \right> = \left< \frac{\displaystyle\sum_i^n{c_i \alpha_i}}{\displaystyle\sum_{i}^n{\alpha_i}},\max_{i=1..n}{\alpha_i} \right>$.

For this I do three passes and use two floating point textures:

  1. Render the primitives into a temp texture with
    glBlendFuncSeparate( GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE );

    to get $latex \left< {\displaystyle\sum_i^n{c_i \alpha_i}},{\displaystyle\sum_{i}^n{\alpha_i}} \right> $.

  2. Next I set the FBO to the real transfer function texture and use the temp texture as source and divide the color values by their alpha using a custom shader.
  3. Finally I use
    glBlendEquation( GL_MAX );

    and only masks all except the alpha channel and render all primitives again into the transfer function texture. This gets the correct term into the alpha channel of the texture.

This usually works and although it's a bit cumbersome it yields the correct result. Only now I identified it to be the source of all my trouble.

Here's the relevant part in our source code:

_checkGLErrors();
m_fbo.AttachTexture( GL_COLOR_ATTACHMENT0_EXT, m_tempTexture.glTarget, m_tempTexture.glTexID );
assert( m_fbo.IsValid() );
m_fbo.Bind();
_checkGLErrors();

glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClear( GL_COLOR_BUFFER_BIT );

// C = srcC * srcA + dstC = C * A + C' * A' + ...
// A = srcA + dstA = A + A' + A'' + ...
glBlendFuncSeparate( GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE );
glBlendEquationSeparate( GL_FUNC_ADD, GL_FUNC_ADD );

for( Primitive::PList::const_iterator i = m_primitives.begin() ; i != m_primitives.end() ; i++ ) {
(*i)->bake();
}

m_fbo.Unattach( GL_COLOR_ATTACHMENT0_EXT );
m_fbo.Disable();
_checkGLErrors();

// divide color by alpha
glMatrixMode( GL_PROJECTION );
glLoadIdentity();

glBlendFunc( GL_ONE, GL_ZERO );

procInf.imageOp( m_tempTexture, m_transferFunction, m_program );

// render again this time to figure out the max alpha value

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0, 1.0, 0.0, 1.0, -1.0, 1.0 );

m_fbo.AttachTexture( GL_COLOR_ATTACHMENT0_EXT, m_transferFunction.glTarget, m_transferFunction.glTexID );
assert( m_fbo.IsValid() );
m_fbo.Bind();
_checkGLErrors();

glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE );
glBlendEquation( GL_MAX );

for( Primitive::PList::const_iterator i = m_primitives.begin() ; i != m_primitives.end() ; i++ ) {
(*i)->bake();
}

Now I was ready to hunt the bug but the problem the revision was written more than a few days before I left in August and it was working back then. I refused to believe that it was broken and I went to my boss who had been using his rig in the last days and indeed it worked. I couldn't really believe my eyes. Two workstations appeared to be broken for some reason (driver issues or even the gfx cards? - who would know..).

I went back and somehow managed to change the appearance of the bug on one of the workstations - all the framebuffer corruptions went away and were replaced with what seemed like an unchanging alpha channel of one of the FBO textures with alpha being 0 on the initial position of the primitive and 1.0 everywhere else, so it masked it out at its initial position.

For some reason I thought that maybe using BlendFuncSeparate and the normal BlendFunc function together maybe left OGL's state machine in a mess for some reason so I added calls to disable and enable blending to code to render the call to glBlendFunc useless (see the code above and/or below).

_checkGLErrors();
m_fbo.AttachTexture( GL_COLOR_ATTACHMENT0_EXT, m_tempTexture.glTarget, m_tempTexture.glTexID );
assert( m_fbo.IsValid() );
m_fbo.Bind();
_checkGLErrors();

glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClear( GL_COLOR_BUFFER_BIT );

// C = srcC * srcA + dstC = C * A + C' * A' + ...
// A = srcA + dstA = A + A' + A'' + ...
glBlendFuncSeparate( GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE );
glBlendEquationSeparate( GL_FUNC_ADD, GL_FUNC_ADD );

for( Primitive::PList::const_iterator i = m_primitives.begin() ; i != m_primitives.end() ; i++ ) {
(*i)->bake();
}

m_fbo.Unattach( GL_COLOR_ATTACHMENT0_EXT );
m_fbo.Disable();
_checkGLErrors();

// divide color by alpha
glMatrixMode( GL_PROJECTION );
glLoadIdentity();

---> glDisable(GL_BLEND); <---
glBlendFunc( GL_ONE, GL_ZERO );

procInf.imageOp( m_tempTexture, m_transferFunction, m_program );

// render again this time to figure out the max alpha value

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0, 1.0, 0.0, 1.0, -1.0, 1.0 );

m_fbo.AttachTexture( GL_COLOR_ATTACHMENT0_EXT, m_transferFunction.glTarget, m_transferFunction.glTexID );
assert( m_fbo.IsValid() );
m_fbo.Bind();
_checkGLErrors();

---> glEnable( GL_BLEND ); <---
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE );
glBlendEquation( GL_MAX );

for( Primitive::PList::const_iterator i = m_primitives.begin() ; i != m_primitives.end() ; i++ ) {
(*i)->bake();
}

m_fbo.Disable();

When I ran the program, it decided to work normally and render everything the way it should. I was stunned once again.
Now the good thing with causality is that everything is supposed to be repeatable, so I removed the statements again and was expecting to see the bug appear again.. - but guess what it did not and suddenly the machine was working again as supposed.

I tried the same fix with the other workstation in our lab and it fixed it before I had time to take some screenshots of the persisting framebuffer corruption.

I'm still at a loss here and I guess I won't be able to come up with an explanation of my own for this, so if anyone has an idea, feel free to tell me :-)

Cheers,
Andreas

Halo: Combat Evolved

Yay, I've finally found time to play through Halo 1 for the PC. To be honest I didn't even know that I owned the game a few days ago, but when I looked through one of my drawers, I found it together with Supreme Commander and GTA: San Andreas \o/

To make playing it look like work or at least like something worthier than just playing, I've taken notes occasionally and here they are:

  • The vehicles are very easy to steer: they always automatically try to drive towards your current view direction and you only use forward and backward to accelerate and slow down. I was used to ETQW's steering system and it took me some time to get used to, but it's pretty ok for the game.
  • I like to use my rifle as club. For the first half of the game I had a really closed-combat fighting style: start shooting while running on and when you need to reload or simply are near enough, hit the enemies with your gun before jumping to cover. It was very effective against Grunts and against Elites, too, since my timing was right most of the times and I was there, when their shield broke down.
    The ability to throw grenades and shooting at the same time (pretty much) also increased combat speed a lot and made everything more fluid, because I was able to react to everything always in an effective way.
    The Flood was pretty scary at first, because I had to learn a totally different combat technique and after getting used to it during the first few hours, I took me a bit to keep my distance again. After getting the shotgun and surviving the Library level fighting against the Flood became fun or at worst slightly boring and annoying, though I still have to watch out to prevent myself from becoming surrounded.
    I think, it is a pretty neat idea to make the Flood monsters get up again after being shot for the first time. It facilitates being surrounded and increases the risk of being overrun.
  • Level design is pretty weird sometimes. And with weird I mean repetitive - just look at the Library level to see the beauty of copy'n'paste. The last level, where you have to drive the buggy through a weird obstacle course that makes no sense whatsoever is pretty awkward, too - the buggy is a bit to wide to be driven through everything elegantly using the controls and I got stuck all the time. Moreover the buggy is too slow for all the little ramps you can find and I was left wondering why they put them there (maybe the buggy's speed was changed after the level was designed?)
  • I don't like checkpoints. Especially when they're used to tune the game difficulty by spreading them lighter in later levels >_<

So far, so good. I like Halo a lot and although some levels seemed a bit stretched (Library again), playing it was fun. I don't know, what I'm going to play next, but I think that maybe I should spend some of my time coding again - nah, just joking, next I'm going to play Call of Duty or more Sam & Max...

Cheers,
Black

Mirror's Edge

Mirror's Edge is one awesome game.
There is hardly any information out about the game yet and the official homepage is lacking but if you're interested, there is at least one good fansite (I haven't checked for others yet) and a few trailers that really make me want to see more (or work for DICE - you decide..).

Check out the trailers:

YouTube Preview Image
YouTube Preview Image
YouTube Preview Image
YouTube Preview Image

If you're interested in some additional thoughts, please continue and read on:

Read more »

Random Notes

I can't come up with anything to write right now, so I've decided to publish some random notes :-)

Random notes:

  • I'm listening to Duffy - Mercy on thesixtyone right now - I'm kind of surprised to find it there to be honest.
  • Right now I try to read "Design Patterns" by the "Gang of Four". Reading it is kind of tedious though because it contains a lot of text for simple things, but I don't just want to skim over it either, so constantly have to force myself to continue reading.
  • I've stumbled over some good links from going through the Wikipedia entries for some design patterns. One interesting one in particular is: http://c2.com/cgi/wiki?PatternBacklash
    Quote (so true):

I've gained the impression that DesignPatterns violate OnceAndOnlyOnce. If you need to use a design-pattern often enough for it to become a 'pattern', it should be refactored into a single language statement just like every other 'pattern' you refactor. If you can't refactor the design-pattern due to language limitations or other constraints, you'll end up apply the same pattern, by hand, repeatedly (thus the name 'pattern'). Of course, given a TuringComplete language you can potentially refactor anything, but beware GreenspunsTenthRuleOfProgramming and the overhead required to refactor design patterns in any generic manner. The need for DesignPatterns should be considered a LanguageSmell. A language that has a lot of DesignPatterns smells a great deal worse than one that requires only a few. DesignPatternsAreMissingLanguageFeatures

  • I've installed Visual Studio 2008 because I had a) access to it b) I once read that it contained some stuff to simplify the addition of new languages to it.
    There is an SDK available and I recommend to anyone to check it out - especially the stuff about using the Visual Studio Shell for your own projects (it's neat-o).
    My only issue with it is that all my work projects, etc. are still using Visual Studio 2005 and there is no way to open 2005 projects without converting them which sucks - I let you guess why :-)
  • There is an SDK available for Visual Studio 2005, too.
  • I'm looking into writing a language extension for QuakeC, though I'm not sure whether it is worth the trouble, because most people I know who still code in QuakeC use Linux >_>'
  • Doing the same for TorqueScript might be a good idea though, and I could probably even sell it - again I'm not sure whether coding it would be that rewarding.
  • I've been playing Aquaria a lot in the last days and I really enjoy it, although it's not the game I usually play. It certainly is worth its 30 USD.
  • http://grammar.ccc.commnet.edu/grammar/adverbs.htm is an awesome site about English grammar!
  • The latest Linux-Hater is simply awesome - and funny: Bundle me this

I think that's enough for now and I'm going to back to reading/playing/listening to music.

Cheers,
Andreas