Roadmap for VASSAL 4

I’ve converted the Python demo I made a few weeks ago to C++. I’m posting a link to an archive containing the source code here for anyone who wants to try it or have a look. The dependencies are only OpenGL, GLUT, and libjpeg. I haven’t had time to do a Windows build yet; I intend to try that this evening. I’m assuming that anyone on Linux will be able to compile this with no problems; hopefully this is also the case on Macs.

vassalengine.org/~uckelman/cpp-test.tar.bz2

The good:

  • Fast. The parts which are in software (as opposed to in the graphics hardware) are much, much faster than in Python. This is unsurprising, but nice to see. The only siginificant thing which happens in software in the demos is image loading. The map image I’ve been using for testing is 8149x3514. On my laptop, it takes about 5 seconds to load this image in Python; in C++, libjpeg loads it in under one second.

  • Very low RAM usage. Image data takes up close to 100% of the memory the demo uses. (This is similar to VASSAL.) The test map is about 81MB in memory. However, once we’ve carved it into texture tiles and handed those off to OpenGL, we can free all the memory we allocated to store image data—OpenGL stores textures in video RAM. The demo was using about 7MB RAM for me after image loading was finished; the max was around 150MB (for a few seconds) during tile carving.

  • Little code. The C++ demo is about 1200 lines, which is approximately twice the number that the Python demo has. Half of the extra “code” comes from lines which are blank or have only a curly brace on them (332 lines); the rest comes from the code which gets data from libjpeg and from managing OpenGL handles properly rather than leaking them.

The bad:

  • I’m not seeing any bad, yet, actually.

The ugly:

  • Building for multiple platforms. I can (probably) make Windows builds on Linux using the mingw cross-compiler. I’ve done that once before, for mkhexgrid. I have no idea whether I can cross-compile on Linux for Mac OS. I’d very much like to be able to build for all platforms in once place.

terminate called after throwing an instance of ‘std::logic_error’
what(): basic_string::_S_construct NULL not valid
Aborted

This is on Ubuntu

That’s not the most helpful exception I’ve ever seen either.

  • M.

On 3 May 2011 07:13, uckelman uckelman@nomic.net wrote:

[This message has been edited.]

I’ve converted the Python demo I made a few weeks ago to C++. I’m
posting a link to an archive containing the source code here for anyone
who wants to try it or have a look. The dependencies are only OpenGL,
GLUT, and libjpeg. I haven’t had time to do a Windows build yet; I
intend to try that this evening. I’m assuming that anyone on Linux will
be able to compile this with no problems; hopefully this is also the
case on Macs.

vassalengine.org/~uckelman/cpp-test.tar.bz2[1]

The good:

  • Fast. The parts which are in software (as opposed to in the graphics
    hardware) are much, much faster than in Python. This is unsurprising,
    but nice to see. The only siginificant thing which happens in software
    in the demos is image loading. The map image I’ve been using for testing
    is 8149x3514. On my laptop, it takes about 5 seconds to load this image
    in Python; in C++, libjpeg loads it in under one second.

  • Very low RAM usage. Image data takes up close to 100% of the memory
    the demo uses. (This is similar to VASSAL.) The test map is about 81MB
    in memory. However, once we’ve carved it into texture tiles and handed
    those off to OpenGL, we can free all the memory we allocated to store
    image data—OpenGL stores textures in video RAM. The demo was using
    about 7MB RAM for me after image loading was finished; the max was
    around 150MB (for a few seconds) during tile carving.

  • Little code. The C++ demo is about 1200 lines, which is approximately
    twice the number that the Python demo has. Half of the extra “code”
    comes from lines which are blank or have only a curly brace on them (332
    lines); the rest comes from the code which gets data from libjpeg and
    from managing OpenGL handles properly rather than leaking them.

The bad:

  • I’m not seeing any bad, yet, actually.

The ugly:

  • Building for multiple platforms. I can (probably) make Windows builds
    on Linux using the mingw cross-compiler. I’ve done that once before, for
    mkhexgrid. I have no idea whether I can cross-compile on Linux for Mac
    OS. I’d very much like to be able to build for all platforms in once
    place.

[1] vassalengine.org/~uckelman/cpp-test.tar.bz2

Thus spake Michael Kiefte:

terminate called after throwing an instance of ‘std::logic_error’
what(): basic_string::_S_construct NULL not valid
Aborted

This is on Ubuntu

That’s not the most helpful exception I’ve ever seen either.

Are you specifying the map image as an argument when you run it? I
neglected to mention that you need to do that. My guess is that’s
what’s wrong.

If that’s not the problem, would you mind compiling with debugging on,
running it in gdb and giving me a backtrace?


J.

Oops. Yes, it works. However, strangely it shifts to all blue whenever I
pan the map. But when I move a counter it goes back to normal. For some
reason the R and G channels are getting zeroed out. Initially, I thought it
was because my GPU didn’t support the encoding scheme you have, but it’s
switching back and forth. I’ve never seen that before.

  • M.

On 3 May 2011 10:17, Joel Uckelman uckelman@nomic.net wrote:

Thus spake Michael Kiefte:

terminate called after throwing an instance of ‘std::logic_error’
what(): basic_string::_S_construct NULL not valid
Aborted

This is on Ubuntu

That’s not the most helpful exception I’ve ever seen either.

Are you specifying the map image as an argument when you run it? I
neglected to mention that you need to do that. My guess is that’s
what’s wrong.

If that’s not the problem, would you mind compiling with debugging on,
running it in gdb and giving me a backtrace?


J.


messages mailing list
messages@vassalengine.org
vassalengine.org/mailman/listinfo/messages


Michael Kiefte, Ph.D.
Associate Professor
School of Human Communication Disorders
Dalhousie University
Halifax, Nova Scotia, Canada
tel: +1 902 494 5150
fax: +1 902 494 5151

Thus spake Michael Kiefte:

Oops. Yes, it works. However, strangely it shifts to all blue whenever I
pan the map. But when I move a counter it goes back to normal. For some
reason the R and G channels are getting zeroed out. Initially, I thought it
was because my GPU didn’t support the encoding scheme you have, but it’s
switching back and forth. I’ve never seen that before.

That’s strange. The encoding scheme I’m using is GL_RGB (no alpha, because
the source images are JPEGs). I wonder if converting to GL_RGBA would make
any difference?


J.

That’s strange. The encoding scheme I’m using is GL_RGB (no alpha, because
the source images are JPEGs). I wonder if converting to GL_RGBA would make
any difference?

Actually, I think it does! I seem to recall that some graphics cards have
problems with 24bit alignment. That brings back some recollections.

  • M.

Thus spake Michael Kiefte:

That’s strange. The encoding scheme I’m using is GL_RGB (no alpha, because
the source images are JPEGs). I wonder if converting to GL_RGBA would make
any difference?

Actually, I think it does! I seem to recall that some graphics cards have
problems with 24bit alignment. That brings back some recollections.

Aha. I will adjust that this evening, then. RGB is how it comes from
libjpeg, at least by default. I’ll see whether it’s possible to get
libjpeg to give us 32-bit aligned output instead. If not, I can just
twiddle the scanlines as they come.


J.

Michael, here’s a diff to apply to load_jpeg.cpp which will modify it (in an ugly way) to load JPEGs to to RGBA instead of RGB format. If you recompile with this, does your “blue” problem go away?

[code]diff --git a/cpp-test/load_jpeg.cpp b/cpp-test/load_jpeg.cpp
index 8f86fb3…49df46b 100644
— a/cpp-test/load_jpeg.cpp
+++ b/cpp-test/load_jpeg.cpp
@@ -6,6 +6,8 @@

#include <jpeglib.h>

+#include <boost/scoped_array.hpp>
+
#include “image.h”

Image load_jpeg(std::string filename) {
@@ -44,13 +46,21 @@ Image load_jpeg(std::string filename) {
const unsigned int w = cinfo.image_width;
const unsigned int h = cinfo.image_height;
const unsigned int bpp = cinfo.num_components;

  • boost::shared_array data(new GLubyte[whbpp]);
  • boost::shared_array data(new GLubyte[wh4]);

  • boost::scoped_array scan(new GLubyte[w*bpp]);

    // Extract each scanline of the image
    JSAMPROW j;
    for (unsigned int i = 0; i < h; ++i) {

  • j = data.get() + ((h-(i+1))wbpp);
  • j = scan.get();
    jpeg_read_scanlines(&cinfo, &j, 1);
  • GLubyte *dst = data.get() + ((h-(i+1))w4);
  • GLubyte *src = scan.get();
  • for (unsigned int x = 0; x < w*bpp; ++x, ++dst) {
  •  *dst = *(src + x);
    
  •  if (x % 3 == 2) ++dst; // skip alpha component in dst
    
  • }
    }

// Finish decompression and release memory
@@ -58,5 +68,5 @@ Image load_jpeg(std::string filename) {
jpeg_destroy_decompress(&cinfo);

fclose(fp);

  • return Image(w, h, bpp, bpp == 1 ? GL_LUMINANCE : GL_RGB, data);
  • return Image(w, h, 4, GL_RGBA, data);
    }[/code]

I’m partway there. The MinGW (cross-compiler) setup in Fedora is neat. I have a handful of errors I need to fix before it will compile for Windows.

Is OpenGL and GLUT open-source? Where can one get the libraries otherwise?

Lance

Please ignore my last post. I should have searched a bit more. :slight_smile:

Lance

Thus spake lancel:

Is OpenGL and GLUT open-source? Where can one get the libraries
otherwise?

Both are open-source.

The GLUT implementation I’m linking against is Freeglut:

freeglut.sourceforge.net/

Freeglut uses the X License.

If you’re compiling on and for Linux, you’ll most likely already
have both OpenGL and GLUT. If you’re compiling on Windows, I’m not
exactly sure where you get the headers you need; I haven’t had
time to look yet. I don’t have access to a Mac, but I suspect that
the Mac situation is similar to Linux.


J.

Got it working on Ubuntu. It looks great. I can zoom in and out without any problem.

Lance

Thus spake lancel:

Got it working on Ubuntu. It looks great. I can zoom in and out
without any problem.

Did you need to make any changes in order to get it working?


J.

I did not make any changes.

Lance

On Thu, May 05, 2011 at 02:53:41AM -0700, Joel Uckelman wrote:

Thus spake lancel:

Got it working on Ubuntu. It looks great. I can zoom in and out
without any problem.

Did you need to make any changes in order to get it working?

I ran the original fine on Ubuntu with no changes needed.

Jeff


“The man who does not read good books has no advantage over
the man who cannot read them.”
– Mark Twain

I tried to use Visual Studio 2010 C++ Express to see how far I can go. I was able to compile all the way but whenever I ran it, I would run into a crash at the following line inside map.cpp:

glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

I got the GLee SDK from opengl.org/sdk/libs/GLee/ and recompiled it with VS2010. I got the Win32 version of freeglut. I even recompiled its source but the outcome was the same. I got the jpeglib versions 8c and 6b but both got me the same error. I am curious to see if you also run into the same error with MinGW.

Lance

Thus spake lancel:

I tried to use Visual Studio 2010 C++ Express to see how far I can go.
I was able to compile all the way but whenever I ran it, I would run
into a crash at the following line inside map.cpp:

glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

Any idea why that would cause a crash? The vertex VBO has 4 vertices in
it, so I don’t think the problem is that we’re overrunning the end of
the VBO.

I got the GLee SDK from opengl.org/sdk/libs/GLee/[2] and
recompiled it with VS2010. I got the Win32 version of freeglut. I even
recompiled its source but the outcome was the same. I got the jpeglib
versions 8c and 6b but both got me the same error. I am curious to see
if you also run into the same error with MinGW.

I haven’t been able to successfully compile with MinGW yet, due to my
MinGW headers not having all the extension definitions that my Linux
ones do. I’m just about to try GLEW (glew.sourceforge.net/) for
handling that, so I’ll let you know how it turns out.


J.

Thus spake Joel Uckelman:

I haven’t been able to successfully compile with MinGW yet, due to my
MinGW headers not having all the extension definitions that my Linux
ones do. I’m just about to try GLEW (glew.sourceforge.net/) for
handling that, so I’ll let you know how it turns out.

Huh. On switching to GLEW, I’m now getting a segfault on the first
glGenBuffersARB() call. No idea why.


J.

Thus spake Joel Uckelman:

Thus spake Joel Uckelman:

I haven’t been able to successfully compile with MinGW yet, due to my
MinGW headers not having all the extension definitions that my Linux
ones do. I’m just about to try GLEW (glew.sourceforge.net/) for
handling that, so I’ll let you know how it turns out.

Huh. On switching to GLEW, I’m now getting a segfault on the first
glGenBuffersARB() call. No idea why.

Aha, got it. I was neglecting to initialize GLEW before the call to
glGenBuffers().


J.