2013-06-30 22 views
3

我目前正在嘗試用C++編寫OpenGL程序。當我嘗試編譯我的程序,我得到未定義的引用,這裏到處都是我打電話給我的類的成員函數,雖然我調用這些函數從成員函數...雖然函數在同一個文件中定義了C++未定義的引用

這些都是錯誤的消息,我得到:

make clean && make 
rm -f *.o *~ main 
g++ -c main.cpp -o main.o 
g++ -c renderer.cpp -o renderer.o 
g++ -o main main.o renderer.o -lglut -lGL -lGLEW 
renderer.o: In function `Renderer::resize(int, int)': 
renderer.cpp:(.text+0x299): undefined reference to `Renderer::Perspective(float*, float, float, float, float)' 
renderer.o: In function `Renderer::setupShaders()': 
renderer.cpp:(.text+0x43d): undefined reference to `Renderer::loadShaderSrc(char const*, int&)' 
renderer.cpp:(.text+0x456): undefined reference to `Renderer::loadShaderSrc(char const*, int&)' 
renderer.cpp:(.text+0x4e7): undefined reference to `Renderer::printShaderInfoLog(int)' 
renderer.cpp:(.text+0x4fe): undefined reference to `Renderer::printShaderInfoLog(int)' 
renderer.cpp:(.text+0x568): undefined reference to `Renderer::printProgramInfoLog(int)' 
collect2: Fehler: ld gab 1 als Ende-Status zurück 
make: *** [main] Fehler 1 

這是我的源文件:

main.cpp中:

#include "renderer.h" 

static Renderer *renderer; 

static void glutDisplay() 
{ 
    renderer->display(); 
    glutSwapBuffers(); 
} 

static void glutResize(int w, int h) 
{ 
    renderer->resize(w, h); 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 
    glutInitWindowPosition(100, 100); 
    glutInitWindowSize(320, 320); 
    glutCreateWindow("Title"); 

    GLenum res = glewInit(); 
    if(res != GLEW_OK) 
     return -1; 

    glutDisplayFunc(glutDisplay); 
    glutReshapeFunc(glutResize); 
    renderer = new Renderer; 
    renderer->init(); 
    glutMainLoop(); 
    return 0; 
} 

renderer.cpp:

#include "renderer.h" 

Renderer::Renderer() : programID(0.0), vao(0), vbo(0), vertexLoc(0), colorLoc(0), projectionLoc(0), modelviewLoc(0) 
{} 

Renderer::~Renderer() 
{ 
    glDeleteVertexArrays(1, &vao); 
    glDeleteBuffers(1, &vbo); 
    glDeleteProgram(programID); 
    glDeleteShader(vertShaderID); 
    glDeleteShader(fragShaderID); 
} 

void Renderer::init() 
{ 
    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_DEPTH); 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 

    setupShaders(); 

    //glGenVertexArrays(1, vao); 
    glGenBuffers(1, &vbo); 

    float triangleVertexData[] = { 
     0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 
     -0.5f,-0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 
     0.5f,-0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 
    }; 

    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertexData), triangleVertexData, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 

void Renderer::resize(int w, int h) 
{ 
    glViewport(0, 0, w, h); 
    Perspective(projection, 45.0f, (float)w/(float)h, 0.5f, 4.0f); 
} 

void Renderer::display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glUseProgram(programID); 
    glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, projection); 
    glUniformMatrix4fv(modelviewLoc, 1, GL_FALSE, modelview); 

    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glEnableVertexAttribArray(vertexLoc); 
    glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), 0); 
    glDisableVertexAttribArray(vertexLoc); 
    glEnableVertexAttribArray(colorLoc); 
    glVertexAttribPointer(colorLoc, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*) (3 * sizeof(float))); 
    glDisableVertexAttribArray(colorLoc); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 

void Renderer::setupShaders() 
{ 
    vertShaderID = glCreateShader(GL_VERTEX_SHADER); 
    fragShaderID = glCreateShader(GL_FRAGMENT_SHADER); 

    GLint vertlength, fraglength; 
    const char* vertexshader = loadShaderSrc("shaders/simple.vert", vertlength); 
    const char* fragmentshader = loadShaderSrc("shaders/simple.frag", fraglength); 

    glShaderSource(vertShaderID, 1, &vertexshader, &vertlength); 
    glShaderSource(fragShaderID, 1, &fragmentshader, &fraglength); 

    free((char*) vertexshader); 
    free((char*) fragmentshader); 

    glCompileShader(vertShaderID); 
    glCompileShader(fragShaderID); 

    printShaderInfoLog(vertShaderID); 
    printShaderInfoLog(fragShaderID); 

    programID = glCreateProgram(); 
    glAttachShader(programID, vertShaderID); 
    glAttachShader(programID, fragShaderID); 

    glLinkProgram(programID); 
    printProgramInfoLog(programID); 

    vertexLoc = glGetAttribLocation(programID, "vertex_position"); 
    colorLoc = glGetAttribLocation(programID, "vertex_color"); 

    projectionLoc = glGetUniformLocation(programID, "projection"); 
    modelviewLoc = glGetUniformLocation(programID, "modelview"); 
} 

void printShaderInfoLog(GLint obj) 
{ 
    int infoLogLength = 0; 
    int returnLength = 0; 
    char *infoLog; 
    glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infoLogLength); 
    if (infoLogLength > 0) { 
     infoLog = (char *)malloc(infoLogLength); 
     glGetShaderInfoLog(obj, infoLogLength, &returnLength, infoLog); 
     printf("%s\n",infoLog); 
     free(infoLog); 
    } 
} 

void printProgramInfoLog(GLint obj) 
{ 
    int infoLogLength = 0; 
    int returnLength = 0; 
    char *infoLog; 
    glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infoLogLength); 
    if (infoLogLength > 0) { 
     infoLog = (char *)malloc(infoLogLength); 
     glGetProgramInfoLog(obj, infoLogLength, &returnLength, infoLog); 
     printf("%s\n",infoLog); 
     free(infoLog); 
    } 
} 

const char* loadShaderSrc(const char *filename, GLint &filesize) 
{ 
    std::ifstream file(filename, std::ios::in); 
    std::string shader((std::istreambuf_iterator<char>(file)), 
         (std::istreambuf_iterator<char>() )); 
    filesize = (GLint) shader.length(); 
    return shader.c_str(); 
} 

void Perspective(float *a, float fov, float aspect, float zNear, float zFar) 
{ 
    float f = 1.0f/float(tan(fov/2.0f * (PI/180.0f))); 
    for(int i = 0; i < 16; i++) a[i] = 0.0f; 
    a[0] = f/aspect; 
    a[1 * 4 + 1] = f; 
    a[2 * 4 + 2] = (zNear + zFar)/(zNear - zFar); 
    a[3 * 4 + 2] = 2.0f * zNear * zFar/(zNear - zFar); 
    a[2 * 4 + 3] = -1.0f; 
} 

void Modelview(float *mv) 
{ 
    for(int i = 0; i < 16; i++) mv[i] = 0.0f; 
    for(int i = 0; i < 4; i++) mv[i * 4 + i] = 1.0f; 
    mv[3 * 4 + 2] = -2.0f; 
} 

renderer.h:

#include <cmath> 
#include <stdio.h> 
#include <iostream> 
#include <fstream> 
#include <string> 
#include <GL/glew.h> 
#include <GL/glut.h> 

#define PI 3.14159 

class Renderer { 
    private: 
     GLuint programID; 
     GLuint vertShaderID; 
     GLuint fragShaderID; 
     GLuint vao; 
     GLuint vbo; 
     GLint vertexLoc; 
     GLint colorLoc; 
     GLint projectionLoc; 
     GLint modelviewLoc; 
     float projection[16]; 
     float modelview[16]; 
    public: 
     Renderer(); 
     ~Renderer(); 
     void init(); 
     void resize(int w, int h); 
     void display(); 
    private: 
     void setupShaders(); 
     void printShaderInfoLog(GLint obj); 
     void printProgramInfoLog(GLint obj); 
     const char* loadShaderSrc(const char *filename, GLint &filesize); 
     void Perspective(float *a, float fov, float aspect, float zNear, float zFar); 
     void Modelview(); 
}; 

我編譯使用這個Makefile(使用G ++與Linux):

CC = g++ 
CFLAGS = -Wall -g 
INCLUDES = 
LFLAGS = 
LIBS = -lglut -lGL -lGLEW 
SRCS = main.cpp renderer.cpp 
OBJS = $(SRCS:.cpp=.o) 
MAIN = main 

all:  $(MAIN) 

$(MAIN): $(OBJS) 
      $(CC) $(CLFAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS) 

.cpp.o:  
      $(CC) $(CLFAGS) $(INCLUDES) -c $< -o [email protected] 

clean:  
      $(RM) *.o *~ $(MAIN) 

這可能只是一個愚蠢的錯誤,初學者,但我不能找到它。我只是不明白,如果我可以得到一個未定義的函數的引用,如果該函數在同一個文件中定義。

我希望你能幫助我=)

+1

寫得不錯的問題。 –

+1

無關的makefile錯誤:「CFLAGS」與「CLFAGS」的標識符不同。 – Casey

+0

@Casey謝謝,我沒有看到,現在我爲什麼不能使用gdb調試我的代碼。 – Horstinator

回答

6

在你cpp文件Perspective函數被調用Perspective而非Renderer::Perspective。這意味着Perspective方法實際上並未定義,即使現在有一個未使用的函數稱爲Perspective

注意:您與Renderer類的其他private方法有相同的問題。

+0

修復它,謝謝=) – Horstinator

相關問題