I am using OpenGL version 4.2. I am calling a function inside another function in OpenGL fragment shader where the inner function (pix2loc) returns a bool variable as function argument and then the outer function (pix2ang) uses this bool variable to take a decision. More precisely, I have:
void pix2ang (int order_, bool is_nest, int pix, out double theta, out double phi)
{
double z, sth;
bool have_sth;
pix2loc (order_, is_nest, pix, z, phi, sth, have_sth);
if(have_sth)
theta = atan(float(sth),float(z));
else
theta = acos(float(z));
}
where the function pix2loc returns boolean variable have_sth as function argument as follows:
void pix2loc (int order_, bool is_nest, int pix, out double z, out double phi, out double sth, out bool have_sth)
{
.....
if <condition true>
have_sth = true;
else
have_sth = false;
}
I noticed that inside pix2ang have_sth does not work as expected, but if I inverse the if statements and change it to
if(!have_sth)
theta = acos(float(z));
else
theta = atan(float(sth),float(z));
then it works as expected. This makes the code un-reliable and I don't exactly understand what the problem is.
Ok. I decided to write the whole function of pix2loc such that it may help to understand the problem.
void pix2loc (int order_, bool is_nest, int pix, out double z, out double phi, out double sth, out bool have_sth)
{
int nside_ = int(1)<<order_;
int npface_ = nside_<<order_;
int ncap_ = (npface_-nside_)<<1;
int npix_ = 12*npface_;
double fact2_ = 4./npix_;
double fact1_ = (nside_<<1)*fact2_;
have_sth=false;
if (!is_nest)
{
if (pix<ncap_) // North Polar cap
{
int iring = (1+int(isqrt(1+2*pix)))>>1; // counted from North pole
int iphi = (pix+1) - 2*iring*(iring-1);
double tmp=(iring*iring)*fact2_;
z = 1.0 - tmp;
if (z>0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
phi = (iphi-0.5) * halfpi/iring;
}
else if (pix<(npix_-ncap_)) // Equatorial region
{
int nl4 = 4*nside_;
int ip = pix - ncap_;
int tmp = (order_>=0) ? ip>>(order_+2) : ip/nl4;
int iring = tmp + nside_;
int iphi = ip-nl4*tmp+1;
// 1 if iring+nside is odd, 1/2 otherwise
double fodd = bool((iring+nside_)&1) ? 1. : 0.5;
z = (2*nside_-iring)*fact1_;
phi = (iphi-fodd) * pi*0.75*fact1_;
}
else // South Polar cap
{
int ip = npix_ - pix;
int iring = (1+int(isqrt(2*ip-1)))>>1; // counted from South pole
int iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
double tmp=(iring*iring)*fact2_;
z = tmp - 1.0;
if (z<-0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
phi = (iphi-0.5) * halfpi/iring;
}
}
else
{
int face_num, ix, iy;
nest2xyf(order_, pix,ix,iy,face_num);
int jr = (int(jrll[face_num])<<order_) - ix - iy - 1;
int nr;
if (jr<nside_)
{
nr = jr;
double tmp=(nr*nr)*fact2_;
z = 1 - tmp;
if (z>0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
}
else if (jr > 3*nside_)
{
nr = nside_*4-jr;
double tmp=(nr*nr)*fact2_;
z = tmp - 1;
if (z<-0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
}
else
{
nr = nside_;
z = (2*nside_-jr)*fact1_;
}
int tmp=int(jpll[face_num])*nr+ix-iy;
if (tmp<0) tmp+=8*nr;
phi = (nr==nside_) ? 0.75*halfpi*tmp*fact1_ : (0.5*halfpi*tmp)/nr;
}
}
where pi, halfpi, jrll and jpll are constant variable defined in the begining of the fragment shader as
#version 420 core
const double pi = 3.141592653589793;
const double halfpi = 0.5 * pi;
const int jrll[] = { 2,2,2,2,3,3,3,3,4,4,4,4 };
const int jpll[] = { 1,3,5,7,0,2,4,6,1,3,5,7 };
Related
The code starts with declaring various arrays with a size that is pre-calculated, and will be used in the rest of the program. However, after a certain point in the list of declarations, C++ will fail to generate any output even after a successful compilation. After the comment in the middle of the code, no outputs can be generated. I have tried simple outputs like "cout" and writing in a file.
Edit: I have added a sample output written by one of the answers to demonstrate. The program just runs and does not generate anything. This is the terminal output:
"
PS C:\Users\umroot.COLLAR\projects\CrackHole> g++ .\Peridynamics.cpp -o peri
PS C:\Users\umroot.COLLAR\projects\CrackHole> .\peri.exe
PS C:\Users\umroot.COLLAR\projects\CrackHole>
#include <math.h>
#include <iostream>
#include <vector>
#include <string>
#include <conio.h>
// #include "Ellipse.h"
#include <fstream>
using namespace std;
int main () {
float length = 0.5;
float width = 0.5;
float radiusMajor = 0.05;
float radiusMinor = 0.05;
double ellipseCurvature = radiusMinor * radiusMinor / radiusMajor;
float radiusPath = 0.08;
int dt = 1;
const double ELASTIC_MODULUS = 200e9;
const float POISSON_RATIO = 0.3;
const int NumofDiv_x = 100;
const int NumofDiv_y = 100;
int timeInterval = 2500;
const double appliedPressure = 500e7;
int initialTotalNumMatPoint = NumofDiv_x * NumofDiv_y;
int maxFam = 200;
float dx = length / NumofDiv_x;
float delta = 3.015 * dx;
float thick = dx;
float volCorrRadius = dx / 2;
const double SHEAR_MODULUS = ELASTIC_MODULUS / (2 * (1 + POISSON_RATIO));
const double BULK_MODULUS = ELASTIC_MODULUS / (2 * (1 - POISSON_RATIO));
const double ALPHA = 0.5 * (BULK_MODULUS - 2 * SHEAR_MODULUS);
float area = dx * dx;
float volume = area * thick;
const float BCD = 2 / (M_PI * thick * pow(delta, 4));
int temp = floor(9 * M_PI * initialTotalNumMatPoint);
float nodeFam[100000][3] = {0.0};
int nnum = 0;
float coord_excess[initialTotalNumMatPoint][2] = {0.0};
int path_horizontal[NumofDiv_x] = {0};
// Ellipse centerHole(0, 0, radiusMajor, radiusMinor);
// Ellipse leftTip((-1) * radiusMajor, 0, 0.005, 0.005);
// Ellipse rightTip(radiusMajor, 0, 0.005, 0.005);
float coordx = 0.0;
float coordy = 0.0;
int counter = 0;
for (int i = 0; i < NumofDiv_x; i++) {
for (int j = 0; j < NumofDiv_y; j++) {
coordx = (length / 2) * (-1) + (dx / 2) + i * dx;
coordy = (width / 2) * (-1) + (dx/2) + j * dx;
// if (centerHole.InEllipse(coordx, coordy)){
// continue;
// }
if (abs(coordy) <= dx && coordx >= 0) {
path_horizontal[counter] = nnum;
counter++;
}
coord_excess[nnum][0] = coordx;
coord_excess[nnum][1] = coordy;
nnum++;
}
}
int totalNumMatPoint = nnum;
float coord[totalNumMatPoint][2] = {0.0};
for (int j = 0; j < 2; j++ ) {
for (int i = 0; i < totalNumMatPoint; i++) {
coord[i][j] = coord_excess[i][j];
}
}
int numFam[totalNumMatPoint] = {0};
int pointFam[totalNumMatPoint] = {0};
float PDForce[totalNumMatPoint][2] = {0.0};
float bodyForce[totalNumMatPoint][2] = {0.0};
float PDforceold[totalNumMatPoint][2] = {0.0};
float PD_SED_Distortion[totalNumMatPoint][2] = {0.0};
float surCorrFactorDilatation[totalNumMatPoint][2] = {0.0};
float surCorrFactorDistorsion[totalNumMatPoint][2] = {0.0};
float disp[totalNumMatPoint][2] = {0.0};
float totalDisp[totalNumMatPoint][2] = {0.0};
float vel[totalNumMatPoint][2] = {0.0};
// AFTER THIS POINT DOWNWARDS, NO OUTPUTS WILL BE GENERATED
float velhalfold[totalNumMatPoint][2] = {0.0};
float velhalf[totalNumMatPoint][2] = {0.0};
float massvec[totalNumMatPoint][2] = {0.0};
float PD_SED_Dilatation[totalNumMatPoint][2] = {0.0};
float PD_SED_Dilatation_Fixed[totalNumMatPoint][2] = {0.0};
int checkTime[timeInterval] = {0};
float steadyCheck_x[timeInterval] = {0.0};
float steadyCheck_y[timeInterval] = {0.0};
float relPositionVector = 0.0;
for (int j = 0; j < 2; j++ ) {
for (int i = 0; i < totalNumMatPoint; i++) {
coord[i][j] = coord_excess[i][j];
std::cout << coord[i][j] << std::endl;
}
}
Your code, as is, is not "outputting" anything. I compiled and ran your code and added std::cout statements below and above your comment "AFTER THIS POINT DOWNWARDS, NO OUTPUTS WILL BE GENERATED". This successfully writes to stdout.
If, for example, you wanted to output all the values in the coords array you could do something like this while you are building it:
for (int j = 0; j < 2; j++ ) {
for (int i = 0; i < totalNumMatPoint; i++) {
coord[i][j] = coord_excess[i][j];
std::cout << coord[i][j] << std::endl;
}
}
I used another PC with a different OS (i.e. Ubuntu) and it is running fine. Not sure what the problem was. Probably something run with my compiler and/or editor on the first computer.
I have a problem, probably, with memory leaking in C++ threads. I receive a runtime error with code 11. I am writing an optimization algorithm, which aims to optimize parameters of 2D reactors. It generates instances of reforming function, which creates Reformer objects. The reformers have 2 different parameters, which can differ locally in a single reformer and are passed to the reforming function from the main function. To specify, each reformer is divided into a specified number of zones (same dimensions and locations in each reformer), and each zone can have different parameters. Therefore, size of each of 2 vectors is equal to [NUMBER OF REFORMERS] * [NUMBER OF ZONES]. Then, the reforming function creates Segment objects, which number is equal to the number of zones.
I assume that the issue here is that threads try to access the same vector simultaneously and I would really appreciate a solution for that matter.
Remarks:
If I change the main.cpp to substitute the threads with a usual loop, no error is returned.
If I comment out the setProp method in the set_segments functions, no error is returned (with threads).
Threads are highly recommended here, due to long computation time of a single Reformer, and I have an access to a multi-core computing units.
To clarify, I will explain everything with a minimal reproducible example:
input.h
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
int reactor_no = 2; // number of reformers
int zones_X = 5; // number of zones in a single reformer, X direction
int zones_Y = 2; // number of zones in a single reformer, Y direction
double dim_X = 0.5; // reactor's length
double dim_Y = 0.2; // reactor's height
double wall_t = 0.1; // thickness of the reactor wall
size_t zones = zones_X * zones_Y;
Reformer.h:
#include "input.h"
class Reformer {
public:
Reformer() {}
Reformer(const double& L, const double& Y, const double& wall_t,
const int& zones_X = 1, const int& zones_Y = 1) {
length_ = L;
height_ = Y;
zonesX_ = zones_X;
zonesY_ = zones_Y;
wall_thickness_ = wall_t;
dx_ = length_ / static_cast<double> (zonesX_);
dr_ = height_ / static_cast<double> (zonesY_);
}
private:
double wall_thickness_; // wall thickness (m)
double length_; // recactor length (m)
double height_; // reactor height (m) (excluding wall thickness)
int zonesX_; // number of segments in the X direction
int zonesY_; // number of segments in the Y direction
double dx_; // segment width (m)
double dr_; // segment height (m)
}
Segment.h:
#include "input.h"
class Segment{
public:
Segment() : Segment(0, 0) {}
Segment(int i, int j) {
i_ = i;
j_ = j;
}
void setXR(const double& dx, const double& dr, const int& SL, const int& SR) {
x0_ = i_ * dx;
x1_ = x0_ + dx;
r0_ = j_ * dr;
r1_ = r0_ + dr;
if (i_ == SL - 1) {
x1_ = length;
}
if (j_ == SR - 1) {
r1_ = radius;
}
}
void setWall() {
x0_ = 0;
x1_ = length;
r0_ = radius;
r1_ = radius + wall_t;
}
void setProp(const double& por, const double& por_s, const bool& cat) {
porosity_ = por;
catalyst_ = cat;
}
private:
size_t i_; //segment column no.
size_t j_; //segment row no.
double x0_; //beginning of segment - x coordinate (m)
double x1_; //ending of segment - x coordinate (m)
double r0_; //beginning of segment - r coordinate (m)
double r1_; //ending of segment - r coordinate (m)
int catalyst_; //1 - catalytic, 0 - non-catalytic
double porosity_; //porosity (-)
};
main.cpp:
#include "input.h"
int main() {
int zones = zones_X * zones_Y;
size_t pop_size = reactor_no * zones;
std::vector<int> cat;
cat.reserve(pop_size);
std::vector<double> porosity;
porosity.reserve(pop_size); // the values in the vectors are not important, therefore I will just fill them with 1s
for (int i = 0; i < pop_size; i++) {
cat[i] = 1;
porosity[i] = 1.0;
}
std::vector<std::thread> Ref;
Ref.reserve(reactor_no);
for (k = 0; k < reactor_no; k++) {
Ref.emplace_back(reforming, k, cat, porosity);
}
for (auto &X : Ref) { X.join(); }
}
reforming.cpp:
#include "input.h"
void reforming(const int m, const std::vector<int>& cat_check, const std::vector<double>& por) {
Reformer reactor(length, radius, wall_t, zonesX, zonesY);
std::vector<Segment> seg; // vector holding segment objects
seg.reserve(zones);
set_segments(seg, reactor, zones, m, por, por_s, cat_check);
}
set_segments function:
#include "input.h"
void set_segments(std::vector<Segment> &seg, Reformer &reac, const int m,
const std::vector<double> &por, const std::vector<int> &check) {
int i, j, k, n;
double dx = dim_X / static_cast<double> (zones_X);
double dy = dim_Y / static_cast<double> (zones_Y);
std::vector<Segment*> ptr_seg;
ptr_seg.reserve(zones);
k = 0;
for (i = 0; i < zones_X; i++) {
for (j = 0; j < zones_Y; j++) {
n = m * zones + (i * zones_Y + j);
seg.emplace_back(Segment(i, j));
seg[k].setProp(por[n], check[n]);
seg[k].setXR(dx, dy, zones_X, zones_Y);
k++;
}
}
}
Adding std::ref() to the reforming function call parameters solved the problem.
for (k = 0; k < spec_max; k++) {
Ref.emplace_back(reforming, k, std::ref(cat), std::ref(porosity));
}
I have a for loop that looks like this:
for (int i = Particles.size() - 1; i >= 0; i--) {
if (Particles[i].Dead) {
Particles.erase(Particles.begin() + i);
}
}
When I compile, I get this error:
Error C2280 'Particle &Particle::operator =(const Particle &)': attempting to reference a deleted function
Gravity C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xutility 2518
Anyone know what I'm doing wrong? Here's the particle code.
Header file
class Particle
{
public:
const float G = 6.674 * pow(10, -11);
float Mass, Radius;
Vector2 Position, Velocity, Force;
bool Dead = false;
void Gravity(Particle Particle2);
void Move();
void Draw(SDL_Surface *Surface, Uint32 Color);
Particle(float MassBounds[2], Vector2 PositionBounds[2], float Density);
Particle::Particle(float Mass, Vector2 Position, float Density, bool NonRandom);
Particle();
};
Source file
void Particle::Gravity(Particle Particle2)
{
float GravityMagnitude = (Particle::G*Mass*Particle2.Mass) / Vector2::DistanceSquared(Position, Particle2.Position);
Force += (Particle2.Position - Position).Normalised()*GravityMagnitude;
}
void Particle::Move()
{
Velocity += Force/Mass;
Position += Velocity;
}
void Particle::Draw(SDL_Surface *Surface, Uint32 Color)
{
if (int(Radius) > 0) { SDLDrawFilledCircle(Surface, int(Position.x), int(Position.y), Radius<1?1:int(Radius), Color); }
}
Particle::Particle(float MassBounds[2], Vector2 PositionBounds[2], float Density)
{
Mass = RandRange(MassBounds);
Position = Vector2(RandRange(PositionBounds[0].x, PositionBounds[1].x), RandRange(PositionBounds[0].y, PositionBounds[1].y));
Radius = pow((3.0 * Mass) / (4 * M_PI*Density), 1.0 / 3.0);
Velocity = Vector2();
Force = Vector2();
}
Particle::Particle(float Mass, Vector2 Position, float Density, bool NonRandom)
{
this->Mass = Mass;
this->Position = Position;
Radius = pow((3.0 * Mass) / (4 * M_PI*Density), 1.0 / 3.0);
Velocity = Vector2();
Force = Vector2();
}
Particle::Particle()
{
Mass = 1;
Position = Vector2();
Radius = 1;
Velocity = Vector2();
Force = Vector2();
}
inline bool operator==(const Particle& a, const Particle& b) { return a == b; }
You may have better luck using remove_if and erase:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
struct Vector {
int x;
int y;
};
bool is_negative (Vector a) {
return a.x < 0 && a.y < 0;
}
int main() {
vector<Vector> vectors;
vectors.push_back({-1, -2});
vectors.push_back({-1, 2});
vectors.push_back({1, 2});
vectors.push_back({-1, -2});
vectors.erase(
std::remove_if(vectors.begin(), vectors.end(), is_negative),
vectors.end());
for (auto v : vectors) {
cout << v.x << " " << v.y << endl;
}
}
I could not help notice this in your for loop:
Particles.erase(Particles.begin() + i-1)
More importantly
i - 1
You start with
i = Particles.size() - 1
and do not stop until
i < 0
This
Particles.begin()
gives you the head of the list.
When
i == 0
Particles.begin() + (i - 1)
will try to get invalid node.
Which translates to
Particles.begin() - 1
I do not know when your code breaks, I am going based on your loop
Here is link w/doc http://www.cplusplus.com/reference/vector/vector/erase/
Hope this helps
This question already has answers here:
Calling a function in main
(4 answers)
Closed 4 years ago.
So I'm trying to make a simple pool ball simulation, and when trying to check the collision between balls, my bounce function is being skipped in the loop. There should be a display on the console with the random letters in the function bounce in the PoolTable.cpp file, but its skipped and doesn't process the hits or output the text to the console. Not sure why its not running the function. No warnings. No errors. compiles fine. Im on windows machine, using code blocks, and the GLUT library/project.
Walkthrough
So I initialize and place the balls with the constructor. Then I draw the balls on the screen with the drawBalls function. After drawing the balls, i update their positions and move them with moveBalls function. After moving each ball, while still in the moveball function, I check for collisions with checkCollisions function. checkCollisions then starts two for loops, but never runs the bounce function, as the balls don't bounce off eachother, and the cout isn't printed in the terminal. for some reason it is skipped.
PoolTable.cpp
#include "PoolTable.h"
#include "poolball.h"
#include "Graphics.h"
#include <iostream>
using namespace std;
#include <cmath>
PoolTable::PoolTable( int x){
placeBalls( x );
}
void PoolTable::placeBalls( int x ){
number_of_balls = x;
for( int i = 0; i < x; i++){
balls[i].setX( balls[i].getRadius() + i * 20 );
balls[i].setY( balls[i].getRadius() + i * 30 );
}
}
double find_angle(double vx, double vy) {
// determine the angle between poolballs when they collide
double t; double PI = acos(-1.0);
if(vx < 0) // vertical collision
t = PI + atan(vy/vx);
else if(vx > 0.0 && vy >= 0.0) // 1st quardant collision
t = atan(vy/vx);
else if(vx > 0.0 && vy < 0.0) //
t = 2.0*PI + atan(vy/vx);
else if( vx == 0.0 && vy == 0.0)
t = 0.0;
else if(vx == 0 && vy >= 0.0)
t = PI/2.0;
else
t = 1.5 * PI;
return t;
}
void PoolTable::bounce(int i, int j) {
cout << "klasdjflkadsjflkasjfsadk" << endl;
double PI = acos(-1.0);
double x1 = balls[i].getX();
double y1 = balls[i].getY();
double x2 = balls[j].getX();
double y2 = balls[j].getY();
double dx = x2 - x1;
double dy = y2 - y1;
double dist = sqrt(dx*dx+dy*dy);
// did a collision occur
if(dist <= 2 * balls[i].getRadius()) {
double phi; // angle between the two ball centers
if(dx == 0.0)
phi = PI/2.0;
else
phi = atan2 (dy, dx);
// now compute the total velocities of the two balls
double vx1 = balls[i].xSpeed;
double vy1 = balls[i].getYSpeed();
double v1total = sqrt(vx1*vx1 + vy1*vy1);
double vx2 = balls[j].getXSpeed();
double vy2 = balls[j].getYSpeed();
double v2total = sqrt(vx2*vx2 + vy2*vy2);
// find the angle of each ball's velocity
double ang1 = find_angle(vx1,vy1);
double ang2 = find_angle(vx2,vy2);
// transform velocities into normal.tangential components
double v1xr = v1total * cos(ang1 - phi);
double v1yr = v1total * sin(ang1 - phi);
double v2xr = v2total * cos(ang2 - phi);
double v2yr = v2total * sin(ang2 - phi);
// now find the final velocities (assuming equal mass)
double v1fxr = v2xr;
double v2fxr = v1xr;
double v1fyr = v1yr;
double v2fyr = v2yr;
// reset the velocities
balls[i].setXSpeed(cos(phi)*v1fxr + cos(phi+PI/2)*v1fyr);
balls[i].setYSpeed(sin(phi)*v1fxr + sin(phi+PI/2)*v1fyr);
balls[j].setXSpeed(cos(phi)*v2fxr + cos(phi+PI/2)*v2fyr);
balls[j].setYSpeed(sin(phi)*v2fxr + sin(phi+PI/2)*v2fyr);
}
}
void PoolTable::checkCollisions(void){
for( int i = 0; i < number_of_balls; i++){
for( int j = i + 1; j < number_of_balls; j++){
bounce(i, j);
}
}
}
void PoolTable::moveBalls(void){
for( int i = 0; i < number_of_balls; i++){
balls[i].move();
void checkCollisions();
}
}
void PoolTable::drawBalls(void){
for( int i = 0; i < number_of_balls; i++){
balls[i].draw();
}
}
void checkCollisions(); (in moveBalls) is a function prototype, not a function call. Remove the void.
I've created a Perlin noise function. My issue is when I generate a terrain map from the noise it ends up blocky, nothing like the cloudlike images I've seen. I'm curious on what I'm doing wrong (if anything).
here's my code:
main.cpp
#include "PerlinNoise.h"
#include <stdio.h>
#include <SDL/SDL.h>
void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B);
SDL_Surface *Render_Noise(int w, int h, int r, int g, int b);
PerlinNoise noiseGen(2,.5,25);
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface *screen = SDL_SetVideoMode(500,500,32,SDL_SWSURFACE);
SDL_Surface *noise = Render_Noise(500,500,255,255,255);
SDL_SaveBMP(noise, "noise.bmp");
bool quit = false;
while(!quit)
{
SDL_Event e;
SDL_WaitEvent(&e);
switch(e.type)
{
case SDL_QUIT:
quit = true;
}
SDL_BlitSurface(noise,NULL,screen,NULL);
SDL_Flip(screen);
SDL_Delay(2000);
}
SDL_FreeSurface(noise);
SDL_Quit();
return 0;
}
void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
if(SDL_MUSTLOCK(screen))
{
if(SDL_LockSurface(screen) < 0)
{
return;
}
}
switch(screen->format->BytesPerPixel)
{
case 1:
{
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*bufp = color;
}
break;
case 2:
{
Uint16 *bufp;
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
*bufp = color;
}
break;
case 3:
{
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*(bufp+screen->format->Rshift/8) = R;
*(bufp+screen->format->Bshift/8) = B;
*(bufp+screen->format->Gshift/8) = G;
}
break;
case 4:
{
Uint32 *bufp;
bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
*bufp = color;
}
break;
}
if(SDL_MUSTLOCK(screen))
{
SDL_UnlockSurface(screen);
}
SDL_UpdateRect(screen, x, y, 1, 1);
}
SDL_Surface *Render_Noise(int w, int h, int r, int g, int b)
{
SDL_Surface *ret = SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,32,0,0,0,0); //create an empty image
for(int y = 0; y < h; y++)
{
for(int x = 0; x < w; x++)
{
double getnoise = 0;
for(int a = 0; a < noiseGen.n; a++)
{
getnoise += noiseGen.generateNoise(x,y);
noiseGen.z = rand() % 100;
}
getnoise / noiseGen.n;
int color = (int)((getnoise * 128.0) + 128.0); //convert noise to 0-256 value
if (color > 255)
color = 255;
if (color < 0)
color = 0;
DrawPixel( ret, x, y, (int)((r/255.0) * (double)color), (int)((g/255.0) * (double)color), (int)((b/255.0) * (double)color) );
}
}
return ret;
}
perlinnoise.cpp
#include "PerlinNoise.h"
PerlinNoise::PerlinNoise(int octaves, double persistence, int zoom)
{
p = persistence;
n = octaves - 1;
z = zoom;
}
PerlinNoise::~PerlinNoise()
{
}
///<summary>Gets a random number using x and y as seeds </summary>
///<param name = x> A double value </param>
///<param name = y> A double value </param>
///<returns> A random number between -1.0 and 1.0 </returns>
inline double PerlinNoise::noise(double x, double y)
{
int n = x + y * 57;
n = (n << 13) ^ n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
///<summary> Smooths out noise values </summary>
///<param name = x> a double value </param>
///<param name = y> a double value </param>
///<returns> a smoothed value between -1.0 and 1.0 </returns>
double PerlinNoise::smoothNoise(double x, double y)
{
double corners = (noise(x+1, y+1) + noise(x+1,y-1) + noise(x-1,y+1) + noise(x-1,y-1)) / 16;
double sides = (noise(x,y+1) + noise(x,y-1) + noise(x+1,y) + noise(x-1,y)) / 8;
double center = noise(x,y) / 4;
return corners + sides + center;
}
///<summary> Cosine Interpolation </summary>
///<param name = a> The low value to be interpolated </param>
///<param name = b> The high value to be interpolated </param>
///<param name = x> A value between -1.0 and 1.0 </param>
///<returns> Interpolated value between a and b </returns>
double PerlinNoise::cosineInterpolation(double a, double b, double x)
{
double ft = x * 3.1415927;
double f = (1.0 - cos(ft)) * .5;
return a * (1.0 - f) + b * f;
}
///<summary> Gets smoothed noise values and interpolates them </summary>
///<param name = x> a double value </param>
///<param name = y> a double value </param>
///<returns> a value between -1 and 1 that's been smoothed and interpolated </returns>
double PerlinNoise::interpolatedNoise(double x, double y)
{
double integer_x = (int)x;
double fractional_x = x - integer_x;
double integer_y = (int)y;
double fractional_y = y - integer_y;
double v1 = smoothNoise(integer_x, integer_y);
double v2 = smoothNoise(integer_x + 1, integer_y);
double v3 = smoothNoise(integer_x, integer_y + 1);
double v4 = smoothNoise(integer_x + 1, integer_y + 1);
double inter1 = cosineInterpolation(v1, v2, fractional_x);
double inter2 = cosineInterpolation(v3, v4, fractional_x);
return cosineInterpolation(inter1, inter2, fractional_y);
}
double PerlinNoise::generateNoise(double x, double y)
{
double total = 0;
for(int i = 0; i < n; i++)
{
frequency = pow(2.0,i);
amplitude = pow(p,i);
total = total + interpolatedNoise(x * frequency / z, y * frequency / z) * amplitude;
}
return total;
}
Found the problem, my persistence was much lower than it should be, upping that I got the cloudlike image I expected