Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

3641 Excellent

About Adam_42

  • Rank

Personal Information

  • Role
  • Interests

Recent Profile Visitors

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

  1. Adam_42

    Avoid branch instructions

    If you want to work out which has fewest branches, then just compile it and look at the disassembly: https://godbolt.org/z/4W1y2Y Of course the results will vary somewhat between compilers, and will depend on the implementations of the other functions that you don't show the source for.
  2. Beware that as well as choosing a sort order for opaque objects to optimize performance, you'll also need to separate out transparent objects and render them separately. There's also post-processing, and the user interface to consider. A generic rendering order might look something like this: 1. Depth only pass to minimize overdraw (ideally you only want to render stuff in this pass that's a good occluder (i.e. it's got a relatively low poly count for it's size, and is likely to be in front of other things). 2. Opaque render pass, sorted to optimize performance. 3. Some full screen post-processing might need to happen here if it shouldn't (or can't) be applied to transparent objects. For example, SSAO. 4. Render all transparent geometry, furthest away things first (you'll need to sort by distance to the camera). The sorting is for correctness, and not performance. 5. Render any other post-processing effects (bloom, etc.) 6. Render the user interface (assuming it's 2D, and not part of the 3D scene). Obviously most of those passes are optional. Some games will also have more rendering passes than that, especially if they use some form of deferred shading. One common way to handle the sorting within each render pass, is to create an integer sort key for each thing you render. See http://realtimecollisiondetection.net/blog/?p=86 for an example.
  3. Are you processing the whole of the windows message queue on each game loop?
  4. Firstly, 0x80004003 is E_POINTER which might just mean there's a null pointer been passed to a COM function somewhere, and something has translated it to an exception. Finding out what's gone wrong could be tricky though. The way most video recording tools work is that they hook the D3D API so a call to Present() with them loaded will not just call the standard function - it will also do some extra stuff to capture a video frame. It sounds like your program exposes some sort of bug in the video recording program - they should be completely transparent to the game programmer. Also note that inside D3D a lot of the things you ask the API to do are buffered up, and delayed until the Present() call. This means that Present() can report problems which are actually caused by earlier API calls. You're probably doing something which most other games don't do. Off the top of my head I'd suggest: - Enable D3D11_CREATE_DEVICE_DEBUG (or rather the SharpDX equivalent of that) and make sure the debug runtimes aren't reporting any issues with the way you're using the API. Note that if you're using Windows 10 you'll need to install the optional "Graphics Tools" component for this to work. - Try some different options for recording the game output. Windows 10 has built in support to record games - just press Win+G. I'm sure you can also find some other programs that are free, or have a free trial (OBS Studio, and FRAPS spring to mind). You may well find that some work and some don't. If that's the case then submitting a bug report for the software that doesn't work might be be easier than trying to work round their bugs. - Simplify things as much as possible. Try taking the most basic SharpDX example program that you can find, and record the output of that. Gradually add stuff from your code to the example until you find out what breaks it. I'd start with the device creation and setup code. - The last resort is to do some native code debugging to try to work out what's gone wrong. At the very least the debugger should be able to catch that exception when it's thrown and show you a call stack.
  5. If you're interested in details of what commercial games do, http://www.adriancourreges.com/blog/ has some interesting breakdowns of how frames are put together in various games.
  6. Hmm. Maybe as that CreateTextFormat() call is done using COM, it's actually talking to another process.
  7. You might prefer to use AddFontResourceEx() with the FR_PRIVATE flag, that way the font is only available for your game, and will be automatically unregistered when the process exits.
  8. Adam_42

    Frame analyzer without swapchain

    I think RenderDoc can do it, but you'll need to call its API to tell it where the capture should start and end. See the discussion on: https://github.com/baldurk/renderdoc/issues/817
  9. As the main component of your game will be audio, I'd suggest looking at audio libraries first. Once you've chosen a library, you can select a programming language based on which ones your chosen audio library supports, and what language you're most comfortable using. I'd expect that most audio libraries will be usable from C, C++, C# and Python on Windows - although some languages may be better supported than others. For example, FMOD comes with C, C++ and C# APIs, but not a Python API, although a quick search found a third party one - http://pysonic.sourceforge.net/. The runtime performance of your chosen programming language probably won't make any significant difference. In addition, if performance does become a problem both Python and C# can call into C/C++ code.
  10. There are various tools that can do this for you. Here's a couple of examples: - http://www.fraps.com/ Can capture screenshots and videos. - https://renderdoc.org/ - This is a graphics debugger, that can be very handy for other things too, but it also lets you save any render target out as an image. If you're using Windows 10, you can also just press Windows Key + G to capture images and videos from games.
  11. Adam_42

    Running x86 build crashes

    Those two instructions load the edx register with the contents of the "__that" parameter to the ModelPart move constructor, and then load 16 bytes from there into xmm0. It looks like that's where it has crashed. That isn't going to be an alignment issue, as movups (as opposed to movaps) won't crash for misaligned addresses. I'm thinking that the contents of __that is actually NULL, or otherwise an invalid pointer. You can check what the pointer is by looking at the contents of the edx register at the point it crashes. However, since it's a reference, and not a pointer, it really shouldn't be NULL. Could your custom allocator have returned nullptr?
  12. Adam_42

    Running x86 build crashes

    One thing worth noting, is that on x86 the standard Windows memory allocator only returns 8 bytes aligned memory. On x64 it's 16 byte aligned. That could be causing you problems. I'd suggest overriding global operator new and delete (don't forget the array and nothrow variants) to use _aligned_malloc() to force 16 byte alignment for everything. Having said that, if you want to debug a crash in optimized code, then what you really need to be looking at is the disassembly. I'd also recommend using the /Zo compiler option (which requires edit and continue to be disabled). In addition, you want to disable the "just my code" option. This will let you see more details on what's going on as you have some external code in your crash callstack. I also wouldn't fully trust the diagnosis of "_that is 0x1". I have seen incorrect messages there before, especially for uncommon crash reasons like data misalignment. Looking at the assembly instruction that it crashed on, and the registers used to calculate the memory address that it's accessing can give a more reliable answer. If you're not familiar with reading x86 assembly, then I found a basic guide at: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html. You probably won't need to read past the section on data movement instructions to get started with debugging your crash. If need be you could, post the contents of the disassembly window and registers window here for someone else to look at.
  13. Windows actually provides an API for retrieving the names of keys - GetKeyNameText(). A quick search found some old C++ example code at: http://www.setnode.com/blog/mapvirtualkey-getkeynametext-and-a-story-of-how-to/ - you probably don't need to worry about XP compatibility any more. To use it from C# you'll probably want something like the example code at: https://stackoverflow.com/questions/38584015/using-getkeynametext-with-special-keys
  14. Clang will happily accept the first example with one small change: struct Point2 { Point2() = default; Point2(int a, int b) {x = a; y = b;} // extra constructor for ease of use int x, y; }; Adding the "=default;" in place of {} makes different C++11 rules apply to it and makes it a POD type. To make gcc happy, you need to go one step further: struct Point2 { Point2() = default; int x, y; }; // Non-member function that works like a constructor inline Point2 Make_Point2(int a, int b) {Point2 result; result.x = a; result.y = b; return result;} I'm not sure if gcc is being overly strict here, or if Clang is being lenient in regards to the standard.
  15. The default stack size on Windows is 1MB. 1. The stack size doesn't change on different computers. Maybe some people don't use the feature that consumes lots of stack space, or its stack consumption depends on the input data? 64-bit code will also consume more stack space than 32-bit. 2. Windows supports any stack size that will fit in RAM. You can change it in the linker settings, or as a parameter when creating a thread. I guess 1MB is a reasonable trade off between how much space the program gets to use, and the memory that's consumed by creating a thread, but if you have different requirements you can change it. Also if your stack is too big buggy recursive functions could take a long time before they fail with a stack overflow. 3. When it's crashed in the debugger add the esp (or rsp for x64) register to the watch window. That's the stack pointer, and you can watch it change as you move up and down the call stack in the debugger. Looking at how much it changes by will tell you how much stack is used. Alternatively just look at the size of the local variables in each function on the call stack until you find the big ones - you can use sizeof(variableName) in the watch window to see how big something is.
  • Advertisement

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!