Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

155 Neutral

About Jemme

  • Rank

Personal Information

  • Role
  • Interests

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I am willing to help if it goes towards game programming portfolio etc.
  2. Jemme

    CubeMap Conversion

    Im not sure if they have a cubemap tool, the format i use isn't really dds its custom because its easier to load in my case so i have to build the tool myself.
  3. Jemme

    CubeMap Conversion

    Hi, i meant a sky map you download off the internet for use as a skybox or IBL, they come in the various formats shown in the picture i posted. I originally wanted to convert from those into a texture array, it means extracting each individual image out of the original and adding its data onto the end of my binary file. I eventually gave up because the copy operations seemed Over the top, so i settled for forcing separate image assignment and convert that way: When the user clicks build it converts each image into a dds style format, by default it uses DXT5 with mipmapping enabled. It adds the bytes from each image 1 after another itno a huge buffer of data and sets arraysize and mips to what ever the image needs. Then i just load it up at run time using my Texture2D class. If you know how to split the images automatically from the original map's without doing 6000+ std::memcpy operations then id be happy to hear your suggestion
  4. Hello, Im trying to automatically convert a cubemap image into an array of textures for a dds file: I have detected which Cubemap type the files are in, however i need to copy the data of each individual square into an array, this would require performing (ImageWidth * 6) std::memcpy operations, so for a 1024x1024 individual cubemap size map your doing 6144 copy operations. Is there anyway to copy a section from an image (think paint select and copy) in a more efficient way? Thanks,
  5. Yeah that makes sense,loading can benefit from the entire read but compiling can do the pre-flip.
  6. The original reason was encase i needed to implement endian flip if i ignore platforms that are not x86 then it is a simple case of doing: //----------------------------------------------------------------------------- bool BinaryIO::WriteBuffer(byte * data, unsigned int byteCount) { if (!mFile && (mMode == BINARY_FILEMODE::WRITE_BINARY)) { //log: file null or you tried to read from a write only file! return false; } mFile.write((char*)data, byteCount); return true; } //----------------------------------------------------------------------------- bool BinaryIO::ReadBuffer(byte * data, unsigned int byteCount) { if(!mFile && (mMode == BINARY_FILEMODE::READ_BINARY)) { //log: file null or you tried to read from a write only file! return false; } mFile.read((char*)data, byteCount); return true; } Which is pretty much instantaneous load, so ill just leave it at that for the time being.
  7. Hello, I have a custom binary ImageFile, it is essentially a custom version of DDS made up of 2 important parts: struct FileHeader { dword m_signature; dword m_fileSize; }; struct ImageFileInfo { dword m_width; dword m_height; dword m_depth; dword m_mipCount; //atleast 1 dword m_arraySize; // atleast 1 SurfaceFormat m_surfaceFormat; dword m_pitch; //length of scanline dword m_byteCount; byte* m_data; }; It uses a custom BinaryIO class i wrote to read and write binary, the majority of the data is unsigned int which is a dword so ill only show the dword function: bool BinaryIO::WriteDWord(dword value) { if (!m_file && (m_mode == BINARY_FILEMODE::READ)) { //log: file null or you tried to read from a write only file! return false; } byte bytes[4]; bytes[0] = (value & 0xFF); bytes[1] = (value >> 8) & 0xFF; bytes[2] = (value >> 16) & 0xFF; bytes[3] = (value >> 24) & 0xFF; m_file.write((char*)bytes, sizeof(bytes)); return true; } //----------------------------------------------------------------------------- dword BinaryIO::ReadDword() { if (!m_file && (m_mode == BINARY_FILEMODE::WRITE)) { //log: file null or you tried to read from a write only file! return NULL; } dword value; byte bytes[4]; m_file.read((char*)&bytes, sizeof(bytes)); value = (bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | bytes[3] << 24); return value; } So as you can Imagine you end up with a loop for reading like this: byte* inBytesIterator = m_fileInfo.m_data; for (unsigned int i = 0; i < m_fileInfo.m_byteCount; i++) { *inBytesIterator = binaryIO.ReadByte(); inBytesIterator++; } And finally to read it into dx11 buffer memory we have the following: //Pass the Data to the GPU: Remembering Mips D3D11_SUBRESOURCE_DATA* initData = new D3D11_SUBRESOURCE_DATA[m_mipCount]; ZeroMemory(initData, sizeof(D3D11_SUBRESOURCE_DATA)); //Used as an iterator byte* source = texDesc.m_data; byte* endBytes = source + m_totalBytes; int index = 0; for (int i = 0; i < m_arraySize; i++) { int w = m_width; int h = m_height; int numBytes = GetByteCount(w, h); for (int j = 0; j < m_mipCount; j++) { if ((m_mipCount <= 1) || (w <= 16384 && h <= 16384)) { initData[index].pSysMem = source; initData[index].SysMemPitch = GetPitch(w); initData[index].SysMemSlicePitch = numBytes; index++; } if (source + numBytes > endBytes) { LogGraphics("Too many Bytes!"); return false; } //Divide by 2 w = w >> 1; h = h >> 1; if (w == 0) { w = 1; } if (h == 0) { h = 1; } } } It seems rather slow particularly for big textures, is there any way i could optimize this? as the render grows too rendering multiple textured objects the loading times may become problematic. At the moment it takes around 2 seconds to load a 4096x4096 texture, you can see the output in the attached images. Thanks.
  8. Yeah, I just made the user pass in a vector of Rener targets and grab the count. It's split into setRenderTarget and setRenderTargets if you pass nullptr to the singular one it Debra all to null accept [0] which gets default or the main target. Either way it turns out the solution for both Oop and dod will be the same just one with handles. I'm doing both eventually.
  9. Hello, I have been trying to set up multiple render target views in a traditional oop style architecture (as opposed to DOD), DX11 forces binding of RenderTargets as an array with the depth view as well. This is annoying when it comes to binding multiple buffers when you have objects such as DX11Rendertarget2D which stores an ID3D11RenderTargetView*, if it worked like everything else did in the sense that it used slots such that you can do: SetRenderTarget(slot, RenderTarget); ,Then it would be a lot better as you could set the slots you want and set the depth buffer or leave it as the default one by passing null such is the way of a state-full API. Any input on how others have managed there RenderTargets would be appreciated, storing an array of ID3D11RenderTargetView*[8] doesn't seem like a good idea due to ownership and ref counting. Thanks.
  10. There is another thing, if everything is stored as an ID then don't you loose some of the details for example in an oop environment we could do. //just some random example Rectangle CalculateBounds() { return Rectangle(m_pos.x, m_pos.y, myTextureObject.Width, myTextureObject.Height); } But if your sprite or "insert object with texture" just stores a Handle to a texture then you cant easily grab the data, you would have to always have a reference to the GraphicsDevice hanging around in order to do a long fetch to the pool. //Just some random example Rectangle CalculateBounds(GraphicsDevice* graphicsDevice) { Texture* myTextureObject = m_graphicsDevice->GetTexture(m_texID); return Rectangle(m_pos.x, m_pos.y, myTextureObject->Width, myTextureObject->Height); } So Pools are nice and cache friendly but everywhere else becomes less efficient because of it, so is the solution some hybrid approach such that: struct Texture2D { unsigned int m_width; unsigned int m_height; unsigned int m_levelCount; SurfaceFormat m_surfaceFormat; TextureHandle m_textureID; } class GraphicsDevice { //...Other stuff TexturePool m_texturePool; //Stores 4096 texture ptr? with a Index and Generation? void CreateTextureFromImage(ImageFile file, Texture2D* pResult){//Creats sets data, returns;} } //Back in some other User Class Rectangle CalculateBounds() { return Rectangle(m_pos.x, m_pos.y, m_texture.m_width, m_texture.m_height); } Designing the GraphicsDevice in a stateless way changes the entire low-level framework, its important to make sure its efficient but also easy to use.
  11. Do you mean like this: Reflection Lumberyard had a talk about reflection I think I'd have to try find it again.
  12. The storage method for component data is kind of free choice, XML, Json, LUA are fine tbh, i do have a custom BinaryIO class in the low-level engine to read and write binary, i haven't set up endian flip or anything though. A previous project of mine had an asset pipeline tool that dynamically displayed the "import" templates when you selected assets of different types so you could change there settings liek compile as DXT1 etc. It used xml for that, but yeah serializing and deserting in binary is a possible route for the component data, but for now i will probably do it in lua or JSON so i can quickly edit things until i get an editor and automate it. Like Kylotan said i need to just get on with it and refactor and improve things as i go, that's probably the main thing a "junior" needs to learn to do otherwise you get caught up with the thousands of different possibilities and limitations of every possible implementation that you never start.
  13. I'm building everything from scratch, all the low-level, dx11, gl etc. In the past many years ago I used xna and sfml for specific projects like build an RPG etc. But now I'm doing everything and I want it to be reuseable, I'm going the route of having a game logic system which initialises all the logic systems and using lua for behaviour scripts and JSON for components initialisation on entities.
  14. Are you storing all your data on the RenderDevice? for example lets say i have a Mesh which needs a Vertex buffer and index buffer. are you just storing them as handles like VertexBufferHandle inside the mesh but creating the actual buffers on the device such that: void Init(RenderDevice* device, char* data) //function in mesh? { //Load data into some internal representation like MeshData VertexBufferDesc desc; //agnostic desc NOT GL or DX //fill in descusing MeshData device.CreateBuffer(desc, &vertexBufferHandle) } Then when you submit your DrawItem your just passing in all the handles for the vert, index and constant buffers for the RenderDevice to just fetch and set from its pool's? you would think the fetch via a handle would be slower then just a pointer chase. But cache could be better?
  15. There isn't really a good way to implement the game logic / components that interact with the underlying engine, these are the common approaches which i have used in different projects with the pro/cons. OOP Inheritance: Pro: Makes sense to normal programmers, easy to explain. Works for simple systems Con Deadly diamond Monolithic class hierarchies Multiple inheritance Deep wide hierarchies bubble up effect Entity Component pro Easy to implement / explain Works for most systems Allows many Entities of different types Con Not friendly to cache pointer chasing Non-sequential component updates virtrual function, vtable cache miss spaghetti pointer chasing in the Update loop Entity Component System pro Easy to implement / explain Works for most systems Allows entities of different types Data Orientated Design (contiguous) No vtables ID's allow reallocation + avoid dangling pointer con Claimed cache benefits fall away when you have to chase a pointer to a GameObject to get a Transform for a meshrender or physics system to act upon it. Using ID's causes dependency on systems. e.g (RenderSystem.GetComponent(Entity.ID)) so now the script / other system has to suddenly know about every other system it needs data from as opposed to just having a pointer to the data. Still spaghetti pointer chasing in the update loop. There the common way's you see being talked about, another method is to use a message system which makes sense. However, should you really have a message for every possible thing that can happen + every system having to know about every possible thing that can happen and just ignoring it. You could store a position with your MeshRenderer if a message is received to update position you can just update it that way it is cached with the MeshRender, the physics can cache its version, yes its duplication of data but ti stops pointer chasing. So basically every system/method i have encountered improves something at the cost of making something else less efficient.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!