ic0de

Members
  • Content count

    318
  • Joined

  • Last visited

Community Reputation

1013 Excellent

About ic0de

  • Rank
    Member

Personal Information

  • Interests
    Art
    Audio
    Design
    Programming
  1. In my 2D Graphic adventure engine I use a really simple file format for storing animation data for sprites. Sequencing animations was previously done in my room editor tool but it was really clunky and error prone and didn't make much sense to have in that tool. I decided that rather than write a new tool that somebody might already have created something I could use that could either be scripted to output my format (I've done this for 3d with blender) or that can output a simple file I could convert to my own with all the information I need. The format I use is a binary file containing the following: the number of animations in the file (16 bit integer) for each animation:     the number of frames in each animation (16 bit integer)     for each frame:         the filename of a bitmap (16 bit integer length followed by n characters)         the origin point, this is important for lining up frames of different sizes (2x 16 bit integers)         the length of time to display measured in jiffies (1/60th of a second) (8 bit integer)   Does anyone one know a GUI tool that I could use so I don't have to edit these in hex anymore? I'm looking for something for sequencing  and playback only as I already have tools for editing pixels.
  2. Hey everyone, for almost a year now I've have been developing a brand new adventure game for the "obsolete" MS-DOS platform and I've decided to share my experiences and the things I've learned in the process. The game is called Chuck Jones: Space Cop of the Future and if you're interested in learning about retro programming, extreme optimization, assembly code or adventure games you might wanna check it out. https://chuckjonesdevblog.wordpress.com/
  3. So here's what I managed to do, I get the sign of the determinant for each edge and make sure all the edges have the same sign if they do then the point is in the quad. Seems to work ok so far. bool pointInBox(quad q, point p) { point* v = q.vertices; bool d0 = ((int32_t)(v[1].x - v[0].x) * (int32_t)(p.y - v[0].y)) > ((int32_t)(v[1].y - v[0].y) * (int32_t)(p.x - v[0].x)); bool d1 = ((int32_t)(v[2].x - v[1].x) * (int32_t)(p.y - v[1].y)) > ((int32_t)(v[2].y - v[1].y) * (int32_t)(p.x - v[1].x)); bool d2 = ((int32_t)(v[3].x - v[2].x) * (int32_t)(p.y - v[2].y)) > ((int32_t)(v[3].y - v[2].y) * (int32_t)(p.x - v[2].x)); bool d3 = ((int32_t)(v[0].x - v[3].x) * (int32_t)(p.y - v[3].y)) > ((int32_t)(v[0].y - v[3].y) * (int32_t)(p.x - v[3].x)); return d0 == d1 && d1 == d2 && d2 == d3; }
  4. So I'm writing an adventure game for DOS, don't ask why, its because I like to torture myself. I'm working on pathfinding and I need a way to figure out if a point is in a convex quad, but here's the catch: processors prior to the 486dx which my game targets (specifically a 286 or 386sx) had no builtin floating point support, this makes anything using floating point extremely slow, unfortunately most of the algorithms I've seen use floating point. Any know how I might do this?   EDIT: I should mention that this is all using 2D co-ordinates.
  5. Do you put the heightmap in the same data structure as the rest of the world scenery (buildings etc.) though?
  6. In my OpenGL based renderer I organize all the scenery in my world into a BVH tree which allows me to efficiently cull objects outside of the frustum. The leaves of the BVH tree are a data structure that I called a chunk, a chunk is simply a bunch of vertex data that is rendered using one draw call. The other day I added a loader for heightmaps and that was fairly straightforward, it generated a bunch of triangle tiles and offset the vertices by the heightmap value then the resulting data was stored in one chunk. Obviously drawing all the vertices in the heightmap in one go results in terrible performance. So I looked into geomipmapping which seems to fit my needs, the problem is the fact that geomipmapping requires I split up my chunks obviously but I am unsure how I should organize this from a Software architecture point of view. Should I totally separate terrain from the rest of the world and keep it in a separate tree? or should I just throw heightmap chunks into the regular BVH tree probably deriving a class heightmapChunk which adds LoD code? should I nest a quad tree inside my BVH as a node, in that case the whole quadtree is analogous to one regular chunk? 
  7. This doesn't look like a perspective problem, it looks like you're culling the wrong faces. Have you set glCullFace(GL_BACK)? If not that may fix your problem. You may also need to set glFrontFace(GL_CCW).
  8. OK so after filtering my shadow map with a separable log space Gaussian blur and capping the shadow frustum far plane at the point where light fades to zero, I have started to see some improvement. I have determined that the problem originates from the fact that I appear to be getting less depth buffer precision for objects that are far away from the light. Shortening the distance between the near and far planes of the light frustum seems to combat this. I'm not really sure if I can shorten them any more, especially the near plane as I could miss objects between the light and the shadow receiver. As of now I'm not using any polygon offset, is this technique still relevant for ESM?   Anyways this is where I'm at now (although the lighting conditions are slightly different):     [sharedmedia=core:attachments:24672]   Its better than before but occluders far from the light experience a far worse manifestation of this artifact.
  9. So after procrastinating for a long time I finally decided to add shadows to my game. I got regular shadow maps up and running pretty quickly but that had was not enough for me. After a failed attempt at variance shadow mapping I settled on exponential shadow mapping (ESM). It was fairly easy to get working but my implementation seems to have artifacts which were expected but for more severely the other implementations I have seen. The problem is where the shadow fades to nothing near the occluder, I expected this but not as severely as my results. So I was wondering if anyone knew of any ways to improve this property of ESM?   My worlds linear depth is rendered to a 32 bit floating point fbo from the light's point of view and then sampled using textureProj in glsl.   the area where the artifact is the worst is circled in the screenshot.   Here are screenshots and my code:   shadow.fsh in vec4 v_pos; void main() { float linearDepth = length(v_pos) / nearSubFar; gl_FragColor.r = linearDepth; } shadow.vsh void main(void) { v_pos = modelViewProjectionMatrix * localTransform * vec4(position, 1.0); gl_Position = v_pos; } lighting.fsh float getOcclusion(vec4 coord, float d) { float occluder = textureProj(shadow_texture, coord).r; return clamp(exp(620.0 * (occluder - d / nearSubFar)), 0.0, 1.0); }
  10. Thanks for the amazingly quick fix. I know that new isn't guaranteed to be aligned but I overloaded the operator to ensure this as I was having trouble in other parts of application. EDIT: tested your revision with my code and it works like magic, you really are a wizard.
  11. Well it's real ugly but here it is, I'm using extensive macros and lambdas so I can declare wrapper functions inline and I apologize for the messiness. The crash still happens without the lambda approach.   //these do lambda magic to allow the definition of wrappers inline #define WRAPFUNC(ret, args, body) asFUNCTION(static_cast<ret(*)args>([]args -> ret body)) #define WRAPEXPR(ret, args, expr) WRAPFUNC(ret, args, {return expr;}) void registerVec() { r = engine->RegisterObjectType("vec", 0, asOBJ_REF | asOBJ_SCOPED); assert(r >= 0); r = engine->RegisterObjectBehaviour("vec", asBEHAVE_FACTORY, "vec @f()", WRAPEXPR(vec*, (), new vec()), asCALL_CDECL); assert(r >= 0); r = engine->RegisterObjectBehaviour("vec", asBEHAVE_FACTORY, "vec @f(const vec &in v)", WRAPEXPR(vec*, (const vec &o), new vec(o)), asCALL_CDECL); assert(r >= 0); r = engine->RegisterObjectBehaviour("vec", asBEHAVE_FACTORY, "vec @f(float nx, float nx, float nz)", WRAPEXPR(vec*, (float x, float y, float z), new vec(x, y, z)), asCALL_CDECL); assert(r >= 0); r = engine->RegisterObjectBehaviour("vec", asBEHAVE_FACTORY, "vec @f(float n)", WRAPEXPR(vec*, (float n), new vec(n)), asCALL_CDECL); assert(r >= 0); r = engine->RegisterObjectBehaviour("vec", asBEHAVE_RELEASE, "void f()", WRAPFUNC(void, (vec* t), {if(t) { delete t; }}), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "vec &opAssign(const vec &in v)", asMETHODPR(vec, operator =, (const vec&), vec&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec &opMulAssign(const float)", asMETHODPR(vec, operator *=, (const float), vec&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec &opDivAssign(const float)", asMETHODPR(vec, operator /=, (const float), vec&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec @opDiv(const float) const", WRAPEXPR(vec*, (float o, vec* v), new vec(*v / o)), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "vec @opMul(const float) const", WRAPEXPR(vec*, (float o, vec* v), new vec(*v * o)), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "bool opEquals(const vec &in v) const", asMETHODPR(vec, operator==, (const vec &) const, bool), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec &opAddAssign(const vec &in v)", asMETHODPR(vec, operator +=, (const vec&), vec&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec &opSubAssign(const vec &in v)", asMETHODPR(vec, operator -=, (const vec&), vec&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec &opMulAssign(const vec &in v)", asMETHODPR(vec, operator *=, (const vec&), vec&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec &opDivAssign(const vec &in v)", asMETHODPR(vec, operator /=, (const vec&), vec&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec @opDiv(const vec &in) const", WRAPEXPR(vec*, (const vec &vo, vec* v), new vec(*v / vo)), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "vec @opMul(const vec &in) const", WRAPEXPR(vec*, (const vec &vo, vec* v), new vec(*v * vo)), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "vec @opSub(const vec &in) const", WRAPEXPR(vec*, (const vec &vo, vec* v), new vec(*v - vo)), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "vec @opAdd(const vec &in) const", WRAPEXPR(vec*, (const vec &vo, vec* v), new vec(*v + vo)), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "void normalize()", asMETHOD(vec, normalize), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("vec", "vec @normalized()", WRAPEXPR(vec*, (vec* v), new vec(v->normalized())), asCALL_CDECL_OBJLAST); assert(r >= 0); r = engine->RegisterObjectMethod("vec", "float magnitude()", asMETHOD(vec, magnitude), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectProperty("vec", "float x", asOFFSET(vec, x)); assert( r >= 0 ); r = engine->RegisterObjectProperty("vec", "float y", asOFFSET(vec, y)); assert( r >= 0 ); r = engine->RegisterObjectProperty("vec", "float z", asOFFSET(vec, z)); assert( r >= 0 ); }
  12. Hi,   I've was having a little trouble with aligned data types so I tried using scoped reference types to represent these in angelscript. While they seem to work pretty well for managing aligned data I've noticed some funny behavior when they are declared in the global scope. Specifically When I try to access them from the script it causes my application to crash, not the script but my application. So here is an example of this behavior:   vec pos = vec(-74.25679016113281f, 0.0f, 27.4027156829834f); //this is a scoped reference type void loop() { if(playerInSphere(pos, 25)) //it crashes where I access pos { //do stuff } } My guess is that the engine is somehow erroneously determining that 'pos' is out of scope and deleting it so that it ends up passing my application a null pointer which it tries to access and then crashes. Of course I could be wrong, I may have registered the type incorrectly or misunderstood the use of scoped reference types. Does anyone know what might be causing this or is it normal?
  13. So I often have a dilemma when coding where I have to make things run faster but the project isn't finished. As programmers we are often told to code first and then optimize later, this is related to the famous saying "premature optimization is the root of all evil". However adhering by this philosophy is not necessarily always practical, this would require a costly review of a huge codebase, a much more economical approach would be to optimize "as you go" or basically making things as efficient as possible before moving on. I always have trouble figuring out which method is the most practical, when I'm faced with the fact that my project while not finished it simply does not meet performance requirements for the given hardware. What approach should I take to speeding it up?
  14.   Bullet physics is really quick and easy to get up and running quickly but the documentation is a little sparse after that. 
  15. In my game I need enemies to turn towards the object they are chasing. So I tried to make a function to turn their rigid body towards the point their going to by applying a rotational impulse proportional to the dot product between the way they're facing and the direction they need to do to. Here is my code:   void lookAtPoint(btVector3 point, btRigidBody* body) { btVector3 pos = body->getCenterOfMassPosition(); btVector3 dir = (point - pos); dir.setY(0.0); //restrict to two dimentsions dir.normalize(); btTransform t; body->getMotionState()->getWorldTransform(t); btVector3 forwards(t.getBasis()[2]); forwards.normalize(); body->applyTorqueImpulse(btVector3(0.0f, forwards.dot(dir), 0.0f)); } The problem is that the object seems to turn in the direction opposite to where it's supposed to even if I reverse the direction of the impulse. For example if the object is to their right they will turn left. Is their any problem with my approach or am I making a simple stupid mistake with my code?