Issue with drawn object speeding up in a loop - c++

So I have an assignment where I have to get bugs to draw to the screen (no problem) and then shoot off from the bugbag drawn at the bottom of the screen (also no problem). However, my issue is that when the code loops, the speed picks up for some reason and everything I've tried to move around to fix the issue has proved fruitless. I either get it to slow was day (but not loop through the amount taken in) or nothing changes. Here is a code snippet from where the loop resides, I can provide more if need be, but I'm positive the problem stems from this method.
Point2D creatureThrow(Creature& myCreature, BugBag& theBag)
{
//Added for creature
Point2D creatureLocation = Point2D(CREATURE_DRAW_LEFT, 0);
int startingBugCount = theBag.getBugCount();
//std::vector<Bug> deadBugs(startingBugCount);
//Create bug
Bug* bug = new Bug();
// Display all the bugs
for (int bugNumber = 1; bugNumber <= startingBugCount; bugNumber++)
{
bug->moveTo(0, -90);
for (int step = 0; step < BUG_STEP_SIZE; step++) // 20 is the number of steps
{
gdsWindow.clear();
for (int j=0; j < bugNumber; j++) //move bugs
{
//bug->draw();
bug->moveBy(0, 8);
}
myCreature.draw();
theBag.draw();
bug->draw();
Sleep(FRAME_SLEEP);
}
}
return creatureLocation;
}

Related

How to create a Minecraft chunk in opengl?

I'm learning OpenGL and I have tried to make a voxel game like Minecraft. In the beginning, everything was good. I created a CubeRenderer class to render a cube with its position. The below picture is what I have done.
https://imgur.com/yqn783x
And then I got a serious problem when I try to create a large terrain, I hit a slowing performance. It was very slow and fps just around 15fps, I thought.
Next, I figured out Minecraft chunk and culling face algorithm can solve slowing performance by dividing the world map into small pieces like chunk and just rendering visible faces of a cube. So how to create a chunk in the right way and how the culling face algorithm is applied in Chunk?
So far, that is what I have tried
I read about Chunk in Minecraft at https://minecraft.gamepedia.com/Chunk
I created a demo Chunk by this below code (it is not the completed code because I removed it out)
I created a CubeData that contains cube position and cube type.
And I call the GenerateTerrain function to make a simple chunk data (16x16x16) like below (CHUNK_SIZE is 16)
for (int x = 0; x < CHUNK_SIZE; x++) {
for (int y = 0; y < CHUNK_SIZE; y++) {
for (int z = 0; z < CHUNK_SIZE; z++) {
CubeType cubeType = { GRASS_BLOCK };
Location cubeLocation = { x, y, z };
CubeData cubeData = { cubeLocation, cubeType };
this->Cubes[x][y][z] = cubeData;
}
}
}
After that, I had a boolean array which is called "mask" contains two values are 0 (not visible) or 1 (visible) and matches with their cube data. And then I call Render function of Chunk class to render a chunk. This code below like what I have done (but it is not complete code because I removed that code and replaced with new code)
for (int x = 0; x < CHUNK_SIZE; x++) {
for (int y = 0; y < CHUNK_SIZE; y++) {
for (int z = 0; z < CHUNK_SIZE; z++) {
for(int side = 0; side < 6;side++){
if(this->mask[x][y][z][side] == true) cubeRenderer.Render(cubeData[x][y][z]);
}
}
}
}
But the result I got that everything still slow (but it is better than the first fps, from 15fps up to 25-30fps, maybe)
I guess it is not gpu problem, it is a cpu problem because there is too many loops in render call.
So I have kept research because I think my approach was wrong. There may have some right way to create a chunk, right?
So I found the solution that puts every visible verticle to one VBO. So I just have to call and bind VBO definitely one time.
So this below code show what I have tried
cout << "Generating Terrain..." << endl;
for (int side = 0; side < 6; side++) {
for (int x = 0; x < CHUNK_SIZE; x++) {
for (int y = 0; y < CHUNK_SIZE; y++) {
for (int z = 0; z < CHUNK_SIZE; z++) {
if (this->isVisibleSide(x, y, z, side) == true) {
this->cubeRenderer.AddVerticleToVBO(this->getCubeSide(side), glm::vec3(x, y, z), this->getTexCoord(this->Cubes[x][y][z].cubeType, side));
}
}
}
}
}
this->cubeRenderer.GenerateVBO();
And call render one time at all.
void CubeChunk::Update()
{
this->cubeRenderer.Render(); // with VBO data have already init above
}
And I got this:
https://imgur.com/YqsrtPP
I think my way was wrong.
So what should I do to create a chunk? Any suggestion?

SFML createMaskFromColor() not working correctly

I'm creating a game where I have 3 separate objects to display. A floor, a player sprite and multiple crates. Below is the code for all three.
#include <iostream>
#include <fstream>
#include "Game.h"
Game::Game()
{
std::ifstream fileHndl;
fileHndl.open("Assets/mapdata.txt");
fileHndl >> mapCols;
fileHndl >> mapRows;
playerX = mapCols / 2;
playerY = mapRows / 2;
mapData = new int *[mapRows];
for (int i = 0; i < mapRows; i++) {
mapData[i] = new int[mapCols];
}
for (int i = 0; i < mapRows; i++) {
for (int j = 0; j < mapCols; j++) {
fileHndl >> mapData[i][j];
}
}
window.create(sf::VideoMode(1280, 1024), "COMP2501 Demo");
window.setFramerateLimit(5);
playerImage.loadFromFile("Assets/actor.png");
playerImage.createMaskFromColor(sf::Color::White);
playerTexture.loadFromImage(playerImage);
playerTexture.setSmooth(true);
playerSprite.setTexture(this->playerTexture);
floorTexture.loadFromFile("Assets/floor.png");
floorTexture.setSmooth(true);
crateImage.loadFromFile("Assets/crate.png");
crateImage.createMaskFromColor(sf::Color::White);
crateTexture.loadFromImage(crateImage);
crateTexture.setSmooth(true);
mapSprites = new sf::Sprite *[mapRows];
for (int i = 0; i < mapRows; i++) {
mapSprites[i] = new sf::Sprite[mapCols];
}
for (int i = 0; i < mapRows; i++)
{
for (int j = 0; j < mapCols; j++)
{
mapSprites[i][j].setPosition(j * 64, i * 64);
if (mapData[i][j] == 1)
{
mapSprites[i][j].setTexture(this->floorTexture);
}
else
{
mapSprites[i][j].setTexture(this->crateTexture);
}
}
}
}
I'm attempting to remove the white background of all 3 images as they're all .pngs however when doing so I get the following result.
http://i.stack.imgur.com/KG3H2.png
The crates appear to be drawing a black border around themselves. Is there a better way to go about removing the white background on PNGs as textures?
Crate
http://i.stack.imgur.com/DA5Dv.png
In the absence of additional information, this would be my logical chain towards a guess:
Since we see the createMaskFromColor() function work fine for the player model, it's not the error source. Since we see the same code being invoked for the other two objects, the chroma keying is working fine there as well. Hence, the following answer:
There is nothing but the black background behind the crate sprites. The chroma keying works correctly, and happily demonstrates us the black background behind the transparent corners.
How to fix:
Make sure the floor sprite is present behind the crate sprites as well. Maybe create an additional sprite, "crate over a floor", to not overlay them every time such a combination is encountered (no idea if this really affects performance, just a guess.)

Time step independence of Molecular Dynamics code

I am writing a basic MD code in C++ using LJ potential for an NVE system. The starting configuration is FCC and the starting velocities are randomly generated.
I am facing a strange problem in that the evolution of the system seems to be independent of the time step I implement, it is my understanding that the energy losses are smaller for small time steps and larger for larger time steps. However I am getting the same result at the end of the simulation in terms of energy whether I run (0.0001step)*(10000steps) or 0.001*1000 and so on.
The entire code is to big for me to post here, so I am posting what I think is relevant and leaving out binning etc., kindly let me know if any additional information is required. I have been through countless codes available online and though they look similar to mine I just am not able to figure out what the difference is and where I am going wrong.
The main cpp contains the following loop
for (int i=0; i<t;i++)
{
potential_calc(neighlist,fromfile, run_parameters,i);//calculating the force fields
velverlet(neighlist,fromfile, run_parameters, bin, dt);//calculating the velocities
}
The declarations of the 2 cpp files for potential calculation & verlet integration are
void potential_calc(neighborlist_type *neighlist, config_type *fromfile, potential *run_parameters, int t)
void velverlet(neighborlist_type *neighlist, config_type *fromfile, potential *run_parameters, bin_type *bin, double dt)
The code for calculating the force - potential_calc.cpp is below
for (long i=0; i<fromfile->N; i++)
{
long atom_p=i;
for (long j=0; j<neighlist[i].countsn; j++)
{
long atom_s=neighlist[i].numb[j];
for (int k=0; k<Dim; k++)
{
dist[k]= fromfile->r[atom_p][k] - (fromfile->r[atom_s][k] + neighlist[atom_p].xyz[j][k]*fromfile->L[k]);
//the .xyz indicates the image being considered real or mirror(if mirror then in which direction)
}
disp2 = pow(dist[0],2)+pow(dist[1],2)+pow(dist[2],2);
if (disp2<rb2)
{
int c1=fromfile->c[atom_p];
int c2=fromfile->c[atom_s];
double long force_temp;
disp=pow(disp2,0.5);
sig_r6=pow(run_parameters->sigma[c1-1][c2-1]/disp,6);//(sigma/r)^6
sig_r8=pow(run_parameters->sigma[c1-1][c2-1]/disp,8);//(sigma/r)^8
run_parameters->pe[atom_p] += (4*run_parameters->epsilon[c1-1][c2-1]*((sig_r6*sig_r6)-sig_r6)) - potential_correction[c1-1][c2-1];
force_temp=(-1*((48*run_parameters->epsilon[c1-1][c2-1])/pow(run_parameters->sigma[c1-1][c2-1],2)*((sig_r6*sig_r8)-((sig_r8)*0.5))));
for (int k=0; k<Dim;k++)
{
run_parameters->force[atom_p][k]+=force_temp*(-1*dist[k]);
}
}
}
//calculating kinetic energy
run_parameters->ke[atom_p] = 0.5*(pow(fromfile->v[atom_p][0],2)+pow(fromfile->v[atom_p][1],2)+pow(fromfile->v[atom_p][2],2));
}
Once the force calculation is done it goes to the updation of velocity and position in the velverlet.cpp
for (long i=0; i<fromfile->N; i++)
{
for (int j=0; j<Dim; j++)
{
fromfile->v[i][j] += (dt*run_parameters->force[i][j]);
}
}
for (long i=0; i<fromfile->N; i++)
{
for (int j=0; j<Dim; j++)
{
fromfile->r[i][j] += dt*fromfile->v[i][j];
}
}
There may be slight differences in how velocity verlet is implemented by different people but I can't figure out how I am getting time step independent results.
Please help. Any input is appreciated
Sorry if any formatting/tagging is wrong, this is the first time I am posting here

SFML 2.0 c++ sprite in array/vector

I have this in my file blocks.h:
#include <vector>
class Blocks{
public:
string files_name[4];
vector < Sprite > sprites;
void load(){
for(int i=0;i<=sizeof(files_name);i++){
Texture my_texture;
my_texture.loadFromFile(this->files_name[i]);
sprites[i].setTexture( my_texture );
}
}
Blocks(){
this->files_name[0] = "wall.png";
this->files_name[1] = "floor.png";
this->files_name[2] = "live.png";
this->files_name[3] = "coins.png";
this->load();
}
void show(int id, int X, int Y){
sprites[id].setPosition(X, Y);
window.draw(sprites[id]);
}
};
I have no errors, but my game crashed. I think, the problem is in the line which reads sprites[i].setTexture(...)
I only have the message: Process terminated with status -1073741819 (0 minutes, 2 seconds)
My IDE is Code::Blocks 10.05, and I have Windows 8.
Of course, in the file main.cpp, I have defined the window:
RenderWindow window( VideoMode(920, 640, 32 ), "Game" );
#include "blocks.h"
Blocks BLOCKS;
----UPDATE:
Ok, now it's not crashing, thanks! But, now I can't see textures! I read the post by Benjamin Lindley and I added a new vector with textures. My code looks like this now:
const int arraySize = 4;
string files_name[4];
vector < Sprite > sprites;
vector < Texture > textures;
and, in load(), I have:
for(int i = 0; i < arraySize; i++){
Texture new_texture;
new_texture.loadFromFile(this->files_name[i]);
textures.push_back(new_texture);
sprites[i].setTexture(textures[i]);
and then it crashes again!
---UPDATE: Now I have again changed my code and I don't have a crash, but my textures are white squares. My texture live.png works, but the other textures are white! Here's my new code:
Sprite new_sprite;
new_sprite.setTexture(textures[i]);
sprites.push_back(new_sprite);
The problem is this line:
for(int i=0;i<=sizeof(files_name);i++){
If you print out the value of sizeof(files_name), you will find that it is 16 instead of 4! Don't use sizeof here. Also, don't use <= here, since even if you had replaced sizeof(files_name) with 4, you would have tried to access files_name[4], which would also give you an error.
Instead you could use:
const int arraySize = 4;
string files_name[arraySize];
...
for(int i = 0; i < arraySize; i++)
or something of that sort.
Also, hopefully you initialize sprites at some point. You need to fill your vector with Sprites (with something like sprites.push_back(mySprite)) before you call load().
SFML sprites store their associated textures by pointer. The textures you are creating are local to the loop, and so are destroyed at the end of each iteration, thereby invalidating the pointer in the sprite. You need to keep your textures alive for the duration of whatever sprite uses them.
Also, your sprites vector has no elements, you need to either specify a size, or use push_back in your loop.
Also, as Scott pointed out, sizeof(files_name) is not the appropriate terminating value for your loop, since that gives you sizeof(string) * number of elements in the array. You only want the number of elements in the array.
Ok, it works only in two loop: Thanks for helping :)
vector < Sprite > sprites;
vector < Texture > tekstures;
and:
for(int i = 0; i < arraySize; i++){
Texture new_texture;
new_texture.loadFromFile(this->files_name[i]);
tekstures.push_back(new_texture);
}
for(int i = 0; i < arraySize; i++){
Sprite new_sprite;
new_sprite.setTexture(tekstures[i]);
sprites.push_back(new_sprite);
}
and in one loop it doesn't work, i have white textures:
for(int i = 0; i < arraySize; i++){
Texture new_texture;
new_texture.loadFromFile(this->files_name[i]);
tekstures.push_back(new_texture);
Sprite new_sprite;
new_sprite.setTexture(tekstures[i]);
sprites.push_back(new_sprite);
}
Greetings !

xna 4.0 perparing for multiple collision detection with list

I have a List of objects of which all have a bounding rectangle updated everytime... How can I effectively iterate among them ? I thought that checking it like this is fine but any ideas ?
for (int i = 0; i < birds.Count; i++)
{
for (int j = 0; j < birds.Count; j++)
{
if (j > i)
{
if (birds[j].boundingRectangle.Intersects(birds[i].boundingRectangle))
{
birds[i].tintColor = Color.Yellow;
birds[j].tintColor = Color.Yellow;
}
else
{
birds[i].tintColor = Color.White;
birds[j].tintColor = Color.White;
}
}
}
}
I can't see there why it would fail to detect the collision, the code seems to be ok. You should output some string showing the values of the bounding rectangles to see if they're properly set, or if you are executing that code at all, or if your "birds" array survives the scope in where this code is executed (you may be modifying a copy instead of the actual array).
As for improvements, you can do:
for (int j = i+1; j < birds.Count; j++)
and then you can remove the if (j > i) (j will always be > i).
Other thing that I would recommend is not declaring int j in the for statement. It's always better to having it declared outside than instancing on every i, so:
int i, j;
for (i = 0; i < birds.Count; i++)
for (j = i+1; j < birds.Count; j++)
I don't think there is much more room for improvement there without being able to use pointers. Your method is fine for 2D graphics anyway, unless you're checking for hundreds of objects.
PS: I believe your question could fit in the Game Development - SE site (unless you're using XNA and bounding boxes for something else :P)
Your problem is that when comparing rectangles you set the bird to white, even if it was previously set to yellow by a previous hit detection, so it may have been set to yellow, but it'll be set back again if the last test fails.
How about at the start of each frame (before collision detection) set the rectangles to white then if you get a collision set them to yellow (leaving them alone if there's no collision).