0

我制作了一个简单的纹理类,在尝试使用 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

纹理.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

纹理.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;
            }
    }
};

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

主要.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;
}
4

3 回答 3

4

当你定义函数时,你需要说TEXTURE::,像这样:

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

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

于 2012-12-12T00:04:32.463 回答
2

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

GLuint loadFromFile(const char* filename, imagetype extension)

GLuint TEXTURE::loadFromFile(const char* filename, imagetype extension)
于 2012-12-12T00:04:55.713 回答
1

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

看:

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

这些东西也在 MS Visual Studio 的项目属性 Linker 部分中定义。

于 2012-12-12T00:07:18.100 回答