OpenGL/Glut: glutTimerFunc seems not to start - opengl

I would like to use glutTimerFunc to move the camera around the scene which is composed of some mesh models. The camera path is build with a Bezier curve like the following:
if(sel == MODE_CAMERA_MOTION) {
mode = MODE_CAMERA_MOTION;
stepsCounter = 0;
// Building camera track
int i, j, k;
for(j=0; j<MAX_CV; j++) {
tmpCV[j][0] = CV[j][0];
tmpCV[j][1] = CV[j][1];
tmpCV[j][2] = CV[j][2];
}
for(i=0; i<STEPS; i++) {
for(j=1; j<MAX_CV; j++) {
for(k=0; k<MAX_CV-j; k++) {
lerp(i/(float)(STEPS*10), tmpCV[k], tmpCV[k+1], tmpCV[k]);
}
}
cameraPosition[i][0] = tmpCV[0][0];
cameraPosition[i][1] = tmpCV[0][1];
cameraPosition[i][2] = tmpCV[0][2];
}
glutTimerFunc(250, moveCamera, STEPS);
}
where the moveCamera function is:
void moveCamera() {
if (mode == MODE_CAMERA_MOTION) {
camE[0] = cameraPosition[stepsCounter][0];
camE[1] = cameraPosition[stepsCounter][1];
camE[2] = cameraPosition[stepsCounter][2];
if(stepsCounter < STEPS) {
stepsCounter++;
}
else {
/* come back to the first point */
camE[0] = 8.8;
camE[1] = 4.9;
camE[2] = 9.0;
stepsCounter = 0;
}
glutPostRedisplay();
}
}
But nothing moves. Maybe I have misunderstood the behaviour of that function.
Where am I wrong?

The prototype to the function passed to glutTimerFunc should be
void (*func)(int value)
Where the last parameter of glutTimerFunc is the passed value. So your moveCamera should be:
void moveCamera( int STEPS )
Also, even so, the moveCamera function will be called once. You need to reregister at end of execution. This might be a possible solution:
// instead of global STEPS and stepsCounter, we decrement at reexecution
void moveCamera( int STEPS ) {
... do stuff
glutTimerFunc(250, moveCamera, STEPS-1 );
}

Related

How to center a widget in QScrollArea?

Constructor:
ScrollArea::ScrollArea(...)
{
...
end = myItems.count();
for(int i=0; i<end; i++)
{
scrollItems.append(new ScrollItem(myItems.at(i), 0, width, i, this));
}
scrollArea->setWidget(this); //must be last for auto-scrolling to work
}
Member function:
void ScrollArea::updateSelection(int selection)
{
foreach(ScrollItem* item, scrollItems)
{
if(item->updateSelection(selection, 0))
{
scrollArea->ensureWidgetVisible(item);
}
}
}
After running ScrollArea::updateSelection, it looks like this:
I want it to look like this:
Google returns a mis-titled question (as far as I can tell: Place widget in center of QScrollArea) and a bunch of junk.
Still don't know why QScrollArea::ensureWidgetVisible doesn't work, even with explicit margins, but I found something that does:
void ScrollArea::updateSelection(int selection)
{
int item = -1;
int i = scrollItems.count();
while(i)
{
i--;
if(scrollItems.at(i)->updateSelection(selection, 0))
{
item = i;
}
}
if(item < 0)
{
return;
}
i = scrollItems.first()->height();
item *= i;
item += i / 2;
//item is now the position that should be centered
scrollArea->verticalScrollBar()->setValue(
item - (scrollArea->height() / 2)
);
}
So I'm basically brute-forcing what I want instead of having the library do it. (and fail)

Store and pass array in MFC-single-document

I am doing a small project of drawing tool.
When button down, capture the start point. When mouse move, draw a line. When button up, capture the final point. I use line to draw a polygon, so I use array m_polygonx to store final point.x of a line, and m_polygony to store final point.y, uint m_count to count the numbers of final points.
Here is my code:
void CDrawToolView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_startRect=FALSE;
::ClipCursor(NULL);
dc.MoveTo(m_startPoint);
dc.LineTo(m_OldPoint);
dc.MoveTo(m_startPoint);
dc.LineTo(point);
m_count++;
m_polygonx[m_count] = point.x;
m_polygony[m_count] = point.y;
}
And then I pass the array to a dialog.
In my calling function:
void CDrawToolView::OnEditProperty()
{
CPropertyDlg dlg;
dlg.origin_x = m_startPoint.x;
dlg.origin_y = m_startPoint.y;
dlg.count = m_count;
for (int i=0; i < m_count ; i++)
{
dlg.polygonx[i] = m_polygonx[i];
dlg.polygony[i] = m_polygony[i];
}
if (dlg.DoModal() == IDOK)
{
m_startPoint.x = dlg.origin_x;
m_startPoint.y = dlg.origin_y;
m_count = dlg.count;
for (int i=0; i < dlg.count ; i++)
{
m_polygonx[i] = dlg.polygonx[i];
m_polygony[i] = dlg.polygony[i];
}
}
}
But the array does not stored and passed successfully. Could some one help me?

platform game using sfml 1.6 in c++ collision using AABB's

I am using tile mapping and have my map class in place to draw the map by using an array of sprites. i have it to set the position of the sprite and then create a bounding box array around it and then draw the sprite.
i then have a collision class which gets the player bounding box and compares it with each bounding box for the sprite. i have an array called platformboundingBox. this stores each bounding box of each sprite in the array. however when i compare the values it seems that the platform bounding box has no values in any of the locations yet the i have checked that the values of each sprite go into the bounding box array.
here is my map class. see the drawmap and collision functions to take a look. if anyone can help i would really appreciate it.
#include "Map.h"
#include "Block.h"
#include <sstream>
using namespace std;
Map::Map()
{
//map ctor;
}
Map::~Map()
{
// map dtor
}
void Map::Initialise(const char *filename)
{
if(!BlockImage.LoadFromFile("Images/block.png"))
cout<<endl<<"failed to load block image"<<endl;
if(!GemImage.LoadFromFile("Images/Gem.png"))
cout<<endl<<"failed to load Gem Image"<<endl;
if(!leftBlockImage.LoadFromFile("Images/blockLeft.png"))
cout<<endl<<"failed to load left block Image"<<endl;
if(!rightBlockImage.LoadFromFile("Images/blockRight.png"))
cout<<endl<<"failed to load right block Image"<<endl;
std::ifstream openfile(filename);
std::vector <int> tempvector;
std::string line;
while(std::getline(openfile, line))
{
for(int i =0; i < line.length(); i++)
{
if(line[i] != ' ') // if the value is not a space
{
char value = line[i];
tempvector.push_back(value - '0');
}
}
mapVector.push_back(tempvector); // push back the value of the temp vector into the map vector
tempvector.clear(); // clear the temp vector readt for the next value
}
}
void Map::DrawMap(sf::RenderWindow &Window)
{
Player playermap;
for(i = 0; i < mapVector.size(); i++)
{
for(j = 0; j < mapVector[i].size(); j++)
{
if(mapVector[i][j] == 1)
{
sprite[j].SetImage(BlockImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Bottom = sprite[j].GetPosition().y;
platformBoundingBox[j].Left = sprite[j].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[j].GetPosition().x;
Window.Draw(sprite[j]);
}
else if(mapVector[i][j] == 2)
{
sprite[j].SetImage(GemImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Top = sprite[j].GetPosition().y - 5;
platformBoundingBox[j].Bottom = sprite[j].GetPosition().y;
platformBoundingBox[j].Left = sprite[j].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[j].GetPosition().x;
Window.Draw(sprite[j]);
}
else if(mapVector[i][j] == 3)
{
sprite[j].SetImage(leftBlockImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Top = sprite[i].GetPosition().y - 5;
platformBoundingBox[j].Bottom = sprite[i].GetPosition().y;
platformBoundingBox[j].Left = sprite[i].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[i].GetPosition().x;
Window.Draw(sprite[j]);
}
else if(mapVector[i][j] == 4)
{
sprite[j].SetImage(rightBlockImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Top = sprite[i].GetPosition().y - 5;
platformBoundingBox[j].Bottom = sprite[i].GetPosition().y;
platformBoundingBox[j].Left = sprite[i].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[i].GetPosition().x;
Window.Draw(sprite[j]);
}
}
}
}
void Map::collisions(float x, float y)
{
Player playermap;
this->x = x;
this->y = y;
playerboundingbox.Top = y - 5;
playerboundingbox.Bottom = y ;
playerboundingbox.Left = x - 5;
playerboundingbox.Right = x;
for(i = 0; i < 100; i++)
{
if(playerboundingbox.Intersects(platformBoundingBox[i]))
cout << " praise the lord";
}
}
Please switch to SFML 2 because 1.6 have a lot of bugs.
Let's say you create a class named handler where you will put:
handler::handler()
// window initialization
Map Map; // here initialize the Map class
/* why don't use Map::Map( ctor) for initialization? */
// player initialization
// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
//draw player
Map.DrawMap(); // also need to improve the drawing for less lag
window.display();
update(Map &Map, Player &Player);
// every time to use & because without the compiler will create another object
}
}
update(Map &Map, Player &Player)
{
// verify if exists some interacts
if (intersects(Map &Map, Player &Player))
{
//verify from where and put to the correct position
/* e.g: if we have a collide with a down tile map will say something like this:
Player.setPosition(Player.getPosition().x, (Player.getGlobalBounds().top+Player.getGlobalBounds().height)-(Map.getGlobalBounds().top-(Player.getGlobalBounds().top+Player.getGlobalBounds().height)); */
}
}
intersects(Map &Map, Player &Player)
{
sf::FloatRect fPlayer = Player.getGlobalBounds();
for (int i=0; i<Map.NrOfYourTiles; ++i)
{
sf::FloatRect fMap = YourTile.getGlobalBounds();
if (fPlayer.intersects(fMap))
return 1;
}
return 0;
}
Hope this will help you( the code is in SFML 2.0). You can find a lot more help on forums of the creator sfml-dev.org.

How do I made shooting multiple bullets function correctly using a for loop?

I'm working on a prototype for a shmup game in C++ using SDL...Right now I'm just trying to get the basics working without using classes. Now, I have it so it shoots multiple bullets, but it behaves strangely which I believe is because of the way the counter is reset...The bullets will appear and disappear, and some will keep blinking in the original spot they were shot at, and there will sometimes be a delay before any can be shot again even if the limit isn't on the screen...And sometimes the player character will suddenly jump way to the right and only be able to move up and down. How do I fix this so it smoothly shoots? I've included all relevent code...
[edit] Please note that I intend on cleaning it up and moving it all to a class once I get this figured out...This is just a simple prototype so I can have the basics of the game programmed in.
[edit2] ePos is the enemy position, and pPos is the player position.
//global
SDL_Surface *bullet[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
bool shot[10];
int shotCount = 0;
SDL_Rect bPos[10];
//event handler
case SDLK_z: printf("SHOT!"); shot[shotCount] = true; ++shotCount; break;
//main function
for(int i = 0; i <= 9; i++)
{
shot[i] = false;
bullet[i] = IMG_Load("bullet.png");
}
//game loop
for(int i = 0; i <= shotCount; i++)
{
if(shot[i] == false)
{
bPos[i].x = pPos.x;
bPos[i].y = pPos.y;
}
if(shot[i] == true)
{
bPos[i].y -= 8;
SDL_BlitSurface(bullet[i], NULL, screen, &bPos[i]);
if( (bPos[i].y + 16 == ePos.y + 16) || (bPos[i].x + 16 == ePos.x + 16) )
{
shot[i] = false;
}
else if(bPos[i].y == 0)
{
shot[i] = false;
}
}
}
if(shotCount >= 9) { shotCount = 0; }
Here is something like I was suggesting in the comment. It was just written off the top of my head but it gives you a general idea of what I'm talking about..
class GameObject
{
public:
int x;
int y;
int width;
int height;
int direction;
int speed;
GameObject()
{
x = 0;
y = 0;
width = 0;
height = 0;
direction = 0;
speed = 0;
}
void update()
{
// Change the location of the object.
}
bool collidesWidth(GameObject *o)
{
// Test if the bullet collides with Enemy.
// If it does, make it invisible and return true
}
}
GameObject bullet[10];
GameObject enemy[5];
while(true)
{
for(int x=0; x<=10;x++)
{
bullet[x].update();
for(int y=0;y<=5;y++)
{
if(bullet[x].collidesWith(&enemy[y])
{
// Make explosion, etc, etc.
}
}
}
}

Help in combining two functions in c++

I am just trying something with somebody else's code.
I have two functions:
int Triangle(Render *render, int numParts, Token *nameList, Pointer *valueList)
int i;
for (i=0; i<numParts; i++)
{
switch (nameList[i])
{
case GZ_NULL_TOKEN:
break;
case GZ_POSITION:
return putTrianglePosition(render, (Coord *)valueList[i]);
break;
}
}
return SUCCESS;
}
int putTrianglePosition(Render *render, Coord vertexList[3]) /*vertexList[3][3:xyz]*/
{
Coord *pv[3];
int i,j;
// sort verts by inc. y and inc. x
pv[0] = &vertexList[0];
pv[1] = &vertexList[1];
pv[2] = &vertexList[2];
for (i=0; i<2; i++)
for (j=i+1; j<3; j++)
{
if ((*pv[i])[1]>(*pv[j])[1] ||
(*pv[i])[1]==(*pv[j])[1] && (*pv[i])[0]>(*pv[j])[0]) {
Coord *tmp;
tmp = pv[i];
pv[i] = pv[j];
pv[j] = tmp;
}
}
;
// all y the same?
if ((*pv[0])[1] == (*pv[2])[1]) {
drawHorizonLine(render, *pv[0], *pv[2]);
return SUCCESS;
}
// assign middle point
Coord mid;
mid[1] = (*pv[1])[1]; // y
float ratio = ((*pv[1])[1] - (*pv[0])[1]) / ((*pv[2])[1] - (*pv[0])[1]);
mid[0] = (*pv[0])[0] + ratio * ((*pv[2])[0] - (*pv[0])[0]); // x
mid[2] = (*pv[0])[2] + ratio * ((*pv[2])[2] - (*pv[0])[2]); // z
if (mid[0]<=(*pv[1])[0]) { // compare X
drawTrapzoid(render, *pv[0], mid, *pv[0], *pv[1]); // upper tri
drawTrapzoid(render, mid, *pv[2], *pv[1], *pv[2]); // lower tri
}else{
drawTrapzoid(render, *pv[0], *pv[1], *pv[0], mid); // upper tri
drawTrapzoid(render, *pv[1], *pv[2], mid, *pv[2]); // lower tri
}
return SUCCESS;
}
I don't want two functions here. I want to copy the putTrianglePosition() function into the Triangle() function.
I tried doing that, but I got a lot of errors.
Can somebody else show me how to do this?
You shouldn't put functions together, you should split them apart. Put a new function wherever you can name them -- try to make them as small as you can. If you want a function that does all of that stuff, have a function that calls the other functions.
int foobar() {
int a;
int b;
/* do a whole bunch of stuff with a */
/* do a whole bunch of stuff with b */
return a + b;
}
this is sort of what you're trying to do. Instead, do this:
int foo(){
int a;
/* do a bunch of stuff with a */
return a;
}
int bar() {
int b;
/* do a bunch of stuff with b */
return b;
}
int foobar() {
return foo() + bar();
}
The result will be cleaner, easier to maintain and re-usable.
If you just change the line
return putTrianglePosition(render, (Coord *)valueList[i]);
into:
Coord* vertexList = (Coord*) valueList[i];
followed by the whole body of what's now putTrianglePosition from the opening { to the closing } included, I believe it should just work. If not, please edit your question to add the exact, complete, code as obtained by this edit and the exact, complete error messages you get.
I strongly recommend you to go with Functions because it allows better separation of logic and allows you to reuse the logic. But still in case if you want to use it that way please check the function below :
int Triangle(Render *render, int numParts, Token *nameList, Pointer *valueList)
{
int iOuter;
for (iOuter=0; iOuter<numParts; iOuter++)
{
switch (nameList[iOuter])
{
case GZ_NULL_TOKEN:
break;
case GZ_POSITION:
{
Coord* vertexList = (Coord*) valueList[i];
Coord *pv[3];
int i,j;
// sort verts by inc. y and inc. x
pv[0] = &vertexList[0];
pv[1] = &vertexList[1];
pv[2] = &vertexList[2];
for (i=0; i<2; i++)
for (j=i+1; j<3; j++)
{
if ((*pv[i])[1]>(*pv[j])[1] ||
(*pv[i])[1]==(*pv[j])[1] && (*pv[i])[0]>(*pv[j])[0]) {
Coord *tmp;
tmp = pv[i];
pv[i] = pv[j];
pv[j] = tmp;
}
}
;
// all y the same?
if ((*pv[0])[1] == (*pv[2])[1]) {
drawHorizonLine(render, *pv[0], *pv[2]);
return SUCCESS;
}
// assign middle point
Coord mid;
mid[1] = (*pv[1])[1]; // y
float ratio = ((*pv[1])[1] - (*pv[0])[1]) / ((*pv[2])[1] - (*pv[0])[1]);
mid[0] = (*pv[0])[0] + ratio * ((*pv[2])[0] - (*pv[0])[0]); // x
mid[2] = (*pv[0])[2] + ratio * ((*pv[2])[2] - (*pv[0])[2]); // z
if (mid[0]<=(*pv[1])[0]) { // compare X
drawTrapzoid(render, *pv[0], mid, *pv[0], *pv[1]); // upper tri
drawTrapzoid(render, mid, *pv[2], *pv[1], *pv[2]); // lower tri
}else{
drawTrapzoid(render, *pv[0], *pv[1], *pv[0], mid); // upper tri
drawTrapzoid(render, *pv[1], *pv[2], mid, *pv[2]); // lower tri
}
return SUCCESS;
}
break;
}
}
return SUCCESS;
}
Well, since the tag says C++ (even though the code seems to be pure C), the solution would be to put an inline modifier before the function:
inline int putTrianglePosition(Render *render, Coord vertexList[3])
{
...
}
However, even after thinking about this for ten minutes, I still fail a valid reason for wanting this.