Sign in to follow this  
Bozebo

OpenGL app crash while loading textures

Recommended Posts

Bozebo    108
I have a texture class and a method to load raw image files into it. It works completely fine if I leave size as default but whenever I pass anything else to it my program just crashes. I don't think the array can be going out of range but it seems to be what is happening, no matter how much I look at it I can't find any problems - it even crashes if I pass size as a value smaller than 128 (not making any value too big to store). If I use a raw image of dimensions 256x256 and leave the size parameter empty it works correctly (loads half the bytes as a 128x128 texture - which displays oddly of course - but the function is doing it's job correctly). The variables size and path are not used/set anywhere else, so there can't be some strange global issue going on. Can anybody see the problem that I cannot?
class texture{
  public:
  GLuint texture; //texture resource
  
  //24bpp raw image file
  bool loadRawRGB(char* path,int size = 128){
    int bytes = size * size * 3; //3 bytes per pixel
    BYTE data[bytes]; //buffer to hold raw image data
    FILE * file; //file handle
    
    //open and read texture data
    file = fopen(path,"rb"); //attempt to open the file
    if(!file) //don't continue if it couldn't be opened
      return false;
    
    fread(&data,bytes,1,file); //copy file contents into the buffer
    fclose(file); //close the file
    
    //allocate a texture resource
    glGenTextures(1,&texture);
    //set as target
    glBindTexture(GL_TEXTURE_2D,texture);
    //tell opengl to make a the texture piramid
    gluBuild2DMipmaps(GL_TEXTURE_2D,3,size,size,GL_RGB,GL_UNSIGNED_BYTE,&data);
       
    //free buffer
    free(&data);
    
    return true;
  }
};

//example use
texture brickWall;
brickWall.loadRawRGB("resources/textures/brickWall.raw");


Thanks for your time. [Edited by - Bozebo on March 18, 2010 1:47:46 PM]

Share this post


Link to post
Share on other sites
Bozebo    108
Quote:
Original post by HuntsMan
BYTE data[bytes];

Use new to create a dynamic array of bytes, not a stack one.


no... I couldn't see why that would help, but I tried it anyway:


int bytes = size * size * 3; //3 bytes per pixel
BYTE * data;
data = new BYTE[bytes]; //buffer to hold raw image data
FILE * file; //file handle






Exact same issue. The problem is nothing to do with dynamic arrays. This is really annoying it is holding me back; there doesn't seem to be anything wrong with it :S

edit:
Seems I am wrong about smaller values than 128 not working, I must have been doing something wrong because I tested that again now with a dynamic array and without and it seems to work, now I still cannot get 512 working. Surely an array can have 512x512x3 = 786432 indexes? If not how do I load the texture, load it in 2 parts?

[Edited by - Bozebo on March 18, 2010 8:19:09 PM]

Share this post


Link to post
Share on other sites
diablos_blade    257
I'm actually suprised the compiler lets you allocate an array onto the stack when it doesn't know the size at compile time. You would normally have to do what HuntsMan suggested and use a dynamic array, since it is dynamically sized.

Also, why are you calling free? If it is stack allocated then there is nothing to free, and if it is created with new[] then it should be destroyed with delete [].

Do you know which line it crashes on? That would be a major help obviously. Put a breakpoint in and step through to find which line causes it.

Share this post


Link to post
Share on other sites
Bozebo    108
OK. Right I've edited this I think I have figured it out.

There were a few different issues, the one I ended up with here was I forgot to change:
gluBuild2DMipmaps(GL_TEXTURE_2D,3,size,size,GL_RGB,GL_UNSIGNED_BYTE,&data);
to:
gluBuild2DMipmaps(GL_TEXTURE_2D,3,size,size,GL_RGB,GL_UNSIGNED_BYTE,data);

Silly really, data was a pointer already.

It is being odd but I need to work with it a bit and check I am loading the texture correctly, no crashes now but the texture appears mostly black with some small areas of dull brown.

[Edited by - Bozebo on March 18, 2010 9:45:34 PM]

Share this post


Link to post
Share on other sites
diablos_blade    257
I wasn't expecting that one either. I had my money on it being the free (although I'd have also though that would've crashed no matter the size.)

The most likely cause is incorrect format/internalFormat values, although that should just raise an error, not crash. I haven't used any of the GLU stuff for a while, so thats a shot in the dark.

You should really be using either the GL_GENERATE_MIPMAP texture parameter or (even better) the glGenerateMipMap function, they're both full of hardware accelerated goodness. They should both be available on most machines.

Does it crash when just using glTexImage2D instead?

Share this post


Link to post
Share on other sites
Bozebo    108
glTexImage2D(GL_TEXTURE_2D,0,3,size,size,0,GL_RGB,GL_UNSIGNED_BYTE,data);
makes the texure completely white :S

GL_GENERATE_MIPMAP and glGenerateMipMap are both unrecognised, where do I get a new OpenGL version from? It might be that I have some old version which doesn't like textures of 512x512?

edit:
[url=http://www.gamedev.net/community/forums/showfaq.asp?forum_id=25#q5]FAQ[/url]
Oh. "Although the current OpenGL version is 1.5 (as of 2004/03/29)"
Still outdated.

edit:
(ok why doesn't that link work?)

Share this post


Link to post
Share on other sites
diablos_blade    257
Yip, the bain of everyone who uses OpenGL. The extensions =P
GLEW and GLee are your options on this one. I use GLEW myself, it pretty much reduces the whole thing down to 1 function call which gives you access to everything.

However, back to your white texture. Chances are now all you'll have to do is turn off mipmapping for that texture (just as a test obviously).
Just put this before your call to glTexImage2D and it should be able to see if that works.

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

I seem to remember that being the cause last time I got a full white texture, I'm still not sure why it was because of the mipmapping.

Edit: To make links work you just the html tags for it. < a href="target"></a > (without the spaces)

Share this post


Link to post
Share on other sites
Bozebo    108
Oops, I forgot the gamedev.net forums use some html >_< I got confused because I was using bbcode tags for code blocks.

anyway:
No I wasn't actually using mipmapping before, oddly. I recycled that function from somewhere else to start with and didn't realise I should have been better off using glTexImage2D.

This is where I load some textures to test the simple scene I am making:

//choose filtering options
if(linear){
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
} else {
//nearest-neighbour filtering
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
}

//colours of this texture chosen to test blending of the particles etc
//also good for seeing world scale
texture texChecks;
texChecks.loadRawRGB("resources/textures/checkered2.raw");

//brick wall texture
texture texBricks;
texBricks.loadRawRGB("resources/textures/brick080.raw",512);




Annoyingly none of the opaque textures are working, they are all white now.

I have a loadRawRGBA method in the texture class, which is used to load a pane of glass and some particle textures, that method basically gives an alpha value the same as the pixel's red value (yes cheap, but all I wanted was some basic "greyscale" alpha - and it let me play about with the texture formats a bit).

I am still really confused :S

Just to make sure here is my current loadRawRGB method:

bool loadRawRGB(char* path,int size = 128){
int bytes = size * size * 3;
BYTE * data;
data = new BYTE[bytes];
//BYTE * data[bytes];
FILE * file;

file = fopen(path,"rb");
if(!file)
return false;

fread(data,bytes,1,file);
fclose(file);

glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D,0,3,size,size,0,GL_RGB,GL_UNSIGNED_BYTE,data);

return true;
}





I am so puzzled, if I go back to gluBuild2DMipmaps(GL_TEXTURE_2D,3,size,size,GL_RGB,GL_UNSIGNED_BYTE,data); and just avoid any textures larger than 128x128 it works fine, with glTexImage2D none of them work. I don't understand the purpose of border, but I assume it should be 0? Setting it to 1 doesn't help.

Share this post


Link to post
Share on other sites
diablos_blade    257
Texture parameters can only be applied to the currently bound texture, they can't be applied globally. In the code you posted, there is no texture bound when you set the minification filter. Also the min/magnification filters are also set via glTexParameteri not glTexParameterf as your code states, they're integer flags, not floating point values =].

So when you load the texture, it takes the default per-texture values. According to the docs the default value for the minification filter is GL_NEAREST_MIPMAP_LINEAR, meaning that mipmaps are enabled. =P

Try pasting the code I posted between your calls to glBindTexture and glTexImage2D.

Share this post


Link to post
Share on other sites
Bozebo    108
Ok. I have taken that into account and the blasted thing is still messing up :O

The problem now seems to be a bit more related to what I should be able to understand however, the texture is being loaded but it doesn't seem to be loading as the right format but I am so sure I'm doing it right :S

Take a look at what I am working on, and see this screenshot of the problem:



I have seen that before when working on the texture loading but I can't see how it is still happening :S The function should be fine because the grass texture is good (128x128 texture). And I am so sure I exported the image properly from gimp (I exported it again to make sure). You have been a great help, and solved filtering problems I would have encountered later if I wasn't corrected now.

current state of the method:

//24bpp raw image file
bool loadRawRGB(char* path,int size = 128){
/*
using pow is far slower than * for small integers, I made a small program to test this.
*/

int bytes = size * size * 3; //3 bytes per pixel
BYTE * data;
data = new BYTE[bytes]; //buffer to hold raw image data
//BYTE * data[bytes];
FILE * file; //file handle

//errorMsg("variables initialised");

//open and read texture data
file = fopen(path,"rb"); //attempt to open the file
if(!file) //don't continue if it couldn't be opened
return false;

//errorMsg("file opened");

fread(data,bytes,1,file); //copy file contents into the buffer
fclose(file); //close the file

//errorMsg("file read");

//allocate a texture resource
glGenTextures(1,&texture);
//set as target
glBindTexture(GL_TEXTURE_2D,texture);
//choose filtering options
//if(linear){
//bilinear filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
//} else {
//nearest-neighbour filtering
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//}
//tell opengl to make a the texture piramid
//gluBuild2DMipmaps(GL_TEXTURE_2D,3,size,size,GL_RGB,GL_UNSIGNED_BYTE,data);
glTexImage2D(GL_TEXTURE_2D,0,3,size,size,0,GL_RGB,GL_UNSIGNED_BYTE,data);
//errorMsg("texture associated");

return true;
}



I tried with glBuild2DMipmaps instead of glTexImage2D commented and it still loaded the same way.

I need to sleep on this (4AM here) and check back tomorrow.

Can't wait to get all this sorted so I can make some more interesting stuff, and no doubt overcome various other difficulties >_<

Share this post


Link to post
Share on other sites
diablos_blade    257
I loaded the bricks raw file into photoshop and found out that it is a 512x512 CYMK image apparently. With 4 texture chanels, not 3. Which obviously causes a few problems for your file loading which assumes RGB =P

I saved it back out as a RGB and it now works fine in the app. If you need me to send you it then let me know, but if you can do it yourself it'd be much quicker than downloading a raw texture file. [smile]

Share this post


Link to post
Share on other sites
Bozebo    108
Yes! Got it working thanks for the help.

gimp insisted it was the format I was looking for. Had to stick the tga on my camera as a usb pen, take it to my flatmate's machine and export it with photoshop ^_^

Now I need to tackle model loading, and take a look at direct input.

One other question that no doubt I will end up making a thread for later.
When ordering transparent objects by the z-depth, is there a trick to do this or do I calculate the distance from the camera object?

Once I have a class structure setting up a list and ordering it appropriately shouldn't be an issue, if that is the correct way.

Share this post


Link to post
Share on other sites
diablos_blade    257
Sorting based on distance from the camera should do the trick. It's not technically right, since the sorting should really be done in eye space to get the best results, but it's easier and you'll never notice any differences unless you're really looking for them. Neither method is perfect though, there are still some cases where it can screw up. [smile]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Similar Content

    • By Arulbabu Donbosco
      There are studios selling applications which is just copying any 3Dgraphic content and regenerating into another new window. especially for CAVE Virtual reality experience. so that the user opens REvite or CAD or any other 3D applications and opens a model. then when the user selects the rendered window the VR application copies the 3D model information from the OpenGL window. 
      I got the clue that the VR application replaces the windows opengl32.dll file. how this is possible ... how can we copy the 3d content from the current OpenGL window.
      anyone, please help me .. how to go further... to create an application like VR CAVE. 
       
      Thanks
    • By cebugdev
      hi all,

      i am trying to build an OpenGL 2D GUI system, (yeah yeah, i know i should not be re inventing the wheel, but this is for educational and some other purpose only),
      i have built GUI system before using 2D systems such as that of HTML/JS canvas, but in 2D system, i can directly match a mouse coordinates to the actual graphic coordinates with additional computation for screen size/ratio/scale ofcourse.
      now i want to port it to OpenGL, i know that to render a 2D object in OpenGL we specify coordiantes in Clip space or use the orthographic projection, now heres what i need help about.
      1. what is the right way of rendering the GUI? is it thru drawing in clip space or switching to ortho projection?
      2. from screen coordinates (top left is 0,0 nd bottom right is width height), how can i map the mouse coordinates to OpenGL 2D so that mouse events such as button click works? In consideration ofcourse to the current screen/size dimension.
      3. when let say if the screen size/dimension is different, how to handle this? in my previous javascript 2D engine using canvas, i just have my working coordinates and then just perform the bitblk or copying my working canvas to screen canvas and scale the mouse coordinates from there, in OpenGL how to work on a multiple screen sizes (more like an OpenGL ES question).
      lastly, if you guys know any books, resources, links or tutorials that handle or discuss this, i found one with marekknows opengl game engine website but its not free,
      Just let me know. Did not have any luck finding resource in google for writing our own OpenGL GUI framework.
      IF there are no any available online, just let me know, what things do i need to look into for OpenGL and i will study them one by one to make it work.
      thank you, and looking forward to positive replies.
    • By fllwr0491
      I have a few beginner questions about tesselation that I really have no clue.
      The opengl wiki doesn't seem to talk anything about the details.
       
      What is the relationship between TCS layout out and TES layout in?
      How does the tesselator know how control points are organized?
          e.g. If TES input requests triangles, but TCS can output N vertices.
             What happens in this case?
      In this article,
      http://www.informit.com/articles/article.aspx?p=2120983
      the isoline example TCS out=4, but TES in=isoline.
      And gl_TessCoord is only a single one.
      So which ones are the control points?
      How are tesselator building primitives?
    • By Orella
      I've been developing a 2D Engine using SFML + ImGui.
      Here you can see an image
      The editor is rendered using ImGui and the scene window is a sf::RenderTexture where I draw the GameObjects and then is converted to ImGui::Image to render it in the editor.
      Now I need to create a 3D Engine during this year in my Bachelor Degree but using SDL2 + ImGui and I want to recreate what I did with the 2D Engine. 
      I've managed to render the editor like I did in the 2D Engine using this example that comes with ImGui. 
      3D Editor preview
      But I don't know how to create an equivalent of sf::RenderTexture in SDL2, so I can draw the 3D scene there and convert it to ImGui::Image to show it in the editor.
      If you can provide code will be better. And if you want me to provide any specific code tell me.
      Thanks!
    • By Picpenguin
      Hi
      I'm new to learning OpenGL and still learning C. I'm using SDL2, glew, OpenGL 3.3, linmath and stb_image.
      I started following through learnopengl.com and got through it until I had to load models. The problem is, it uses Assimp for loading models. Assimp is C++ and uses things I don't want in my program (boost for example) and C support doesn't seem that good.
      Things like glVertexAttribPointer and shaders are still confusing to me, but I have to start somewhere right?
      I can't seem to find any good loading/rendering tutorials or source code that is simple to use and easy to understand.
      I have tried this for over a week by myself, searching for solutions but so far no luck. With tinyobjloader-c and project that uses it, FantasyGolfSimulator, I was able to actually load the model with plain color (always the same color no matter what I do) on screen and move it around, but cannot figure out how to use textures or use its multiple textures with it.
      I don't ask much: I just want to load models with textures in them, maybe have lights affect them (directional spotlight etc). Also, some models have multiple parts and multiple textures in them, how can I handle those?
      Are there solutions anywhere?
      Thank you for your time. Sorry if this is a bit confusing, English isn't my native language
  • Popular Now