Advertisement Jump to content
  • Advertisement

Arcibald Wearlot

Member
  • Content Count

    238
  • Joined

  • Last visited

Community Reputation

190 Neutral

About Arcibald Wearlot

  • Rank
    Member
  1. Arcibald Wearlot

    Alpha Testing in Direct3D10

    The clip() function was exactly what I was looking for, thank you!
  2. Hello, I'm writing a 3D simulation with a large number of particles. I want to apply a texture with an alpha channel to the particles, to make them appear spherical. I wanted to use simple alpha testing in order to draw only the "solid" pixels of the texture, but according to the DirectX documentation: "Direct3D 10 does not implement an alpha test (or alpha testing state). This can be controlled using a pixel shader or with depth/stencil functionality." I tried implementing alpha testing using with alpha blending, but it does not work correctly unless I sort the particles by distance. Here's why: if there are two particles, one closer than the other, and the closer one is drawn first, then the other particle is not fully drawn because the depth buffer has been updated on the ENTIRE area of the first particle (even the transparent part). Disabling depth writing also looks wrong unless I use additive blending, but that's not the effect I'm looking for, as I want to draw spherical-looking distinct particles. Sorting the particles by distance is not an option because there are too many of them. So, how can I implement alpha testing in D3D10? Thanks for your help!
  3. Hello, I'd like some advice from you guys. I'm new to web development: I've done HTML and SQL databases, and that's pretty much it. I want to educate myself on the topic. My objective is being able to create a good-looking website for a small company, possibly with database interaction and user-insertable content. Which technologies should I learn first? php? ASP.Net? And what about CMS systems such as Wordpress? Are they suitable for creating professional-looking websites? Also, could you suggest me some good books to buy? Please note that I'm an experienced C/C++ programmer, so I'm not looking for total newbies books. I also know Java and C#. Thanks for your help!
  4. Arcibald Wearlot

    Win32 HandlerRoutine deadlock

    I downloaded ProcessExplorer and discovered some interesting things. The main process is not blocked as I was thinking. It actually runs the console handler, sets the event, calls ExitProcess() and quits. The child processes receive the event and quit. If I run my executable file directly, everything works. What really happens is that I was running the program from the Visual Studio IDE, clicking on "Start Without Debugging". This actually starts cmd.exe with the "/c" parameter, followed by the name of the executable and by the "& pause" string. From ProcessExplorer I can see that all of my processes terminate, while the cmd.exe process remains blocked. The same happens if I manually start the executable from the command line, with just the "/c filename" parameter. This could be because cmd.exe also register its own console handler, and it gets called along with my console handler (cmd.exe and my process share the same console so both handlers get called when I close the window). For some reason, cmd.exe could get blocked in its own console handler. The fact that this happens only certain times could depend from who catches the CTRL_CLOSE_EVENT first (I'm totally guessing here). For example, my process catches it first, sets the event and terminates, then cmd.exe catches the event, sees that my process is terminated, and quits without hanging. The other way around: cmd.exe catches the event first, sees that my process is still running, and waits for my process to terminate (this is where it gets blocked for some reason). My process eventually catches the event and quits, but cmd.exe remains blocked. I still don't know why cmd.exe hangs. I'd really like to take a look at the source code of its console handler routine. If any of you have any idea, please share it with me.
  5. Arcibald Wearlot

    Win32 HandlerRoutine deadlock

    Quote:Original post by LessBread Have you tried calling SetConsoleCtrlHandler before the CreateProcess loop? Yes, the problem is there even if I set the console handler before doing anything else. Quote: Have you considered using threads instead of processes? 50 new processes invites a lot of system overhead. If I use threads, everything is fine. The problem only happens with processes. I use processes because I am doing this for an university project and according to the specs I must support both multithreaded and multiprocess mode. The project is actually a multiplatform (Unix/Windows) HTTP server. The Windows version is 95% done :) Quote: For what it's worth, Control-C is a much older method of exiting a console program. It goes back to the days of DOS. The close event is a windows based signal. What happens if you intercept both? In the actual project I intercept both: with Control-C there is no problem, but if I close the console window there is a chance to lock the process. This really puzzles me. The situation is very simple: some processes wait for an event to happen and another process sets this event. This works in almost any case, but if I set the event while handling a CTRL_CLOSE_EVENT, sometimes I lock up the process. I also noticed that while the process is hanging, the task manager is also not responding. Is this related to the fact that my process is locked inside a system call? I'm no kernel expert. Quote: In the call to OpenEvent, why is EVENT_MODIFY_STATE specified? The child processes don't call the functions that require that access right. Yes, they don't need it. I removed the flag but the bug is still there.
  6. I have a main process that spawns a certain number of child processes. The main process is a Win32 console application and it uses SetConsoleCtrlHandler() to intercept console events such as CTRL_CLOSE_EVENT. The child processes are not associated to a console. That's because I don't want them to catch console events: only the main process catches them and eventually terminates the children. I want to intercept CTRL_CLOSE_EVENT in the main process, terminate the children processes, and exit. The main process creates a named events, creates the child processes, sets the console handler, and goes in an infinite loop. On CTRL_CLOSE_EVENT, the console handler calls SetEvent() with the named event and then calls ExitProcess(). Every child process calls WaitForSingleObject() and waits for the named event. Here is the problem: sometimes, when I close the console window, the main process locks up on SetEvent(). I have no idea of why this happens. The process will not respond and will be automatically terminated by the system after 5 seconds, as MSDN describes. This is more likely to happen if I use a bigger number of child processes. This problem is not related to race conditions at initialization time (for example, I close the console window when the children still have not started) because I've seen this happen even if I wait some seconds so that every child is blocked on WaitForSingleObject(). Another strange thing: if I use the exact same code to handle an event that is not CTRL_CLOSE_EVENT (for example, CTRL_C_EVENT), this never happens. Here is my code: #include <windows.h> #include <cstdio> #define EVENT_NAME "event_terminate_children" #define NUMWORKERS 50 static HANDLE terminate_workers_event; static BOOL WINAPI console_handler( DWORD ctrl_type ) { if( ctrl_type == CTRL_CLOSE_EVENT ) { SetEvent( terminate_workers_event ); ExitProcess( 0 ); } return FALSE; } void child_main() { terminate_workers_event = OpenEvent( SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, EVENT_NAME ); WaitForSingleObject( terminate_workers_event, INFINITE ); return; } void parent_main() { terminate_workers_event = CreateEvent( NULL, TRUE, FALSE, EVENT_NAME ); char process_command_line[ 300 ]; int i; for( i = 0; i < NUMWORKERS; ++i ) { STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; si.cb = sizeof( si ); sprintf( process_command_line, "%s c", "Debug/Test.exe" ); CreateProcess( "../Debug/Test.exe", process_command_line, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi ); } fprintf( stderr, "processes created\n" ); SetConsoleCtrlHandler( console_handler, TRUE ); while( 1 ) ; } int main( int argc, char** argv ) { if( argc == 2 ) { child_main(); } else { parent_main(); } return 0; }
  7. Arcibald Wearlot

    Visual Studio 2005

    In your code, RegisterClassEx() returns 0 because you do not set the cbClsExtra member of the WNDCLASSEX structure, and thus it contains garbage. I suggest using a declaration like this to automatically zero out the entire structure, and then initialize only the fields you need: WNDCLASSEX wcx = {0};
  8. Arcibald Wearlot

    Money value of a program

    I've been told by a friend that a company is looking for a programmer to write a simple application. The program should basically load some images from a database and display them, and should be protected by a password. Now the company wants to know how much I want to be payed for it. I never wrote programs for money so I have no idea of how much I should ask. The program should have a graphical interface and some sort of protection with passwords and encrypted data files, but it's nothing complicated, I think I can write it it in a few hours of work. How much should I ask?
  9. Arcibald Wearlot

    Quake3-style sphere-brush collision issue

    Quote:Original post by tthibault Subtract the plane's distance to accurately compute the distance to the plane. The plane equation is ( ax + by + cz + dw = 0 ), and D3DXPlaneDotCoord() computes ( a*x + b*y + c*z + d*1 ), so I'm already doing this. This is an image that tries to show the problem. By just adding the sphere radius to the plane distances, I'm actually testing a ray against the red and green brushes, and I get struck in the top left red corner.. Anyway I'm wondering why I don't get struck in the top green corner when I move backwards from the top of the cube.. clicky [Edited by - Arcibald Wearlot on September 29, 2006 12:02:36 PM]
  10. In my engine I can load quake 3 .bsp files, and I implemented sphere-brush collision detection with the help of this tutorial: http://www.devmaster.net/articles/quake3collision/ I am discarding all the BSP stuff and just storing the brushes in a big array. My system seemed to work with all of the quake 3 levels I tested. Now I downloaded GTKRadiant, created some simple geometry, and discovered a big problem I have with my system. Say that I have two brushes: a cube, and an adjacent prism, so I can reach the top of the cube walking on the prism. This is a side view of it: ______ /| | / | | /__|_____| I discovered that if I try to get to the cube walking from left to right, I cannot reach the top of the cube: i remain strucked at the end of the prism, just a bit before reaching the cube. This is what goes on: The player goes right, I detect the collision with the prism and slide the player velocity along the plane, so it is going up-right now, then I check all the brushes again and this time I detect a collision with the left plane of the cube, that stops the player. In theory I should not collide with the cube when I modify my velocity sliding on the prism, but I do, because basically when I check for a collision with a brush, I'm actually testing a ray against an "inflated" brush, extending all the planes by the sphere radius (This is what the tutorial does, anyway). But doing this, I'm detecting non-existant collisions with, for example, a cube edge! If you aren't following me, think of a cube: if I inflate it by 1 unit, this means that I move the up plane by 1 and the left plane by 1, but the top-left corner was actually moved by ~1.4! The proper way, I think, would be to use a cylinder for brush edges and a sphere for brush corners, but this is not possible due to the structure of brush data, wich is just an array of planes. I wonder if and how Quake3 solves this problem, I'm probably going to take a look at the source code. This is my source: bool CBrush::TraceSphere( const D3DXVECTOR3& Start, const D3DXVECTOR3& End, float SphereRadius, float* pDistance, D3DXPLANE* pPlane ) { float EnterDistance = -1.0f; // Farthest distance the line enters a plane [-1, 1] float LeaveDistance = 1.0f; // Closest distance the line exits a plane [-1, 1] for( unsigned int i = 0; i < m_Planes.size(); ++i ) { float StartDistance = D3DXPlaneDotCoord( &m_Planes[ i ], &Start ) - SphereRadius; float EndDistance = D3DXPlaneDotCoord( &m_Planes[ i ], &End ) - SphereRadius; // If both Start and End are outside the plane, the line is not intersecting if( ( StartDistance > 0.0f ) && ( EndDistance > 0.0f ) ) { return false; } // If both Start and End are inside the plane, ignore the plane if( ( StartDistance <= 0.0f ) && ( EndDistance <= 0.0f ) ) { continue; } // If we get here the line is intersecting the plane // Check if we are entering the plane if( StartDistance > EndDistance ) { // Compute the distance until we enter the plane [-1,1] float Dist = StartDistance / ( StartDistance - EndDistance ); if( Dist > EnterDistance ) { EnterDistance = Dist; if( pPlane ) { ( *pPlane ) = m_Planes[ i ]; } } } else { // Compute the distance until we leave the plane [-1,1] float Dist = StartDistance / ( StartDistance - EndDistance ); if( Dist < LeaveDistance ) { LeaveDistance = Dist; } } } if( LeaveDistance < EnterDistance ) { // We leave the brush before entering it. No collision. return false; } else { // Output the distance until the line touches the brush if( pDistance ) { ( *pDistance ) = EnterDistance; } return true; } }
  11. Arcibald Wearlot

    Stack corruption problem, VC++ .NET 2002

    Maybe I solved it, you are right NotAYakk, the problem was in these lines: const D3DXVECTOR3& EntPos = pEnt->GetPosition(); FinalVelocity *= D3DXVec3Length( &pEnt->GetPhysics()->GetVelocity() ); GetPosition() and GetVelocity() both return a D3DXVECTOR3. In the first line I was binding a reference to a temporary variable, and maybe this is unsafe. I was doing a similar thing here in the second line, I was getting the address of a temporary variable. I modified the lines to this: D3DXVECTOR3 EntPos = pEnt->GetPosition(); D3DXVECTOR3 Vel = pEnt->GetPhysics()->GetVelocity(); FinalVelocity *= D3DXVec3Length( &Vel ); Anyway changing the second line had no effect, it looks like the problem was only caused by the first line. I realize that it doesn't seem a safe thing to mess up with the addresses of temporary variables, but shouldn't a temporary variable be usable within the scope it is created in? Edit: Regarding this line math::SphereSphereCollide( pEnt->GetPhysics()->GetSphere(), pEnt->GetPhysics()->GetGravityVelocity() * DeltaTime, pSecond->GetPhysics()->GetSphere(), pSecond->GetPhysics()->GetGravityVelocity() * DeltaTime ) ) // Prototype bool math::SphereSphereCollide( const CSphere& First, const D3DXVECTOR3& FirstVel, const CSphere& Second, const D3DXVECTOR3& SecondVel ) GetSphere() returns a const CSphere&, GetGravityVelocity() returns a D3DXVECTOR3. Is this safe?
  12. Since I rewrote this function adding some functionality, I keep getting this debug error: "Run-time Check Failure #2 - Stack around the variable '$1' was corrupted." The strange thing is that there isn't a precise line that causes the error, rather it seems as if I run out of stack space because I'm using too many auto variables or something like that. I can say this because if I comment out one of the variables, or even make it static, I don't get the error. For example I can eliminate the FinalVelocity vector, and the problem disappears. But then if I create anywhere in the function (even outside loops) two or more float variables, the problem reappears, while it goes fine with just one float in this case. So it really seems that I'm reaching some stack limit, but look at the function, I don't think I'm doing nothing that should cause this. There are only two nested loops, and I'm getting this problem with only two entities in the game world. The function gets called once per frame. This is really driving me crazy. Do you have any idea of what I'm doing wrong? void CEntityManager::UpdateEntities( float DeltaTime, IWorldModel* pWorld, CTerrain* pTerrain ) { if( DeltaTime == 0.0f ) { return; } // Check for "noclip" CVar bool CheckCollisions = true; if( g_pCVarMgr->CVarExists( "noclip" ) && ( g_pCVarMgr->GetBool( "noclip" ) == true ) ) { CheckCollisions = false; } if( CheckCollisions ) { //--------------------------------------------------------------------- // // Pass 1: Gravity // //--------------------------------------------------------------------- for( Map_HandleToEntity::iterator itor = m_Entities.begin(); itor != m_Entities.end(); ++itor ) { CEntity* pEnt = itor->second; const D3DXVECTOR3& EntPos = pEnt->GetPosition(); // Check if will collide with the world if( pWorld && pWorld->CheckGravityCollision( pEnt->GetPhysics(), DeltaTime ) ) { pEnt->ResetGravity(); continue; } // Check if we will collide with another entity bool Stopped = false; for( Map_HandleToEntity::iterator j = itor; j != m_Entities.end(); ++j ) { if( itor == j ) { continue; } CEntity* pSecond = j->second; if( pSecond->IsDead() ) { continue; } if( math::SphereSphereCollide( pEnt->GetPhysics()->GetSphere(), pEnt->GetPhysics()->GetGravityVelocity() * DeltaTime, pSecond->GetPhysics()->GetSphere(), pSecond->GetPhysics()->GetGravityVelocity() * DeltaTime ) ) { pEnt->ResetGravity(); pSecond->ResetGravity(); Stopped = true; break; } } if( Stopped ) { continue; } // Go down pEnt->UpdateGravity( DeltaTime ); // Align with the terrain if( pTerrain ) { float Height = pTerrain->GetHeight( EntPos.x, EntPos.z ) + pEnt->GetPhysics()->GetSphere().GetRadius(); if( EntPos.y <= Height ) { pEnt->SetPosition( D3DXVECTOR3( EntPos.x, Height, EntPos.z ) ); pEnt->ResetGravity(); } } } //--------------------------------------------------------------------- // // Pass 2: Velocity // //--------------------------------------------------------------------- // Check for collisions with the world for( Map_HandleToEntity::iterator itor = m_Entities.begin(); itor != m_Entities.end(); ++itor ) { CEntity* pEnt = itor->second; if( pWorld ) { pWorld->ResolveCollisions( pEnt->GetPhysics(), DeltaTime, WORLD_SLIDE ); } // Set the new velocity modified by the terrain D3DXVECTOR3 FinalPos = pEnt->GetPosition() + ( pEnt->GetPhysics()->GetVelocity() * DeltaTime ); float TerrainHeight = pTerrain->GetHeight( FinalPos.x, FinalPos.z ) + pEnt->GetPhysics()->GetSphere().GetRadius(); if( FinalPos.y <= TerrainHeight ) { FinalPos.y = TerrainHeight; } D3DXVECTOR3 FinalVelocity = ( FinalPos - pEnt->GetPosition() ); D3DXVec3Normalize( &FinalVelocity, &FinalVelocity ); FinalVelocity *= D3DXVec3Length( &pEnt->GetPhysics()->GetVelocity() ); pEnt->GetPhysics()->SetVelocity( FinalVelocity ); } // Check for collisions between entities for( Map_HandleToEntity::iterator itor = m_Entities.begin(); itor != m_Entities.end(); ++itor ) { CEntity* pFirst = itor->second; if( pFirst->IsDead() ) { continue; } for( Map_HandleToEntity::iterator j = itor; j != m_Entities.end(); ++j ) { if( itor == j ) { continue; } CEntity* pSecond = j->second; if( pSecond->IsDead() ) { continue; } pFirst->ResolveCollision( pSecond, DeltaTime ); } } } // Finally update each entity for( Map_HandleToEntity::iterator i = m_Entities.begin(); i != m_Entities.end(); ++i ) { CEntity* e = i->second; e->Update( DeltaTime ); } }
  13. Arcibald Wearlot

    Quake 3 dynamic collision

    I implemented collision detection with quake3 levels a few weeks ago. This tutorial was very useful to me: http://www.devmaster.net/articles/quake3collision/ I try to show you the basic idea. For dynamic collision detection you have to use the velocity vector of your entity. If you consider your entity a point, you just have to check if the velocity vector intersects the brush. You can do this by looping for all the brush planes and computing the farthest point in wich the ray enters a plane, and the closest point in wich the ray exits a plane. If the first point is (along the ray) before the second, the ray will intersect the brush. You can then use the first plane to slide the entity. This process can easily be extended to spheres, just adding the sphere radius to some distance calculations (I did this in my system). This can also be extended to bounding boxes. It is all explained in the article.
  14. Arcibald Wearlot

    Single-instance classes

    Quote:Original post by simon10k If you dont need multiple instances, why use a class? That's basically what I meant to say. I won't use a class, but so many persons do it, and I want to understand why. Quote:Original post by Antheus Since globals are bad practice, they converted their globals into OOP. Of course, the way they did it is pointless, but technically, they are now OO. But this does not solve anything. I don't see any reason to do it, maybe people is a little too obsessed with OOP. Quote: Usually they would be defined as members of sphere class. I don't think this type of function should really belong to a class, for example, should the SphereBoxCollide() function go into CSphere or CBox? What's the problem in making them standalone routines, in a Collision.cpp file? Quote:Original post by EasilyConfused Does anyone else reckon that if namespaces had private sections like classes, it might help discourage needless use of single-instance classes or am I talking rubbish as usual? Anyway, no one should be able to access the namespace data you define in your .cpp file but don't declare in the header, so it's kind of private.
  15. Say that I need only one instance of a certain class: for example, I cound have a CLogFile class, and I only want one logfile to be in the application plus I want it to be globally accessible. I don't need class inheritance. There are several solutions to this problem.. I could create a global instance of the class, and I could solve the problem of undefined order of creation/destruction of globals by using my own Init() and Term() functions: //--------------------------------------------------------------- // LogFile.h //--------------------------------------------------------------- #include <cstdio> class CLogFile { public: CLogFile() { } ~CLogFile() { } void Init(); void Term(); void Print( char* ); private: FILE* m_File; }; extern CLogFile g_Log; //--------------------------------------------------------------- // LogFile.cpp //--------------------------------------------------------------- #include "LogFile.h" CLogFile g_Log; void CLogFile::Init() { // init } void CLogFile::Term() { // terminate } void CLogFile::Print( char* ) { // do stuff } //--------------------------------------------------------------- // Main.cpp: //--------------------------------------------------------------- g_Log.Init(); g_Log.Print( "Hello, world!" ); g_Log.Term(); Another possibility is to use some variant of the singleton pattern. With it we can ensure there is only one instance of the class, it is globally accessible and it is created when requested, and we could add a static function to destroy the instance to be called at the end of the program.. //--------------------------------------------------------------- // LogFile.h //--------------------------------------------------------------- #include <cstdio> class CLogFile { CLogFile(); public: ~CLogFile(); void Print( char* ); static CLogFile* GetInstance(); static void DestroyInstance(); private: static CLogFile* m_Instance; FILE* m_File; }; //--------------------------------------------------------------- // LogFile.cpp //--------------------------------------------------------------- CLogFile* CLogFile::m_Instance = NULL; CLogFile* CLogFile::GetInstance() { if( !m_Instance ) { m_Instance = new CLogFile(); } return m_Instance; } void CLogFile::DestroyInstance() { delete m_Instance; m_Instance = NULL; } void CLogFile::Print( char* ) { // do stuff } //--------------------------------------------------------------- // Main.cpp: //--------------------------------------------------------------- CLogFile::GetInstance()->Print( "Hello, world!" ); CLogFile::DestroyInstance(); My point is that there is a much simpler solution: the LogFile doesn't need to be a class. Its functions could just go in a namespace, including Init() and Term(). The code, in my opinion, is more clean, and encapsulation is better because all the private members of CLogFile are hidden in LogFile.cpp. There are less #include files in the header, resulting in faster compile times and less dependencies. //--------------------------------------------------------------- // LogFile.h //--------------------------------------------------------------- namespace LogFile { void Init(); voit Term(); void Print( char* ); }; //--------------------------------------------------------------- // LogFile.cpp //--------------------------------------------------------------- #include "LogFile.h" #include <stdio.h> namespace LogFile { FILE* m_File; void Init() { // init } void Term() { // terminate } void Print( char* ) { // do stuff } } //--------------------------------------------------------------- // Main.cpp: //--------------------------------------------------------------- LogFile::Init(); LogFile::Print( "hello, world!" ); LogFile::Term(); The problem is that, seeing other people's code, this solution is seldom used, and people tend to use classes just about anywhere. I was pretty shocked when I saw code like this in some open source engine: class Collision { static void PointSphere( Vec3& v, Sphere& s ); static void SphereSphere( Sphere& s1, Sphere& s2 ); } What's the point in using a class with only static methods? Those functions are just collision routines that share no data and should go into a common namespace IMHO.
  • 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!