Saturday, April 30, 2011

PhysX Basics Tutorial: Joint Basics



In this tutorial, we will see how to create a simple distance joint. We will reuse the picking code in this tutorial to make things a bit more interesting. So without any further ado, lets get started. We will create two boxes one of which will be a static object. The other box will be manipulated by the mouse hence it will be dynamic.
Creating the boxes
The dynamic box
We simply call the box descriptor as discussed in the past tutorials. Nothing new here.

NxBodyDesc bodyDesc;
bodyDesc.angularDamping = 0.75f;
bodyDesc.linearVelocity = NxVec3(0,0,0);

NxBoxShapeDesc boxDesc;
size_t box_size = 1;
boxDesc.dimensions = NxVec3(box_size/2.0f, box_size/2.0f, box_size/2.0f);

actorDesc2.shapes.pushBack(&boxDesc);
actorDesc2.body = &bodyDesc;
actorDesc2.density = 1.0f;
actorDesc2.globalPose.t = NxVec3(0.0f,3.0f,0.0f);

NxActor* dynamicBox = gScene->createActor(actorDesc2);
dynamicBox->userData= (void*)box_size;


The static box
For static box, we simply create the actor as before and then raise the body flag to be NX_BF_FROZEN.

//create another box which is static
actorDesc2.globalPose.t = NxVec3(0.0f,5.0f,0.0f);

NxActor* staticBox = gScene->createActor(actorDesc2);
staticBox->userData= (void*)box_size;
staticBox->raiseBodyFlag(NX_BF_FROZEN);


Creating joint
For creating a very basic distance joint, we need to fill in the descriptor called
NxDistanceJointDesc. The first things we will give it are the actors that the joint links.

//create a joint
NxDistanceJointDesc desc;
desc.actor[0] = dynamicBox;
desc.actor[1] = staticBox;

For this, we store the references returned from createActor function as shown in the previous section. Next, we specify the different properties of the joint descriptor.
The max/minDistance denote the limits of stretch/compression for this joint respectively.

desc.maxDistance = 2.0f;
desc.minDistance = 1.0f;

The damper determines how damped the springiness of the spring is. A high value dampens the spring and vice verse for spring value.

desc.spring.damper = 1.0f;
desc.spring.spring = 200.0f;

The next two lines are very important. The first setsup the desc's flags. This controls whether the min, max limit of the distance joint, and the spring in the distance joint is enabled. If you dont add these flags, there will be no limit and no springiness to the joint. Likewise the jointFlags are also important. If u want that the actors connected to the distance joint collide, you must pass the NX_JF_COLLISION_ENABLED flag to the jointFlags descriptor. Finally, the spring is created as any other object that we have covered in the past tutorials.

desc.flags |= NX_DJF_MIN_DISTANCE_ENABLED | NX_DJF_MAX_DISTANCE_ENABLED | NX_DJF_SPRING_ENABLED;
desc.jointFlags |= NX_JF_COLLISION_ENABLED;
gScene->createJoint(desc);


Rendering of the distance joint
For rendering of the distance joint, we do a fairly simple thing by creating a global array for 2 NxVec3 types. When we are about to draw the box actors, we store their current positions in the global array so the new DrawCube function is this,

//Stored globally
NxVec3 pos[2]; //for storing the two end points of spring

void DrawBox(NxShape* pShape, size_t size) {
static int count=0;
pos[(count++)%2] = pShape->getGlobalPosition();
NxMat34 pose = pShape->getGlobalPose();
float mat[16];
pose.getColumnMajor44(mat);
glPushMatrix();
glMultMatrixf(mat);
glutSolidCube(size);
glPopMatrix();
}

Next, in the render function, we draw the line between the two positions just stored.

glColor3f(gMouseJoint!=NULL,gMouseJoint==NULL,gMouseJoint==NULL);
//Draw the spring
glBegin(GL_LINES);
glVertex3f(pos[0].x, pos[0].y, pos[0].z);
glVertex3f(pos[1].x, pos[1].y, pos[1].z);
glEnd();


That's it we have a simple distance joint between two boxes. Here is the snapshot from this application.

PhysX Basics

Source code of this tutorial

Thursday, April 28, 2011

PhysX Basics Tutorial: Using the Visual Debugger



In this tutorial, we will see how to connect our client application to the visual debugger. Usually, when you start the visual debugger, it will try to connect to an application. If there is no application connecting to it, it will do nothing.

How to enable remote debugging in your application
On the client side (your application) after you have created the sdk object call this line of code.

gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect ("localhost", 5425);

The first parameter of the connect function is the ip address (for local debugging, you can use localhost (127.0.0.1)), the second parameter is the port where the connection will be made.

Demo run
We will now try to see the debugger in action. First, run the visual debugger. Then run your application. You should see all of your objects in the visual debugger. The active objects are green and the inactive (sleep) objects are yellow. This can turn out to be an invaluable tool when we are working on a fairly large project.

That's it for this demo. There is no source code for this tutorial. Just use any of the existing codes and add in the code snippet given earlier and see it in action.
Here is a snapshot of a debugging session.

Using PhysX Visual Debugger

We will look at how to create joints in the next tutorial.

PhysX Basics Tutorial: Picking



In this tutorial, we will use the scene of multiple boxes from the last tutorial. This tutorial assumes that you have successfully understood the basics of how to create an actor using the scene object. If not, u may want to review the previous tutorials as a refresher. Ok so now lets get started. There are a lot of things similar between this and the previous tutorial.

General picking
We will first look at how picking works in general. The user picks on a point on the window. The 2D point coordinates are converted to a 3d point. Then, a ray is generated. The origin and direction of the ray are first calculated by unprojecting the clicked point at different depths. The same point coordinates are used but with two depths (z=0 and z=1) for the near hit point and the far hit point respectively. Once we have constructed the ray, the scene is asked to find an intersecting actor. If the ray has intersected with any actor, a dynamic spring is created between the intersected actor and a sphere at the intersection point. In the mouse motion funciton, depending on whether the actor has been intersected the intersected actor is manipulated.

Picking in PhysX
We define two new functions ViewProject and ViewUnProject as follows,

void ViewProject(NxVec3 &v, int &xi, int &yi, float &depth)
{
GLdouble winX, winY, winZ;
gluProject((GLdouble) v.x, (GLdouble) v.y, (GLdouble) v.z, modelMatrix, projMatrix, viewPort, &winX, &winY, &winZ);
xi = (int)winX; yi = viewPort[3] - (int)winY - 1; depth = (float)winZ;
}
void ViewUnProject(int xi, int yi, float depth, NxVec3 &v)
{
yi = viewPort[3] - yi - 1;
GLdouble wx, wy, wz;
gluUnProject((GLdouble) xi, (GLdouble) yi, (GLdouble) depth,
modelMatrix, projMatrix, viewPort, &wx, &wy, &wz);
v.set((NxReal)wx, (NxReal)wy, (NxReal)wz);
}

The above functions simply call the glu[Un]Project function. Nothing fancy here. Both of these functions need the viewport, modelview and projection matrices so we store these matrices globally. We obtain the viewport values and projection matrix when they are setup (in the resize handler) as shown below.

void OnReshape(int nw, int nh) {
glViewport(0,0,nw, nh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)nw / (GLfloat)nh, 0.1f, 1000.0f);
glGetIntegerv(GL_VIEWPORT, viewPort);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
glMatrixMode(GL_MODELVIEW);
}

Similarly, we obtain the modelview matrix in the render function just after the viewing transformation is set.

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//setting up modelview matrix
glTranslatef(0,0,dist);
glRotatef(rX,1,0,0);
glRotatef(rY,0,1,0);
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
...
//rest of display function

So now we have our matrices. We now come on the Pick function. This function takes an x, y screen coordinate, cast a ray from into the scene and returns true if there is an intersection. It also stores a sphere object at the hit point, stores reference to the intersected actor and also store a spring between the hitpoint sphere and the actor. This function is defined as follows,


bool PickActor(int x, int y)
{
ReleaseHelpers();

We first release all previous helpers (the spring and the last intersection sphere.


NxRay ray;
ViewUnProject(x,y,0.0f, ray.orig);
ViewUnProject(x,y,1.0f, ray.dir);
ray.dir -= ray.orig; ray.dir.normalize();

The above lines create a ray as given in the previous paragraph.


NxRaycastHit hit;
NxShape* closestShape = gScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit);
if (!closestShape) return false;
if (!closestShape->getActor().isDynamic()) return false;

The above lines is where the ray is cast to find the closest actor. If there is none, we return false.


int hitx, hity;
ViewProject(hit.worldImpact, hitx, hity, gMouseDepth);
gMouseSphere = CreateSphere(hit.worldImpact, 0.1f, 1.0f);

gMouseSphere->raiseBodyFlag(NX_BF_KINEMATIC);
gMouseSphere->raiseActorFlag(NX_AF_DISABLE_COLLISION);

The above lines project the hit point back to get the world space position. This is done so that the picking cursor (sphere) could be drawn at the intersection point.
The sphere's body flag is raised to kinematic since it will be attached to an actor(see next few lines). The collisions are also disabled since we donot want our cursor to intersect with any geometry.



NxDistanceJointDesc desc;
gSelectedActor = &closestShape->getActor();
gSelectedActor->wakeUp();

desc.actor[0] = gMouseSphere;
desc.actor[1] = gSelectedActor;

These lines create a descriptor for a joint having one end point, our sphere cursor and the other end point our intersected actor.


gMouseSphere->getGlobalPose().multiplyByInverseRT(hit.worldImpact, desc.localAnchor[0]);
gSelectedActor->getGlobalPose().multiplyByInverseRT(hit.worldImpact, desc.localAnchor[1]);

The above lines modify the transformation of the intersected actor based on the hit point.


desc.maxDistance = 0.0f;
desc.minDistance = 0.0f;
desc.spring.damper = 1.0f;
desc.spring.spring = 200.0f;
desc.flags |= NX_DJF_MAX_DISTANCE_ENABLED | NX_DJF_SPRING_ENABLED;
NxJoint* joint = gScene->createJoint(desc);
gMouseJoint = (NxDistanceJoint*)joint->is(NX_JOINT_DISTANCE);
return true;
}

Finally, the descriptor parameters are filled in and a joint is created. Note that on every mouse click, the old cursor (sphere) and joint are released and a new pair is created. The ReleaseHelpers function is defined as follows,

void ReleaseHelpers()
{
if (gMouseJoint)
gScene->releaseJoint(*gMouseJoint);
gMouseJoint = NULL;
if (gMouseSphere)
gScene->releaseActor(*gMouseSphere);
gMouseSphere = NULL;
}

Nothing fancy here either. We just release the created objects (the sphere cursor and the joint).

That's it. You need to call the pick function in the mouse function and handle the drag event. Enjoy this snapshot from the demo.

PhysX Picking

Source code of this tutorial

Wednesday, April 27, 2011

PhysX Basics Tutorial: Multiple Bouncing Box



In this tutorial, we will add multiple boxes to the scene. This tutorial assumes that you have successfully understood the basics of how to create an actor using the scene object. If not, u may want to review the previous tutorials as a refresher. Ok so now lets get started. There are a lot of things similar between this and the previous tutorial on the simple box. In fact, the only thing changed when we need to add multiple boxes is the InitializePhysX function. This function is given as follows,


void InitializePhysX() {
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
if(gPhysicsSDK == NULL) {
cerr<<"Error creating PhysX device."<<endl;
cerr<<"Exiting..."<<endl;
exit(1);
}
//Create the scene
NxSceneDesc sceneDesc;
sceneDesc.gravity.set(0.0f, -9.8f, 0.0f);

gScene = gPhysicsSDK->createScene(sceneDesc);

NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.5);
defaultMaterial->setStaticFriction(0.5);
defaultMaterial->setDynamicFriction(0.5);

gScene->setTiming(myTimestep / 4.0f, 4, NX_TIMESTEP_FIXED);


//Create actors
//1) Create ground plane
NxPlaneShapeDesc planeDesc;
NxActorDesc actorDesc, actorDesc2;

actorDesc.shapes.pushBack(&planeDesc);
gScene->createActor(actorDesc);

//2) Create cube
NxBodyDesc bodyDesc;
bodyDesc.angularDamping = 0.75f;
bodyDesc.linearVelocity = NxVec3(0,0,0);

NxBoxShapeDesc boxDesc;
size_t box_size = 1;
boxDesc.dimensions = NxVec3(box_size/2.0f, box_size/2.0f, box_size/2.0f);

actorDesc2.shapes.pushBack(&boxDesc);
actorDesc2.body = &bodyDesc;
actorDesc2.density = 1.0f;

We are repeating the same steps as we did in the last tutorial. The only thing that we need to do in case when we need multiple objects of the same type is that we need to create new actors using the scene object. All of this reuse the same actor descriptor object.


for(int i=0;i<10;i++) {
actorDesc2.globalPose.t = NxVec3(0.0f,5.0f+5*i,0.0f);
gScene->createActor(actorDesc2)
}
}

In the above lines, we loop 10 times. We generate a new y position using the loop variable and then assign this position to the global pose of the actor descriptor. Next we call the createActor function passing it the modified descriptor to create a new object for us.

That's it. The rest of the code remains the same since it will loop through all of the actors and determine their types to call the appropriate draw function as detailed in the last tutorial.

Running the code gives us the following output.
PhysX Multiple Bouncing Boxes

Source code of this tutorial

PhysX Basics Tutorial: A Simple Bouncing Box


In this tutorial, I will show you how to create a simple box at a specific position and let it bounce under influence of gravity. We will be adding to the code base from the previous tutorials. We first create the PhysX sdk object and store it into a global pointer like this,
#include <iostream>

#include <GL/freeglut.h>

#include <NxPhysics.h>



#pragma comment(lib, "PhysXLoader.lib")



NxPhysicsSDK* gPhysicsSDK = NULL;

NxScene* gScene = NULL;

NxActor* groundPlane; 

NxActor* box; 



NxReal myTimestep = 1.0f/60.0f;



void InitializePhysX() {

   gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);

   if(gPhysicsSDK == NULL) {

      cerr<<"Error creating PhysX device."<<endl;

      cerr<<"Exiting..."<<endl;

      exit(1);

   }

In the above lines, we just store pointers to the PhysX sdk object, the scene object and two actors (our ground plane and the box) and the timeStep value for stepping the PhysX simulation.

   //Create the scene

   NxSceneDesc sceneDesc;

   sceneDesc.gravity.set(0.0f, -9.8f, 0.0f); 

   gScene = gPhysicsSDK->createScene(sceneDesc);



In PhysX any physics object you want to make, you need to fill a relevant descriptor and then pass that descriptor to the sdk function (through the PhysX sdk pointer) responsible for creating the object for you. In this case, we ask PhysX to set up the global scene gravity to 9.8 m/s^2 The -ve sign is to make it point downwards.

   NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);

   defaultMaterial->setRestitution(0.5);

   defaultMaterial->setStaticFriction(0.5);

   defaultMaterial->setDynamicFriction(0.5);



   gScene->setTiming(myTimestep / 4.0f, 4, NX_TIMESTEP_FIXED);

In the above lines, we set the default material's physical properties like static and dynamic friction and the coefficient of restitution. Next, we set the update timing for the PhysX sdk. We ask the sdk to use a fix time stepping. For the simple demo like this, fixed time steps should suffice.
Creating actors
   //Create actors 

   //1) Create ground plane

   NxPlaneShapeDesc planeDesc;

   NxActorDesc actorDesc, actorDesc2;

   actorDesc.shapes.pushBack(&planeDesc);

   gScene->createActor(actorDesc);



   //2) Create cube  

   NxBodyDesc bodyDesc;

   bodyDesc.angularDamping = 0.75f;

   bodyDesc.linearVelocity = NxVec3(0,0,0);

   NxBoxShapeDesc boxDesc;

   boxDesc.dimensions = NxVec3(0.5, 0.5, 0.5);

   actorDesc2.shapes.pushBack(&boxDesc);

   actorDesc2.body   = &bodyDesc;

   actorDesc2.density  = 1.0f;

   actorDesc2.globalPose.t  = NxVec3(0,10,0);

   gScene->createActor(actorDesc2);

}

In the above lines, we create two actors for the ground plane and the box. For each of these actors, their descriptors are filled first to allow us to adjust the parameters. For the ground plane, the default parameters create a ground plane at origin and a positive Y normal direction. Once created, the actor descriptor is given to the scene's createActor function. Next, the same steps are taken for the box. In case of box however the body descriptot is first filled to store the box's linear velocity and angular damping. Then the box's shape descriptor is filled to fill its dimensions. This shape is then adde to the actors shapes list. Next, the actor descriptor sets the body, density and the initial position (globalPose.t). Finally, the createActor function is invoked again. Thats it, we have successfully added the two actors to the PhysX engine.

Handling PhysX stepping loop
Once the actor stuff is done, the next thing we need to handle is the PhysX loop. This will allow the simulation to step ahead in time. We will implement an asynchronous loop which can be done using the following lines of code.
void StepPhysX() 

{ 

   gScene->simulate(myTimestep);        

   gScene->flushStream();        

   //...perform useful work here using previous frame's state data        

   while(!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false) )     

   {

      // do something useful        

   }

} 

These lines were copied directly from the documentation so rather than commenting anything on these, I would ask you to go and read the asynchronous loop section in the PhysX documentation. We will call this function once from our display function.

Rendering of Actors
The next step is to render the actors. To make easier for use to work with PhysX, I have modularized the code into functions. First, the RenderActors() function is implemented as follows,
void RenderActors() 

{ 

    // Render all the actors in the scene 

    int nbActors = gScene->getNbActors(); 

    NxActor** actors = gScene->getActors(); 

    while (nbActors--) 

    { 

        NxActor* actor = *actors++; 

        DrawActor(actor); 

    } 

} 

Nothing fancy here, we first query the scene for the total number of actors it contains. Then, we loop through each actor and draw it by calling the DrawActor function. The DrawActor function is implemented as follows,

 

void DrawActor(NxActor* actor) 

{ 

    NxShape* const* shapes = actor->getShapes(); 

    NxU32 nShapes = actor->getNbShapes(); 

     

    while (nShapes--) 

    { 

        DrawShape(shapes[nShapes]); 

    } 

} 

It looks a lot like the previous function doesn't it. It basically ask the actor for the number of shapes it has and then calls the DrawShapes function with the shape parameter. The DrawShape function is implemented as follows,

void DrawShape(NxShape* shape) 

{ 

   int type = shape->getType();

   switch(type) 

   {          

      case NX_SHAPE_BOX:

         DrawBox(shape);

      break;

   } 

} 

This function first identifies the type of the shape and then uses a switch case to call the appropriate Draw function. For our case, we check for the Box object and then call the DrawBox function passing it the shape parameter. THe DrawBox function is implemented as follows,

void DrawBox(NxShape* pShape) {

   NxMat34 pose = pShape->getGlobalPose(); 

   float mat[16];

   pose.getColumnMajor44(mat);

   glPushMatrix(); 

      glMultMatrixf(mat);

      glutSolidCube(1);

   glPopMatrix(); 

}

The DrawBox function gets the current Global pose (basically the shapes tranform matrix) and then converts it into a column major form (so that we can pass this matrix to OpenGL). Next, the currnet transformation matrix is stored (glPushMatrix) and then the box's matrix is multiplied to the current matrix. Then, we draw the box's geometry (using the glutSolitCube function) and finally revert the old transformation back by calling glPopMatrix.

The Display Function
Now after these function definitions, the display function becomes this,
void Display() {

   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

   glLoadIdentity();

   //setup the view transformation using 

   //gluLookAt(...);



   //Update PhysX 

   if (gScene) 

   { 

       StepPhysX(); 

   }   



   RenderActors();



   glutSwapBuffers();

}


That's it. Attached is the complete source code for this tutorial. Here is the snapshot of the application.
PhysX Simple Box

Source code for this tutorial

Tuesday, April 26, 2011

PhysX Basics Tutorial: Using GLUT with PhysX



This tutorial is on how to setup freeglut with NVIDIA PhysX sdk.


#include <iostream>
#include <GL/freeglut.h>
#include <NxPhysics.h>

using namespace std;

#pragma comment(lib, "PhysXLoader.lib")

const int WINDOW_WIDTH=1024,
WINDOW_HEIGHT=768;

static NxPhysicsSDK* gPhysicsSDK = NULL;

In the above lines, we first include the required headers. Then the requried linker library is linked programmatically. Next we setup the variables for the screen size and a global pointer to the PhysX sdk. This is done so that PhysX is conveniently accessible throughout the code.


void InitializePhysX() {
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
if(gPhysicsSDK == NULL) {
cerr<<"Error creating PhysX device."<<endl;
cerr<<"Exiting..."<<endl;
exit(1);
}
}
void ShutdownPhysX() {
NxReleasePhysicsSDK(gPhysicsSDK);
}

These two functions were discussed in the previous tutorial so nothing new here. For the NXCreatePhysicsSDK function, the other parameters are ignored.


void InitGL() {
}

void OnReshape(int nw, int nh) {
glViewport(0,0,nw, nh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)nw / (GLfloat)nh, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}

void OnRender() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glutSwapBuffers();
}

void OnShutdown() {
ShutdownPhysX();
}
void main(int argc, char** argv) {
atexit(OnShutdown);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutCreateWindow("GLUT PhysX Demo");

glutDisplayFunc(OnRender);
glutReshapeFunc(OnReshape);

InitGL();
InitializePhysX();

glutMainLoop();
}

These lines setup a glut window with double buffer support. It also hooks up two functions for resize handling and display. Thats it. The glut window is now setup with PhysX. The next tutorial will discuss how to add a basic cube that falls due to gravity into a glut window. Source codes are here

PhysX Basics Tutorial: Getting started with NVIDIA PhysX



I went to see the power of the NVIDIA PhysX sdk. So I downloaded the sdk from the PhysX developer site. While the sdk contains a lot of demos, for a beginner like me it was quite tedious to get started. I initially started with the documentation and I must say it is pretty good at explaining the API. So my next step was to look at the internet to find out if there are any basic tutorials. Fortunately, I came across Swiftless Tutorials (http://www.swiftless.com/misctuts/physxtuts.html) on AGEIA PhysX (before acquired by NVIDIA, AGEIA owned this sdk). These were very helpful for me in understanding how to get up and running with NVIDIA PhysX sdk. So I will try to fill the gap by doing basic PhysX tutorials.

These tutorials are based on the latest NVIDIA PhysX sdk version 2.8.4. This sdk does not ask u for installing the system software. Thus its your responsibilty to handle the dlls required. Which dlls u need I will explain in a minute. I will use freeglut in this tutorial series.

Getting started with NVIDIA PhysX
We need to include the headers first.

#include <iostream >
#include <nxphysics.h >
using namespace std;
#pragma comment(lib, "PhysXLoader.lib")

The last header NxPhysics.h is the header needed for PhysX. The rest are for c++ output/input stuff. I like to programmatically add the linker libraries. For this basic startup demo, we only need the PhysxLoader.lib/dll so we link to it.
void main() {

NxSDKCreateError whatError;
NxPhysicsSDK* pPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION,0,0, NxPhysicsSDKDesc(), &whatError);
if(pPhysicsSDK) {
NxReleasePhysicsSDK(pPhysicsSDK);
} else {
cerr << "Cannot create PhysX device." << endl;
cerr << "Reason: " << whatError;
}


Thats it. If u try to compile and run the code, the pPhysicsSDK pointer will be NULL and the error code will be NXCE_PHYSX_NOT_FOUND. The reason for this is because the required dlls are needed to be copied to the current solution folder. These dlls are PhysXLoader.dll and PhsyXCore.dll. That's it you have the helloworld PhysX program.

Next, we will look at how to hook glut with PhysX in the next tutorial.
Hope you will enjoy the rest of the tutorials. Source codes are here

Wednesday, April 6, 2011

ARB_transform_feedback2

I could not find enough demos on how to use the new ARB transform feedback2 extension. Basically it goes like this,
1) You need to call
 
glGenTransformFeedbacks(1, &tfID);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);

like any other function in OpenGL.

2) You specify the buffer and the shader varyings.
 
glBindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfvbo ); glTransformFeedbackVaryings( pg, 1, attr, GL_INTERLEAVED_ATTRIBS); //(my cards does not support the EXT function


3) In the render function u don’t call glDraw[*] functions instead u call
 
glDrawTransformFeedback(GL_POINTS, tfID);

The buffer binding is taken from the tfID transform feedback buffer.
Thats it. The new way simplifies the handling of buffers.
Attached is the full source code.

Source Code
Binary (Requires freeglut and glew)
Visual Studio 2008 sln (Requires freeglut and glew)

Download solution from Google Docs

Popular Posts

Copyright (C) 2011 - Movania Muhammad Mobeen. Awesome Inc. theme. Powered by Blogger.