Jump to content
  • Advertisement

ValMan

Member
  • Content count

    270
  • Joined

  • Last visited

Community Reputation

466 Neutral

About ValMan

  • Rank
    Member
  1. ValMan

    Sprite rotation woes

    Set identity transform only once before drawing all the walls, no need to set it for each wall. How does your collision work? What do you mean by rotating the thing and not its axes? You are not using a camera transform in your program, so no axis should be affected.
  2. ValMan

    Sprite rotation woes

    "Isn't spritebatch for XNA? Or is there something else I need to do?" ID3DXSprite interface is used to render a sprite batch. This increases efficiency when sprites (each being 4 vertices and 2 triangle primitives) share the same texture, transform and shaders because all sprites that share these render options can be submited to video card in one Draw call (meaning DrawIndexedPrimitive). Sprite batches are also convenient because ID3DXSprite will sort your sprites within a batch by Z order or texture if you specify. For 2D games, you usually want both options on when drawing the world, and none when drawing UI. In your case, the player sprite does NOT share the same transform as the walls, so it cannot be drawn in the same batch since render states have to be set. Chances are, you are also using a different texture, in which case drawing player will break the batch no matter what. 3D games face exactly the same issues, and you start worrying about the number of batches you submit only when you find your performance unacceptable. I personally target 60 FPS with v-sync, and if my game runs at least at 59-60 on debug build I find no reason to worry about optimizing. "Also are you basically saying that I should have multiple id3dSprite->Begin() and id3dSprite->End() function calls?" Yes, let me correct my previous post - there is no need to end the batch by calling End() after every batch. End() will attempt to restore all render states on the device to values captured at the time of Begin() call, which is unnecessary until you finish all drawing for the frame. Call Flush() instead to submit current batch and change render states for the next batch. SetTransform may cause Flush() to be called automatically - I use a custom sprite class in my engine so I don't remember the nuts and bolts of D3DXSprite as well as I used to. In any case, make sure to set transform to identity matrix before drawing things that aren't supposed to be transformed, as opposed to using D3DXMatrixRotateZ with angle of 0. "Also I was unaware of the memory leak thing. Do you have anything I could use to read up further on this?" new operator in C++ will allocate an object on the heap. This object will remain allocated until you explicitly deallocate it with delete. If the object is never deallocated, this creates a memory leak - your program bit off a chunk of memory and never returned it back. This is especially problematic inside loops, such as this render loop. Every time the loop is run, a new D3DXVECTOR3 object is allocated to pass to Draw method, and never released. So every frame, you loose at least 24 bytes of heap memory (D3DXVECTOR3 takes at least 12 bytes and you have two heap allocations with new). With time, this will make your program run slower and then crash. Read about heap memory allocation and new/delete operators in C++.
  3. ValMan

    Sprite rotation woes

    Looks like you are on the right path. The workflow for drawing rotated and non-rotated sprites is typically the following: Begin Batch Set Identity Transform (means no transform will take place) Draw some non-transformed sprites... End Batch Begin Batch Set Transform (matrix generated by RotationX, RotationY, RotationZ or Transformation2D functions in your case) Draw some rotated or otherwise transformed sprites... End Batch Begin Batch Set Identity Transform Draw some non-transformed sprites... End Batch Here are the things you are missing: 1. Every time you change transform, you need to Begin/End a sprite batch before calling Sprite->SetTransform to set another transform. The way rendering works, a sprite batch will get drawn all at the same time (which is the whole point of sprite batching), with the last transform you set for that batch. Setting transform more than once for the same batch will not have any effect. 2. To "reset" a transform, you pass an identity matrix to SetTransform to cancel out any previous rotation, etc. D3DXMatrixIdentity will generate you an identity matrix. So in your case, call Sprite->Begin, set your transform matrix generated by D3DXMatrixRotationZ, draw player sprite, call Sprite->End, call Sprite->SetTransform passing identity matrix generated by D3DXMatrixIdentity, then Begin, then draw your walls, then End. This will draw the player sprite rotated and walls will be untransformed. When rotating sprites, you also should be aware of the point you are rotating by, called pivot point or hot spot depending on terminology. If I remember correctly, D3DXSprite will generate its vertices so that any Z rotation applied will automatically rotate the sprite using center as the pivot point. However, if you should want to change this pivot point, you can do so with a Translation matrix generated by D3DXMatrixTranslation and then multiply that with RotationZ matrix to get a rotation about a different pivot point. The translation before rotation will be an offset from current pivot point to the new point. The last thing I saw in your code is you are using new operator to pass D3DXVECTORs into Sprite->Draw method. If you are using C++ this will create a memory leak, so I recommend allocating the position vars on the stack and taking their address instead. Of course when you progress to the point of having a real game, your data structures for the walls and the player should already use D3DXVECTORs and you can just take an address of those. For your walls you will probably not want to use transform matrices, because it will make collision detection more difficult later. If you represent your walls as AABBs internally (meaning x, y, width, height rectangle structure) drawing them will be more efficient and collision detection will be easier later on. If you still have problems, maybe post a screen or two. I don't know what "rotating the wall, but not visibly" means.
  4. ValMan

    First release!

    I've been meaning to ask this, but how do I place the tree sprite on the map? I managed to place land/grass tiles and the small plants, but the tree doesn't show up in the texture browser. I messed around with the Build and Actor tabs, and I managed to create an actor using the tree texture, but when placed on the map, the actor showed up as a traced box, without the texture.
  5. ValMan

    First release!

    I had to install OpenAL, but after that worked fine. Very fast performance, high quality display. Got a message box (but only after quitting): --------------------------- Terminating editor, following errors occurred --------------------------- shaders/nimrod_lightshader0.vert - shaders/nimrod_lightshader0.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader1.vert - shaders/nimrod_lightshader1.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader2.vert - shaders/nimrod_lightshader2.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader3.vert - shaders/nimrod_lightshader3.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader4.vert - shaders/nimrod_lightshader4.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader0_bi.vert - shaders/nimrod_lightshader0_bi.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader1_bi.vert - shaders/nimrod_lightshader1_bi.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader2_bi.vert - shaders/nimrod_lightshader2_bi.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader3_bi.vert - shaders/nimrod_lightshader3_bi.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader shaders/nimrod_lightshader4_bi.vert - shaders/nimrod_lightshader4_bi.fragValidation failed! - Different sampler types for same sample texture unit in fragment shader My specs are: Intel Celeron 2.26 Ghz 1.5 GB RAM GeCube Radeon X1550 (driver ver 8.530.0.0) WinXP SP2
  6. ValMan

    Art Issue, Camera, GUI

    Crashed on startup :( Error: Tried to execute code at 0x00000000, called from 004051e8() Assuming you can believe the call stack, since you didn't attach any debug info. Log contains same info as already mentioned (LoadTexture/invalid enumerant). I can upload crash dump if you are interested.
  7. ValMan

    Pod Collisions

    I got interested in your problem after reading and thought about it. Here's what I came up with: 1. For each type of tile, store its convex hull as an array of 4 lines. In terms of storage you could do this by having a "tile template" file that specifies the bitmap the tile will display and include the convex hull info. The best way to represent a 2D line is by using 1 point that lies on the line plus line's normal (the vector that points in the direction of line's positive halfspace). This representation is most optimal for collision detection. You can reduce the memory this will take by storing only 4 normals (2 floats for each), and then assuming that the first and the second line's point is the tile's top left corner and the third and fourth line's point is the tile's bottom right corner. So for a simple square tile, you would store: [0] = ( -1.0, 0.0) // left edge - normal points left (implicit point is tile top left) [1] = ( 0.0, -1.0) // top edge - normal points up (implicit point is tile top left) [2] = ( 1.0, 0.0) // right edge - normal points right (implicit point is tile bottom right) [3] = ( 0.0, 1.0) // bottom edge - normal points down (implicit point is tile bottom right) Notice that all normals are pointing "out" of the tile (away from center). 2. When doing collision detection: For each tile that pod overlays, Calculate 4 lines that define that tile's convex hull by using the stored normals and calculating the points based on current tile's AABB min & max (top left & bottom right). Thus, "decompressing" the hull info to prepare for collision testing. Then for each "decompressed" hull line, check if the line faces toward the pod or away from pod. If it faces away, you can early-out of collision detection. This will prevent testing collision against the sides of tiles that face away from the pod and are not a part of the complex shape that defines pod's "immediate environment" that it's inside of. To do this, you would probably take the dot product of the line's normal versus the vector difference of line's point and pod's center point (pod.center - line.point). If the dot product is negative or [close to] zero, the normal points away from the pod, so it would be on the "other side" of the tile. If on the other hand the result is positive, you proceed to test collision. You can work out the specifics, but it sounds about right. To test collision, you would reuse the projection you just did. Compare the dot product result (if positive and non-zero) to the pod's radius. If less than radius, flag collision. The last part is moving the pod out of intersection after detecting collision. To do this, keep a list of separation vectors and add to it every time a collision is detected. To calculate the separation vector from each collision, take the normal of the line that the pod collided with and multiply it by the penetration (the difference between pod's radius and the distance to the line's point along line's normal (that would be the dot product you took earlier). Don't do any separation just yet - only store those penetration vectors. Once you finish testing against all close-by tiles, loop through the list of penetration vectors and choose the smallest one, or use some kind of biasing algorithm (based on pod's velocity) to choose one. The biasing algorithm way would work best if your pod sometimes has velocity with a magnitude that exceeds the size of a tile in your world.
  8. ValMan

    All work and no play

    So, looks like you are opting out of alpha blending for sprites? This may not be so noticeable on the foliage, but less chaotic sprites will suffer from highly visible pixelated edges. I am mentioning this after I saw the black border on your player sprite, which likely resulted from selecting a black matte for conversion to a palletized format. In my engine, I am drawing all tiles with alpha blending turned off (optionally) because it's stupid to waste GPU power to fill the whole screen and perform a blending operation for each opaque pixel. However, having to switch a render state such as alpha blending on and off will break the rendering batch (at the very least), so for cases where slow down caused by switching state is greater than slowdown caused by blending, alpha blending can be left on (for instance, if number of tiles on screen is below threshold). Then I just draw all sprites with alpha blending enabled - seeing as how I am designing my engine mostly to handle 32bit sprites with lots of transparent areas, any sorting and state switching here would just slow it down without a good excuse. Well, and last but not least - in my experience, poor performance drawing many objects on screen at once usually comes from either too much state switching (like switching a texture) or too much overdraw. Submitting lots of verts using the same texture and not drawing any pixel more than required usually results in acceptable performance (assuming other things like vertex cache optimization have also been considered). I am mentioning this as a possible argument in favor of using real 3D models instead of pre-rendered sprites.
  9. ValMan

    Walking cycle

    Walking animation is done in two stages. Stage one is roughing out the animation with main keyframes (called pose-to-pose), stage two is tweaking in-between keyframes. It looks like you executed stage one pretty well - the 4 main walking frames look good and in their place. Frame 1 should be both feet spread and on the ground, frame 2 is standing on one foot and second foot bent at an angle with sole slightly behind the other foot, frame 3 is once again both feet stepped down but with the other foot forward, frame 4 is like frame 2 but with feet switched, then loop to 1. Once the keyframes for all bones are set on those 4 frames, you did a simple interpolation (by spacing out the keyframes) and let Max do the curves for you. Now you need to tweak in-betweens to raise his feet higher in transition from both feet on the ground to one foot on the ground and back, and to make his center-of-weight change its pitch and roll angles in response to step-downs. When the character steps down on a foot, the pelvis should change its roll angle to tilt the character (very slightly) in the direction of that foot. It looks like what you actually did is change the yaw angle on the chest in response to moving the arms - I suggest toning down the yaw angle animation and animating pelvis roll angle more. Also when the character steps down, he should bend spine and neck very slightly down/forward, and then raise them back up when shifting weight over the next foot. Pelvis should also sink slightly during step-down, but it looks like you already have that going. Perhaps tweak it a little to make it stronger. Well, and then there is foot-kick. You may notice when you walk that just before you step on a foot, it is rotated with toes pointing slightly down because that's the position the foot assumed after being lifted off the ground. So just before you step on that foot, you quickly rotate it to a horizontal position (maybe even slightly upwards). This whole deal ends up looking like a kick, so it's called a foot-kick. The last thing to mention is the elbow-lock and knee-lock. Your knee locks when you step off one foot and shift your weight onto another foot. Same with the elbow, when you move your arms in response to walking - when the upper arm is rotated backwards, the lower arm is also rotated backwards and the elbow gets locked when the two arm bones are at 180 degree to each other. Then the arm starts moving forward again - upper arm rotates forward as does the lower arm and the elbow unlocks. It looks like you do have knee-locks but they are a little weak (you don't clearly see when the knee locks - looks too smooth). It also looks like you don't have the elbow-locks yet: there is no lower arm movement (or not much), only the upper arm rotates.
  10. ValMan

    Ready to rock

    I was one of those people who downloaded your game to test it out (I've been reading your journal for a while so I was pleasantly surprised to hear this baby is out). The first time I downloaded it, it wouldn't run because the d3dx dll was missing. I didn't feel like downloading the DLL from Microsoft because it usually comes with a huge installer and it's impossible to find, and I didn't want to go to dllfiles because they are known to have bad versions. So I deleted the whole thing. Now I decided to re-download it, and got the DLL. It works. Well done graphics and effects as well as music. I couldn't figure out how to get out of Credits screen so I closed down the program in Task Manager, but it never crashed by itself.
  11. ValMan

    dammit

    Are you planning to continue work on Invasion: Fall of Man?
  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!