SFML community forums

Help => Graphics => Topic started by: dartosgamer on July 01, 2013, 03:06:51 pm

Title: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 03:06:51 pm
I just got started with opengl so forgive me if I am missing something huge.

I am trying to load a 128x128 png into a simple opengl context. I have a function that takes in a pixel pointer in GLuint* form (shown below)

        bool Texture::loadTextureFromPixels32(GLuint* pixels, GLuint width, GLuint height)
        {
                freeTexture();

                mTextureWidth = width;
                mTextureHeight = height;

                glGenTextures(1, &mTextureID);

                glBindTexture(GL_TEXTURE_2D, mTextureID);

                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

                glBindTexture(GL_TEXTURE_2D, NULL);

                GLenum error = glGetError();
                if(error != GL_NO_ERROR);
                {
                        printf("Error loading texture from %p. %s\n", pixels, gluErrorString(error));
                        return false;
                }

                return true;
        }
 

I have to cast image->getPixelsPtr() to GLuint* to get it to pass into that function but then opengl spits out an error saying it can't load that image.

Does anyone have any idea of what is going wrong?

Thanks in advance,
Dartos
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 03:09:45 pm
Your API is wrong: since you use GL_UNSIGNED_BYTE, your pointer should be a GLubyte* (and it should be const!).

What is the exact error message?
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 03:26:34 pm
I changed GLuint* to GLubyte*. No dice.

Then I changed it back and changed GL_UNSINGED_BYTE to GL_UNSIGNED_INT and still.. no dice.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 03:29:41 pm
OH the error  (Derp) I forgot

Error loading texture from 0x1d6b7a0. no error

Added note:

Since the gluGetErrorString() says "no error" I tried to remove that

return false;

line and see if the texture would load. It wouldn't... just saying... I tried that.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 03:37:04 pm
Try this, right after the call to glTexImage2D:

printf("error code = %u\n", glGetError());
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 03:56:06 pm
it says "error code = 0"

This is... strange...
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 04:03:22 pm
Duplicate it after every OpenGL call.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 04:18:31 pm
One of the calls gave me 1282 but I'm not sure which one. I'm looking for it now.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 04:24:37 pm
Error code 1282:

Quote
GL_INVALID_OPERATION​, 0x0502: Given when the set of state for a command is not legal for the parameters given to that command. It is also given for commands where combinations of parameters define what the legal parameters are.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 04:30:15 pm
that error comes right after one of the glVertx3f calls. The strange thing is that error only shows up if I have a whole bunch of those error checks in the code.

It does keep running even though this error was thrown. I don't know if that's important but... it does.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 04:37:08 pm
wait... the error comes from glEnd(); but only if I have those printf calls after the glVertex3f calls.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 06:33:50 pm
I am going to try using DevIL... i really don't want to but... if that works then at least we know it's not an issue with my computer.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 07:15:40 pm
I don't think that using DevIL will solve your OpenGL error. If you want to make sure that the problem is not caused by the image data, call your function with a hard-coded array of black pixels (filled with zeroes).
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 07:46:51 pm
just make an array of 0's?


Just made it but it made no difference. I don't think that error has anything to do with the image loading... That error is only there if there is a printf call in between glBegin() and glEnd()
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 07:55:03 pm
Yes. That will give you a black texture. Or an array of 255s, if you prefer white (that would be better actually, as it will also be opaque).
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 08:14:22 pm
Well on the screen it shows a white box. But the texture should be black...

Currently this is the screen offset

SCREEN_WIDTH - tex->getTextureWidth() / 2, SCREEN_HEIGHT - tex->getTextureHeight() / 2

That is fed into glTranslatef before glBegin (shown below)

 
void Texture::render(GLfloat x, GLfloat y)
          {
                  if(mTextureID != 0)
                  {
                          glLoadIdentity();
 
                          glTranslatef(x, y, 0);
 
                          glBindTexture(GL_TEXTURE_2D, mTextureID);
                  }
 
                  glBegin(GL_QUADS);
                          glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
                          glTexCoord2f(1, 0); glVertex3f(mTextureWidth, 0, 0);
                          glTexCoord2f(1, 1); glVertex3f(mTextureWidth, mTextureHeight, 0);
                          glTexCoord2f(0, 1); glVertex3f(0, mTextureHeight, 0);
                  glEnd();
          }
 

But there is only like a quarter of a white box in the bottom right corner of the screen.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 08:40:20 pm
I can't help you if you don't show a complete an minimal example that reproduces the problem. A single OpenGL state can mess up your whole rendering, so it's important to see everything.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 08:48:39 pm
Oh sorry...

main.cpp
#include "LazySpace/LazySpace.hpp"

int main()
{
        if(!ls::initGL()) return -1;

        ls::update();
}
 

LazySpace.hpp
#ifndef LAZY_HEADER
#define LAZY_HEADER

#include "SFML/OpenGL.hpp"
#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"

#include <stdio.h>

#include "../Texture/Texture.hpp"

namespace ls
{
        extern sf::Window* mainWin;

        const int SCREEN_WIDTH = 400;
        const int SCREEN_HEIGHT = 480;
        const int SCREEN_BPP = 32;

        bool initGL();
        bool loadMedia();
        void update();
        void render();
}

#endif
 

LazySpace.cpp
#include "LazySpace.hpp"

namespace ls
{
        sf::Window* mainWin;
        sf::Image image;
        Texture* tex;

        bool initGL()
        {
                mainWin = new sf::Window(sf::VideoMode(800, 600), "This");

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, -1);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();

                GLuint error = glGetError();
                if(error != GL_NO_ERROR)
                {
                        printf("GL init error: %s\n", gluErrorString(error));
                        return false;
                }

                if(!loadMedia()) return false;

                return true;
        }

        bool loadMedia()
        {
                // if(!image.loadFromFile("assets/smile.png"))
                // {
                //         printf("CAN'T LOAD THIS THING");
                //         return false;
                // }

                GLubyte* pixels = new GLubyte[128*128];

                for(int i = 0; i < 128*128; i++)
                {
                        pixels[i] = 1;
                }

                tex = new Texture();
                tex->loadTextureFromPixels32(pixels, 128, 128);
               
                return true;
        }

        void update()
        {
                sf::Event ev;

                while(mainWin->isOpen())
                {
                        if(mainWin->pollEvent(ev))
                        {
                                if(ev.type == sf::Event::Closed) mainWin->close();
                        }

                        render();
                }
        }

        void render()
        {
                // glClear(GL_COLOR_BUFFER_BIT);

                // glMatrixMode(GL_MODELVIEW);
                // glLoadIdentity();

                // glTranslatef(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0);

                // glBegin(GL_QUADS);
                //         glTexCoord2f(0, 0); glVertex2i(50, 50);
                //         glVertex2i(50, -50);
                //         glVertex2i(-50, -50);
                //         glVertex2i(-50, 50);
                // glEnd();
               
                tex->render(SCREEN_WIDTH - tex->getTextureWidth() / 2, SCREEN_HEIGHT - tex->getTextureHeight() / 2);
             

                mainWin->display();
        }
};
 

Texture.hpp
#ifndef TEXTURE_H
#define TEXTURE_H

#include "../LazySpace/LazySpace.hpp"

namespace ls
{
        class Texture
        {
        public:
                Texture();
                ~Texture();

                bool loadTextureFromPixels32(GLubyte* pixels, GLuint width, GLuint height);

                void freeTexture();

                void render(GLfloat x, GLfloat y);

                GLuint getTextureID();

                GLuint getTextureWidth();

                GLuint getTextureHeight();

        private:
                GLuint mTextureID;

                GLuint mTextureWidth;
                GLuint mTextureHeight;
        };
}
#endif
 

Texture.cpp
#include "Texture.hpp"

namespace ls
{
        Texture::Texture()
        {
                mTextureID = 0;

                mTextureWidth = 0;
                mTextureHeight = 0;
        }

        Texture::~Texture()
        {
                freeTexture();
        }

        GLuint Texture::getTextureWidth()
        {
                return mTextureWidth;
        }

        GLuint Texture::getTextureHeight()
        {
                return mTextureHeight;
        }

        bool Texture::loadTextureFromPixels32(GLubyte* pixels, GLuint width, GLuint height)
        {
                freeTexture();

                mTextureWidth = width;
                mTextureHeight = height;

                glGenTextures(1, &mTextureID);

                glBindTexture(GL_TEXTURE_2D, mTextureID);

                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

                glBindTexture(GL_TEXTURE_2D, NULL);

                GLenum error = glGetError();

                if(error != GL_NO_ERROR);
                {
                        printf("Error loading texture from %p. %s\n", pixels, gluErrorString(error));
                        return false;
                }

                return true;
        }

        void Texture::freeTexture()
        {
                if(mTextureID != 0)
                {
                        glDeleteTextures(1, &mTextureID);
                        mTextureID = 0;
                }

                mTextureWidth = 0;
                mTextureHeight = 0;
        }

        void Texture::render(GLfloat x, GLfloat y)
        {
                if(mTextureID != 0)
                {
                        glLoadIdentity();

                        glTranslatef(x, y, 0);

                        glBindTexture(GL_TEXTURE_2D, mTextureID);
                }

                glBegin(GL_QUADS);
                        glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
                        glTexCoord2f(1, 0); glVertex3f(mTextureWidth, 0, 0);
                        glTexCoord2f(1, 1); glVertex3f(mTextureWidth, mTextureHeight, 0);
                        glTexCoord2f(0, 1); glVertex3f(0, mTextureHeight, 0);
                glEnd();
        }
}
 

There... thats all of it.


btw, thanks so much for helping with this. I've used SFML for a few years and it's really nice to see that its creator is so involved :D

Thank you.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 08:54:27 pm
If I wanted to see your code I would say "show your code". If I say "a complete and minimal code that reproduces the problem", there's a very good reason for it :P

http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 10:14:54 pm
DOH! DX sorry. I'm REALLY new to opengl so... idk what's relevant and what isn't (though I don't think main.cpp is important.) I'll post a minimal program later today.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: Laurent on July 01, 2013, 10:20:45 pm
Quote
idk what's relevant and what isn't
That's why you must experiment with your code, remove one part after the other, making sure that the bug is still there after each modification.

By doing this you will not only provide a code that is easy to test for us, but you will also understand your code better, and maybe even find the problem yourself.
Title: Re: loading a png from sf::Image to an openGL useable format
Post by: dartosgamer on July 01, 2013, 11:50:08 pm
Well I am officialy silly.... I forgot to put in glEnable(GL_TEXTURE_2D) AND the error variably was a GLenum type not GLuint.... well.... dern... thanks for all the help though.