Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: GetPixelsPtr() power of two it pot is not allowed?  (Read 8951 times)

0 Members and 2 Guests are viewing this topic.

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
GetPixelsPtr() power of two it pot is not allowed?
« on: January 08, 2009, 08:40:00 pm »
Hi,
I'm using sf::Image to load an image from a file and I'm using GetPixelsPtr() to get the pixeldata. The documentation states that the size of the image is GetWidth() * GetHeight() * 4 but is this always true? For example if there's no GL_ARB_texture_non_power_of_two is GetPixelsPtr NPOT?
And is there an easy way to get a pot pixel data with sfml(I mean sfml has to do this somewhere so...)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
GetPixelsPtr() power of two it pot is not allowed?
« Reply #1 on: January 08, 2009, 09:19:57 pm »
You don't have to care about that, everything is properly handled internally.
Laurent Gomila - SFML developer

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
GetPixelsPtr() power of two it pot is not allowed?
« Reply #2 on: January 08, 2009, 11:49:50 pm »
But I don't want to use SFML to draw the image, I just want to use SFML to load the image and give me the pixeldata, so that I can use it as a texture in OpenGL. What I want to know if the pixeldata is pot, if it is needed (so if there is a 15*15 texture and an sf::Image containing the image and the OpenGL Implementation only supports pot textures, would GetPixelPtr() return an array of size 15*15*4 or of size 16*16*4?)

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
GetPixelsPtr() power of two it pot is not allowed?
« Reply #3 on: January 09, 2009, 01:21:39 am »
because I'm also using SFML for creating the window, handling input and audio, so it would be better to use sf::Image in order to not have to add an additional dependency.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
GetPixelsPtr() power of two it pot is not allowed?
« Reply #4 on: January 09, 2009, 08:06:19 am »
Like I said, you don't have to care about that... The usage of power-of-two textures is purely an internal detail, which doesn't affect the public interface. So, to answer your question, calling GetPixelsPtr() will always return an array of WxH pixels even if the internal texture uses power-of-two dimensions.
Laurent Gomila - SFML developer

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
GetPixelsPtr() power of two it pot is not allowed?
« Reply #5 on: January 09, 2009, 01:39:09 pm »
Isn't this a bit inconsistent?
You are providing a function to calculate the correct texels, a function to calculate the next valid texture size dependant on the existing extensions so you already provided functions to use sf::Image with OpenGL. Wouldn't it be good to also have a method which returns valid pixeldata (which doesn't need to be converted if there's no npot?)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
GetPixelsPtr() power of two it pot is not allowed?
« Reply #6 on: January 09, 2009, 04:36:34 pm »
Quote
Isn't this a bit inconsistent?

You mean, to load a WxH image and retrieve a WxH array of pixels? So, what would be consistent for you is to return a POT array padded with white pixels? For what? This doesn't make any sense.
Laurent Gomila - SFML developer

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
GetPixelsPtr() power of two it pot is not allowed?
« Reply #7 on: January 09, 2009, 04:52:19 pm »
of course not with this function but it may be usefull to have an additional function which returns pixeldata which can be used with OpenGL.
You are already providing functions to use sf::Images as texture (sf::Image::GetTexCoords, sf::Image::GetValidTextureSize) why not having a function which returns pixeldata which can be used for texturing?
It would be a nice addition and if you are drawing images with OpenGL you will already have this somewhere internally?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
GetPixelsPtr() power of two it pot is not allowed?
« Reply #8 on: January 09, 2009, 05:06:09 pm »
There's already a much powerful feature: you can directly use sf::Image instances as OpenGL textures (using their Bind function).

Quote
sf::Image::GetTexCoords, sf::Image::GetValidTextureSize

They are public only because many other classes in SFML need them, but they are not meant to be used externally. They're not exposed in bindings.

And you don't need to get a padded array to create a POT OpenGL texture. Actually, those extra pixels don't even exist in sf::Image. All you need is to pass the POT dimensions to glTexImage2D and a NULL pixels pointer, and then call glTexSubImage2D with the NPOT dimensions and the NPOT array of pixels. Just look at the sf::Image source code.
Laurent Gomila - SFML developer

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
GetPixelsPtr() power of two it pot is not allowed?
« Reply #9 on: January 09, 2009, 05:22:47 pm »
Quote
There's already a much powerful feature: you can directly use sf::Image instances as OpenGL textures (using their Bind function).

Well, that i even better :)
But how do I use it? I'm just getting a red rectangle(well, the color is a little bit odd, could you please take a look at my other thread about the textcolor?).
I tried the following code
Code: [Select]

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(x, y, layer);

/*
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_tex_name);*/
m_tex_img.Bind();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glVertexPointer(coord_per_vertex, GL_SHORT, coord_per_vertex*sizeof(GLshort), &m_vertices[0]);
glTexCoordPointer(texel_per_vertex, GL_FLOAT, texel_per_vertex*sizeof(GLfloat), &m_tex_coords[0]);

glDrawElements(GL_QUADS, vertices_per_square, GL_UNSIGNED_BYTE, &m_indices[0]);

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
GetPixelsPtr() power of two it pot is not allowed?
« Reply #10 on: January 09, 2009, 05:50:16 pm »
That should work. Can you provide a minimal / complete example which reproduces the problem?
Laurent Gomila - SFML developer

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
GetPixelsPtr() power of two it pot is not allowed?
« Reply #11 on: January 09, 2009, 06:21:59 pm »
Well, no, the minimal example works *g* I will try to find the difference
but now I have another odd problem:
The image is a png file but when I'm trying to use it as a texture it isn't transparent.
Code: [Select]
#include <vector>
#include <sstream>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

using namespace std;
using namespace sf;

int main()
{
RenderWindow win(VideoMode(800, 600), "minimal example");
win.Show(true);

Image img;
img.LoadFromFile("/home/ankou/Pictures/001-Grassland01.png");

vector<GLshort> vertices(8);
vector<GLubyte> indices(4);

vertices[0] = 0;
vertices[1] = 0;
vertices[2] = img.GetWidth();
vertices[3] = 0;
vertices[4] = img.GetWidth();
vertices[5] = img.GetHeight();
vertices[6] = 0;
vertices[7] = img.GetHeight();
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;

GLfloat left(0);
GLfloat right(1);
GLfloat top(0);
GLfloat bottom(1);
vector<GLfloat> tex_coords(8);
tex_coords[0] = left;
tex_coords[1] = top;
tex_coords[2] = right;
tex_coords[3] = top;
tex_coords[4] = right;
tex_coords[5] = bottom;
tex_coords[6] = left;
tex_coords[7] = bottom;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 800, 600, 0);

glClearColor(0, 1, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

while(42)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(10, 10, 0);

img.Bind();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glVertexPointer(2, GL_SHORT, 2*sizeof(GLshort), &vertices[0]);
glTexCoordPointer(2, GL_FLOAT, 2*sizeof(GLfloat), &tex_coords[0]);

glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[0]);

win.Display();
}
}



But when I'm executing
Code: [Select]

String fps_drawable("some string", Font::GetDefaultFont(), 10);
win.Draw(fps_drawable);

before I render the rectangle the image is displayed correctly(with transparency)

edit: oh, I forgot an GLenable