Thursday, February 28, 2013
[opengl] glutMainLoop(), glutDisplayFunc(), glutPostRedisplay()
http://stackoverflow.com/a/1862505
glutMainLoop only calls the display callback when a glut event triggers the display callback, such as resizing the window, uncovering the window, or calling glutPostRedisplay. You have to put code in your program to trigger glut into calling your display callback at a proper frame rate to produce animation in your program. For example, you can put a call to glutPostResdisplay into your idle callback function, so when GLUT is idle your display callback will get called.
http://www.gamedev.net/topic/379278-what-exactly-does-glutmainloop-do/
glutMainLoop() is a function that loops within itself, processing events and triggering your callback functions when necessary (glutDisplayFunc, etc). After a call to glutMainLoop(), you have no control over the execution of your program besides the callback functions you initialized before the call.
And another thing, the glutDisplayFunc() callback only gets triggered when your app's window receives a refresh event, unless you explicity post a redisplay. If you want your display function to be called repeatedly (i.e. for a game), you need to set your glutIdleFunc to post a redisplay.
Something like this:
int main()
{
/* ... */
glutIdleFunc(updateGame);
/* ... */
glutMainLoop();
}
void updateGame()
{
glutPostRedisplay();
}
http://www.lighthouse3d.com/tutorials/glut-tutorial/glutpostredisplay-vs-idle-func/
Wednesday, February 27, 2013
Setup SVN from Google Code Project
1. Set up a project at
code.google.come
2. set up your members under
Project Home –> People
3.
http://mzaher.wordpress.com/2009/03/02/how-to-use-svn-with-google-code/
Sunday, February 24, 2013
How to find environment variable (e.g. VSInstallDir, WinSDKDir, etc) in Visual C++ 2010
[YourProject]
-> Properties
-> Configuration Properties
-> VC++ Directories
-> Click on one of the property values e.g. Include Directories
-> edit
-> Macro >>
Saturday, February 23, 2013
[c/c++] error: CrtIsValidHeapPointer(pUserData) - free memory not on the heap
That's right, when you try to 'free()' memo
- that is already freed or
- that is not on the heap (e.g. a local varible to the function)
CrtIsValidHeapPointer(pUserData) error occurs (VC++)
[c/c++] For who think they don't need to use dynamic allocation (malloc, calloc) for data structures
Look at the following code to add a node to a queue
void Queue1::add(int p_data)
{
Node newNode;
newNode.data = p_data;
newNode.next = 0;
// if tail exists
if(tail)
{
tail->next = &newNode;
tail = tail->next;
}
// otherwise
else
{
head = &newNode;
tail = &newNode;
}
}
This will not work as the 'newNode' created is only sitting on the stack not on the heap, therefore, every time this method is called, head and tail will be pointing at some junk from the get go.
We want the head to stay where it is and move the tail, hence need to put every Node created onto the heap.
void Queue1::add(int p_data)
{
Node* newNodePtr = (Node*) calloc(1, sizeof(Node));
newNodePtr->data = p_data;
newNodePtr->next = 0;
// if tail exists
if(tail)
{
tail->next = newNodePtr;
tail = tail->next;
}
// otherwise
else
{
head = newNodePtr;
tail = newNodePtr;
}
}
The full version of the main code file:
void Queue1::add(int p_data)
{
Node newNode;
newNode.data = p_data;
newNode.next = 0;
// if tail exists
if(tail)
{
tail->next = &newNode;
tail = tail->next;
}
// otherwise
else
{
head = &newNode;
tail = &newNode;
}
}
This will not work as the 'newNode' created is only sitting on the stack not on the heap, therefore, every time this method is called, head and tail will be pointing at some junk from the get go.
We want the head to stay where it is and move the tail, hence need to put every Node created onto the heap.
void Queue1::add(int p_data)
{
Node* newNodePtr = (Node*) calloc(1, sizeof(Node));
newNodePtr->data = p_data;
newNodePtr->next = 0;
// if tail exists
if(tail)
{
tail->next = newNodePtr;
tail = tail->next;
}
// otherwise
else
{
head = newNodePtr;
tail = newNodePtr;
}
}
The full version of the main code file:
#include "Queue1.h" Queue1::Queue1(void) { head = 0; tail = 0; } Queue1::~Queue1(void) { } void Queue1::add(int p_data) { Node* newNodePtr = (Node*) calloc(1, sizeof(Node)); newNodePtr->data = p_data; newNodePtr->next = 0; // if tail exists if(tail) { tail->next = newNodePtr; tail = tail->next; } // otherwise else { head = newNodePtr; tail = newNodePtr; } } int Queue1::remove() { int data = -1; if (head) { data = head->data; if (head == tail) tail = tail->next; Node* temp = head; head = head->next; // so how to free the previous header occupied block? free(temp); } return data; } int main(int argc, char* argv[]) { Queue1 q1; q1.add(1); q1.add(2); q1.remove(); q1.remove(); }
Tuesday, February 19, 2013
[c/c++] Open GL display list example
Notice that:
- The drawParticle() method is static
- That's why this method can be put onto the GL 'display list', it will be loaded once but run many times, if you put 'cout', for example, in drawParticle() method, it will only show output once
- The position of drawing the points are actually specified by assigning value to the member variable x, at the end of the caller to the drawParticle() method.
--Particle.h--
----Particle.cpp----
- The drawParticle() method is static
- That's why this method can be put onto the GL 'display list', it will be loaded once but run many times, if you put 'cout', for example, in drawParticle() method, it will only show output once
- The position of drawing the points are actually specified by assigning value to the member variable x, at the end of the caller to the drawParticle() method.
--Particle.h--
#pragma once #include <GL\glut.h> #define _USE_MATH_DEFINES #include <math.h> #include <limits.h> #include <iostream> #include "Vector3D.h" #include "Constants.h" using namespace std; class Particle { public: /** Display list index. */ static int PARTICLE_DISPLAY_LIST; /** Highlighted appearance if true, otherwise white. */ bool highlight; /** If true, then particle is pinned in space. */ bool pin; /** mass. */ float m; /** Deformed Position. */ Point3D x; /** Undeformed/material Position. */ Point3D x0; /** Velocity. */ Vector3D v; /** Force accumulator. */ Vector3D f; /** * Draws a canonical circular particle. */ static void drawParticle(Point3D p); public: /** * Constructor: */ Particle() { setDefaultMemebers(); } /** * Constructor: Constructs particle with the specified material/undeformed coordinate, * p0. */ Particle(Point3D p_x0) { setDefaultMemebers(); x0.Set(p_x0.x, p_x0.y, p_x0.z); x.Set(p_x0.x, p_x0.y, p_x0.z); } /** Set default values to some of the members */ void setDefaultMemebers(){ highlight = false; pin = false; m = PARTICLE_MASS; PARTICLE_DISPLAY_LIST = -1; } // Setters /** Specifies whether particle should be drawn highlighted. */ void setHighlight(bool p_highlight) { highlight = p_highlight; } /** * Specifies whether or not this particle is fixed in space via a pin * constraint. (Should probably be elsewhere in a generic constraint list). */ void setPin(bool fix) { pin = fix; } // Getters /** True if particle should be drawn highlighted. */ bool getHighlight() { return highlight; } /** Returns true if currently pinned. */ bool isPinned() { return pin; } /** Draws circular particle using a display list. */ void display(); };
----Particle.cpp----
#include "Particle.h" /** * Simple particle implementation, with miscellaneous adornments. * * @author James Wang, Feb, 2013 * based on code orginally developed by Doug James in Java with JOGL 1.x */ int Particle::PARTICLE_DISPLAY_LIST = -1; /** Draws circular particle using a display list. */ void Particle::display() { //cout << "NEW PARTICLE FOR DISPLAY LIST " << PARTICLE_DISPLAY_LIST << "\n"; if (PARTICLE_DISPLAY_LIST < 0) {// MAKE DISPLAY LIST: int displayListIndex = glGenLists(1); glNewList(displayListIndex, GL_COMPILE); drawParticle(Point3D(0.0f, 0.0f, 0.0f));// /particle at origin glEndList(); std::cout<<"MADE LIST" << displayListIndex << " : " << glIsList(displayListIndex); PARTICLE_DISPLAY_LIST = displayListIndex; } // COLOR: DEFAULT WHITE; GREEN IF HIGHLIGHTED; ADD RED IF PINNED Point3D c (1.0f, 1.0f, 1.0f);// default: white if (pin) { c.x = 1.0f;// add red c.y *= 0.2f; c.z = 0; } if (highlight) { c.y = 1; c.z = 0; } glColor3f(c.x, c.y, c.z); // / DRAW ORIGIN-CIRCLE TRANSLATED TO "p": glPushMatrix(); glTranslated(x.x, x.y, x.z); glCallList(PARTICLE_DISPLAY_LIST); glPopMatrix(); } /** * Draws a canonical circular particle. */ void Particle::drawParticle(Point3D p) { double radius = PARTICLE_RADIUS; double vectorX1 = p.x; double vectorY1 = p.y; double vectorZ1 = p.z; cout << "\n" << "MAKING COORDINATE SPOT AT " << p.x << " " << p.y << " "<< p.z << "\n"; // Draw the particle as 3D spheres glColor4f(1, 0, 0, 0); glutSolidSphere(radius, 10, 10); glEnd(); }
Sunday, February 17, 2013
[c/c++] LNK2019: unresolved external symbol
1. if you have static variable, check if it is both declared and defined
http://stackoverflow.com/questions/195207/unresolved-external-symbol-on-static-class-members
in header file:
http://stackoverflow.com/questions/195207/unresolved-external-symbol-on-static-class-members
in header file:
unsigned char test::X;
unsigned char test::Y;
in the cpp file:
unsigned char test::X;
Then in the caller function, you can do
test::X = 3;
2. Check if you copy, pasted and renamed to generate a .h file.
- you can 'toggle' the 'Show All File' button in the Solution Explorer of Visual Studio to show the structure where Header Files and Source Files are shown in separate folders and check if that header file is there in the Header Files folder.
- if not, exclude it from and then include it into the project
[c/c++] c++ Vector of Abstract Class type
http://www.cplusplus.com/forum/general/17754/
#include <iostream>
#include <vector>
using namespace std;
// abstract base class
class Animal
{
public:
// pure virtual method
virtual void speak() = 0;
// virtual destructor
virtual ~Animal() {}
};
// derived class
class Dog : public Animal
{
public:
// polymorphic implementation of speak
virtual void speak() { cout << "Ruff!"; }
};
int main( int argc, char* args[] )
// container of base class pointers
vector<Animal*> barn;
// dynamically allocate an Animal instance and add it to the container. Note: new returns a pointer
barn.push_back( new Dog() );
// invoke the speak method of the first Animal in the container
barn.front()->speak();
// free the allocated memory
for( vector<Animal*>::iterator i = barn.begin(); i != barn.end(); ++i )
{
delete *i;
}
// empty the container
barn.clear();
return 0;
}
[c/c++] initialization and instantiation... prototyped function not called (was a variable definition intended?)
// Correct initialization with default Constructor of A
ClassA a;
// Incorrect initialization
ClassA a();
// Correct initialization, returning a pointer to an object (http://www.cplusplus.com/reference/new/operator%20new/)
MyClass * p1 = new MyClass;
// allocates memory by calling: operator new (sizeof(MyClass))
// and then constructs an object at the newly allocated space
[c/c++] problem with fatal error LNK1561: entry point must be defined
Simply that you are missing a main() function or its alike. This is so even if you started in Visual Studio with an empty c++ project.
Subscribe to:
Posts (Atom)