[SOLVED] Repeating texture and Freeing memory help!

Started by
9 comments, last by Nads 16 years, 1 month ago
Hi Guys, I needed help with two questions. [1] In my game i am trying to create a floor terrain (using vertex buffer and creating a square with UV coords added on). Now before I had the floor at a small size, and it was textured with D3DXCreateTextureFromFileEx. This was fine as the texture resolution was 2048x2048 so it didnt appear stretched. But now I am wanting to increase the size of this terrain floor, therefore I have scaled the box by quite a huge factor! My problem is that the texture is now obviously appearing streatched! Instead is their a way for me to draw the same texture multiple times on the terrain without stretching it creating a seamless tile of grass(the texture im using)? One idea i had was to keep the original floor size(one without the scaleing done) and create a FOR loop to draw multiple squares for the floor and make it look like one big square! But i dont know how effective this would be compared to the first idea? Which one should I do, i would idearlly like to implement the first one(seamless tiles of texture) but only if it doesnt require much changing to existing code? [2] My second problem is to do with classes. I have a Sky class, in my main.cpp im calling it to render the skybox. Hence in the main.h i have an pointed object of the class:
Sky *skyBox = new Sky;

and then I use this successfully in the main.cpp
 skyBox->RenderSkyBox();

but then I want to know how I can delete the pointer reference to prevent leak of memory? I have a CleanD3D function in main.cpp, and I tried this in their:
delete[] skyBox;

but when im exiting my application im getting a problem on this line. It shows a dialog box saying: Debug Assertion Failed! Then it gives me option of Abort/Retry/Fail. And says to click Retry to debug. I do that and it says Application triggered a breakpoint (when it doesnt even have a breakpoint) and points to the delete[] line! Im not even sure if its possible to do what im trying to do, because from most websites ive seen only array pointers being deleted and not class objects. And im a bit confused if i can use delete[] where I am trying to use it or is it only allowed to be used in a destructor?!? Thanks guys for your kind help. [Edited by - Nads on February 20, 2008 4:55:15 AM]
Advertisement
new pairs with delete.
new [] pairs with delete [].

Best of all, allocate it on the stack, or use a std::auto_ptr<> (or boost::scoped_ptr<>, or boost::shared_ptr<>).
In order to repeat the texture just set the uv coordinates of the square to range from (0,0) to (x,x) where x is the time you want the texture to be repeated.

And be sure that you are setting:
d3ddevice->SetSamplerState(D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP)
d3ddevice->SetSamplerState(D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP)

for the texture coordinates to wrap.
Quote:Original post by arc4nis
In order to repeat the texture just set the uv coordinates of the square to range from (0,0) to (x,x) where x is the time you want the texture to be repeated.

And be sure that you are setting:
d3ddevice->SetSamplerState(D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP)
d3ddevice->SetSamplerState(D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP)

for the texture coordinates to wrap.


thanks that worked for me!
Quote:Original post by rip-off
new pairs with delete.
new [] pairs with delete [].

Best of all, allocate it on the stack, or use a std::auto_ptr<> (or boost::scoped_ptr<>, or boost::shared_ptr<>).


im sorry but could you please elaborate on that? I didnt understand what you were trying to say!

At the momoent I would rather stay with the first method instead of trying to use stacks etc..

whats a new pair with delete? Could you please give an example with code of how i can do this in my game?

thanks
When dynamically creating a single instance of an object, one uses new. When dynamically creating an array, one uses new [].

However, everything you dynamically allocated, through either new or new [], must also be deallocated. Each allocate "function" has a corresponding deallocation "function": something allocated with new is deallocated with delete, and something allocated with new [] is deallocated with delete []. Hence I said new was paired with delete, and new[] paired with delete[] (typing all those bold tags is tiring [smile])

Those square brackets make a big difference! So, in your code, you use:
Sky *skyBox = new Sky;


Followed by:
delete[] skyBox;


Can you see how that is wrong? Since you only allocated single instance, not an array (note: even if the array is only a single element long it is still different from a single instance) you must use delete to correctly deallocate the Sky object.

The next part of my post suggested alternatives. The alternative to new and delete is to use a smart object which will delete the object in its destructor. The Standard C++ Library smart pointer type std::auto_ptr would probably suffice in your example:
// old, corrected codeint main(){    Sky *skyBox = new Sky;    skyBox->RenderSkyBox();    delete skyBox;}// newer code: self cleaning up#include <memory>int main(){    std::auto_ptr<Sky> skyBox(new Sky);    skyBox->RenderSkyBox();        // ~auto_ptr calls delete on the sky object    // voila, no memory leaks here!}


Of course, you could also allocate it on the stack (AKA: automatic allocation)
int main(){    Sky skyBox;    skyBox.RenderSkyBox();        // we didn't dynamically allocate, so we are good!}


As I alluded too, the Boost library ([boost]) contains a number of smart pointers to suit most situations (std::auto_ptr is rather misbehaved, its copy semantics are not for the inexperienced or faint of heart).
Quote:Original post by rip-off
When dynamically creating a single instance of an object, one uses new. When dynamically creating an array, one uses new [].

However, everything you dynamically allocated, through either new or new [], must also be deallocated. Each allocate "function" has a corresponding deallocation "function": something allocated with new is deallocated
with delete, and something allocated with new [] is deallocated with delete []. Hence I said new was paired with delete, and new[] paired with delete[] (typing all those bold tags is tiring [smile])

Those square brackets make a big difference! So, in your code, you use:
*** Source Snippet Removed ***

Followed by:
*** Source Snippet Removed ***

Can you see how that is wrong? Since you only allocated single instance, not an array (note: even if the array is only a single element long it is still different from a single instance) you must use delete to correctly deallocate the Sky object.

The next part of my post suggested alternatives. The alternative to new and delete is to use a smart object which will delete the object in its destructor. The Standard C++ Library smart pointer type std::auto_ptr would probably suffice in your example:
*** Source Snippet Removed ***

Of course, you could also allocate it on the stack (AKA: automatic allocation)
*** Source Snippet Removed ***

As I alluded too, the Boost library ([boost]) contains a number of smart pointers to suit most situations (std::auto_ptr is rather misbehaved, its copy semantics are not for the inexperienced or faint of heart).

Thanks alot mate.

That was very well explained and you made it very easy to understand all the methods!

I will try them all out and see how it goes.

In your opinion which would you sujjest is the best method for using?
Generally earlier i had all my class objects like this:

CTerrain terrain;
then used it:
terrain.Draw();

but then I wanted to do it with pointers instead like u showed:
CTerrain *terrain = new CTerrain;
terrain->Draw();
delete terrain;

should I make all my code like this one (above), should I keep it like it is(first method aka. CTerrain terrain) or should I use smart pointer method you sujjested?

Which one would work/run the best/fastest? Or would it not really make much difference?

Thanks alot!
Pointers, in general, trade ease of use for flexibility. Where possible, use automatic allocation. There are times when you can't. The stack (where automatic allocations occur) is of limited size (on Windows, it defaults to roughly a Megabyte IIRC).

If you can't use automatic allocation, then use some kind of smart object to automate the control of deletion.

The key point is this: "then I wanted to do it with pointers instead".

Make this decision for a reason. Pointers are an easy way to create difficult to find bugs.

As for speed: a pointer will often be slower. But if you only use a pointer because you cannot do it any other way, you aren't losing speed, because there is no quicker alternative. An exception to this rule is passing parameters to functions. It is often faster to pass non-primitive types by indirect reference. There are two ways of doing this in C++, using a pointer or a C++ reference. Where possible, choose a C++ reference (const if it makes sense in the function's context) over a pointer, again to reduce the likelihood of bugs.

thanks alot mate for your help!

Quote:Original post by arc4nis
In order to repeat the texture just set the uv coordinates of the square to range from (0,0) to (x,x) where x is the time you want the texture to be repeated.

And be sure that you are setting:
d3ddevice->SetSamplerState(D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP)
d3ddevice->SetSamplerState(D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP)

for the texture coordinates to wrap.
Hmm, I have a similar question. I have a mesh which I want to apply a tiling texture to but I don't understand the first bit of what you said about setting "the uv coordinates of the square to range from (0,0) to (x,x)".

This topic is closed to new replies.

Advertisement