I'm manipulating a Texture2D with Texture2D.Setdata and change its color.
But i want to reset the Texture2D after a Time again, currently im having the whole Texture Datas in Memory, but now i have OutOfMemoryExceptions in my App.
I Tried this:
Color[] bla = new Color[thetexture.Width * thetexture.Height];
this.Content.Load<Texture2D>(".\\textures\\mytexture").GetData(bla);
thetexture.SetData(bla);
But it doesn't change anything, the texture just stays colored.
How can I reset the texture, so that it looks like freshly loaded, but with a small Memoryuse?
ContentManager caches objects. Your call to Load is returning what is presumably the same object as your thetexture (the one you already modified).
You need to load a separate instance of your texture with the original data. You need a separate ContentManager for that. Possibly one that has been customised to never cache objects.
Alternately, create a new Texture2D object and copy the original data into that before modifying it, leaving the original untouched.
Related
Is there a way to adjust the width and height of a texture while not zeroing or overwriting its contents? I'd like to do this without a drawing cycle since for some operations a certain arrangement of W-H would be more suitable than others.
Is there a direct way? No.
You'd have to copy the contents to another texture, then resize the original, then copy it back.
But, if you're going to go to that trouble you might as well just make some texture class that when you resize makes a new texture, copies the old contents to the new texture and deletes the old texture.
I have a texture which I use as a texture map. Its a 2048 by 2048 texture divided in squares of 256 pixels each. So I have 64 "slots". This map can be empty, partly filled or full. On screen I am drawing simple squares with a slot of the sprite map each.
The problem is that I have to update this map from time to time when the asset for the slot becomes available. These assets are being downloaded from the internet but the initial information arrives in advance so I can tell how many slots I will use and see the local storage to check which ones are already available to be drawn at the start.
For example. My info says there will be 10 squares, from these 5 are available locally so when the sprite map is initialized these squares are already filled and ready to be drawn. On the screen I will show 10 squares. 5 of them will have the image stored in the texture map for those slots, the remaining 5 are drawn with a temporal image. As a new asset for a slot is downloaded I want to update my sprite map (which is bound and used for drawing) with the new corresponding texture, after the draw is finished and the sprite map has been updated I set up a flag which tells OpenGL that it should start drawing with that slot instead of the temporal image.
From what I have read, there are 3 ways to update a sprite map.
1) Upload a new one with glTextImage2D: I am currently using this approach. I will create another updater texture and then simply swap it. But i frequently run into memory warnings.
2) Modify the texture with glTextSubImage2D: I cant get this to work, I keep getting memory access errors or black textures. I believe its either because the thread is not the same or I am accessing a texture in use.
3) Use Frame Buffer Objects: I could try this but I am not certain if i can Draw on my texturebuffer while it is already being used.
What is the correct way of solving this?
This is meant to be used on an iPhone so resources are limited.
Edit: I found this post which talks about something related here.
Unfortunately I dont think its focused on modifying a texture that is currently being used.
the thread is not the same
OpenGL-ES API is absolutely not multi-threaded. Update your texture from main thread.
Because your texture must be uploaded on gpu, glTextSubImage2D is the fastest and simplest path. Keep this direction :)
Render on a Frame Buffer (attached on your texture) is very fast for rendering data which are already on gpu. (not your case). And yes you can draw on a frame buffer bound to a texture (= a frame buffer which use the texture as color attachment).
Just one contrain: You can't read and write the same texture in one draw call (The texture attached to the current frame buffer can't be bound to a texture unit)
I'm trying to go for a 2D game like Legend of Mana and Star Ocean Second Story rather than tile based 2D games.
OVERVIEW
Currently, the way I'm going about building my game is like so:
I have geometry files and texture files. Geometry files store width, height, XY position, Texture ID number to use and texture name to use.
The way I'm trying to do is:
I will have a scene manager object that loads "scene" objects. Each scene object stores a list of all geometry objects in that scene as well as texture and sound objects (to be implemented).
Each scene is rendered using vertex array whereby the scene manager object would call a method like get scene vertices by scene name which returns a pointer to an array of GLFloats (GLfloat *) and this pointer to GLfloat gets used in OpenGL's glVertexPointer() function.
When I want to update each character's position (like the hero for example), my aim is to use the "hero" game objects in the current scene and call a function like:
Hero.Move(newXPosition, newYPosition);
which will actually alter the hero geometry object's vertex data. So it will do something like:
for(int i = 0; i < 8; i++)
{
vertexList[i] = vertexList[i] + newXPosition;
vertexList[i+1] = vertexList[i+1] + newYPosition;
...
}
This way, when I go to render the scene in the render frame, it will render the entire scene again with the updated vertex coordinates.
Each object in the game will just be a quadrilateral with a texture mapped to it.
THE PROBLEM
I'm using Objective C for my programming and OpenGL. This is for iOS platform.
I have been successful thus far using this method to render 1 object.
The problem I have is I'm using a NSMutableDictionary which is a data structure that uses key-value pair to store geometry instance objects in the scene object class. Dictionaries in Objective C doesn't retrieve data in the same order every time the code is run. It retrieves then in random order.
Becausing of this, I am having trouble combining all the vertex array data from each geometry object in the scene object and passing out 1 single vertex pointer to GLfloats.
Each geometry object stores it's own array of 8 vertex values (4 pairs of X,Y coordinate value). I would like each geometry object to manage it's own vertices (so I can use Move, Rotate like mentioned earlier) and at the same time, I would like my scene object to be able to output a single pointer reference to all vertices data of all geometry objects in the current scene for using in OpenGL's glVertexArray() function.
I am trying to avoid calling OpenGL's glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) multiple times. Like draw hero, draw map, draw AI agents, draw BG objects. That would not be very efficient. Minimizing the amount of GL draw calls as much as possible (to 1 draw call preferably), especially on limited hardware like the iPhone is what was suggested when I was reading about OpenGL game development.
SUGGESTIONS?
What is the best practice way of going about doing what I'm trying to do?
Should I use a SQL database to store my game data like geometry vertices data and load JUST 1 scene into iPhone memory from the sql database file on iPhone's disk?
You can use a a list of lists to keep track of draw layer and order, and use the dictionary solely for fast lookup.
What I don't understand is why you don't use Cocos2D, that happens to be built on the scene manager paradigm. Think of all the development time you will save...
I have worked in a company that did wonderful games. It eventually died because they kept putting out buggy games, due to the lack of development time for debugging. They did however find time to create a graphics rendering engine.
I thought, and still think, they had wrong priorities. It seems to me you are doing the same mistake: are you trying to make an iOS game, or are you trying to learn how to do a 2D gaming engine for iOS?
Note: Cocos2D is Open Source, you can therefore read it, now that you have thought about the process to create such an engine.
Morning all (if its morning where you are)
I have been looking around and have not seen a satisfactory method for doing this so thought I would ask around...
Ideal world I would like to be able to generate a transparent Texture2D object. Drawing this to the screen I would like to be able to "paint" to it, i.e. when the left mouse button is down whatever pixel the cursor is over should be set to black. Following this I would then need to be able to use this texture.
Using the texture is the easy part, we can simply make a new Texture2D attribute for a "painting" object and use that in the SpriteBatch.Draw method. The two tricky parts are
Generating a texture2D object of a specified size, filled with transparency in code.
Editing that texture2D on the fly (i.e. being able to alter pixel colours)
If anyone has any experience of these you input would be very much appreciated.
You can either use a RenderTarget2D (MSDN), which is itself a Texture2D (so you can use it in SpriteBatch.Draw). This allows you to render onto a texture in the same way you render onto the screen. You need to use GraphicsDevice.SetRenderTarget (MSDN) to set this up.
Or you can use Texture2D.SetData (MSDN) to manipulate pixels directly. You can construct a transparent Texture2D directly (MSDN). Don't forget to Dispose of any textures or other resources you create yourself!
If I have a texture file how would I be able to load up only a part of it using a defined rect (top, left, bottom, right)?
Is it technically possibly to only read in the parts I want to load while leaving the rest of the texture untouched?
What exactly are you trying to achieve. Its pretty simple to load up only a small part of a file into a single texture that encompasses it all. You'll probably need to write your own image parser, though.
If you want to load a partial image into a texture thats the same size as the original image (ie only update the area you are after) then this is relaitvely simple as well. You can LockRcts with a rect that is the area you want you update. You'll still need to write your own image parser though.
Personally in situations like this I prefer to use my own texture format that is already in the format I'm after ...
Look at D3DXCreateTextureFromFileEx: http://msdn.microsoft.com/en-us/library/bb172802%28v=VS.85%29.aspx
Otherwise, load the portion of the data you require yourself into memory, create an empty texture and lock it and copy the data.