PREFACE
So I've been recently programming c++ in Code::Blocks and have run into a problem compiling recently when trying to compile projects that include freeglut. I'm on windows 8, and I have installed freeglut correctly according to the code::blocks wiki. I also have git bash installed as well as mingw64. The problem is that I cannot compile the source code that my professor (project using freeglut) has written using code::blocks or using g++ commands in gitbash.
main.cpp:
/* Copyright (c) Mark J. Kilgard, 1996. */
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain. */
#include "Graphics.h"
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
setColor(RED);
drawFilledTriangle(0,0,100,100,200,0);
setColor(BLUE);
drawFilledCircle(200,200,150);
glFlush(); /* Single buffered, so needs a flush. */
}
int main(int argc, char **argv)
{
graphicsSetup( argc, argv, &display);
glutMainLoop();
return 0;
}
Graphics.cpp
#include <iostream>
using namespace std;
#include "Graphics.h"
#include <cmath>
const double PI = acos(-1.0);
const double ANGLE_STEP = PI/180.0;
void keyboard(unsigned char key, int x, int y)
{
if (key == 27)
exit(1);
}
void clearWindow() {
glClear( GL_COLOR_BUFFER_BIT );
}
void setColor(ColorName name) {
switch(name) {
case WHITE: glColor3d(1.0, 1.0, 1.0); break;
case GREY: glColor3d(0.4, 0.4, 0.4); break;
case BLACK: glColor3d(0.0, 0.0, 0.0); break;
case RED: glColor3d(1.0, 0.0, 0.0); break;
case ORANGE: glColor3d(1.0, 0.5, 0.0); break;
case YELLOW: glColor3d(1.0, 1.0, 0.0); break;
case GREEN: glColor3d(0.0, 1.0, 0.0); break;
case FOREST_GREEN: glColor3d(0.0, 0.25, 0.0); break;
case BLUE: glColor3d(0.0, 0.0, 1.0); break;
case CYAN: glColor3d(0.0, 1.0, 1.0); break;
case MIDNIGHT_BLUE: glColor3d(0.0, 0.0, 0.25); break;
case PURPLE: glColor3d(0.5, 0.25, 0.0); break;
case MAGENTA: glColor3d(1.0, 0.0, 1.0); break;
case BROWN: glColor3d(0.36, 0.16, 0.1); break;
default: cerr << "Trying to set invalid color. Color unchanged" << endl;
}
}
void graphicsSetup(int argc, char *argv[], void (*display)()) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
if (! glutGet(GLUT_DISPLAY_MODE_POSSIBLE))
glutInitDisplayMode(GLUT_INDEX);
glutInitWindowPosition(50,50);
glutInitWindowSize(640, 480);
glutCreateWindow("single triangle");
glClearColor(1.0,1.0,1.0,0.0);
glutDisplayFunc(display);
// set "esc" key to end program
glutKeyboardFunc(keyboard);
// set coordinates to "normal"
glLoadIdentity();
glOrtho(0,640,0,480, 1, -1);
}
void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
glBegin(GL_LINE_STRIP);
glVertex2i(x1,y1);
glVertex2i(x2,y2);
glVertex2i(x3,y3);
glVertex2i(x1,y1);
glEnd();
}
void drawFilledTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
glBegin(GL_POLYGON);
glVertex2i(x1,y1);
glVertex2i(x2,y2);
glVertex2i(x3,y3);
glVertex2i(x1,y1);
glEnd();
}
void drawLine(int x1, int y1, int x2, int y2) {
glBegin(GL_LINE_STRIP);
glVertex2i(x1,y1);
glVertex2i(x2,y2);
glEnd();
}
void drawBox(int x1, int y1, int x2, int y2) {
glBegin(GL_LINE_STRIP);
glVertex2i(x1,y1);
glVertex2i(x2,y1);
glVertex2i(x2,y2);
glVertex2i(x1,y2);
glVertex2i(x1,y1);
glEnd();
}
void drawFilledBox(int x1, int y1, int x2, int y2) {
glBegin(GL_POLYGON);
glVertex2i(x1,y1);
glVertex2i(x2,y1);
glVertex2i(x2,y2);
glVertex2i(x1,y2);
glVertex2i(x1,y1);
glEnd();
}
void drawCircle(int x, int y, int radius) {
double angle;
int X, Y;
glBegin(GL_LINE_STRIP);
for (angle=0;angle< 2.0*PI + ANGLE_STEP; angle += ANGLE_STEP) {
X = x + int(double(radius) * cos(angle));
Y = y + int(double(radius) * sin(angle));
glVertex2i(X,Y);
}
glEnd();
}
void drawFilledCircle(int x, int y, int radius) {
double angle;
int X0, Y0, X1, Y1;
glBegin(GL_TRIANGLES);
X1 = x + radius;
Y1 = y;
for (angle=0;angle< 2.0*PI + ANGLE_STEP; angle += ANGLE_STEP) {
X0 = X1;
Y0 = Y1;
X1 = x + int(double(radius) * cos(angle));
Y1 = y + int(double(radius) * sin(angle));
glVertex2i(x,y);
glVertex2i(X0,Y0);
glVertex2i(X1,Y1);
}
glEnd();
}
Graphics.h
#include <GL/glut.h>
// set the pre-defined colors
enum ColorName {
WHITE,
GREY,
BLACK,
RED,
ORANGE,
YELLOW,
GREEN,
FOREST_GREEN,
BLUE,
MIDNIGHT_BLUE,
CYAN,
PURPLE,
MAGENTA,
BROWN,
NUM_COLORS
};
void clearWindow();
void setColor(ColorName name);
void graphicsSetup(int argc, char *argv[], void (*display)());
// graphic object primatives
void drawTriangle(int x1, int y1,int x2,int y2,int x3,int y3);
void drawLine(int x1, int y1, int x2, int y2);
void drawBox(int x1, int y1, int x2, int y2); // x-y coords of upper-right and lower-left corners
void drawCircle(int x, int y, int radius);
// filled graphics primatives
void drawFilledTriangle(int x1, int y1,int x2,int y2,int x3,int y3);
void drawFilledBox(int x1, int y1, int x2, int y2);
void drawFilledCircle(int x, int y, int radius);
makefile
TARGET = test.exe
CXX = c:\usr\local\mingw32\bin\g++.exe
FILES = main.cpp Graphics.cpp
OBJS = $(FILES:.cpp=.o)
GINCS = -I/usr/local/include/GL
GLIBS = -L/usr/local/lib -lfreeglut -lglu32 -lopengl32 -Wl,--subsystem,windows
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(GLIBS)
%.o: %.cpp
$(CXX) -c $< -o $@ $(GINCS)
clean:
del $(TARGET) $(OBJS)
COMPILING IN GIT
I cd
into the directory containing main.cpp ; Graphics.cpp ; Graphics.h ; makefile
.
I then run make
and get the following even though I have added all the freeglut lib, include, and bin content files into the correct directories under C:\usr\local\mingw32(inlcude\,lib\,bin) and GL\glut.h is definently there...
$ make c:\usr\local\mingw32\bin\g++.exe -c main.cpp -o main.o -I/usr/local/include/GL In file included from main.cpp:7:0: Graphics.h:1:21: fatal error: GL/glut.h: No such file or directory compilation terminated. makefile:16: recipe for target 'main.o' failed make: *** [main.o] Error 1
COMPILING IN CODE::BLOCKS
main.cpp ; Graphics.h ; Graphics.cpp
in code::blocks.C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `_imp____glutInitWithExit@12' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `_imp____glutCreateWindowWithExit@8' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `_imp____glutCreateMenuWithExit@8' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `glClear@4' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `setColor(ColorName)' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `drawFilledTriangle(int, int, int, int, int, int)' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `setColor(ColorName)' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `drawFilledCircle(int, int, int)' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `glFlush@0' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `graphicsSetup(int, char**, void (*)())' C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `_imp__glutMainLoop@0' === Build failed: 11 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===
build and run
, I get the same errors as before, but Graphics.o is created.WRAPPING THIS UP:
After I have created the object files using code::blocks, I am able to then get on gitbash and run the makefile to link them, and it does create a working test.exe that I can run and see where my placement is, but I am perplexed and frustrated that I cannot use just code::blocks or just git, as doing this makes adjustments to the code take an unreasonable amount of time to get satisfactory and is sure to cause problems later on
EDIT
All other Programs I have written, as well as 'hello world' compile with no problem on code::blocks and gitbash.
Building project using Makefile
consists of two steps:
It can be done using just MinGW from pure cmd
console. The only requirement is to set the PATH
variable to point to MinGW binaries. It can be done locally only for that console, for example:
PATH=c:\MinGW\mingw-w64\i686-5.1.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
Suppose that the binary freeglut 3.0.0 MinGW Package is extracted to folder c:\freeglut
.
::compilation
g++ -c main.cpp -o main.o -I"c:\freeglut\include"
g++ -c Graphics.cpp -o Graphics.o -I"c:\freeglut\include"
::linkage
g++ Graphics.o main.o -o test -L"c:\freeglut\lib" -lfreeglut -lglu32 -lopengl32 -Wl,--subsystem,windows
During compilation main.o
and Graphics.o
object files are generated.
In your case the error is on this step. It is related to the header path. Check that in your gitbash
the path /usr/local/include/
indeed exists by listing it ls /usr/local/include/
. If it exists then note that in your source files the header is included as GL/glut.h
and also GL
directory is present in GINCS
. It is an error if the header path is /usr/local/include/GL/glut.h
. So, remove GL
from GINCS
.
The linkage step produces the target test.exe
binary.
The Code::Blocks IDE can be tuned to make GLUT project template to work with freeglue
as described in Using FreeGlut with Code::Blocks.
It is just needed to replace Glut32
by freeglut
in the wizard script glut\wizard.script
and in the project template glut.cbp
.
Now it is possible to create a new project using GLUT project
preset. It will only ask you glut
path. Then Code::Blocks automatically creates project configured with required compiler options (header path) and linker options (path and libraries). It also gives the main.cpp
file with basic example that can be compiled as is.
It looks that you created not a GLUT project
but just a regular empty application project. To make it work you need to configure Project build options
:
Search directories
: add path in the Compiler
tab (c:\freeglut\include
) and in the Linker
tab (c:\freeglut\lib
);Linker settings
: add names of required libraries without l
prefix (freeglut
, glu32
, opengl32
).