Friday, March 4, 2011

Compiling FTGL-2.1.3~rc5 on Windows Using the Mingw Compiler Bundled With Qt

If you are trying to compile FTGL on Windows, you may have run into the same problem I did: it's not really set up to make that easy. I couldn't get it to work with Cygwin's configure tool. So I tried to make my own Makefile. After searching a fair amount, I found this page to be useful:

http://www.pitt.edu/~mwr12/compcorner/linuxstuff/ftgl.html

I followed Step 3, adding the following to the bottom of FTGL/ftgl.h just before the last #endif:

#ifdef WIN32
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <windows.h>
#endif

Then, after studying the Makefile for FTGL, and after looking at the script in Step 5 (from the website linked above), I finally came up with a Makefile that worked for me:

# Makefile.in generated by automake 1.10.1 from Makefile.am.
# src/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.


top_builddir = ..
COMPILER_DIR = C:/Qt/2010.05/mingw
CONFIG_HEADER = $(top_builddir)/config.h
CPPFLAGS =  -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wshadow -Wsign-compare
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS)
CXX = g++ -g -O2
DEFAULT_INCLUDES = -I. -I$(top_builddir) -IFTGL/
DEFS = -DHAVE_CONFIG_H
FT2_CFLAGS = -I$(COMPILER_DIR)/include/freetype -I$(COMPILER_DIR)/include
FT2_LIBS = -L$(COMPILER_DIR)/lib -lfreetype
GL_CFLAGS = -I$(COMPILER_DIR)/include
GL_LIBS = -lglu32 -lopengl32
HEADER_FLAGS = -I$(COMPILER_DIR)/include
NULL = 
libftgl_dll_CXXFLAGS = $(FT2_CFLAGS) $(GL_CFLAGS)
libftgl_dll_LIBADD = $(GL_LIBS) $(FT2_LIBS)

libftgl_a_objects = \
    FTBuffer.o \
    FTCharmap.o \
    FTContour.o \
    FTFace.o \
    FTGlyphContainer.o \
    FTLibrary.o \
    FTPoint.o \
    FTSize.o \
    FTVectoriser.o \
    $(ftglyph_objects) \
    $(ftfont_objects) \
    $(ftlayout_objects) \
    $(NULL)

libftgl_a_SOURCES = \
    FTBuffer.cpp \
    FTCharmap.cpp \
    FTCharmap.h \
    FTCharToGlyphIndexMap.h \
    FTContour.cpp \
    FTContour.h \
    FTFace.cpp \
    FTFace.h \
    FTGlyphContainer.cpp \
    FTGlyphContainer.h \
    FTInternals.h \
    FTLibrary.cpp \
    FTLibrary.h \
    FTList.h \
    FTPoint.cpp \
    FTSize.cpp \
    FTSize.h \
    FTVector.h \
    FTVectoriser.cpp \
    FTVectoriser.h \
    FTUnicode.h \
    $(ftglyph_sources) \
    $(ftfont_sources) \
    $(ftlayout_sources) \
    $(ftgl_headers) \
    $(NULL)

ftgl_headers = \
    FTGL/ftgl.h \
    FTGL/FTBBox.h \
    FTGL/FTBuffer.h \
    FTGL/FTPoint.h \
    FTGL/FTGlyph.h \
    FTGL/FTBitmapGlyph.h \
    FTGL/FTBufferGlyph.h \
    FTGL/FTExtrdGlyph.h \
    FTGL/FTOutlineGlyph.h \
    FTGL/FTPixmapGlyph.h \
    FTGL/FTPolyGlyph.h \
    FTGL/FTTextureGlyph.h \
    FTGL/FTFont.h \
    FTGL/FTGLBitmapFont.h \
    FTGL/FTBufferFont.h \
    FTGL/FTGLExtrdFont.h \
    FTGL/FTGLOutlineFont.h \
    FTGL/FTGLPixmapFont.h \
    FTGL/FTGLPolygonFont.h \
    FTGL/FTGLTextureFont.h \
    FTGL/FTLayout.h \
    FTGL/FTSimpleLayout.h \
    ${NULL}

ftglyph_objects = \
    FTGlyph/FTGlyph.o \
    FTGlyph/FTGlyphGlue.o \
    FTGlyph/FTBitmapGlyph.o \
    FTGlyph/FTBufferGlyph.o \
    FTGlyph/FTExtrudeGlyph.o \
    FTGlyph/FTOutlineGlyph.o \
    FTGlyph/FTPixmapGlyph.o \
    FTGlyph/FTPolygonGlyph.o \
    FTGlyph/FTTextureGlyph.o \
    $(NULL)

ftglyph_sources = \
    FTGlyph/FTGlyph.cpp \
    FTGlyph/FTGlyphImpl.h \
    FTGlyph/FTGlyphGlue.cpp \
    FTGlyph/FTBitmapGlyph.cpp \
    FTGlyph/FTBitmapGlyphImpl.h \
    FTGlyph/FTBufferGlyph.cpp \
    FTGlyph/FTBufferGlyphImpl.h \
    FTGlyph/FTExtrudeGlyph.cpp \
    FTGlyph/FTExtrudeGlyphImpl.h \
    FTGlyph/FTOutlineGlyph.cpp \
    FTGlyph/FTOutlineGlyphImpl.h \
    FTGlyph/FTPixmapGlyph.cpp \
    FTGlyph/FTPixmapGlyphImpl.h \
    FTGlyph/FTPolygonGlyph.cpp \
    FTGlyph/FTPolygonGlyphImpl.h \
    FTGlyph/FTTextureGlyph.cpp \
    FTGlyph/FTTextureGlyphImpl.h \
    $(NULL)

ftfont_objects = \
    FTFont/FTFont.o \
    FTFont/FTFontGlue.o \
    FTFont/FTBitmapFont.o \
    FTFont/FTBufferFont.o \
    FTFont/FTExtrudeFont.o \
    FTFont/FTOutlineFont.o \
    FTFont/FTPixmapFont.o \
    FTFont/FTPolygonFont.o \
    FTFont/FTTextureFont.o \
    $(NULL)

ftfont_sources = \
    FTFont/FTFont.cpp \
    FTFont/FTFontImpl.h \
    FTFont/FTFontGlue.cpp \
    FTFont/FTBitmapFont.cpp \
    FTFont/FTBitmapFontImpl.h \
    FTFont/FTBufferFont.cpp \
    FTFont/FTBufferFontImpl.h \
    FTFont/FTExtrudeFont.cpp \
    FTFont/FTExtrudeFontImpl.h \
    FTFont/FTOutlineFont.cpp \
    FTFont/FTOutlineFontImpl.h \
    FTFont/FTPixmapFont.cpp \
    FTFont/FTPixmapFontImpl.h \
    FTFont/FTPolygonFont.cpp \
    FTFont/FTPolygonFontImpl.h \
    FTFont/FTTextureFont.cpp \
    FTFont/FTTextureFontImpl.h \
    $(NULL)

ftlayout_objects = \
    FTLayout/FTLayout.o \
    FTLayout/FTLayoutGlue.o \
    FTLayout/FTSimpleLayout.o \
    $(NULL)

ftlayout_sources = \
    FTLayout/FTLayout.cpp \
    FTLayout/FTLayoutImpl.h \
    FTLayout/FTLayoutGlue.cpp \
    FTLayout/FTSimpleLayout.cpp \
    FTLayout/FTSimpleLayoutImpl.h \
    $(NULL)

all: libftgl.a ftgl.dll

.cpp.o:
 $(CXXCOMPILE) -c $(HEADER_FLAGS) -DFTGL_LIBRARY_STATIC -o $@ $<

libftgl.a: $(libftgl_a_objects)
 ar -r $@ $(libftgl_a_objects)

ftgl.dll: $(libftgl_a_SOURCES)
 $(CXXCOMPILE) $(libftgl_a_SOURCES) $(libftgl_dll_CXXFLAGS) $(libftgl_dll_LIBADD) -DFTGL_LIBRARY -DFTGL_DLL_EXPORTS -shared -Wl,--out-implib,libftgl.dll.a -o ftgl.dll
  
clean:
 @-del /S *.o
 @-del ftgl.dll
 @-del libftgl.dll.a
 @-del libftgl.a


This will compile the library for static and dynamic use. You will need to copy the FTGL folder to mingw/include. Then, to use as a static library, copy the resulting file src/libftgl.a to mingw/lib. To use as a dynamic library, copy the file src/libftgl.dll.a to mingw/lib and rename it to libftgl.a, and then copy src/ftgl.dll to the folder in your application.

As a side note, I am using this in a Qt application, so I had to update the .pro file to include the following line:

LIBS += -lftgl -lfreetype -lglu32 -lopengl32

When using ftgl.dll, I didn't need to add the '-lglu32 -lopengl32'. After using the static library, however, the linker complained about not having opengl functions defined. Also note the ordering of the libraries. Placing the opengl includes before the ftgl include didn't work. I had to put them after to satisfy the linker.

I could then follow the tutorials and get them to work. Also, another side note: The resulting text turned out to be far bigger than the -1,1 box in opengl, since it is measured in bigger units. Either scaling or using projection should help with that.

Another issue I found when using FTGLTextureFont is that the depth test needed to be set correctly, or the letter boxes seemed to overlap each other, blocking some of the letters. Setting the depth function using glDepthFunc(GL_LEQUAL); solved this problem for the most part. Another problem remained: at some font sizes, some of the letters seem to be clipped by either their neighbor or their own box. It is especially noticable on the letters 'e' and 'o'. This problem can be avoided by changing the font size to a size where this doesn't happen and then scaling to compensate.

3 comments:

  1. Hi there!
    I'm trying to use ftgl for a project, and before i have to compile it using mingw. On my odyssey in the net, I found your blog, and I've tried to do as you say. But executing make on my computer, it gives me the following error:

    C:\Qt\FTGL>mingw32-make.exe
    mingw32-make.exe: *** No rule to make target `FTBuffer.o', needed by `libftgl.a'. Stop.

    I'm not a make expert, but could it be that the ".cpp.o" option/syntax is not 'compatible' with my make version??
    Any help will be very appreciated.
    Thanks a lot!
    natxo.vergara@gmail.com

    ReplyDelete
  2. Hi there!
    I'd like to thank you for your work and for sharing it! It's been very usefull for me, i really appreciate it.
    I just have to add that I had to make few changes on your Makefile to work on my computer (changes on paths excluded).
    I downloaded the "ftgl-2.1.3-rc5" from http://sourceforge.net/projects/ftgl/files/ . Then, I copied your Makefile on the "src" folder, and changed:

    * on the ".cpp.o" target, my command is:
    $(CXXCOMPILE) -c $(FT2_CFLAGS) -DFTGL_LIBRARY_STATIC $< -o $@

    ...and i think that's all.
    Just in case it could be usefull for someone else.
    Thanks again!

    ReplyDelete
    Replies
    1. Thanks for your comment. In reviewing that line, I found that there was an error in converting the makefile to html when I originally posted it, which caused a problem at that line. The makefile code above should be correct now. Thanks.

      Delete