mr_mo

Members
  • Content count

    19
  • Joined

  • Last visited

Community Reputation

122 Neutral

About mr_mo

  • Rank
    Member
  1. Serializing a struct

    Thanks for the fast replies! @frob: What I understand is, you divided the specific data(MapHeader, TileHeader, TileData, BackgroundTile) and than used the previous data to read the next data. So it went like: MapHeader > TileHeader > TileData > BackgroundTile|OtherTile So you showed me the second approach you mentioned. Quote:Original post by Zahlman 1) '.Net' is properly capitalize '.NET', and is not itself a language. You seem to be thinking of managed C++. 'Cpp' also isn't a proper name for the language you're thinking of; the file name extension '.cpp' is sometimes used because some file systems don't like the character '+' in file names. But in case you were wondering, '+' works just fine in GDNet posts - just not in the preview. Sorry, about that and I know .NET is not a language, but when .NET is mentioned, it generally means managed code(probably a bad habit though) and on top of that, my code is all in C++ so I didn't really thought about writing "This is managed C++". And yes, you are right, I fell victim to the preview. Quote: 2) I don't understand why you're giving a managed C++ code snippet when your game is in non-managed C++ and you want to serialize in non-managed C++. That is because I didn't attempt to serialize and deserialize in the game yet, only the map editor, which I'm coding in .NET for speed. I want to finish it quickly and move back to working on the game itself. So you see, the problem is not with the game but the serialization method. Quote: Quote:However, I recently learned that I can't serialize pointers which puts me in a bind because I don't know any other way to go about this. Serialization. Quote:note: I don't necessarily need to use "const char*" if there is a way to convert an object to "const char*" but like i said, I don't know any other way to go about this. The reason I'm using "const char*" is because the engine i'm using only accepts "const char*" for loading textures and so on. With std::string, you just call the .c_str() member function. However, you need to understand that you can't "just serialize" objects, either, unless they're POD. See the link. I'm wondering why you have that constant '12' lying around all over. It's like you have a struct of arrays instead of an array of structs (generally considered the better-organized layout). Ok, I'll learn what the difference is exactly. The way I learned to make arrays is: int array[size]; So I did the same thing with const char because this project was the first time i actually used const char. I normally use string really. The way I understood chars before this project was that they hold bytes like so 'a','b','c', instead of like strings "abc" but then when i started this project, I saw that const char* acted similar to a string in respect of "abc". (Coming back after reading seeing the example code you posted, I can see what you mean by the structure and you are totally right.) Quote:Also, noone writes 'typedef struct' in C++ unless they need to interoperate with C code, or unless they learned it from someone incredibly behind the times. Also, data members being const is a bit suspicious in general. Haha, you got me on that one. When I initially started to learn C/C++ I had to communicate between the two in order to use a certain engine, so its a habit from then. That's what I thought about const as well. It totally confused me (see the above paragraph for why). Quote: You should end up with something like: *** Source Snippet Removed *** The 12 fold is.. well I should have explained what I'm doing more in-depth. I'm making a side-scrolling game but not tilebased. All the art will be hand-drawn. So in order to build the maps, I just want to cut the map by 800*800 pieces and just load them in order without really "placing" them. I want to allow 12 max pieces of these 800*800. All those variables will contain is just the name of the files(the 800*800 piece) like so: layer[0][0] = "bgmap1-0.png" layer[0][1] = "bgmap1-1.png" layer[X][N] = "Xmap1-N.png" Note: I'm using 800*800 to test, its not final. I'm probably gonna shrink the size. The main purpose of this editor is for passability edit, nothing more yet. 800*12 was because i was testing size, performance and all. Since the game is not tile based, I want to calculate passability pixel-by-pixel and not tile by tile, hence the 800*12, 12 pieces of 800width files. So I think your guess is wrong because I might be wrong but isn't having a layer for EVERY(12) piece less efficient then having 4 layers that contain 12 pieces? State[0].Layer[0] = "bgmap1-0.png" State[1].Layer[0] = "bgmap1-1.png" but I can do this instead i guess: #define MAPSIZE 12 struct DataMap { std::string name; struct Layer { std::string pieces[12]; } layers[4]; // There are standard library classes that you might want to // use here so that the bits will pack together in memory, // instead of requiring at least one byte for each bool bool passability[MAPSIZE*800][600]; }; I only need one passability array because of the static nature of the maps. Also, I'm interested in the library classes you are talking of, can you please name a few or point me to the right direction? So after testing, I've got 3 errors(but 2 different). 1) error C2440: 'reinterpret_cast' : cannot convert from 'const bool (*)[9600][600]' to 'char *' EDIT: fixed by : to.write((char*)&map.passability, sizeof(map.passability)); 2) error C2660: 'std::basic_ostream<_Elem,_Traits>::write' : function does not take 1 arguments Here is the new code: #define MAPSIZE 12 #include <string> struct DataMap { std::string name; struct Layer { std::string pieces[12]; } layers[4]; // There are standard library classes that you might want to // use here so that the bits will pack together in memory, // instead of requiring at least one byte for each bool bool passability[MAPSIZE*800][600]; }; typedef struct { DataMap Map; }MapManager; // Save private: System::Void SaveMap(MapManager* map) { ofstream ofs(StringToChar(std2gc(map->Map.name + ".map")), ios::binary); serialize(ofs,map->Map); } ostream& serialize(ostream& to, const DataMap::Layer& layers) { for (int i = 0; i < 12; ++i) { to.write(layers.pieces[i].size()); to << layers.pieces[i]; } return to; } ostream& serialize(ostream& to, const DataMap& map) { to.write(map.name.size()); to << map.name; for (int i = 0; i < 4; ++i) { serialize(to, map.layers[i]); } to.write(reinterpret_cast<char*>(&(map.passability)), sizeof(map.passability)); return to; } Also, how would I go about reading it again? I would think doing the reverse but the fact that you also wrote the size kinda puzzles me because the size of the variables are static so I didn't think you would need to write the size as well. I don't have time right now but I'll play around with this later. [Edited by - mr_mo on October 17, 2008 8:46:03 PM]
  2. Hello all, I'm attempting to serialize the following: typedef struct { const char* name; const char* layer1[12]; const char* layer2[12]; const char* layer3[12]; const char* layer4[12]; bool passability[12*800][800]; }DataMap; typedef struct { DataMap map; }MapManager; And my code for serializing this is: // Save private: System::Void SaveMap(MapManager* map) { ofstream ofs(StringToChar(CharToString(map->map.name) + ".map"), ios::binary); ofs.write((char *)&map->map, sizeof(map->map)); } // Load private: System::Void LoadMap(System::String^ fname, MapManager* map) { ifstream ifs(StringToChar(fname), ios::binary); ifs.read((char *)&map->map, sizeof(map->map)); } (This is in .Net but I need to serialize in Cpp cause the game is in non-managed Cpp. You can ignore the StringToChar and CharToString.) However, I recently learned that I can't serialize pointers which puts me in a bind because I don't know any other way to go about this. What I'm trying to do is make a simple map editor that saves map data and loads it. I also want to be able to load this data from the game I'm programming. So I decided to use a simple struct the hold the data. note: I don't necessarily need to use "const char*" if there is a way to convert an object to "const char*" but like i said, I don't know any other way to go about this. The reason I'm using "const char*" is because the engine i'm using only accepts "const char*" for loading textures and so on. What should I do to save/load my data? Is there a workaround I can do? I don't necessarily want to know a way to serialize pointers themselves because it might become troublesome in the future, so a workaround would be better. Such as getting the data that the pointer is pointing to a temporary variable and saving that variable instead and loading it in reverse. (If you need more info than just ask :))
  3. Worked! It was glTexEnv! Thank you so much :).
  4. Edit: I researched more into the topic. From what I see, most people use color key to set the alpha. Code: for( i = 0, j = 0; i < imageSize_RGB; i += 3, j += 4 ) { // Does the current pixel match the selected color key? if( pImage_RGB->data[i] == g_keyColor[0] && pImage_RGB->data[i+1] == g_keyColor[1] && pImage_RGB->data[i+2] == g_keyColor[2] ) { pImage_RGBA[j+3] = 0; // If so, set alpha to fully transparent. } else { pImage_RGBA[j+3] = 255; // If not, set alpha to fully opaque. } pImage_RGBA[j] = pImage_RGB->data[i]; pImage_RGBA[j+1] = pImage_RGB->data[i+1]; pImage_RGBA[j+2] = pImage_RGB->data[i+2]; } Here I see that it looks for the color, and if the current pixel is the colorkey, then makes it fully transparent. And then: glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, pImage_RGB->sizeX, pImage_RGB->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA ); is used to create the texture with alpha. So, at first, I also thought the problem was most likely texture.Pixels. However, then I tested by using byes instead of .Pixels. I created a byte array(which is a equivalent of "unsigned char" in C++) and used the byte array instead, like in the above code. I came up with the same results as i did before. Then I changed the alpha to 0 for all the pixels and tried again and I got just the white QUADS, on a black screen. Shouldn't the quads be transparent in this case? I also made the whole image full solid(255), and it showed the original image: So from this, we can determine that it doesn't not have to do with texture.Pixels. Perhaps.. I'm doing something wrong in the blending part >.< Here is how i enable 2D drawing. glPushAttrib(GL_ENABLE_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); /* This allows alpha blending of 2D textures with the scene */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, Video.Screen.Width, Video.Screen.Height); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0.0, (double)Video.Screen.Width, (double)Video.Screen.Height, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); I've looked at many examples and I can't see a thing wrong. btw, I know use: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, c); where c is the byte array. [Edited by - mr_mo on July 1, 2008 5:15:50 PM]
  5. Thank you for your reply :). First, I'm using SDL.Net, i should have mentioned before. The blend i use is this: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); and to load the texture: glTexImage2D(GL_TEXTURE_2D, 0, textureSurface.BytesPerPixel, textureWidth, textureHeight, 0, Gl.GL_RGBA, GL_UNSIGNED_BYTE, textureSurface.Pixels); *textureSurface is an SDL surface I don't think I'm explaining the problem clearly. Here is the problem: The surface is rendered on the Quad as it should. The surface it self keeps its transparency, meaning, I can see the white quad on the background, everything works fine. However, when I render a second texture, I don't want the quad to show. Here is a screenshot of the problem: http://img261.imageshack.us/my.php?image=opengltextestzs9.png (sorry don't know how to make a link). The first texture is at (0,0), the second is at (32,32). I want it to so i can see through the second texture's transparent parts(which is all white).
  6. Are you saying that...if my image is transparent, then the Quad should also be transparent? Because its not.
  7. Thanks for your reply. The image I'm using already contains transparent, semi-transparent areas. That is the reason I see the white quad under the texture(otherwise i would see greenish-blue). As for the multi-texturing extension, it seems not all hardware can use multi-texturing. It wouldn't matter anyway. I need more then just 1 or 2 texturing and I might need to texture different orders and times.
  8. I've been drawing textures like this: glBindTexture(GL_TEXTURE_2D, this.textureId); glBegin(GL_QUADS); glTexCoord2f(0, heightRatio); glVertex2f(locationX, locationY); glTexCoord2f(widthRatio, heightRatio); glVertex2f(locationX + width, locationY); glTexCoord2f(widthRatio, 0); glVertex2f(locationX + width, locationY + height); glTexCoord2f(0, 0); glVertex2f(locationX, locationY + height); glEnd(); but I'm looking for a way to draw textures on top of textures. I'm trying to make it so you can see through the top texture(which is semi-transparent, with transparent parts) to the bottom texture. Obviously, drawing a solid quad on top of the bottom texture doesn't help(perhaps there is a way to make a transparent Quad?). So how would I draw a texture on top of an another texture? or is there some other method I can use to get the results i want? btw, this is 2D mode.
  9. I just followed SDL's OpenGLFont guide. It contained a class that converted 2D surfaces to textures.
  10. Thank you for the help. I've tested the texture I use with NeHe Lesson 06(C# version) and the texture works fine. I've also tried gluBuild2DMipmaps as well but nope. I'm looking at a working 2D texture source but I just can't figure out what I'm missing. I might have to start from scratch using that as a guide, which I don't mind. Btw, can I use particles in 2D? or must I disable 2D and then enable 3D? Edit: I got it to work :D. Thanks for all your help guys :). [Edited by - mr_mo on June 29, 2008 6:01:00 PM]
  11. Edit: My mistake, there is no error. I added Check error between begin and end, so it gave the Invalid operation. So there is no error and the problem(white quad, not tex) still persists. I added CheckError(Gl.glGetError()), which cases the error type, after everyline that uses OpenGL . [Edited by - mr_mo on June 26, 2008 6:24:26 PM]
  12. Oh sorry, I didn't mean I corrected the code, just re-added the parts that were deleted. So, I added the code you gave me, didn't work. Below is what I ended up with: protected virtual void RenderScreen() { // Enable GL Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); Gl.glLoadIdentity(); // Enable 2D Enable2D(); // Add Texture Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE); Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); // Begin GL Gl.glBegin(Gl.GL_QUADS); // i.e. ll, lr, ur, ul // Lower Left Corner Gl.glTexCoord2d(0, 1); Gl.glVertex2d(0, 1024); // Lower Rigt Corner Gl.glTexCoord2d(1, 0); Gl.glVertex2d(256, 1024); // Upper Right Corner Gl.glTexCoord2d(1, 0); Gl.glVertex2d(256, 0); // Upper Left Corner Gl.glTexCoord2d(0, 0); Gl.glVertex2d(0, 0); // End Gl.glEnd(); // Disable 2D Disable2D(); } Oh, and thanks for the heads up on the order of things. I knew there was a specific order, but I couldn't figure out what it was.
  13. Thank you for your replies :). Quote:Original post by MARS_999 First of all, do you realize that you can't load .png files when you call Bitmap textureImage = new Bitmap(textureName); Unless you are calling your texture loading lib Bitmap for all types? I'm pretty sure it loads it. Its a .Net class(GDI+) and on top of that, I used it to paint on a form several times. Also, I've checked during debug mode to see if it loaded the pixels. Quote:// Begin GL Gl.glBegin(Gl.GL_QUADS); // Upper Left Corner //Gl.glTexCoord2f(.25F, .125F); //Gl.glVertex(0.0F, 30.0F, 0.0F); Gl.glTexCoord2d(0, 1024); Gl.glVertex2d(0, 0); // End Gl.glEnd(); texture coordinates are from 0 to 1. Did you really mean 1024 (repeated textures 1023 times)?? You only have on vertex being drawn for a quad that needs 4 vertcies? No, its seems i somehow deleted rest of the code >.<. My apologies. I've deleted the 3 other coordinates and didn't notice i guess. However, it didn't work with the other 3 corners. Does Gl.glTexCoord2d(0, 1024) really load the texture 1023 times? The size of the image is (256,1024). So, I was under the impression that it positioned the lower left corner(x,y). I've read that texture coordinates must mirror vertex coordinates and so upper becomes lower and left becomes right, is this right? I've updated my original post with correct code. I'm sorry for the confusion.
  14. Hi all, I have a code I put together from Nehe texture tutorial and glEnable2D and glDisable2D code snippets to try and learn how to do 2D in OpenGL. The problem is, for some reason, I keep getting just the Quad(white rect) and no texture. Here is the code(in C# but similar to C++): Initialize protected virtual void Initialize() { InitEvents(); // Texture textureName = "011-PortTown01.png"; // Set the Frames per second. Events.Fps = 60; // Sets Window icon and title this.SetWindowAttributes(); // Creates SDL.NET Surface to hold an OpenGL scene screen = Video.SetVideoMode(width, height, true, true, false, true); // Reset The Current Viewport Gl.glViewport(0, 0, width, height); // Load Textures LoadTextures(); // Render Screen RenderScreen(); } LoadTexture /// <summary> /// Load Textures /// </summary> private void LoadTextures() { // Load Bitmap Bitmap textureImage = new Bitmap(textureName); // Check For Errors, If Bitmap's Not Found, Quit if (textureImage != null) { // Create The Texture Gl.glGenTextures(1,out texture); textureImage.RotateFlip(RotateFlipType.RotateNoneFlipY); // Flip The Bitmap Along The Y-Axis // Rectangle For Locking The Bitmap In Memory Rectangle rectangle = new Rectangle(0, 0, textureImage.Width, textureImage.Height); // Get The Bitmap's Pixel Data From The Locked Bitmap BitmapData bitmapData = textureImage.LockBits(rectangle, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); // Typical Texture Generation Using Data From The Bitmap Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB8, textureImage.Width, textureImage.Height, 0, Gl.GL_BGR, Gl.GL_UNSIGNED_BYTE, bitmapData.Scan0); // Fix image for resoulution Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT); Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT); // If Texture Exists if (textureImage != null) { // Unlock The Pixel Data From Memory textureImage.UnlockBits(bitmapData); // Dispose The Bitmap textureImage.Dispose(); } } } Render /// <summary> /// Render the screen. /// </summary> protected virtual void RenderScreen() { Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); Gl.glLoadIdentity(); // Enable 2D Enable2D(); // Create Texture Gl.glGenTextures(1, out texture); // Enable GL Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE); Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_BLEND); Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_MODULATE); Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); // Begin GL Gl.glBegin(Gl.GL_QUADS); // Upper Left Corner Gl.glTexCoord2d(0, 1024); Gl.glVertex2d(0, 0); // Lower Left Corner Gl.glTexCoord2d(0, 0); Gl.glVertex2d(0, 1024); // Upper Right Corner Gl.glTexCoord2d(256, 1024); Gl.glVertex2d(256, 0); // Lower Rigt Corner Gl.glTexCoord2d(256, 0); Gl.glVertex2d(256, 1024); // End Gl.glEnd(); // Disable 2D Disable2D(); } Enable/Disable 2D Rendering /// <summary> /// Enables 2D Mode /// </summary> void Enable2D() { int[] vPort = new int[4]; Gl.glGetIntegerv(Gl.GL_VIEWPORT, vPort); Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glPushMatrix(); Gl.glLoadIdentity(); Gl.glOrtho(vPort[0], vPort[2], vPort[3], vPort[1], -1, 1); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glPushMatrix(); Gl.glLoadIdentity(); } /// <summary> /// Disables 2D Mode /// </summary> void Disable2D() { Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glPopMatrix(); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glPopMatrix(); } That's all I have and I'm not sure what I'm doing wrong here.. [Edited by - mr_mo on June 26, 2008 12:44:40 PM]
  15. Map Tools

    Quote:Original post by SuperNerd For the circle, I would cycle through the tiles as if you were doing a rectangle but check each tile to see if it's within the radius of the center of the circle. # - Old Tile O - New Tile X - Not in radius ############ ###XOOOOX### ###OOOOOO### ###XOOOOX### ############ And with a line. Find wich axis has the greatest difference in tiles X or Y. (1, 4) - Point A (3, 9) - Point B |1 - 3| = differenceInX = 2 (I am using contants, I'm pretty sure you will have your own variables to put into here. |4 - 9| = differenceInY = 5 *** Source Snippet Removed *** Then we loop through the tiles and draw them *** Source Snippet Removed *** Thanks for the fast reply. For the circle..... I can't believe i didn't think about that.. For the line, I would have naver thaught of it. Thanks again. Quote:Can I point out that a circle tool isn't really all that useful when making a square-tile map editor? I never had any problem just using square brushes. Same thing, mostly, for lines. Of course, if you're mostly doing this as a learning project, I can see why you would want to add these, but for practical work I don't think it's needed. No, you are right. Its not. But its still a cool tool. I'm trying to get as much as tools possible. [Edited by - mr_mo on June 29, 2006 5:56:24 PM]