1
\$\begingroup\$

I've been using OpenGL for a bit so I have a general idea of what I'm doing. Recently, I've been working on a framework to let me test stuff more easily. As part of the framework, I split up loading images into OpenGL into two parts, one where I load the data (ie from a file) and another part where I actually send the data to OpenGL. However, when I use the system I designed, only a black triangle is displayed. When I bypass the system I created and load the texture directly into OpenGL using SOIL's SOIL_load_OGL_texture function, everything works with no other changes. Here's the relevant sections of code:

Main.cpp

// Section commented out to test loading a texture using SOIL instead
/*
Texture::Texture2DSource texData;
texData.loadTextureFromFile("Background.png", Filesystem::FOLDER_TEXTURES);
auto texture = Texture::Interface::getSingleton().loadTexture(texData);
// Debugging function I added to access the texture ID directly
GLuint textureID = texture->getTextureID();
*/

// Load the texture using SOIL as opposed to my texture loading classes
GLuint textureID = SOIL_load_OGL_texture(
    "C:\\Users\\Username\\AppData\\Roaming\\Test\\Textures\\Background.png",
    SOIL_LOAD_RGBA, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);

glActiveTexture(GL_TEXTURE0);
// This line is used when the SOIL texture loading is used
glBindTexture(GL_TEXTURE_2D, textureID);
// I hardcoded in 0 as the uniform ID just for testing; normally I query the 
// uniform ID and use that
glUniform1i(uniformID, 0);

Vertex Shader:

#version 440

layout(location = 0) in vec2 vertex;
layout(location = 1) in vec2 uvData;
out vec2 uv;

void main()
{
    gl_Position = vec4(vertex, 0.0f, 1.0f);
    uv = uvData;
}

Fragment Shader:

#version 440

in vec2 uv;
out vec4 color;
uniform sampler2D textureSampler;

void main()
{
    color = texture(textureSampler, uv);
}

C++ code for loading a texture into memory:

// Create variables to store the image dimensions and properties
int width = 0;
int height = 0;
int channels = 0;

// Load the image
auto data = SOIL_load_image(fileLocation.c_str(), &width, &height, &channels,
    SOIL_LOAD_RGBA);

// Resize the texture's vector to the same size as the array returned from SOIL
m_data.resize(width * height);
// Copy the data from SOIL's array to the vector
const uint32_t BYTES_PER_PIXEL = 4;
memcpy(&m_data[0], data, width * height * BYTES_PER_PIXEL);
// Set the dimensions
m_x = width;
m_y = height;

// Flip the image
// Code omitted as irrelevant

C++ code for loading the texture data into OpenGL:

// Set up the texture storage
GLuint textureID = -1;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
// Load the texture data
glTexImage2D(
    GL_TEXTURE_2D,      // Texture Target
    0,                  // Level of Detail level
    GL_RGBA,            // Internal Format
    data.m_x,           // Width
    data.m_y,           // Height
    0,                  // Border (must be 0)
    GL_RGBA,            // Pixel Data Format
    GL_UNSIGNED_BYTE,   // Data Type
    &data.m_data[0]     // Texture Data
    );

// Set texture filtering options
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

// Create a Texture object and load the texture ID into it, then return it
Texture<GL_TEXTURE_2D> texture;
texture.m_textureID = textureID;
return texture;

Here's some more images:

Issue This is what the window shows when using my texture loading process.

Nsight Info This is what Nvidia NSight shows for the Fragment shader.

Normal This is what the window shows when bypassing my texture loading process.

Nsight Info This is what Nvidia NSight shows when bypassing my texture loading process.

NSight shows the texture as loaded properly for both texture loading processes, and everything else seems to be the same. Any ideas on what's causing the issue?

\$\endgroup\$
  • 3
    \$\begingroup\$ Have you inspected your data to make sure it is what you expect? That its made of uint8's, rgba are in the order you expect etc? You can test that by making test images (eg an all red image) \$\endgroup\$ – Alan Wolfe May 27 '15 at 5:40
  • 1
    \$\begingroup\$ @AlanWolfe The textures are being loaded correctly by my texture loading code. I created text images as you suggested, and I didn't see any issues with the texture data that was loaded. NSight showed the texture properly for both methods, which also seems further validate the texture loading process. \$\endgroup\$ – Shadow May 27 '15 at 23:31
  • \$\begingroup\$ Can you verify that they either both have an alpha channel when loaded, or neither do? \$\endgroup\$ – Alan Wolfe May 27 '15 at 23:34
  • 1
    \$\begingroup\$ The data loaded from my loading process has an alpha value of 255 for all pixels, which makes sense since the image doesn't have any transparent sections. I can't view the data from SOIL before it's loaded, but NSight says that the internal format for the texture is GL_RGBA. \$\endgroup\$ – Shadow May 28 '15 at 1:39
1
\$\begingroup\$

This answer is late, but the problem is because you do not generate mipmaps but you set the texture filter to use a mipmap filtering option.

use

 glGenMipMaps(...)

or change

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

to

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR / GL_NEAREST);
\$\endgroup\$
  • \$\begingroup\$ make sure you check for opengl errors after every opengl call [glGetError()], you can create a macro to do this and surround every opengl function call \$\endgroup\$ – DanielCollier Nov 30 '16 at 3:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.