2015-06-28 3 views
1

Я использую CLion с GCC 7.8 для кодирования на C++. У нас есть этот код, который используется для «рендеринга» изображения из * .OBJ-файлов.Неопределенные символы для архитектуры x86_64 на Mac

#ifndef __GEOMETRY_H__ 
#define __GEOMETRY_H__ 

#include <cmath> 

template <class t> struct Vec2 { 
    t x, y; 
    Vec2<t>() : x(t()), y(t()) {} 
    Vec2<t>(t _x, t _y) : x(_x), y(_y) {} 
    Vec2<t>(const Vec2<t> &v) : x(t()), y(t()) { *this = v; } 
    Vec2<t> & operator =(const Vec2<t> &v) { 
     if (this != &v) { 
      x = v.x; 
      y = v.y; 
     } 
     return *this; 
    } 
    Vec2<t> operator +(const Vec2<t> &V) const { return Vec2<t>(x+V.x, y+V.y); } 
    Vec2<t> operator -(const Vec2<t> &V) const { return Vec2<t>(x-V.x, y-V.y); } 
    Vec2<t> operator *(float f)   const { return Vec2<t>(x*f, y*f); } 
    t& operator[](const int i) { if (x<=0) return x; else return y; } 
    template <class > friend std::ostream& operator<<(std::ostream& s, Vec2<t>& v); 
}; 

template <class t> struct Vec3 { 
    t x, y, z; 
    Vec3<t>() : x(t()), y(t()), z(t()) { } 
    Vec3<t>(t _x, t _y, t _z) : x(_x), y(_y), z(_z) {} 
    template <class u> Vec3<t>(const Vec3<u> &v); 
    Vec3<t>(const Vec3<t> &v) : x(t()), y(t()), z(t()) { *this = v; } 
    Vec3<t> & operator =(const Vec3<t> &v) { 
     if (this != &v) { 
      x = v.x; 
      y = v.y; 
      z = v.z; 
     } 
     return *this; 
    } 
    Vec3<t> operator ^(const Vec3<t> &v) const { return Vec3<t>(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); } 
    Vec3<t> operator +(const Vec3<t> &v) const { return Vec3<t>(x+v.x, y+v.y, z+v.z); } 
    Vec3<t> operator -(const Vec3<t> &v) const { return Vec3<t>(x-v.x, y-v.y, z-v.z); } 
    Vec3<t> operator *(float f)   const { return Vec3<t>(x*f, y*f, z*f); } 
    t  operator *(const Vec3<t> &v) const { return x*v.x + y*v.y + z*v.z; } 
    float norm() const { return std::sqrt(x*x+y*y+z*z); } 
    Vec3<t> & normalize(t l=1) { *this = (*this)*(l/norm()); return *this; } 
    t& operator[](const int i) { if (i<=0) return x; else if (i==1) return y; else return z; } 
    template <class > friend std::ostream& operator<<(std::ostream& s, Vec3<t>& v); 
}; 

typedef Vec2<float> Vec2f; 
typedef Vec2<int> Vec2i; 
typedef Vec3<float> Vec3f; 
typedef Vec3<int> Vec3i; 

template <> template <> Vec3<int>::Vec3(const Vec3<float> &v); 
template <> template <> Vec3<float>::Vec3(const Vec3<int> &v); 


template <class t> std::ostream& operator<<(std::ostream& s, Vec2<t>& v) { 
    s << "(" << v.x << ", " << v.y << ")\n"; 
    return s; 
} 

template <class t> std::ostream& operator<<(std::ostream& s, Vec3<t>& v) { 
    s << "(" << v.x << ", " << v.y << ", " << v.z << ")\n"; 
    return s; 
} 

#endif //__GEOMETRY_H__ 

Этот шаблон используется в моем файле main.cpp, что-то вроде этого:

void triangle(Vec3i t0, Vec3i t1, Vec3i t2, TGAImage &image, TGAColor color, int *zbuffer) { 
    if (t0.y == t1.y && t0.y == t2.y) return; 
    // sort point by Y coordinate 
    if (t0.y > t1.y) std::swap(t0, t1); 
    if (t0.y > t2.y) std::swap(t0, t2); 
    if (t1.y > t2.y) std::swap(t1, t2); 

    int total_height = t2.y - t0.y; 

    for (int i=0; i<total_height; i++) { 
     bool second_half = i > t1.y - t0.y || t1.y == t0.y; 
     int segment_height = second_half ? t2.y - t1.y : t1.y - t0.y; 

     float alpha = (float)i/total_height; 
     float beta = (float)(i - (second_half ? t1.y - t0.y : 0))/segment_height; 

     Vec3i A =    t0 + Vec3f(t2 - t0) * alpha; 
     Vec3i B = second_half ? t1 + Vec3f(t2 - t1) * beta : t0 + Vec3f(t1 - t0) * beta; 

     if (A.x > B.x) std::swap(A, B); 

     for (int j=A.x; j<=B.x; j++) { 
      float phi = B.x == A.x ? 1. : (float)(j - A.x)/(float)(B.x - A.x); 
      Vec3i P = Vec3f(A) + Vec3f(B - A) * phi; 
      int idx = P.x + P.y * width; 
      // Z-buffer 
      if (zbuffer[idx] < P.z) { 
       zbuffer[idx] = P.z; 
       image.set(P.x, P.y, color); 
      } 
     } 
    } 
} 

void add_light_zbuffer(Vec3f light_dir, Model &model, TGAImage &image, int* zbuffer) { 
    for (int i=0; i<model.nfaces(); i++) { 
     std::vector<int> face = model.face(i); 
     Vec3i screen_coords[3]; 
     Vec3f world_coords[3]; 
     for (int j = 0; j < 3; j++) { 
      Vec3f v = model.vert(face[j]); 
      screen_coords[j] = Vec3i((v.x + 1.) * width/2., 
            (v.y + 1.) * height/2., 
            (v.z + 1.) * depth/2.); 
      world_coords[j] = v; 
     } 

     // calculate light intensity 
     Vec3f n = (world_coords[2] - world_coords[0])^(world_coords[1] - world_coords[0]); 
     n.normalize(); 
     float intensity = n * light_dir; 
     // and apply it on image 
     if (intensity > 0) { 
      triangle(screen_coords[0], screen_coords[1], screen_coords[2], image, 
        TGAColor((unsigned char)(intensity * 255), 
           (unsigned char)(intensity * 255), 
           (unsigned char)(intensity * 255), 
           (unsigned char) 255), 
        zbuffer); 
     } 
    } 
} 


void scene_3d_zbuffer() { 
    TGAImage render(width, height, TGAImage::RGB); 
    Model* model = new Model("../assets/african_head.obj"); 

    int* zbuffer = new int[width * height]; 
    for (int i=0; i<width * height; i++) { 
     zbuffer[i] = std::numeric_limits<int>::min(); 
    } 

    Vec3f light_dir = Vec3f(0, 0, -1); 
    add_light_zbuffer(light_dir, *model, render, zbuffer); 

    render.flip_vertically(); 
    render.write_tga_file("output3_2.tga"); 
    delete zbuffer; 
    delete model; 
} 

Но после того, как начать строительство по CMake 3.2.2, я принял это сообщение в моей консоли:

[ 25%] Linking CXX executable /Users/savicvalera/code/LearnComputerGraphics/bin/Lesson_3_Deleting_hidden_surfaces 
[ 66%] Built target Lesson_1_Bresenham_algorithm 
Built target Lesson_2_Trinagles_rasterization 
Undefined symbols for architecture x86_64: 
    "Vec3<float>::Vec3<int>(Vec3<int> const&)", referenced from: 
     triangle(Vec3<int>, Vec3<int>, Vec3<int>, TGAImage&, TGAColor, int*) in main.cpp.o 
    "Vec3<int>::Vec3<float>(Vec3<float> const&)", referenced from: 
     triangle(Vec3<int>, Vec3<int>, Vec3<int>, TGAImage&, TGAColor, int*) in main.cpp.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make[2]: *** [/Users/savicvalera/code/LearnComputerGraphics/bin/Lesson_3_Deleting_hidden_surfaces] Error 1 
make[1]: *** [CMakeFiles/Lesson_3_Deleting_hidden_surfaces.dir/all] Error 2 
make: *** [all] Error 2 

И мой вопрос: что происходит с кодом, и почему сборка окончена каждый раз?

+0

Вы пытаетесь использовать некоторые библиотеки, которые я не признаю, как вы не показываете 'include' имен файлов или что-нибудь, что помогает идентифицировать его. И, похоже, что-то не так в вашем CMAkefile, который вы тоже не показываете. Mmmm .... можете ли вы показать настройки компоновщика, которые вы используете, и предоставить подробную информацию о библиотеках, которые вы надеетесь использовать? –

+0

@MarkSetchell Да, спасибо за отзыв. Я добавил ссылку на «geometry.h» в моем файле CMake. Но теперь принятое сообщение с конструктором Vec3: «конструктор вне строки для« Vec3 »не может иметь аргументы шаблона» – Relrin

ответ

0

Для решения этой проблемы необходимо добавить ссылки на файлы cpp/h в файл CMake. Например, в этой ситуации был:

project(Lesson_3_Deleting_hidden_surfaces) 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 
set(SOURCE_FILES src/IntroCG/Lesson_3_Deleting_hidden_surfaces/main.cpp) 
add_executable(Lesson_3_Deleting_hidden_surfaces ${SOURCE_FILES} 
       src/IntroCG/tgaimage.cpp src/IntroCG/tgaimage.h 
       src/IntroCG/model.cpp src/IntroCG/model.h 
       src/IntroCG/painter.cpp src/IntroCG/painter.h) 

и стал

project(Lesson_3_Deleting_hidden_surfaces) 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 
set(SOURCE_FILES src/IntroCG/Lesson_3_Deleting_hidden_surfaces/main.cpp) 
add_executable(Lesson_3_Deleting_hidden_surfaces ${SOURCE_FILES} 
       src/IntroCG/geometry.cpp src/IntroCG/geometry.h 
       src/IntroCG/tgaimage.cpp src/IntroCG/tgaimage.h 
       src/IntroCG/model.cpp src/IntroCG/model.h 
       src/IntroCG/painter.cpp src/IntroCG/painter.h) 
Смежные вопросы