0
\$\begingroup\$

I've started trying to make a 2D game in C++ using OpenGL, and I'm using SOIL as the imaging loading library. The problem is, I've been trying to get a simple 64x64 image of a red square to open and display, but when I render it, I get a 64x64 white square.

I've used SOIL before to great effect to load textures for a 3D program I was working on earlier. I have copy-pasted code from that program into the new one, but the texture is not displaying for some reason. I've checked that it was loaded properly, and the ID is being set to a proper ID, and it's getting the dimensions correctly, just not the colors. Even more confusing, when I try to get the height and width of the texture, they are both returning 0.

I'm starting to believe more and more that its something I did wrong initializing the Orthographic Projection matrix, or something is missing from my OpenGL initialization code.

Here is the initialization code:

//Init glfw
if (!glfwInit())
{
    fprintf(stderr, "GLFW Initialization failed!\n");
    exit(EXIT_FAILURE);
}

processCmdArgs(argc, argv);

//Create window
glfwWindowHint(GLFW_SAMPLES, g_aaSamples);
g_mainWindow = glfwCreateWindow(g_screenWidth, g_screenHeight, "Stellar Miner", g_appFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
if(!g_mainWindow)
{
    fprintf(stderr, "Could not create glfw window!\n");
    exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(g_mainWindow);

//Create view matrix POSSIBLE PROBLEM AREA
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, g_screenWidth, g_screenHeight, 0.0f, 0.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);

//Init glew
int err = glewInit();
if (err != GLEW_OK)
{
    fprintf(stderr, "GLEW initialization failed!\n");
    fprintf(stderr, "%s\n", glewGetErrorString(err));
    exit(EXIT_FAILURE);
}

Here is the code for the Texture class:

Texture::Texture(const char* path)
{
        //TODO: Detect the settings based on the target hardware capabilities
    filepath = path;
    textureID = LoadSoilTexture(path, SOIL_LOAD_RGBA, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y, true);
    //GetTextureDimentions(textureID, &width, &height);
    this->height = 64;
    this->width = 64;
    if (textureID < 1)
        printf("Error loading texture.\n");
    printf("Using width %f and height %f.\n", height, width);
}
void Texture::Render(vec2 pos, float rot, float scale)
{
    glBindTexture(GL_TEXTURE_2D, textureID);

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(pos.x, pos.y, 0.0f);
    glRotatef(rot, 0.0f, 0.0f, 1.0f);
    glScalef(scale, scale, 0.0f);

    glBegin(GL_QUADS);
    //Top Left
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(0.0f, 0.0f);
    //Top Right
    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(width, 0.0f);
    //Bottom Right
    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(width, height);
    //Bottom Left
    glTexCoord2f(0.0f, 1.0f);
    glVertex2f(0.0f, height);
    glEnd();

    glPopMatrix();

    glBindTexture(GL_TEXTURE_2D, 0);
}

Interestingly, even hardcoding width and height to 64 makes them print out as 0...

And here is how I load textures:

GLuint LoadSoilTexture(const char* file, int channels, unsigned int id, unsigned int flags, bool useLinear)
{
GLuint textureID = SOIL_load_OGL_texture(file, channels, id, flags);

glBindTexture(GL_TEXTURE_2D, textureID);

bool hasMipmaps = (flags & SOIL_FLAG_MIPMAPS) > 0;

if(useLinear)
{
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, hasMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); 
}
else
{
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
}

glBindTexture(GL_TEXTURE_2D, 0);

return textureID;
}

Sorry for the long post, and any help would be greatly appreciated. You can find my entire solution on Github here.

\$\endgroup\$
5
\$\begingroup\$

You never call glEnable(GL_TEXTURE_2D); to switch on texturing. And since you seem to use the fixed function pipeline that means that only the currently set color (which is white by default is used) to draw.

As for why the texture dimensions are not printed correctly: the format specifier %f expects a 64 bit double value on the stack (floats are automatically converted to doubles), but width and height are (probably 32 bit) ints which results in undefined behavior. Use %d or %i instead.

\$\endgroup\$
  • \$\begingroup\$ So it was just silly mistakes that I've made. Thanks for the help, both of your solutions fixed their respective problems. Thanks. \$\endgroup\$ – sm81095 Sep 11 '13 at 16:29

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.