Saturday, October 31, 2015

Online Rich Text Editors

Salesforce.com recently open-sourced Quill, a new entry into the "online rich text editor" category. I only took a quick glance at it; it looks clean and useful, with just enough features that I would consider it for future projects.

I've been wanting something else other than TinyMCE, but the ones I've looked at have lacked one vital function or another which either comes with TinyMCE or can be enabled with a plugin. I still have yet to find one I've liked, but they're either too bloated, or look like they're stuck in the early 2000's MS-Office theme.

The only problem I have with Quill at this point is that, based on my quick glance, one can't specify the type of text being entered, i.e. header, sub-header, paragraph, etc. But it can be faked with specifying Large, Small, Normal sizes, and choosing different fonts. I'd really like the former, though.

Sunday, September 13, 2015

Fixing "you need to install the legacy Java SE 6 runtime." errors

For various reasons I wanted to try out Universal Media Server on my MacBook OS X Yosemite 10.10.5 before I install it for real on my Linux box. However, this was not as easy as I thought it would be, because upon starting the app, an error window appears with the text "you need to install the legacy Java SE 6 runtime."

Yes, doing that would have been the easy fix, but the legacy Java SE 6 runtime is old, with many known security exploits, and  I already have the latest JDK8 installed, why can't I just use that?

This process was not as straightforward as expected, but easy enough, explained at http://stackoverflow.com/a/19594116:
  1. Make sure Java is up to date.
  2. Edit the Info.plist file (I did this via command line):
    • sudo vi /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Info.plist
      •  In the "JVMCapabilities" array, make sure it has the three following entries:
      •                         JNI
                                BundledApp
                                CommandLine
  3. Link a dynamic library:
    • sudo mkdir -p /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bundle/Libraries/
    • sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/server/libjvm.dylib /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bundle/Libraries/libserver.dylib
  4. Reboot.
Once those steps were completed, I was able to run the Universal Media Server app. If only the first step is applied, then the error "LSOpenURLsWithRole() failed with error [XXXXX]" occurs instead.

Saturday, September 12, 2015

Static Analysis

I listened to Floss Weekly podcast episode #352 - FWKNOP earlier this week. In it, the guest mentioned two tools he uses for static analysis: CLANG static analyzer (which, as the name suggests, is only for C/C++ and Objective-C) and the powerful Coverity Scan tool, which is free for open source projects and covers other languages as well.

Friday, September 11, 2015

IPFS

IPFS is short for InterPlanetary File System, a peer-to-peer filesystem. Peers have a choice in what they distribute, unlike Freenode.

Say you want to store a file on IPFS. The unique name is basically a hash of the contents of the file. If the contents change by even one bit, then a completely new hash is made. In one way, this is a good thing because it allows others that care about said content to be able to archive it and distribute it themselves, and others can easily determine if the file they got was altered in some way by hashing it again, and comparing it with the name.

However, what this means is that we can't ever change the file, even if we wanted to change it. IPFS's answer to it is similar to what bitcoin does for wallets, which is to use a public key hash. They call this IPNS, or InterPlanetary Naming System. So we could sign a file with our private key, and people who know our Peer ID can retrieve it, using the public key to verify that the new contents were, in fact, mutated by us. The IPFS folks have a better explanation on their site.

IPFS, written in go, is being used by NeoCities to spearhead their permanent, distributed web movement. While it is usable now, the technology is very much a work in progress. It has stirred up Hacker News a few times in the past, and I'm sure we'll see more of them.

I've been looking for some sort of peer-to-peer filesystem like this for maps, chatrooms, achievements, save games, replays, app updates, rankings, etc. While I don't think IPFS is the answer for all of those use cases, it does work nicely for maps and app updates, at least. The end goal would be an online game where everybody can contribute any amount of their own resources to ensure that the game runs smoothly, and beneficial contributors are rewarded, detrimental users are punished, and it all somehow (and magically) happens without mob rule (all the players ganging up on a few users) yet without a tyrannical ruler (the author of game) either. I've touched on all this before so I'll save my breath fingers from blistering.

Monday, September 7, 2015

Steven Wittens, and the Pixel Factory

Steven Wittens, the man behind acko.net, recently gave a presentation called "The Pixel Factory". This man has put more thought into rendering his website's header than many programmers (yours truly included) have put into entire games. Even the presentation itself reveals a level of quality and polish few others achieve. It's a good introduction into several rendering concepts, and even presents a few different views of said concepts.

Some of the items that came up were new to me but have been used in the field for quite some time, such as drawing text with signed distance fields in order to keep text looking sharp when it appears distant/small.

It also pointed me to WebGL Stats, which, as is said in the name, shows statistics of various web API and WebGL extensions support.

Order-independent transparency in WebGL vs. OpenGL was touched on as well (with WebGL 1.0, it must be two-pass). The original way to do transparency in OpenGL was to order the triangles/geometry back-to-front and disable writing to the depth-buffer so that each transparent object is drawn. With order-independent transparency, the fragments themselves are sorted.

Monday, February 9, 2015

Why does my OpenGL game only support 2.1 on MacOSX 10.7+?

tl;dr: Lion and Mountain Lion (specifically 10.7.5 and 10.8.5) can support 3.2 and Mavericks (10.9) on up can support at least 3.3. To get anything better than 2.1 though, you need to specify:
  • That the context should use an OpenGL Core Profile
  • Set the "forward compatibility" bit to true
  • The major version should be 3, and minor version should be 2 (or use whatever version you can support).
Now your app should support OpenGL versions higher than 2.1 on MacOSX. Note that, because you've set forward compatibility to true, you can't use immediate mode (well, you can... it just won't do anything. Not that you were using immediate mode anyway, right? ;-) )

The Long Version

This particular issue caught me off-guard when I first came across it. We recently got our very alpha game (an overstatement—it's a slightly-fancier hello-world at this point) running on Ubuntu 14.10 and Windows 7. I wanted to get it working on my laptop so I could do some couch coding. This is an aging Late-2009 13-inch MacBook, upgraded to Yosemite 10.10.2. It's rocking an NVIDIA GeForce 9400M (256MB). Pretty boss, I know.

How does one find out what OpenGL version their graphics chip supports on MacOSX? It turns out Apple has an OS X OpenGL Compatibilities Tables for it, and that not only is it hardware dependent, but also OS dependent as well. The takeaway I got from the page was that, if you want to target 10.7 users, don't exceed version OpenGL 3.2. If you want 10.8, you can go to 3.3. Anything above that, you might be able to hit 4.1, but it depends on hardware at that point.

We're programming with golang. All we've got at this point for the graphics library is glfw3. Getting this set up with MacOSX deserves another post entirely, as it requires cgo and was more than a minor annoyance (but not much more). Anyway, I noticed that, upon start up, the game log indicated it was only running OpenGL 2.1, even though I knew for a fact that even this aging GeForce 9400M could go higher than that.

It turns out it has nothing to do with the library we're using and everything to do with the quirks that Apple baked into MacOSX. I will show how to fix this in golang with glfw3, but I'm betting the same concept works in c++ or other languages and even if you're using other libraries like SDL2 or GLU or SFML or...

Here it is:

    if !glfw.Init() {
        panic("Can't init glfw!")
    }
    defer glfw.Terminate()

    glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)
    glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)
    glfw.WindowHint(glfw.ContextVersionMajor, 3)
    glfw.WindowHint(glfw.ContextVersionMinor, 2)
    window, err := glfw.CreateWindow(640, 480, "Awesome Game", nil, nil)
    if err != nil {
        panic(err)
    }

How can we apply this knowledge to the other wrapper libs, like SDL2? All of these hinting values likely line up with GL/glext.h's constants for GL_CONTEXT_PROFILE_MASK, GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT, GL_MAJOR_VERSION, and GL_MINOR_VERSION.

The possible values for glfw.OpenglCoreProfile, glfw.OpenglCompatProfile, and glfw.OpenglAnyProfile, I would also guess, line up with GL_CONTEXT_CORE_PROFILE_BIT, GL_CONTEXT_COMPATIBILITY_PROFILE_BIT, and finally both values OR'ed together.

Those values come directly from OpenGL itself, so if you use a library that wraps OpenGL, chances are good that it will use those too.

But what in the world are OpenGL profiles, anyway? After reading the official page on profiles, I still have no idea, other than it seems to be a way for the process to indicate that it wants to use new the newer features (core), or that it still needs to use the older ones (compatibility).

The profile page talks about the forward compatibility bit as well. This is the part that caught my eye (emphasis theirs):

Recommendation: You should never use the forward compatibility bit. It had a use for GL 3.0, but once 3.1 removed most of the stuff, it stopped having a use.
- OpenGL's Core And Compatibility in Contexts page
So, why should we still have to set the forward compatibility bit in MacOSX, if it doesn't even matter for 3.2 anyway, and the author of the sentence thought this point was so important that he had to go to the trouble of using italics?!

Seriously, why? I have no idea. But I no longer care much, now that the window appears without error.