Компиляция задач с помощью freeglut

ПРЕДИСЛОВИЕ

Итак, я недавно программировал C++ в Code::Blocks и недавно столкнулся с проблемой компиляции при попытке скомпилировать проекты, включающие freeglut. У меня Windows 8, и я правильно установил freeglut в соответствии с code::blocks вики. У меня также установлен git bash и mingw64. Проблема в том, что я не могу скомпилировать исходный код, написанный моим профессором (проект с использованием freeglut), используя code::blocks или используя команды g++ в 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();
    }    

Графика.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);

создать файл

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)

СБОРКА В GIT

  1. Я cdв каталог, содержащий main.cpp ; Graphics.cpp ; Graphics.h ; makefile.

  2. Затем я запускаю make и получаю следующее, хотя я добавил все файлы содержимого lib, include и bin freeglut в правильные каталоги в C:\usr\local\mingw32(inlcude\,lib\,bin) и GL\glut. ч точно есть...

$ 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

КОМПИЛИРОВАНИЕ В CODE::BLOKS

  1. Я открываю main.cpp ; Graphics.h ; Graphics.cpp в code::blocks.
  2. С активным main.cpp я «собираю и запускаю». Я получаю эту ошибку, и кажется, что ничего не происходит, за исключением того, что теперь в каталоге проекта есть файл main.o.
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)) ===
  1. То же самое, что и выше, когда Graphics.cpp активен и я build and run, я получаю те же ошибки, что и раньше, но Graphics.o создается.

ЗАКЛЮЧЕНИЕ:

После того, как я создал объектные файлы с помощью code::blocks, я могу зайти на gitbash и запустить make-файл, чтобы связать их, и он создает рабочий файл test.exe, который я могу запустить и посмотреть, где находится мое размещение. есть, но я озадачен и разочарован тем, что не могу использовать только code::blocks или просто git, так как это приводит к тому, что корректировка кода занимает неоправданно много времени, чтобы получить удовлетворительный результат, и обязательно вызовет проблемы позже

ИЗМЕНИТЬ

Все остальные программы, которые я написал, а также "hello world" без проблем компилируются в коде: :блоки и гитбаш.


person Nolifepothead    schedule 18.10.2015    source источник
comment
Похоже, ваш make-файл, или ваш code::blocks, или оба неправильно сконфигурированы. Я бы порекомендовал просто попытаться скомпилировать чрезвычайно простые программы, такие как int main() {}, до тех пор, пока вы не сможете делать это надежно и последовательно без ошибок в обоих направлениях. Пока вы не можете этого сделать, ваша система нуждается в доработке. Затем постепенно попробуйте включить бесплатное перенасыщение и тому подобное, пока не заработаете, и снова опубликуйте на SO, если вы действительно где-то застряли.   -  person Chris Beck    schedule 18.10.2015
comment
Все другие программы, которые я написал, без проблем скомпилируются в code::blocks и git bash. И я всегда слежу за тем, чтобы hello world компилировался с самого начала.   -  person Nolifepothead    schedule 18.10.2015


Ответы (2)


Сборка в консоли

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

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

Это можно сделать, используя только 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.

Код::Блокирует проект

IDE Code::Blocks можно настроить так, чтобы шаблон проекта 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).
person Orest Hera    schedule 18.10.2015
comment
Спасибо. Ты прав. Но также оказалось, что проблема заключалась в том, что я не создавал свои файлы в шаблоне проекта перенасыщения. - person Nolifepothead; 27.10.2015

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

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

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

person Weregoat    schedule 18.10.2015
comment
Я отредактирую make-файл прямо сейчас и попытаюсь скомпилировать. Я надеюсь, что это все, так как эти исходные файлы прямо от моего профессора, и мне пришлось изменить некоторые make-файлы, но в целом ничего серьезного. По вашему предложению code::blocks вики-направления code::blocks заставили меня пройти через wizard.script для перенасыщения и изменить все ссылки на glut32 на freeglut. Я не уверен, что это сработает, но я готов попробовать что-нибудь прямо сейчас. Спасибо, вернусь после - person Nolifepothead; 18.10.2015
comment
Изменил мой make-файл и удалил l перед ссылками, та же ошибка. При проверке (пути mingw code::blocks и мои библиотеки mingw64) я не вижу ни glut32.lib, ни glut32.a, но файлы freeglut.a есть в обоих. - person Nolifepothead; 18.10.2015