Compiling Problems using freeglut

Refresh

November 2018

Views

906 time

3

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 [email protected] $(GINCS)

clean:
    del $(TARGET) $(OBJS)

COMPILING IN GIT

  1. I cdinto the directory containing main.cpp ; Graphics.cpp ; Graphics.h ; makefile.

  2. I then run makeand 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

  1. I open main.cpp ; Graphics.h ; Graphics.cpp in code::blocks.
  2. With main.cpp active, I "build and run". I get this error and nothing seems to happen, except that now there is a main.o in the project directory.
C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `[email protected]'
C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `[email protected]'
C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `[email protected]'
C:\Users\Admin\Desktop\C++Projects\cosc1337.code\GraphicsLib\examples\ex4\main.o:main.cpp|| undefined reference to `[email protected]'
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 `[email protected]'
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 `[email protected]'
=== Build failed: 11 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===
  1. Same thing as above when Graphics.cpp is active and I 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.

2 answers

1

Строительство в консоли

Строительный проект с использованием Makefileсостоит из двух этапов:

  • Компиляция исходных файлов двоичных объектных файлов
  • связывание объектных файлов excecutable

Это может быть сделано с помощью только MinGW из чистой cmdконсоли. Единственное требование состоит в установке PATHпеременной , чтобы указать на MinGW бинарных файлов. Это может быть сделано только локально для этой консоли, например:

PATH=c:\MinGW\mingw-w64\i686-5.1.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%

Предположим , что бинарная freeglut 3.0.0 MinGW пакет извлекается в папку 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

Во время компиляции main.oи Graphics.oобъектных файлов генерируются.

В вашем случае ошибка на этом этапе. Это связано с пути заголовка. Убедитесь , что в вашем gitbashпути /usr/local/include/действительно существует, перечислив его ls /usr/local/include/. Если он существует , то обратите внимание , что в исходных файлах заголовок включаются как , GL/glut.hа также GLкаталог присутствует в GINCS. Это ошибка , если путь заголовка /usr/local/include/GL/glut.h. Таким образом, удалить GLиз GINCS.

Шаг связи производит целевую test.exeдвоичный.

проект Code :: Blocks

Код :: Blocks IDE может быть настроен , чтобы сделать шаблон проекта GLUT для работы с , freeglueкак описано в Использование FreeGlut с Code :: Blocks .

Это просто необходимо , чтобы заменить Glut32на freeglutв сценарии мастера glut\wizard.scriptи в шаблоне проекта glut.cbp.

Теперь можно создать новый проект с использованием GLUT projectпредустановок. Это будет только задать вам glutпуть. Затем Code :: Blocks автоматически создает проект сконфигурирован с необходимыми параметрами компилятора (пути заголовка) и опцией компоновщика (путь и библиотека). Он также дает main.cppфайл с простым примером , который может быть скомпилирован как есть.

Похоже , что вы создали не GLUT projectтолько просто очередной пустой проект приложения. Для того, чтобы сделать его работу необходимо настроить Project build options:

  • Search directories: Добавить путь в Compilerзакладке ( c:\freeglut\include) и в Linkerзакладке ( c:\freeglut\lib);
  • Linker settings: Добавить имена необходимых библиотек без lпрефикса ( freeglut, glu32, opengl32).
0

В ваших замыкающие файлы , которые я вижу , что вы связываете с флагами , как -lfreeglut. Я использую Linux , и я помню, чтобы поставить все единицы в передней части моих вариантов ссылок для Linux специально. Попробуйте использовать -freeglutи т.д. для остальных.

В коде :: блоков вы можете добавить glut32.lib, перейдя в Project>BuildПараметры , а затем перейдите на linkerвкладку. Там нажмите addпод link libraries. Затем дать ему путь к вам .lib файлов. Убедитесь , что не использовать относительный путь. Вы хотите буквальный путь.

Мое единственное другое предложение является #include <windows.h>. Обычно , когда вы получаете убивание неопределенных ссылок , как это, это какое - то связь ошибки.