我做了一个简单的纹理类,在尝试使用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;
}
答案 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的项目属性“链接器”部分中定义。