使用类时未解析的外部符号(OpenGL,C ++)

时间:2012-12-11 23:54:13

标签: c++ class opengl case

我做了一个简单的纹理类,在尝试使用loadFromFile()时出现了这个错误:

Error   33  error LNK2019: unresolved external symbol "public: unsigned int __thiscall TEXTURE::loadFromFile(char const *,enum imagetype)" (?loadFromFile@TEXTURE@@QAEIPBDW4imagetype@@@Z) referenced in function _main

texture.h:

    #ifndef _TEXTURELOADER
    #define TEXTURELOADER

    #include <GL/glew.h>
    #include <GL/glfw.h>
    #include "debug.h"
    #include <fstream>

    enum imagetype {BMP, TGA, DDS};

    #define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
    #define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
    #define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII

    class TEXTURE
    {

    public:

        float posX;
        float posY;

        GLuint loadFromFile(const char* filename, imagetype extension); // Returns a texture ID; Accepted extensions: BMP, JPG, TGA, PNG, DDS

        GLuint rotate(float degrees); // Positive for clockwise, negative for counterclockwise
        GLuint scale(float multiplier); // Positve for growth, negative for shrinkage
        GLuint move(float x, float y); // Moves the texure x, y

        GLuint setCenter(float x, float y); // Sets centerpoint of texture, used for rotating

        float getPosX();
        float getPosY();

        imagetype getExtension();
        float* getCenter();
    };

    #endif

texture.cpp:

 #include "texture.h"

GLuint loadFromFile(const char* filename, imagetype extension)
{
    switch(extension)
    {
        case BMP:
            {
                // Data read from the header of the BMP file
                unsigned char header[54];
                unsigned int dataPos;     
                unsigned int width, height;
                unsigned int imageSize;  
                // Actual RGB data
                unsigned char* data;

                FILE * file = fopen(filename,"rb");
                if (!file) {
                    printf("Image could not be opened\n");
                    return 0;
                }

                if ( fread(header, 1, 54, file) != 54 ) { 
                    printf("Not a correct BMP file\n");
                    return false;
                }

                if ( header[0]!='B' || header[1]!='M' ){
                    printf("Not a correct BMP file\n");
                    return 0;
                }

                dataPos    = *(int*)&(header[0x0A]);
                imageSize  = *(int*)&(header[0x22]);
                width      = *(int*)&(header[0x12]);
                height     = *(int*)&(header[0x16]);

                if (imageSize==0)    imageSize=width*height*3; 
                if (dataPos==0)      dataPos=54; 

                // Create a buffer
                data = new unsigned char [imageSize];

                // Read the actual data from the file into the buffer
                fread(data,1,imageSize,file);

                //Everything is in memory now, the file can be closed
                fclose(file);

                GLuint textureID;
                glGenTextures(1, &textureID);

                // "Bind" the newly created texture : all future texture functions will modify this texture
                glBindTexture(GL_TEXTURE_2D, textureID);

                // Give the image to OpenGL
                glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);

                delete[] data;

                // Trilinear filtering
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

                glGenerateMipmap(GL_TEXTURE_2D);

                return textureID;
                break;
            }

        case TGA:
            {
                GLuint textureID;
                glGenTextures(1, &textureID);

                // "Bind" the newly created texture : all future texture functions will modify this texture
                glBindTexture(GL_TEXTURE_2D, textureID);

                // Read the file, call glTexImage2D with the right parameters
                glfwLoadTexture2D(filename, 0);

                // Trilinear filtering.
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                glGenerateMipmap(GL_TEXTURE_2D);

                return textureID;
                break;
            }

        case DDS:
            {
                unsigned char header[124];

                FILE* fp;

                fp = fopen(filename, "rb");
                if (fp == NULL)
                    return 0;

                char filecode[4];
                fread(filecode, 1, 4, fp);
                if (strncmp(filecode, "DDS ", 4) != 0) {
                    fclose(fp);
                    return 0;
                }

                fread(&header, 124, 1, fp); 

                unsigned int height      = *(unsigned int*)&(header[8 ]);
                unsigned int width       = *(unsigned int*)&(header[12]);
                unsigned int linearSize  = *(unsigned int*)&(header[16]);
                unsigned int mipMapCount = *(unsigned int*)&(header[24]);
                unsigned int fourCC      = *(unsigned int*)&(header[80]);

                unsigned char* buffer;
                unsigned int bufsize;
                /* how big is it going to be including all mipmaps? */
                bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
                buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
                fread(buffer, 1, bufsize, fp);
                /* close the file pointer */
                fclose(fp);

                unsigned int components  = (fourCC == FOURCC_DXT1) ? 3 : 4;
                unsigned int format;
                switch(fourCC)
                {
                    case FOURCC_DXT1:
                        format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
                        break;
                    case FOURCC_DXT3:
                        format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
                        break;
                    case FOURCC_DXT5:
                        format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
                        break;
                    default:
                        free(buffer);
                        return 0;
                }

                GLuint textureID;
                glGenTextures(1, &textureID);

                glBindTexture(GL_TEXTURE_2D, textureID);
                glPixelStorei(GL_UNPACK_ALIGNMENT,1);   

                unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
                unsigned int offset = 0;

                /* load the mipmaps */
                for (unsigned int level = 0; level < mipMapCount && (width || height); ++level)
                {
                    unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize;
                    glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 
                        0, size, buffer + offset);

                    offset += size;
                    width  /= 2;
                    height /= 2;
                }
                free(buffer); 

                return textureID;
                break;
            }

        default:
            {
                debug.Print("Texture filename extension incorrect or not supported.");
                return 0;
                break;
            }
    }
};

我认为错误不在函数的实际代码中,因为我已经对错误进行了排序。

Main.cpp的:

#include "texture.h"

TEXTURE texture1;

int main( void )
{
    ...
    GLuint Texture = texture1.loadFromFile("uvtemplate.DDS", DDS);

    ...

    do{
            ...
    }
    while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && 
        glfwGetWindowParam( GLFW_OPENED ) );

    glfwTerminate();

    glDeleteBuffers(1, &vertexbuffer);
    glDeleteBuffers(1, &uvbuffer);
    glDeleteProgram(programID);
    glDeleteTextures(1, &TextureID);
    glDeleteVertexArrays(1, &VertexArrayID);

    return 0;
}

3 个答案:

答案 0 :(得分:4)

定义函数时,需要说TEXTURE::,如下所示:

GLuint TEXTURE::loadFromFile(const char* filename, imagetype extension)
{
    // ...

如果没有TEXTURE::前缀,函数loadFromFile()是非成员函数(类似于main())。

答案 1 :(得分:2)

在texture.cpp中,您需要更改:

GLuint loadFromFile(const char* filename, imagetype extension)

GLuint TEXTURE::loadFromFile(const char* filename, imagetype extension)

答案 2 :(得分:1)

此错误表示链接器无法找到TEXTURE :: loadFromFile()函数。我猜测TEXTURE :: loadFromFile()的实现是在一个库中,而不是你项目的一部分。您需要告诉链接器该库所在的位置。

请参阅:

http://msdn.microsoft.com/en-us/library/hcce369f.aspx

这些内容也在MS Visual Studio的项目属性“链接器”部分中定义。