Losing data when passing uint8_t* to void* parameter function? - c++

I wrote this function to generate a texture in OpenGL. It correctly generates the texture I want which is a wooden box.
// This works
bool GenerateTextureFromFile(const int32_t mipMapLevel)
{
int32_t width, height, channels;
uint8_t* data = stbi_load(mProps.mPath.c_str(), &width, &height, &channels, 0);
if (!data)
{
cout << "Failed to generate texture." << endl;
return false;
}
mProps.mWidth = width;
mProps.mHeight = height;
Bind();
glTexImage2D(GL_TEXTURE_2D,
mipMapLevel,
(uint32_t)mProps.mInternalFormat,
mProps.mWidth,
mProps.mHeight,
0,
(uint32_t)mProps.mImageFormat,
mProps.mDataType,
data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mProps.mWrapS);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mProps.mWrapT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mProps.mFilterMin);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mProps.mFilterMax);
if (mipMapLevel)
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(data);
return true;
}
I would like to wrap that functionality into another function but when I do that glTexImage2D doesn't seem to generate the correct texture. Instead of the wooden box I get a black texture which indicates that the texture failed to generate. Am I losing data when I convert from uint8_t* to void*? What is the best way to do this?
// This fails to generate a texture
void SetDataNew(void* data, TextureProperties props, const int32_t mipMapLevel)
{
mProps = std::move(props);
Bind();
glTexImage2D(GL_TEXTURE_2D,
mipMapLevel,
(uint32_t)mProps.mInternalFormat,
mProps.mWidth,
mProps.mHeight,
0,
(uint32_t)mProps.mImageFormat,
mProps.mDataType,
data);
glTextureParameteri(mObjectID, GL_TEXTURE_MIN_FILTER, mProps.mFilterMin);
glTextureParameteri(mObjectID, GL_TEXTURE_MAG_FILTER, mProps.mFilterMax);
glTextureParameteri(mObjectID, GL_TEXTURE_WRAP_S, mProps.mWrapS);
glTextureParameteri(mObjectID, GL_TEXTURE_WRAP_T, mProps.mWrapT);
if (mipMapLevel)
glGenerateMipmap(GL_TEXTURE_2D);
}
bool GenerateTextureFromFile(const int32_t mipMapLevel)
{
int32_t width, height, channels;
uint8_t* data = stbi_load(mProps.mPath.c_str(), &width, &height, &channels, 0);
if (!data)
{
cout << "Failed to generate texture." << endl;
return false;
}
mProps.mWidth = width;
mProps.mHeight = height;
SetDataNew(data, mProps, mipMapLevel);
stbi_image_free(data);
return true;
}
Here is my TextureProperties struct:
struct TextureProperties
{
std::string mPath;
uint32_t mWidth = 1;
uint32_t mHeight = 1;
TextureFormat mInternalFormat = TextureFormat::RGBA;
TextureFormat mImageFormat = TextureFormat::RGBA;
uint32_t mDataType = GL_UNSIGNED_BYTE;
uint32_t mWrapS = GL_REPEAT;
uint32_t mWrapT = GL_REPEAT;
uint32_t mFilterMin = GL_LINEAR;
uint32_t mFilterMax = GL_LINEAR;
};

The issue is here just realized accidentally put objectID instead of GL_TEXTURE_2D
glTextureParameteri(mObjectID, GL_TEXTURE_MIN_FILTER, mProps.mFilterMin);
glTextureParameteri(mObjectID, GL_TEXTURE_MAG_FILTER, mProps.mFilterMax);
glTextureParameteri(mObjectID, GL_TEXTURE_WRAP_S, mProps.mWrapS);
glTextureParameteri(mObjectID, GL_TEXTURE_WRAP_T, mProps.mWrapT);

Related

Assimp load fbx texture failed, POSSIBLE ISSUE: unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float)

I am using this code to load FBX (note: specific for FBX), the textures unable to load successfully
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++) {
aiString str;
mat->GetTexture(type, i, &str);
if (auto texture_inside = scene->GetEmbeddedTexture(str.C_Str())) {
unsigned char *image_data = nullptr;
int width, height, nrComponents;
if (texture_inside->mHeight == 0) {
image_data = stbi_load_from_memory(
reinterpret_cast<unsigned char *>(texture_inside->pcData),
texture_inside->mWidth, &width, &height, &nrComponents, 0);
} else {
image_data = stbi_load_from_memory(
reinterpret_cast<unsigned char *>(texture_inside->pcData),
texture_inside->mWidth * texture_inside->mHeight, &width, &height,
&nrComponents, 0);
}
if (image_data) {
GLenum format;
if (nrComponents == 1)
format = GL_RED;
else if (nrComponents == 3)
format = GL_RGB;
else if (nrComponents == 4)
format = GL_RGBA;
unsigned int t_id;
glGenTextures(1, &t_id);
glBindTexture(GL_TEXTURE_2D, t_id);
glTexImage2D(GL_TEXTURE_2D, 0, format, texture_inside->mWidth,
texture_inside->mHeight, 0, format, GL_UNSIGNED_BYTE,
image_data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
delete image_data;
AnimTexture texture;
texture.id = t_id;
texture.type_name = typeName;
texture.file_path = str.C_Str();
textures.push_back(texture);
}
LOG(INFO) << "loading texture from embeded: " << str.C_Str();
}
}
then I got error message like this:
UNSUPPORTED (log once): POSSIBLE ISSUE: unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) - using zero texture because texture unloadable
My question is:
How to load FBX embedded texture in a correct workable way?
what did I miss here caused above errors possibly?
currently I only got wrong black dark texture.
This is a common question in the assimp-project. You can find an example how to load embedded textures here: How to deal with embedded textures
In short:
Get the data from the embedded texture
Encode it with a image-converter
Put it into your texture on the GPU

OpenGL Texture corruption

i am rendering simple pixel buffer in OpenGL. First, i create a quad, then i create a texture. It works correctly if there is no changes in buffer. When i change my buffer and add new buffer into texture by glTexSubImage2D or glTexImage2D my texture's top section corrupts like image.
I create my buffer like this.
int length = console->width * console->height * 3;
GLubyte buf[length];
for(int i = 0; i < length; i += 3) {
buf[i] = 0;
buf[i + 1] = 0;
buf[i + 2] = 0;
}
console->buffer = buf;
I create texture like this.
glGenTextures(1, &console->textureID);
glBindTexture(GL_TEXTURE_2D, console->textureID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, console->width, console->height, 0, GL_RGB, GL_UNSIGNED_BYTE, console->buffer);
tpUseShader(console); // -> calls glUseShader(console->programID);
glUniform1i(glGetUniformLocation(console->programID, "texture"), 0);
I update texture like this.
glBindTexture(GL_TEXTURE_2D, console->textureID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, console->width, console->height, GL_RGB, GL_UNSIGNED_BYTE, console->buffer);
For testing i change my buffer like this in render function
if(console->buffer[6] == 255) {
console->buffer[6] = 0; // 6 is second pixel's red value.
console->buffer[10] = 255; // 10 is third pixel's green value
} else {
console->buffer[6] = 255;
console->buffer[10] = 0;
}
Then i call tpUseShader and render my quad.
How can i fix this problem?
I changed my console size to 10x10 and run again this time i got same results but, in image you can see from bottom left 3rd pixel is dark blue. When i print printf("3rd pixel: %d- %d - %d\n", console->buffer[12], console->buffer[13], console->buffer[14]);. value i got red: 0 green: 0 blue: 0 values. That means my buffer is normal.
I got the solution. As pleluron said in comments of question. I changed buf in to console->buffer, and it worked!. Now my buffer initialization code is like this:
console->buffer = malloc(sizeof(GLubyte) * length);
for(int i = 0; i < length; i += 3) {
console->buffer[i] = 0;
console->buffer[i + 1] = 0;
console->buffer[i + 2] = 0;
}

C++ OpenGL Texture not loading

void OGLRectangle::LoadTexture(const char* filename)
{
unsigned int texture;
int width, height;
BYTE * data;
FILE * file;
file = fopen(filename, "rb");
width = 1920;
height = 1080;
data = new BYTE[height * width * 3];
fread(data, width * height * 3, 1, file);
fclose(file);
glGenTextures(1.0, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
tex = texture;
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, 2, width, height,0, GL_RGB, GL_UNSIGNED_BYTE, data);
delete [] data;
}
I have this code to render in an image, the method is called with:
LoadTexture("C:\\Users\Rhys\Documents\Hills.bmp");
The file exists.
Then I'm trying to render it to the openGL window using;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex2d(0.0, 0.0);
glTexCoord2d(1.0, 0.0); glVertex2d(100.0, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2d(100.0, 100.0);
glTexCoord2d(0.0, 1.0); glVertex2d(0.0, 100.0);
glEnd();
glDisable(GL_TEXTURE_2D);
However, all I'm getting on screen is a darkish blue box, with no texture rendered in it.
I have searched for tutorials on how to do this, even asked my lecturer and I still cannot seem to find out why its not working.
Any help will be greatly appreciated.
The .bmp files loading must be little different
This code simply loads bmp file to memory m_pcbData without compression and indexed color support.
bool CBMPImage::LoadFromFile(const CString& FileName)
{
BITMAPINFOHEADER BitmapInfo;
ZeroMemory(&BitmapInfo, sizeof(BITMAPINFOHEADER));
BITMAPFILEHEADER BitmapFile;
ZeroMemory(&BitmapFile, sizeof(BITMAPFILEHEADER));
std::ifstream FileStream(FileName, std::ios::binary | std::ios::in);
if (!FileStream.good())
return false;
// Read bitmap file info
FileStream.read(reinterpret_cast<char*>(&BitmapFile), sizeof(BITMAPFILEHEADER));
// Read bitmap info
FileStream.read(reinterpret_cast<char*>(&BitmapInfo), sizeof(BITMAPINFOHEADER));
// Proper bitmap file supports only 1 plane
if (BitmapInfo.biPlanes != 1)
return false;
m_cbAlphaBits = 0;
m_cbRedBits = 0;
m_cbGreenBits = 0;
m_cbBlueBits = 0;
// Retrives bits per pixel info
m_cbBitsPerPel = (BMPbyte)BitmapInfo.biBitCount;
// Width and height of image
m_nWidth = BitmapInfo.biWidth;
m_nHeight = BitmapInfo.biHeight;
// Compute bitmap file size
m_nSize = 4 * ((m_nWidth * m_cbBitsPerPel + 31) / 32) * m_nHeight;
// Less important info
m_nPixelWidthPerMeter = BitmapInfo.biXPelsPerMeter;
m_nPixelHeightPerMeter = BitmapInfo.biYPelsPerMeter;
// Indexes info not important in our case
m_nClrCount = BitmapInfo.biClrUsed;
m_nClrImportant = BitmapInfo.biClrImportant;
// COMPRESSION MUST BE BI_RGB
m_Compression = (BMPCompression)BitmapInfo.biCompression;
delete [] m_pcbData;
m_pcbData = NULL;
// Allocate proper data size
m_pcbData = new BMPbyte[m_nSize];
// Read actual image data, considering offset of file header
FileStream.seekg(BitmapFile.bfOffBits);
FileStream.read(reinterpret_cast<char*>(m_pcbData), m_nSize);
FileStream.close();
return true;
}
than load bmp texture data to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Image.GetWidth(), Image.GetHeight(), 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid*)Image.GetImageData());
GL_BGR_EXT is important because bmp stores image data in reverse byte order.
Secondly you must specify your material color as white because of usage that texture environment GL_TEXTURE_ENV_MODE, GL_MODULATE
And as mentioned #Reto Koradi, you must specify to generate mipmaps before texture image loading using one of these function calls.
glGenerateMipmap(GL_TEXTURE_2D);
or
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
Plus as you used not power of two textures (width = 1920;
height = 1080;) it may not work.
You're setting the attribute to sample with mipmaps:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
You should only set that if your textures actually has mipmaps. To generate mipmaps, you can call:
glGenerateMipmap(GL_TEXTURE_2D);
after the glTexImage2D() call. Or you can simply set the sampler attribute to not use mipmaps:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
As has already been pointed out: If your image file is indeed a BMP, and not just a raw image file, your image loading code will also need work.

Something wrong with converting SDL surface to GL texture

I can't find my mistake, why text has not been created? When using texture instead of text I get nothing or black background with colored points, please help
GLuint texture;
SDL_Surface *text = NULL;
TTF_Font *font = NULL;
SDL_Color color = {0, 0, 0};
font = TTF_OpenFont("../test.ttf", 20);
text = TTF_RenderText_Solid(font, "Hello, SDL !!!", color);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, text->w, text->h, 0, GL_RGB, GL_UNSIGNED_BYTE, text->pixels);
SDL_FreeSurface(text);
One thing you could add is to specify texture filters, e.g.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Few things you have to check first
is the font loaded properly? check if "font == NULL", maybe your
font path is wrong
is the shader (if you use a shader) setup properly?
My guess is that you set the wrong pixel format type in glTexImage2D cause random color dots apear on your texture
Below is my code that load image via SDL_image for OpenGL use, I think it would be a good start to figure out what step you missed or forgot.
BTW, this code is not perfect. The types of pixel format is more than four (like index color) and I only handle some of them.
/*
* object_, originalWidth_ and originalHeight_ are private variables in
* this class, don't panic.
*/
void
Texture::Load(string filePath, GLint minMagFilter, GLint wrapMode)
{
SDL_Surface* image;
GLenum textureFormat;
GLint bpp; //Byte Per Pixel
/* Load image file */
image = IMG_Load(filePath.c_str());
if (image == nullptr) {
string msg("IMG error: ");
msg += IMG_GetError();
throw runtime_error(msg.c_str());
}
/* Find out pixel format type */
bpp = image->format->BytesPerPixel;
if (bpp == 4) {
if (image->format->Rmask == 0x000000ff)
textureFormat = GL_RGBA;
else
textureFormat = GL_BGRA;
} else if (bpp == 3) {
if (image->format->Rmask == 0x000000ff)
textureFormat = GL_RGB;
else
textureFormat = GL_BGR;
} else {
string msg("IMG error: Unknow pixel format, bpp = ");
msg += bpp;
throw runtime_error(msg.c_str());
}
/* Store widht and height */
originalWidth_ = image->w;
originalHeight_ = image->h;
/* Make OpenGL texture */
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &object_);
glBindTexture(GL_TEXTURE_2D, object_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minMagFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, minMagFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(
GL_TEXTURE_2D, // texture type
0, // level
bpp, // internal format
image->w, // width
image->h, // height
0, // border
textureFormat, // format(in this texture?)
GL_UNSIGNED_BYTE, // data type
image->pixels // pointer to data
);
/* Clean these mess up */
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
SDL_FreeSurface(image);
}
For more information, you should check out SDL wiki or deep into it's source code to fully understand the architecture of SDL_Surface.

Unresolved External Symbol When Using A Class (OpenGL, C++)

I've made a simple texture class, and I get this error when trying to use 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;
}
}
};
I don't think the error is within the actual code for the function, as I've already sorted through bugs in that.
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;
}
When you define the function, you need to say TEXTURE::, like so:
GLuint TEXTURE::loadFromFile(const char* filename, imagetype extension)
{
// ...
Without the TEXTURE:: prefix, the function loadFromFile() is a non-member function (kind of like main()).
In textrure.cpp, you need to change:
GLuint loadFromFile(const char* filename, imagetype extension)
to
GLuint TEXTURE::loadFromFile(const char* filename, imagetype extension)
This error means that the linker cannot find the TEXTURE::loadFromFile() function. I'm guessing the implementation of TEXTURE::loadFromFile() is in a library and not part of your project. You need to tell the linker where that library lives.
See:
http://msdn.microsoft.com/en-us/library/hcce369f.aspx
These things are also defined in the project properties, Linker section in MS Visual Studio.