Category Archives: Coding - Page 3

Best-of-Explosm Web 2.0

Yahoo Pipes are an interesting concept, as are the other existing mashup tools (like Microsoft's Popfly or Ubiquity), and it is amazing what can be done with a few clicks with them.

Because I've wanted to learn how to work with Yahoo Pipes (before the Google Mashup Editor is released to the public), I've decided to take my best-of-explosm viewer to a different level and prototype it with Yahoo Pipes.

This just shows the first page (it's easier to view - and create - the feed in groups of 20 pictures than all at once). You can follow the link if you want to view more pages.

Stay tuned for more.
Cheers,
Andreas

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

More WordPress Pimping

PHP and CSS and all that funky web design stuff are funky, because they are so easy to use and you quickly get results. I like it.

I've decided to release my first plugin into the world (it's big hack, but it has turned out to be very useful on my other blog http://info1.blackhc.net).

It supports 3 text replacements:

Xkcd-style Tooltips as Replacement for Footnotes

Example:

[[:This is a default footnote. Hover over it to display it.]]

Result:

´

You can use a different marker, too:
Example:

[[:My Footnote#This is a default footnote. Hover over it to display it.]]

Result:
My Footnote

Linking to Wikipedia

Example:

[[wikipedia:Pie]]

Result:

Pie

The link text can be changed, too, of course.
Example (you can use : as seperator, too):

[[wikipedia:pi#Fake Pie]]

Result:

Fake Pie

Expandable Text

Example:

[[expandable#Expandable Text...]]

Result:

The link text can be changed, too:
Example:

[[expandable#Click me! Click me! Pleeease!#Yay!]]

Result:

And we can nest it and it works with other tags.
Example:

[[expandable:#Expandable Text...

[[expandable:Click me! Click me! Pleeease!#Yay!]]
// some Java code

]]

Result:

We can also use a Heredoc-like mode:
Example:

[[expandable_ex:EOD#Heredoc-like Expandable#[[[[[[[]][[EOD]]

Result:

Escaping [[ and ]]

Example:

Escaping [[escape_left]] and [[escape_right]]

Source Code

Hopefully this can be useful for somebody else, too.
Cheers,
Andreas

WordPress Hacking

Since I've been working on another blog (http://info1.blackhc.net) for my tutorial at university, I've played around with using Microsoft Word for publishing and editing content on the blog. I gotta say that SmartArts are really nice and good way to lighten up blog posts easily.

However Word's support for the current version of WordPress is sub-optimal - that is, it totally messes up formatting when retrieving existing blog posts (that is, Word doesn't recognize any paragraphs or line breaks). I've spent some time digging around in the blog's .php code to find a way to fix it and after an hour or so, I've been able to fix it.
It's one-liner I want to share with you:

//'description' => $post['main'], // line 1939 in xmlrpc.php (function mw_getPost)
'description' => wpautop( $post['main'] ),

The function wpautop adds <p> tags to your text (and by default <br> tags, too).

This will fix the formatting bug in Word. This is a hack, of course, but it works for Word.

WordPress has a bug in its Atom Publishing Protocol code, too:
It messes up the status code header when asking for user credentials, which prevents your browser from displaying the login form.
Again only one line needs to be changed:

// header('Status: ' . $msg); // line 1014 in wp-app.php (function: auth_required)
header('Status: 401 ' . $msg);

Stay tuned for more updates in the next months.. :-)
Cheers,
Andreas

PS: University is really keeping me busy..

A Visual Studio Macro Day

Today I decided to continue work on a Visual Studio macro I started developing on Sunday (I mainly worked on it today though - Sunday was just document reading before heading back to Munich and going out with friends).

The samples from Microsoft simply use the comments from MSDN on functions/methods that are part of a class's interface implementation.

I 'documented' a few of my functions by copying the summary out of MSDN but it's a tedious job and consequently I decided to try and automate it.
Although Visual Basic 'sucks' or is a least quite some change from writing C/C++/C# code all the time, the Automation model is very powerful and quite nice to use.

My macro provides two methods:

  • One to add comments to all methods that are part of an interface's implementation
  • One to add comments to the method the cursor currently resides in

My code currently only adds comments from interface definitions that have been defined outside the current project. It's pretty nifty in my opinion because usually these interface comments won't change a lot and thus it's safe to add them to the source code, while the interfaces one has written themself can still change and the macros can't track that and/or update the comments afterwards.

However, I've added a configuration boolean, so this behavior can be turned off if needed.

My code won't remove or replace comments, it will just add the comment in front of other comments - if the comment doesn't already exist - I've tried to make it quite safe, so code loss or corruption will be avoided.

I hope this code is helpful. I'm releasing it under the Microsoft Public License. If there are good reasons to use a different license, feel free to tell me so :)

Cheers,
Andreas

Read more »

VSTorqueScript #6

I've spent the last two days working on the Debug Engine and I've made some progress:

  • Tracepoint Support
  • Breakpoint Support
  • Support for the Watch window (I might have enlisted this already once but now support is more complete)

I'm not going to post any screenshots this time, instead I'll try to create an alpha package for you to test. This will probably take some time, too, because I want to make sure that you can install and uninstall it cleanly. I've been using the experimental hive so far, so I have to make sure it doesn't corrupt anyone's installation accidentially... :-)

A few implementation notes for interested people as always:

  • If you ever have to marshal an object to an IntPtr, be very careful, because doing the wrong thing will certainly crash your application - I had that happen to me and it took me quite some time to figure out why Visual Studio was suddenly  'experiencing internal problems' and had to be closed' all the time:
    When you have to convert an IntPtr to a wrapped object, use

    MyObject = (MyType) GetObjectFromIUnknown( intPtr ); // or As MyType;
    

    As you see, the intPtr is a COM object and every COM object implements IUnknown, so the call is pretty safe. The conversion afterwards is already 'managed', so safe, too.
    If you want to convert an IntPtr from an object, you have to be more careful though. The Marshal namespace offers at least two methods for it:

    • public static IntPtr GetComInterfaceForObject(
      	Object o,
      	Type T
      )
      
    • public static IntPtr GetIUnknownForObject(
      	Object o
      )
      

    Don't use the latter for anything except if you really need an IUnknown interface IntPtr pointer!
    The method really only returns a pointer to the IUnknown interface of the object, which usually isn't what the unmanaged code expects - which probably will result in misinterpreting some uninitialized memory as a vtable that is not there.
    You have to use GetComInterfaceForObject and don't forget this. Because you're only working with IntPtrs in the end, there is nothing to warn you about your misstep.

  • If you want to use an object with System.Collection.Generic.Dictionary<K,V>, it's not sufficient to implement IEquatable<K> as stated in the documentation - you also have to override GetHashCode (and override the normal Equals, too, then while you're at it), because Dictionary uses GetHashCode for the bucket assignments and you can implement IEquatable as hard as you want, GetHashCode might simply assign two 'equal' objects to different buffers and you have a problem..
  • One of the benefits of COM is that no one cares about your implementation.. take advantage of it!
    I had to remember this the hard way, when I implemented my breakpoint code. At first I wrote a PendingBreakpoint class, which implemented IDebugPendingBreakpoint2, and then a BoundBreakpoint one, which implemented IDebugBoundBreakpoint2. It was unnecessary messy and today I sighed and rewrote the breakpoint code to use just one Breakpoint class that implements both interfaces and it's a lot more elegant now.
  • Funny fact: An enum that is even mentioned in MSDN and the SDK docs is missing from the Interops library:
    public enum enum_BP_UNBOUND_REASON
    {
        BPUR_UNKNOWN = 0x0000,
        BPUR_CODE_UNLOADED = 0x0002,
        BPUR_BREAKPOINT_REBIND = 0x0003,
        BPUR_BREAKPOINT_ERROR = 0x0004
    };
    
  • The initialization process for the DE is as follows:
    1. DebugEngine and Program Creation Events
    2. Load Complete Event
    3. Call CreatePendingBreakpoint for all known breakpoints
    4. First Continue Call
    5. Entry Point Event
    6. Either the second Continue call or the SDM enters break mode

I had to write a few wrapper classes, too, which I might post about next time around. It's enough for today though.

Cheers,
Black

VSTorqueScript #5.1

Sadly there isn't a lot new that I can post since I've hardly had time to work on my pet project during the last week - a few friends from Texas and California came over for the Oktoberfest and it suffices to say that I drank a lot of beer last week.

Nonetheless there is some progress and I've finished support for stepping in break mode (although I still have no idea what enum_STEPKIND.STEP_BACKWARDS is about, since I've never heard of stepping backwards before).

There is no screenshot this time because you wouldn't really see a difference, except if I did, before/after screenshots to show that the stepping works.

A few coding notes as always:

  • The current TorqueScript telnet debugger doesn't really tell you whether it breaks because of stepping or because it has hit a breakpoint, so I have to figure it myself. It is pretty straightforward though because stepping usually implies a certain callstack change (or the lack thereof) when finished:
    • "Step Into" implies that the new callstack height > old height
    • "Step Over" implies no change
    • "Step Out" implies of course: new callstack height < old height

    So it's pretty easy to figure out whether the stepping was finished or interrupted by a breakpoint.

  • The class diagram designer/viewer in Visual Studio 200x is awesome. If you haven't tried it, you've missed a really helpful feature of Visual Studio.
    Lately I've been using it to comment my public functions and parameters, etc. and for small refactorings (like name changes) in general.

Last but not least I think I've written a neat communication class for synchronous and asynchronous message processing which I'd like to share (if you're going to use it though, please tell me and/or send me some feedback):

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

VSTorqueScript #4

My little pet project is actually called VSTorqueScript, so I've decided to use the correct title for my posts, too.

Today has been a somewhat productive day, although not as productive as I've hoped, because I was stuck with a very stupid issue for 3 or 4 hours. I'm not proud of it, but it made me go to the VSX forum and become active there.

I've worked more on the debug engine afterwards (well, actually I went jogging and swimming - in that order.. think about it ) and made some progress. Quite a bit of the stub stuff is implemented now and I think I'll start implementing the real thing tomorrow.

No screenshots this time, I'm sorry, but for the SDK users, I have a little helper file. If you look at the managed debug example, you'll find an AD7Events file that wraps the debug event interfaces.
I wasn't easily able to port it over, so I decided to write my own version of it (while keeping the comments).

I've appended it to the post, if you want to take a look.

On other news I'll probably switch this blog over to my own webspace soon to get some advantages (like expandable sourcecode amongst things), but I think I'll stick to wordpress.com for a few more weeks.
It's really a pity that you can't redirect from wordpress to your domain, but only vice-versa :(

Anyway, off to work some more on my code.

Cheers,
Andreas

Read more »