OpenGL: Bezier surface with triangulation - c++

I tried to draw Bezier surface using OpenGL. My program reads an input file with number of sample points for plot, control points and color palette for surface coloring. It must output a new window with surface plot where I can manipulate properties of surface and control points.
Points generated from Bernstein polynomial are triangulated and assigned a color by color palette by mapping it from minimum and maximum height of triangles.
When I execute it, one row of triangles is assigned with a wrong color. I thought that I have an error in one of my loops but changing values proved nothing.
Here is the code:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cmath>
using namespace std;
struct vertex
{
float x;
float y;
float z;
};
struct RGB
{
float r;
float g;
float b;
};
int main_window;
bool TM = true;
vertex surfaceTranslate;
float surfaceRotate = 0;
vertex camera;
vertex up;
int currentPointX = 0, currentPointY = 0;
vertex toY;
int SampleR, SampleC;
int M, N;
int K;
vector < vector <vertex> > points;
vector <RGB> palette;
vector < vector <vertex> > control;
float minH, maxH;
int fact (int n)
{
if (!n || n == 1)
{
return 1;
}
return n * fact (n - 1);
}
int C (int n, int i)
{
return fact (n) / (fact (i) * fact (n - i));
}
void initialDisplay(void)
{
glClearColor (1.0, 1.0, 1.0, 1.0);
glDisable (GL_LIGHTING);
glEnable (GL_RESCALE_NORMAL);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, 1, 1, 1000000);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
void updateControl()
{
control.clear();
for (int i = 0; i < SampleR; ++i)
{
vector <vertex> temp;
for (int j = 0; j < SampleC; ++j)
{
float u = (float)(i) / (SampleR - 1);
float v = (float)(j) / (SampleC - 1);
vertex p;
p.x = p.y = p.z = 0;
for (int k = 0; k < M; ++k)
{
for (int m = 0; m < N; ++m)
{
float B_u = C (M - 1, k) * pow (u, k) * pow (1 - u, M - 1 - k);
float B_v = C (N - 1, m) * pow (v, m) * pow (1 - v, N - 1 - m);
p.x += B_u * B_v * points[k][m].x;
p.y += B_u * B_v * points[k][m].y;
p.z += B_u * B_v * points[k][m].z;
}
}
temp.push_back (p);
}
control.push_back (temp);
}
maxH = 1 << ((sizeof(float) * 8) - 1);
minH = -maxH;
for (int i = 0; i < SampleR - 1; ++i)
{
for (int j = 0; j < SampleC - 1; ++j)
{
float h = (control[i][j].y + control[i + 1][j].y + control[i][j + 1].y) / 3;
if (h > maxH)
{
maxH = h;
}
if (h < minH)
{
minH = h;
}
h = (control[i + 1][j].y + control[i][j + 1].y + control[i + 1][j + 1].y) / 3;
if (h > maxH)
{
maxH = h;
}
if (h < minH)
{
minH = h;
}
}
}
for (int i = 0; i < SampleR; ++i)
{
for (int j = 0; j < SampleC; ++j)
{
toY.x += control[i][j].x;
toY.z += control[i][j].z;
}
toY.x /= SampleR * SampleC;
toY.z /= SampleR * SampleC;
}
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt (camera.x, camera.y, camera.z, 0, 0, 0, up.x, up.y, up.z);
glTranslatef (surfaceTranslate.x, surfaceTranslate.y, surfaceTranslate.z);
glTranslatef (toY.x, toY.y, toY.z);
glRotatef (surfaceRotate, 0, 1, 0);
glTranslatef (- toY.x, -toY.y, -toY.z);
if (!TM)
{
glPointSize (10);
glBegin (GL_POINTS);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
if (i == currentPointX && j == currentPointY)
{
glColor3f (1.0, 0.0, 0.0);
}
else
{
glColor3f (0.0, 0.0, 1.0);
}
glVertex3f (points[i][j].x, points[i][j].y, points[i][j].z);
}
}
glEnd();
}
glBegin (GL_TRIANGLES);
for (int i = 0; i < SampleR - 1; ++i)
{
for (int j = 0; j < SampleC - 1; ++j)
{
glVertex3f (control[i][j].x, control[i][j].y, control[i][j].z);
glVertex3f (control[i + 1][j].x, control[i + 1][j].y, control[i + 1][j].z);
glVertex3f (control[i][j + 1].x, control[i][j + 1].y, control[i][j + 1].z);
float h = (control[i][j].y + control[i + 1][j].y + control[i][j + 1].y) / 3;
int index = K * (h - minH) / (maxH - minH);
glColor3f (palette[index].r / 255, palette[index].g / 255, palette[index].b / 255);
glVertex3f (control[i + 1][j].x, control[i + 1][j].y, control[i + 1][j].z);
glVertex3f (control[i][j + 1].x, control[i][j + 1].y, control[i][j + 1].z);
glVertex3f (control[i + 1][j + 1].x, control[i + 1][j + 1].y, control[i + 1][j + 1].z);
h = (control[i + 1][j].y + control[i][j + 1].y + control[i + 1][j + 1].y) / 3;
index = K * (h - minH) / (maxH - minH);
glColor3f (palette[index].r / 255, palette[index].g / 255, palette[index].b / 255);
}
}
glEnd();
glutSwapBuffers();
}
void keyboardEvent (unsigned char key, int x, int y)
{
if (TM)
{
switch (key)
{
case ('2'):
TM = false;
glutSetWindowTitle ("Surface Editing Mode");
break;
case ('q'):
--surfaceTranslate.x;
break;
case ('w'):
++surfaceTranslate.x;
break;
case ('a'):
--surfaceTranslate.y;
break;
case ('s'):
++surfaceTranslate.y;
break;
case ('z'):
--surfaceTranslate.z;
break;
case ('x'):
++surfaceTranslate.z;
break;
case ('r'):
++surfaceRotate;
break;
case ('t'):
--surfaceRotate;
break;
}
}
else
{
switch (key)
{
case ('1'):
TM = true;
glutSetWindowTitle ("Transformation Mode");
break;
case ('q'):
--points[currentPointX][currentPointY].x;
updateControl();
break;
case ('w'):
++points[currentPointX][currentPointY].x;
updateControl();
break;
case ('a'):
--points[currentPointX][currentPointY].y;
updateControl();
break;
case ('s'):
++points[currentPointX][currentPointY].y;
updateControl();
break;
case ('z'):
--points[currentPointX][currentPointY].z;
updateControl();
break;
case ('x'):
++points[currentPointX][currentPointY].z;
updateControl();
break;
case ('i'):
if (!(SampleR % 2))
{
SampleR /= 2;
updateControl();
}
break;
case ('o'):
SampleR *= 2;
updateControl();
break;
case ('k'):
if (!(SampleC % 2))
{
SampleC /= 2;
updateControl();
}
break;
case ('l'):
SampleC *= 2;
updateControl();
break;
}
}
glutPostRedisplay();
}
void arrowKeys (int key, int x, int y)
{
if (!TM)
{
switch (key)
{
case (GLUT_KEY_UP):
if (currentPointY < N - 1)
{
++currentPointY;
}
break;
case (GLUT_KEY_DOWN):
if (currentPointY)
{
--currentPointY;
}
break;
case (GLUT_KEY_LEFT):
if (currentPointX)
{
--currentPointX;
}
break;
case (GLUT_KEY_RIGHT):
if (currentPointX < M - 1)
{
++currentPointX;
}
break;
}
glutPostRedisplay();
}
}
void changeDirection (int x, int y)
{
float dist = sqrt (pow (camera.x, 2) + pow (camera.y, 2) + pow (camera.z, 2));
camera.x = dist * sin (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532);
camera.y = dist * cos (360.0 / 800 * y * 0.0174532);
camera.z = dist * cos (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532);
up.x = dist * sin (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532 - 1) - camera.x;
up.y = dist * cos (360.0 / 800 * y * 0.0174532 - 1) - camera.y;
up.z = dist * cos (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532 - 1) - camera.z;
glutPostRedisplay();
}
void mouseEvent (int key, int state, int x, int y)
{
if (key == GLUT_KEY_LEFT)
{
changeDirection (x, y);
}
}
void readFile (char *fname)
{
ifstream file (fname);
if (file.is_open())
{
file >> SampleR >> SampleC;
file >> M >> N;
for (int i = 0; i < M; ++i)
{
vector <vertex> tempv;
for (int j = 0; j < N; ++j)
{
vertex temp;
file >> temp.x >> temp.y >> temp.z;
tempv.push_back (temp);
}
points.push_back (tempv);
}
file >> K;
for (int i = 0; i < K; ++i)
{
RGB temp;
file >> temp.r >> temp.g >> temp.b;
palette.push_back (temp);
}
}
file.close();
}
int main (int argc, char *argv[])
{
surfaceTranslate.x = surfaceTranslate.y = surfaceTranslate.z = toY.x = toY.y = toY.z = up.x = up.z = 0;
up.y = 1;
camera.x = camera.y = camera.z = 100;
readFile (argv[1]);
updateControl();
glutInit (&argc,argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition (50, 50);
glutInitWindowSize (800, 800);
main_window = glutCreateWindow ("Transformation Mode");
glutDisplayFunc (display);
glutKeyboardFunc (keyboardEvent);
glutSpecialFunc (arrowKeys);
glutMouseFunc (mouseEvent);
glutMotionFunc (changeDirection);
initialDisplay();
glutMainLoop();
}

Two things are problematic in display():
glColor3f should be called before the calls to glVertex3f to color them
your palette index calculation is wrong when h == maxH, it makes an out of bounds access
When h == maxH, (h - minH)/(maxH - minH) equals 1.0f, which means the line:
index = K * (h - minH) / (maxH - minH);
simplifies into:
index = K;
and K is the size of the palette. An easy fix would be to add a call to min(), like that:
index = min(K-1, K * (h - minH) / (maxH - minH));

Related

Reflection model does not work correctly in OpenGl using glColor3f

I have a depth map as 2D double array 480x640. I visualize it using openGL using glBegin(GL_TRIANGLES).
This is my code, it works correctly:
int main(int argc, char** argv){
ifstream ifs("D:\\DepthMaps1-20\\DepthMap_1.dat", std::ios::binary);
if (ifs) {
double dheight, dwidth;
ifs.read(reinterpret_cast<char*>(&dheight), sizeof dheight);
ifs.read(reinterpret_cast<char*>(&dwidth), sizeof dwidth);
height = static_cast<size_t>(dheight);
width = static_cast<size_t>(dwidth);
vector<vector<double>> dmap(height, vector<double>(width));
for (auto& row : dmap) {
for (double& col : row)
ifs.read(reinterpret_cast<char*>(&col), sizeof col);
}
double fx = 525.0;
double fy = 525.0; // default focal length
double cx = 319.5;
double cy = 239.5; // default optical center
vector<vector<double>> x(height, vector<double>(width));
vector<vector<double>> y(height, vector<double>(width));
vector<vector<double>> z(height, vector<double>(width));
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
z[i][j] = dmap[i][j] / 500.0;
x[i][j] = (j - cx) * z[i][j] / fx;
y[i][j] = (i - cy) * z[i][j] / fy;
}
}
GLFWwindow * window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(640, 640, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glColor3f(189.0/255.0, 140.0 / 255.0, 194.0 / 255.0);
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
if (j < dmap[i].size() - 2 && i < dmap.size() - 2)
{
if (z[i][j] != 0 && z[i][j + 1] != 0 && z[i + 1][j] != 0 && z[i + 1][j+1] != 0)
{
glVertex3d(x[i][j], y[i][j], z[i][j]);
glVertex3d(x[i][j + 1], y[i][j + 1], z[i][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
glVertex3d(x[i][j+1], y[i][j+1], z[i][j+1]);
glVertex3d(x[i + 1][j + 1], y[i + 1][j + 1], z[i + 1][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
}
}
}
}
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
ifs.close();
}
return 0;}
So now I need to add lighting using mathematical formulas for reflection model. Idea is - lighting is taken as parallel (unidirectional) beams of the same intensity, the size of the light source is not limited. Illumination is set by the direction L [Lx Ly Lz].
This is my code for Lambert reflection model and it works, but I want better result.
float coord = -1.0f;
float coord1 = -1.0f;
float coord2 = -0.0f;
float coord4 = -1.0f;
float coord5 = -2.0f;
float coord6 = -1.0f;
int main(int argc, char** argv)
{
ifstream ifs("D:\\DepthMaps1-20\\DepthMap_1.dat", std::ios::binary);
if (ifs) {
double dheight, dwidth;
ifs.read(reinterpret_cast<char*>(&dheight), sizeof dheight);
ifs.read(reinterpret_cast<char*>(&dwidth), sizeof dwidth);
height = static_cast<size_t>(dheight);
width = static_cast<size_t>(dwidth);
vector<vector<double>> dmap(height, vector<double>(width));
for (auto& row : dmap) {
for (double& col : row)
ifs.read(reinterpret_cast<char*>(&col), sizeof col);
}
double fx = 525.0;
double fy = 525.0; // default focal length
double cx = 319.5;
double cy = 239.5; // default optical center
vector<vector<double>> x(height, vector<double>(width));
vector<vector<double>> y(height, vector<double>(width));
vector<vector<double>> z(height, vector<double>(width));
vector<vector<int>> brightness(height, vector<int>(width));
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
z[i][j] = dmap[i][j] / 500.0;
x[i][j] = (j - cx) * z[i][j] / fx;
y[i][j] = (i - cy) * z[i][j] / fy;
}
}
GLFWwindow * window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(640, 640, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(tippangle, 1, 0, 0);
glRotatef(viewangle, 0, 1, 0);
glScalef(scaleF, scaleF, scaleF);
//x
glRasterPos3f(1.1, 0.0, 0.0);
//y
glRasterPos3f(0.0, 1.1, 0.0);
//z
glRasterPos3f(0.0, 0.0, 1.1);
glTranslatef(d[0], d[1], d[2]);
glBegin(GL_TRIANGLES);
for (unsigned i = 0; i < dmap.size(); i++)
{
for (unsigned j = 0; j < dmap[i].size(); j++)
{
if (j < dmap[i].size() - 2 && i < dmap.size() - 2)
{
if (z[i][j] != 0 && z[i][j + 1] != 0 && z[i + 1][j] != 0 && z[i + 1][j + 1] != 0)
{
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j+1]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i + 1][j]));
glm::vec3 normal = glm::normalize(glm::cross(left, right));
glm::vec3 Position_Light = glm::vec3(coord + 0, coord1+ 0, coord2 + 0); //Light source
glm::vec3 Position_View = glm::vec3(coord4, coord5, coord6); //observer
glm::vec3 Position_Point = glm::vec3(x[i][j], y[i][j], z[i][j]);
//Directions
glm::vec3 Light_Direction = glm::normalize(Position_Light - Position_Point); //To source
glm::vec3 View_Direction = glm::normalize(Position_View - Position_Point); // To the observer
glm::vec3 HalfWay_Direction = glm::normalize(Light_Direction + View_Direction); //Median vector (halfway)
double kd = 1;//diffuse reflectance for the Lambert model
double I = 0; //variable brightness
I = kd * glm::dot(Light_Direction, normal);
glColor3f(I, I, I);
glVertex3d(x[i][j], y[i][j], z[i][j]);
glVertex3d(x[i][j + 1], y[i][j + 1], z[i][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
glVertex3d(x[i][j+1], y[i][j+1], z[i][j+1]);
glVertex3d(x[i + 1][j + 1], y[i + 1][j + 1], z[i + 1][j + 1]);
glVertex3d(x[i + 1][j], y[i + 1][j], z[i + 1][j]);
}
}
}
}
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
ifs.close();
}
return 0;
}
This is my result.
And I want this result.
Second result is an example for this work, but using c#. Sourse code here:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
double[,] depth;
int[,] brightness;
bool glConrerolIsLoaded;
float coord = 501.5f;
float coord1 = -17.5f;
float coord2 = -2979.5f;
float coord4 = -73.0f;
float coord5 = 1269.0f;
float coord6 = 413.5f;
int resNum = 0;
private void glControl1_Load(object sender, EventArgs e)
{
glConrerolIsLoaded = true;
GL.ClearColor(Color.Black);
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void numericUpDown2_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void numericUpDown3_ValueChanged(object sender, EventArgs e)
{
glControl1.Invalidate();
panel1.Invalidate();
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
GL.LoadIdentity();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
Matrix4 perspectiveMatrix = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), glControl1.Width / glControl1.Height, 1.0f, 100.0f);
GL.LoadMatrix(ref perspectiveMatrix);
GL.MatrixMode(MatrixMode.Modelview);
GL.Translate(-25.0, -9.0, -45.0);
GL.Scale(0.04, 0.04, 0.04);
GL.Begin(BeginMode.Points);
for (int i = 0; i < depth.GetLength(0) - 1 ; i++)
{
for (int j = 0; j < depth.GetLength(1) - 1 ; j++)
{
if (depth[i, j] != 0 && depth[i + 1, j] != 0 && /*depth[i + 1, j + 1] != 0 &&*/ depth[i, j + 1] != 0)
{
Vector3 left = new Vector3(0, 1, Convert.ToSingle(depth[i, j + 1]) - Convert.ToSingle(depth[i, j]));
Vector3 right = new Vector3(1, 0, Convert.ToSingle(depth[i + 1, j]) - Convert.ToSingle(depth[i, j]));
Vector3 Normal = Vector3.Normalize(Vector3.Cross(left, right));
Vector3 Position_Light = new Vector3(coord + Convert.ToSingle(numericUpDown1.Value), coord1
+ Convert.ToSingle(numericUpDown2.Value), coord2 + Convert.ToSingle(numericUpDown3.Value));
Vector3 Position_View = new Vector3(coord4, coord5, coord6);
Vector3 Position_Point = new Vector3(i, j, Convert.ToSingle(depth[i, j]));
Vector3 Light_Direction = Vector3.Normalize(Position_Light - Position_Point);
Vector3 View_Direction = Vector3.Normalize(Position_View - Position_Point);
Vector3 HalfWay_Direction = Vector3.Normalize(Light_Direction + View_Direction);
double kd = 1;
double I = 0;
I = kd * Vector3.Dot(Light_Direction, Normal);
GL.Color3(I, I, I);
GL.Vertex3(i, j, depth[i, j]);
}
}
GL.End();
glControl1.SwapBuffers();
}
private void Form1_Load(object sender, EventArgs e)//Считывание карты глубины
{
string path = #"DepthMap_1.dat";
BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open));
double Height1 = reader.ReadDouble();
double Width1 = reader.ReadDouble();
depth = new double[Convert.ToInt16(Height1), Convert.ToInt16(Width1)];
brightness = new int[Convert.ToInt16(Height1), Convert.ToInt16(Width1)];
for (int i = 0; i < depth.GetLength(0); i++)
{
for (int j = 0; j < depth.GetLength(1); j++)
{
depth[i, j] = reader.ReadDouble();
}
}
reader.BaseStream.Close();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
}
}
So my question is what is incorrect in my code? If it light position could you please help me to fix it.
Color is composed of ambient + diffuse + specular. The specular component will add reflection which I think is what you are expecting. The calculations you are doing for color
I_diffuse = kd * glm::dot(Light_Direction, normal);
is just diffuse component.
So what you need will be
I_total = I_diffuse + I_specular;
You already have I_diffuse and you can get I_specular as below,
vec3 viewDir = normalize(viewPos - pointPos);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 I_specular = specularStrength * spec * Ks;
specularStrength can be used to control the strength of reflection.
Note :
The code you are using looks like in a fixed-function pipeline which is way deprecated. If possible please move it to the programmable pipeline with shaders.
You can follow: https://learnopengl.com/Lighting/Basic-Lighting
I found answer, I made mistake here:
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j+1]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i + 1][j]));
It should be like this:
//Determination of the normal
glm::vec3 left = glm::vec3(0, 1, (z[i][j + 1] - z[i][j]));
glm::vec3 right = glm::vec3(1, 0, (z[i + 1][j] - z[i][j]));

How to draw a 45x45 grid with SDL

I am trying to make a grid of 45x45 in SDL but I am not so sure how to do it. Should I use SDL_RenderDrawLine? If so how should I use it inside my void ParticleManager::renderGrid(SDL_Renderer* renderer) function?
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <SDL.h>
#include "Constants.h"
#include "ParticleManager.h"
using namespace std;
Particle::Particle(double _x, double _y) :
x(_x), y(_y),
vx(0.f), vy(0.f),
fx(0.f), fy(0.f),
rho(0.f), p(0.f)
{
}
ParticleManager::ParticleManager()
{
ax = 0;
ay = GRAVITY;
renderMode = "particles";
}
void ParticleManager::init(unsigned long n)
{
cout << "Init with " << n << " particles" << endl;
particles.clear();
particles.reserve(n);
while (particles.size() < n) {
double x = rand() / (double)(RAND_MAX)*SCREEN_WIDTH;
double y = rand() / (double)(RAND_MAX)*SCREEN_HEIGHT;
double centerDist = sqrt(
pow(x - SCREEN_WIDTH / 2.0, 2) +
pow(y - SCREEN_HEIGHT / 2.0, 2));
if (centerDist < fmin(SCREEN_WIDTH, SCREEN_HEIGHT) * 0.25)
particles.push_back(Particle(x, y));
}
}
void ParticleManager::addBlock(double center_x, double center_y)
{
for (int i = 0; i <= 4; i++) {
for (int j = 0; j <= 4; j++) {
double x = center_x + (j - 2) * SCREEN_WIDTH * 0.04f + (rand() / (double)(RAND_MAX)) * H;
double y = center_y + (i - 2) * SCREEN_HEIGHT * 0.04f + (rand() / (double)(RAND_MAX)) * H;
if (x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT)
particles.push_back(Particle(x, y));
}
}
cout << particles.size() << " particles" << endl;
}
void ParticleManager::addOne(double x, double y)
{
particles.push_back(Particle(x, y));
cout << particles.size() << " particles" << endl;
}
void ParticleManager::setGravity(int direction)
{
switch (direction) {
case DOWN:
ax = 0;
ay = +GRAVITY;
break;
case UP:
ax = 0;
ay = -GRAVITY;
break;
case RIGHT:
ax = +GRAVITY;
ay = 0;
break;
default:
ax = -GRAVITY;
ay = 0;
}
}
void ParticleManager::explode() {
for (auto& p : particles) {
p.vx = rand() / (double)RAND_MAX * 10000 - 5000;
p.vy = rand() / (double)RAND_MAX * 10000 - 5000;
}
}
void ParticleManager::integrate(double dt)
{
for (auto& p : particles)
{
// forward Euler integration
if (p.rho != 0 && p.fx == p.fx && p.fy == p.fy) {
p.vx += dt * p.fx / p.rho;
p.vy += dt * p.fy / p.rho;
}
p.x += dt * p.vx;
p.y += dt * p.vy;
// enforce boundary conditions
if (p.x - PARTICLE_RADIUS < 0.0f)
{
p.vx *= BOUND_DAMPING;
p.x = PARTICLE_RADIUS;
}
if (p.x + PARTICLE_RADIUS > SCREEN_WIDTH)
{
p.vx *= BOUND_DAMPING;
p.x = SCREEN_WIDTH - PARTICLE_RADIUS;
}
if (p.y - PARTICLE_RADIUS < 0.0f)
{
p.vy *= BOUND_DAMPING;
p.y = PARTICLE_RADIUS;
}
if (p.y + PARTICLE_RADIUS > SCREEN_HEIGHT)
{
p.vy *= BOUND_DAMPING;
p.y = SCREEN_HEIGHT - PARTICLE_RADIUS;
}
}
}
void ParticleManager::computeDensityPressure()
{
// for each particles
for (auto& pi : particles)
{
pi.rho = 0.f;
// Find all the particles that contribute to the
// pressure / density
for (auto& pj : particles)
{
double distance = sqrt(
pow(pj.x - pi.x, 2) +
pow(pj.y - pi.y, 2));
if (distance < H)
{
// this computation is symmetric
pi.rho += MASS * POLY6 * pow(pow(H, 2) - pow(distance, 2), 3.f);
}
}
pi.p = GAS_CONST * (pi.rho - REST_DENS);
}
}
void ParticleManager::computeForces()
{
// For each particle
for (auto& pi : particles) {
double pressure_x = 0.f;
double pressure_y = 0.f;
double viscosity_x = 0.f;
double viscosity_y = 0.f;
// Calculate the sum of the viscosity and pressure forces
// applied by the other particles
for (auto& pj : particles) {
if (&pi == &pj)
continue;
double r = sqrt(
pow(pj.x - pi.x, 2) +
pow(pj.y - pi.y, 2));
if (r < H) {
// compute pressure force contribution
double fpress = MASS * (pi.p + pj.p) / (2.0 * pj.rho) * SPIKY_GRAD * pow(H - r, 2.0);
pressure_x += (pi.x - pj.x) / r * fpress;
pressure_y += (pi.y - pj.y) / r * fpress;
// compute viscosity force contribution
viscosity_x += VISC * MASS * (pj.vx - pi.vx) / pj.rho * VISC_LAP * (H - r);
viscosity_y += VISC * MASS * (pj.vy - pi.vy) / pj.rho * VISC_LAP * (H - r);
}
}
pi.fx = pressure_x + viscosity_x + ax * pi.rho;
pi.fy = pressure_y + viscosity_y + ay * pi.rho;
}
}
void ParticleManager::update(unsigned long dt)
{
// TODO: calculate the grid here
computeDensityPressure();
computeForces();
integrate(dt / 10000.0f);
}
void ParticleManager::renderParticles(SDL_Renderer* renderer) {
SDL_SetRenderDrawColor(renderer, 230, 120, 0, 100);
SDL_Rect r;
// Draw particles
for (long unsigned int i = 0; i < particles.size(); i++) {
r.x = (int)(particles[i].x - PARTICLE_RADIUS);
r.y = (int)(particles[i].y - PARTICLE_RADIUS);
r.w = (int)(PARTICLE_RADIUS * 2);
r.h = (int)(PARTICLE_RADIUS * 2);
SDL_RenderFillRect(renderer, &r);
}
}
void ParticleManager::renderGrid(SDL_Renderer* renderer) {
// TODO: Draw the lines that form the grid
cout << "Affichage de la grile (TODO)" << endl;
}
void ParticleManager::renderCells(SDL_Renderer* renderer) {
// TODO: Draw the boxes in different colors to
// represent the number of particles in each cell
//
// Use the calculation:
// int alpha = nb_particles * 255/5;
// if (alpha> 255) alpha = 255;
// SDL_SetRenderDrawColor (renderer, 0, 0, 255, alpha);
//
// To assign the color to the cell
cout << "Affichage des cellules (TODO)" << endl;
}
void ParticleManager::render(SDL_Renderer* renderer)
{
if (renderMode.find("particle") != string::npos)
renderParticles(renderer);
if (renderMode.find("grid") != string::npos) {
renderCells(renderer);
renderGrid(renderer);
}
}
The end result should look like this:

3D Cylinder how to calculate vertexSize, indicesSize and textCoordinateSize In openGl

I am trying to draw a 3D cylinder by LWJGL,
and i am trying to generate the vertices, indices and textCoordinate
and storing them in arrays
, but i am stuck how to calculate the size of the vertices, indices and textCoordinate arrays...etc.
anyone knows how i can do it please:
Here the snippet of the code:
// generate vertices for a cylinder
void buildVerticesSmooth() {
//=====> vertices = new float[]; <========
//=====> normals = new float[]; <========
//=====> texcoords = new float[]; <========
int texCoordsIndex = -1;
int verticesIndex = -1;
int normalsIndex = -1;
int indicesIndex = -1; // get unit circle vectors on XY-plane
float[] unitVertices = getUnitCircleVertices();
// put side vertices to arrays
for (int i = 0; i < 2; ++i) {
float h = -height / 2.0f + i * height; // z value; -h/2 to h/2
float t = 1.0f - i; // vertical tex coord; 1 to 0
for (int j = 0, k = 0; j <= sectors; ++j, k += 3) {
float ux = unitVertices[k];
float uy = unitVertices[k + 1];
float uz = unitVertices[k + 2];
// position vector
vertices[++verticesIndex] = (ux * radius); // vx
vertices[++verticesIndex] = (uy * radius); // vy
vertices[++verticesIndex] = (h); // vz
// normal vector
normals[++normalsIndex] = (ux); // nx
normals[++normalsIndex] = (uy); // ny
normals[++normalsIndex] = (uz); // nz
// texture coordinate
texcoords[++texCoordsIndex] = ((float) j / sectors); // s
texcoords[++texCoordsIndex] = (t); // t
}
}
// the starting index for the base/top surface
//NOTE: it is used for generating indices later
int baseCenterIndex = vertices.length / 3;
int topCenterIndex = baseCenterIndex + sectors + 1; // include center vertex
// put base and top vertices to arrays
for (int i = 0; i < 2; ++i) {
float h = -height / 2.0f + i * height; // z value; -h/2 to h/2
float nz = -1 + i * 2; // z value of normal; -1 to 1
// center point
vertices[++verticesIndex] = 0;
vertices[++verticesIndex] = 0;
vertices[++verticesIndex] = h;
normals[++normalsIndex] = 0;
normals[++normalsIndex] = 0;
normals[++normalsIndex] = nz;
texcoords[++texCoordsIndex] = 0.5f;
texcoords[++texCoordsIndex] = 0.5f;
for (int j = 0, k = 0; j < sectors; ++j, k += 3) {
float ux = unitVertices[k];
float uy = unitVertices[k + 1];
// position vector
vertices[++verticesIndex] = (ux * radius); // vx
vertices[++verticesIndex] = (uy * radius); // vy
vertices[++verticesIndex] = (h); // vz
// normal vector
normals[++normalsIndex] = (0); // nx
normals[++normalsIndex] = (0); // ny
normals[++normalsIndex] = (nz); // nz
// texture coordinate
texcoords[++texCoordsIndex] = (-ux * 0.5f + 0.5f); // s
texcoords[++texCoordsIndex] = (-uy * 0.5f + 0.5f); // t
}
}
int[] indices;
int k1 = 0; // 1st vertex index at base
int k2 = sectors + 1; // 1st vertex index at top
// indices for the side surface
for(int i = 0; i < sectors; ++i, ++k1, ++k2)
{
// 2 triangles per sector
// k1 => k1+1 => k2
indices[++indicesIndex] = (k1);
indices[++indicesIndex] = (k1 + 1);
indices[++indicesIndex] = (k2);
// k2 => k1+1 => k2+1
indices[++indicesIndex] = (k2);
indices[++indicesIndex] = (k1 + 1);
indices[++indicesIndex] = (k2 + 1);
}
// indices for the base surface
// NOTE: baseCenterIndex and topCenterIndices are pre-computed during vertex generation
// please see the previous code snippet
for(int i = 0, k = baseCenterIndex + 1; i < sectors; ++i, ++k)
{
if(i < sectors - 1)
{
indices[++indicesIndex] = (baseCenterIndex);
indices[++indicesIndex] = (k + 1);
indices[++indicesIndex] = (k);
}
else // last triangle
{
indices[++indicesIndex] = (baseCenterIndex);
indices[++indicesIndex] = (baseCenterIndex + 1);
indices[++indicesIndex] = (k);
}
}
// indices for the top surface
for(int i = 0, k = topCenterIndex + 1; i < sectors; ++i, ++k)
{
if(i < sectors - 1)
{
indices[++indicesIndex] = (topCenterIndex);
indices[++indicesIndex] = (k);
indices[++indicesIndex] = (k + 1);
}
else // last triangle
{
indices[++indicesIndex] = (topCenterIndex);
indices[++indicesIndex] = (k);
indices[++indicesIndex] = (topCenterIndex + 1);
}
}
}
As httpdigest said:
you know how many iterations every loop performs and you know how
many increments/additions you do per each array. Should be very simple
math now.

Can't draw path on VS2015 but code works fine on VS2010

I am using Nate Robins' GLUT for Win 32. I have been using VS2015 and VS2010 on alternate systems for development. I've created a simulation of Dijkestra's on 5 nodes and the final output is the shortest path from the source node to the destination node printed in red dotted lines.
However, after a few changes the code simply wouldn't print the dotted lines on VS2015.
The same code works flawlessly on VS2010.
Screenshots
Visual Studio 2015
Visual Studio 2010
Code :-
void dijkstra(int s) {
int i, k, mini;
int visited[GRAPHSIZE];
for (i = 1; i <= n; ++i) {
d[i] = INFINITY;
prev[i] = -1;
visited[i] = 0;
dummypath[i] = -1;
}
d[s] = 0;
for (k = 1; k <= n; ++k) {
mini = -1;
for (i = 1; i <= n; ++i)
if (!visited[i] && ((mini == -1) || (d[i] < d[mini])))
mini = i;
visited[mini] = 1;
for (i = 1; i <= n; ++i)
if (dist[mini][i]) {
if (d[mini] + dist[mini][i] < d[i]) {
d[i] = d[mini] + dist[mini][i];
prev[i] = mini;
}
}
}
}
void callPath(int a, int b) {
std::cout << "Source :" << a << std::endl << "Dest :" << b << std::endl;
int i, j, k;
int u, v, w, dest, src;
for (i = 0;i<GRAPHSIZE;i++) {
getPath[i] = '\0';
path[i] = '\0';
}
src = a;
dest = b;
dijkstra(src);
destpath(dest);
k = 0;
std::cout << "Path" << std::endl;
while (path[k] != '\0') {
getPath[k] = path[k];
std::cout << getPath[k] << std::endl;
k++;
}
}
void display4() {
if (a == b) {
if (a == 1) {
getFinalCube1();
glColor3f(0.0, 0.0, 1.0);
drawString(10, 295, 0, "Source");
drawString(10, 210, 0, "Destination");
glFlush();
}
else if (a == 2) {
getFinalCube2();
glColor3f(0.0, 0.0, 1.0);
drawString(110, 460, 0, "Source");
drawString(110, 375, 0, "Destination");
glFlush();
}
else if (a == 3) {
getFinalCube3();
glColor3f(0.0, 0.0, 1.0);
drawString(285, 460, 0, "Source");
drawString(285, 375, 0, "Destination");
glFlush();
}
else if (a == 4) {
getFinalCube4();
glColor3f(0.0, 0.0, 1.0);
drawString(110, 130, 0, "Source");
drawString(110, 45, 0, "Destination");
glFlush();
}
else {
getFinalCube5();
glColor3f(0.0, 0.0, 1.0);
drawString(285, 130, 0, "Source");
drawString(285, 45, 0, "Destination");
glFlush();
}
glFlush();
}
else {
glColor3f(0.0, 0.0, 1.0);
if (a == 1)
drawString(10, 295, 0, "Source");
else if (a == 2)
drawString(110, 460, 0, "Source");
else if (a == 3)
drawString(285, 460, 0, "Source");
else if (a == 4)
drawString(110, 130, 0, "Source");
else if (a == 5)
drawString(285, 130, 0, "Source");
if (b == 1)
drawString(10, 210, 0, "Destination");
else if (b == 2)
drawString(110, 375, 0, "Destination");
else if (b == 3)
drawString(285, 375, 0, "Destination");
else if (b == 4)
drawString(110, 45, 0, "Destination");
else if (b == 5)
drawString(285, 45, 0, "Destination");
i = 0;
while (getPath[i + 1] != '\0') {
if (getPath[i] == 1) {
getFinalCube1();
glFlush();
if (getPath[i + 1] == 2) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 60) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(110 + x, 290 + y, 0);
glVertex3f(125 + x, 307.5 + y, 0);
glVertex3f(130 + x, 302.5 + y, 0);
glVertex3f(115 + x, 285 + y, 0);
glVertex3f(110 + x, 290 + y, 0);
y = y + 33;
x = x + 25;
glFlush();
glEnd();
for (k = 0; k <= 100; k++) {
delay();
}
glFlush();
}
getFinalCube2();
glFlush();
}
else if (getPath[i + 1] == 3) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 31) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(112.5 + x, 250 + y, 0);
glVertex3f(135 + x, 265 + y, 0);
glVertex3f(137.5 + x, 260 + y, 0);
glVertex3f(115 + x, 245 + y, 0);
glVertex3f(112.5 + x, 250 + y, 0);
y = y + 25;
x = x + 48;
glFlush();
glEnd();
for (k = 0; k <= 100; k++) {
delay();
}
glFlush();
}
getFinalCube3();
glFlush();
}
else if (getPath[i + 1] == 4) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 60) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(65 + x, 220 + y, 0);
glVertex3f(80 + x, 200 + y, 0);
glVertex3f(75 + x, 195 + y, 0);
glVertex3f(60 + x, 215 + y, 0);
glVertex3f(65 + x, 220 + y, 0);
y = y - 33;
x = x + 25;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube4();
glFlush();
}
else {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 40) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(95 + x, 210 + y, 0);
glVertex3f(117.5 + x, 197.5 + y, 0);
glVertex3f(115 + x, 192.5 + y, 0);
glVertex3f(92.5 + x, 205 + y, 0);
glVertex3f(95 + x, 210 + y, 0);
y = y - 32;
x = x + 56;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube5();
glFlush();
}
glFlush();
}
else if (getPath[i] == 2) {
getFinalCube2();
glFlush();
if (getPath[i + 1] == 1) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 60) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(120 + x, 375 + y, 0);
glVertex3f(125 + x, 370 + y, 0);
glVertex3f(110 + x, 350 + y, 0);
glVertex3f(105 + x, 355 + y, 0);
glVertex3f(120 + x, 375 + y, 0);
y = y - 25;
x = x - 18;
glFlush();
glEnd();
for (k = 0; k <= 100; k++) {
delay();
}
glFlush();
}
getFinalCube1();
glFlush();
}
else if (getPath[i + 1] == 3) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 50) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(212.5 + x, 445 + y, 0);
glVertex3f(237.5 + x, 445 + y, 0);
glVertex3f(237.5 + x, 438 + y, 0);
glVertex3f(212.5 + x, 438 + y, 0);
glVertex3f(212.5 + x, 445 + y, 0);
y = y;
x = x + 30;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube3();
glFlush();
}
else if (getPath[i + 1] == 4) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 35) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(135 + x, 380 + y, 0);
glVertex3f(137.5 + x, 355 + y, 0);
glVertex3f(142.5 + x, 359 + y, 0);
glVertex3f(140 + x, 383.5 + y, 0);
glVertex3f(135 + x, 380 + y, 0);
y = y - 70;
x = x + 5;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube4();
glFlush();
}
else {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 31) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(182.5 + x, 367.5 + y, 0);
glVertex3f(195 + x, 345 + y, 0);
glVertex3f(190 + x, 342.5 + y, 0);
glVertex3f(177.5 + x, 365 + y, 0);
glVertex3f(182.5 + x, 367.5 + y, 0);
y = y - 66;
x = x + 37;
glFlush();
glEnd();
for (k = 0; k <= 100; k++) {
delay();
}
glFlush();
}
getFinalCube5();
glFlush();
}
glFlush();
}
else if (getPath[i] == 3) {
getFinalCube3();
glFlush();
if (getPath[i + 1] == 1) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 31) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(297.5 + x, 382.5 + y, 0);
glVertex3f(275 + x, 372.5 + y, 0);
glVertex3f(277.5 + x, 367.5 + y, 0);
glVertex3f(300 + x, 377.5 + y, 0);
glVertex3f(297.5 + x, 382.5 + y, 0);
y = y - 25;
x = x - 50;
glFlush();
glEnd();
for (k = 0; k <= 100; k++) {
delay();
}
glFlush();
}
getFinalCube1();
glFlush();
}
else if (getPath[i + 1] == 2) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 60) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(290 + x, 385 + y, 0);
glVertex3f(287.5 + x, 380 + y, 0);
glVertex3f(265 + x, 387.5 + y, 0);
glVertex3f(267.5 + x, 392.5 + y, 0);
glVertex3f(290 + x, 385 + y, 0);
y = y + 6.25;
x = x - 30;
glFlush();
glEnd();
for (k = 0; k <= 100; k++) {
delay();
}
glFlush();
}
getFinalCube2();
glFlush();
}
else if (getPath[i + 1] == 4) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 31) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(295 + x, 372.5 + y, 0);
glVertex3f(282.5 + x, 350 + y, 0);
glVertex3f(287.5 + x, 347.5 + y, 0);
glVertex3f(300 + x, 370 + y, 0);
glVertex3f(295 + x, 372.5 + y, 0);
y = y - 66.25;
x = x - 37.5;
glFlush();
glEnd();
for (k = 0; k <= 100; k++) {
delay();
}
glFlush();
}
getFinalCube4();
glFlush();
}
else {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 35) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(310 + x, 385 + y, 0);
glVertex3f(313 + x, 360 + y, 0);
glVertex3f(317.5 + x, 362.5 + y, 0);
glVertex3f(315 + x, 387.5 + y, 0);
glVertex3f(310 + x, 385 + y, 0);
y = y - 70;
x = x + 5;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube5();
glFlush();
}
glFlush();
}
else if (getPath[i] == 4) {
getFinalCube4();
glFlush();
if (getPath[i + 1] == 1) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 45) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(127.5 + x, 115 + y, 0);
glVertex3f(112.5 + x, 135 + y, 0);
glVertex3f(107.5 + x, 132.5 + y, 0);
glVertex3f(122.5 + x, 112.5 + y, 0);
glVertex3f(127.5 + x, 115 + y, 0);
y = y + 31.25;
x = x - 25;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube1();
glFlush();
}
else if (getPath[i + 1] == 2) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 35) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(210 + x, 125 + y, 0);
glVertex3f(207.5 + x, 155 + y, 0);
glVertex3f(212.5 + x, 157.5 + y, 0);
glVertex3f(215 + x, 127.5 + y, 0);
glVertex3f(210 + x, 125 + y, 0);
y = y + 70;
x = x - 5;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube2();
glFlush();
}
else if (getPath[i + 1] == 3) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 22) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(210 + x, 125 + y, 0);
glVertex3f(222.5 + x, 145 + y, 0);
glVertex3f(226 + x, 138 + y, 0);
glVertex3f(215 + x, 120 + y, 0);
glVertex3f(210 + x, 125 + y, 0);
y = y + 45;
x = x + 25;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube3();
glFlush();
}
else {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 50) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(180 + x, 50 + y, 0);
glVertex3f(205 + x, 50 + y, 0);
glVertex3f(205 + x, 42.5 + y, 0);
glVertex3f(180 + x, 42.5 + y, 0);
glVertex3f(180 + x, 50 + y, 0);
y = y;
x = x + 40;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube5();
glFlush();
}
glFlush();
}
else {
getFinalCube5();
glFlush();
if (getPath[i + 1] == 1) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 30) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(315 + x, 120 + y, 0);
glVertex3f(287.5 + x, 132.5 + y, 0);
glVertex3f(282.5 + x, 127.5 + y, 0);
glVertex3f(310 + x, 115 + y, 0);
glVertex3f(315 + x, 120 + y, 0);
y = y + 25;
x = x - 45;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube1();
glFlush();
}
else if (getPath[i + 1] == 2) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 30) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(362.5 + x, 130 + y, 0);
glVertex3f(350 + x, 150 + y, 0);
glVertex3f(345 + x, 147.5 + y, 0);
glVertex3f(357.5 + x, 127.5 + y, 0);
glVertex3f(362.5 + x, 130 + y, 0);
y = y + 60;
x = x - 35;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube2();
glFlush();
}
else if (getPath[i + 1] == 3) {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 35) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(385 + x, 125 + y, 0);
glVertex3f(382.5 + x, 155 + y, 0);
glVertex3f(387.5 + x, 157.5 + y, 0);
glVertex3f(390 + x, 127.5 + y, 0);
glVertex3f(385 + x, 125 + y, 0);
y = y + 70;
x = x - 5;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube3();
glFlush();
}
else {
x = 0;
y = 0;
x = m[i][i + 1] * y;
for (j = 0; j < 125; j = j + 60) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(295 + x, 95 + y, 0);
glVertex3f(270 + x, 90 + y, 0);
glVertex3f(272.5 + x, 85 + y, 0);
glVertex3f(297.5 + x, 90 + y, 0);
glVertex3f(295 + x, 95 + y, 0);
y = y - 5;
x = x - 35;
glFlush();
glEnd();
for (k = 0; k <= 300; k++) {
delay();
}
glFlush();
}
getFinalCube4();
glFlush();
}
glFlush();
}
i++;
glFlush();
}
}
glFlush();
}
The Complete code is available here.
I really don't understand why the code isn't working on VS2015 but works fine with VS2010. Any help is welcome as I use VS2010 on my desktop and hence carrying it everywhere isn't really possible.

OpenGL: new window displays content of the current window opened

I tried to draw Bezier surface using OpenGL. My program reads an input file with number of sample points for plot, control points and color palette for surface coloring. It must output a new window with surface plot where I can manipulate properties of surface and control points.
Points generated from Bernstein polynomial are triangulated and assigned a color by color palette by mapping it from minimum and maximum height of triangles.
Unfortunately, it opens a window with a portion of the current window opened in OS without creating a new interface for surface.
Here is the code:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cmath>
using namespace std;
struct vertex
{
float x;
float y;
float z;
};
struct RGB
{
float r;
float g;
float b;
};
int main_window;
bool TM = true;
vertex surfaceTranslate;
float surfaceRotate = 0;
vertex camera;
vertex up;
int currentPointX = 0, currentPointY = 0;
vertex toY;
int SampleR, SampleC;
int M, N;
int K;
vector < vector <vertex> > points;
vector <RGB> palette;
vector < vector <vertex> > control;
float minH, maxH;
int fact (int n)
{
if (!n || n == 1)
{
return 1;
}
return n * fact (n - 1);
}
int C (int n, int i)
{
return fact (n) / (fact (i) * fact (n - i));
}
void initialDisplay(void)
{
glClearColor (1.0, 1.0, 1.0, 1.0);
glDisable (GL_LIGHTING);
glEnable (GL_RESCALE_NORMAL);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, 1, 1, 1000000);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
void updateControl()
{
control.clear();
for (int i = 0; i < SampleR; ++i)
{
vector <vertex> temp;
for (int j = 0; j < SampleC; ++j)
{
float u = (float)(i) / (SampleR - 1);
float v = (float)(j) / (SampleC - 1);
vertex p;
p.x = p.y = p.z = 0;
for (int k = 0; k < M; ++k)
{
for (int m = 0; m < N; ++m)
{
float B_u = float (C (M - 1, k)) * pow (u, k) * pow (1 - u, M - 1 - k);
float B_v = float (C (N - 1, m)) * pow (v, m) * pow (1 - v, N - 1 - m);
p.x += B_u * B_v * points[k][m].x;
p.y += B_u * B_v * points[k][m].y;
p.z += B_u * B_v * points[k][m].z;
}
}
temp.push_back (p);
}
control.push_back (temp);
}
maxH = 1 << ((sizeof(float) * 8) - 1);
minH = -maxH;
for (int i = 0; i < SampleR - 1; ++i)
{
for (int j = 0; j < SampleC - 1; ++j)
{
float h = (control[i][j].y + control[i + 1][j].y + control[i][j + 1].y) / 3;
if (h > maxH)
{
maxH = h;
}
if (h < minH)
{
minH = h;
}
h = (control[i][j + 1].y + control[i + 1][j].y + control[i + 1][j + 1].y) / 3;
if (h > maxH)
{
maxH = h;
}
if (h < minH)
{
minH = h;
}
}
}
for (int i = 0; i < SampleR; ++i)
{
for (int j = 0; j < SampleC; ++j)
{
toY.x += control[i][j].x;
toY.z += control[i][j].z;
}
toY.x /= SampleR * SampleC;
toY.z /= SampleR * SampleC;
}
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt (camera.x, camera.y, camera.z, 0, 0, 0, up.x, up.y, up.z);
glTranslatef (surfaceTranslate.x, surfaceTranslate.y, surfaceTranslate.z);
glTranslatef (toY.x, toY.y, toY.z);
glRotatef (surfaceRotate, 0, 1, 0);
glTranslatef (- toY.x, -toY.y, -toY.z);
if (!TM)
{
glPointSize (10);
glBegin (GL_POINTS);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
if (i == currentPointX && j == currentPointY)
{
glColor3f (1.0, 0.0, 0.0);
}
else
{
glColor3f (0.0, 0.0, 1.0);
}
glVertex3f (points[i][j].x, points[i][j].y, points[i][j].z);
}
}
glEnd();
}
glBegin (GL_TRIANGLES);
for (int i = 0; i < SampleR - 1; ++i)
{
for (int j = 0; j < SampleC - 1; ++j)
{
glVertex3f (control[i][j].x, control[i][j].y, control[i][j].z);
glVertex3f (control[i + 1][j].x, control[i + 1][j].y, control[i + 1][j].z);
glVertex3f (control[i][j + 1].x, control[i][j + 1].y, control[i][j + 1].z);
float h = (control[i][j].y + control[i + 1][j].y + control[i][j + 1].y) / 3;
int r = (palette[K - 1].r - palette[0].r) * (h - minH) / (maxH - minH);
int g = (palette[K - 1].g - palette[0].g) * (h - minH) / (maxH - minH);
int b = (palette[K - 1].b - palette[0].b) * (h - minH) / (maxH - minH);
glColor3f (palette[r].r / (palette[K - 1].r - palette[0].r), palette[g].g / (palette[K - 1].g - palette[K - 1].g), palette[b].b / (palette[K - 1].b - palette[0].b));
glVertex3f (control[i + 1][j].x, control[i + 1][j].y, control[i + 1][j].z);
glVertex3f (control[i][j + 1].x, control[i][j + 1].y, control[i][j + 1].z);
glVertex3f (control[i + 1][j + 1].x, control[i + 1][j + 1].y, control[i + 1][j + 1].z);
h = (control[i + 1][j].y + control[i][j + 1].y + control[i + 1][j + 1].y) / 3;
r = (palette[K - 1].r - palette[0].r) * (h - minH) / (maxH - minH);
g = (palette[K - 1].g - palette[0].g) * (h - minH) / (maxH - minH);
b = (palette[K - 1].b - palette[0].b) * (h - minH) / (maxH - minH);
glColor3f (palette[r].r / (palette[K - 1].r - palette[0].r), palette[g].g / (palette[K - 1].g - palette[K - 1].g), palette[b].b / (palette[K - 1].b - palette[0].b));
}
}
glEnd();
}
void keyboardEvent (unsigned char key, int x, int y)
{
if (TM)
{
switch (key)
{
case ('2'):
TM = false;
glutSetWindowTitle ("Surface Editing Mode");
break;
case ('q'):
--surfaceTranslate.x;
break;
case ('w'):
++surfaceTranslate.x;
break;
case ('a'):
--surfaceTranslate.y;
break;
case ('s'):
++surfaceTranslate.y;
break;
case ('z'):
--surfaceTranslate.z;
break;
case ('x'):
++surfaceTranslate.z;
break;
case ('r'):
++surfaceRotate;
break;
case ('t'):
--surfaceRotate;
break;
}
}
else
{
switch (key)
{
case ('1'):
TM = true;
glutSetWindowTitle ("Transformation Mode");
break;
case ('q'):
--points[currentPointX][currentPointY].x;
updateControl();
break;
case ('w'):
++points[currentPointX][currentPointY].x;
updateControl();
break;
case ('a'):
--points[currentPointX][currentPointY].y;
updateControl();
break;
case ('s'):
++points[currentPointX][currentPointY].y;
updateControl();
break;
case ('z'):
--points[currentPointX][currentPointY].z;
updateControl();
break;
case ('x'):
++points[currentPointX][currentPointY].z;
updateControl();
break;
case ('i'):
if (!(SampleR % 2))
{
SampleR /= 2;
updateControl();
}
break;
case ('o'):
SampleR *= 2;
updateControl();
break;
case ('k'):
if (!(SampleC % 2))
{
SampleC /= 2;
updateControl();
}
break;
case ('l'):
SampleC *= 2;
updateControl();
break;
case (GLUT_KEY_UP):
if (currentPointY < N - 1)
{
++currentPointY;
}
break;
case (GLUT_KEY_DOWN):
if (currentPointY)
{
--currentPointY;
}
break;
case (GLUT_KEY_LEFT):
if (currentPointX)
{
--currentPointX;
}
break;
case (GLUT_KEY_RIGHT):
if (currentPointX < M - 1)
{
++currentPointX;
}
break;
}
}
glutPostRedisplay();
}
void changeDirection (int x, int y)
{
float dist = sqrt (pow (camera.x, 2) + pow (camera.y, 2) + pow (camera.z, 2));
camera.x = dist * sin (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532);
camera.y = dist * cos (360.0 / 800 * y * 0.0174532);
camera.z = dist * cos (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532);
up.x = dist * sin (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532 - 1) - camera.x;
up.y = dist * cos (360.0 / 800 * y * 0.0174532 - 1) - camera.y;
up.z = dist * cos (360.0 / 800 * x * 0.0174532) * sin (360.0 / 800 * y * 0.0174532 - 1) - camera.z;
glutPostRedisplay();
}
void mouseEvent (int key, int state, int x, int y)
{
if (key == GLUT_KEY_LEFT)
{
changeDirection (x, y);
}
}
void readFile (char *fname)
{
ifstream file (fname);
if (file.is_open())
{
file >> SampleR >> SampleC;
file >> M >> N;
for (int i = 0; i < M; ++i)
{
vector <vertex> tempv;
for (int j = 0; j < N; ++j)
{
vertex temp;
file >> temp.x >> temp.y >> temp.z;
tempv.push_back (temp);
}
points.push_back (tempv);
}
file >> K;
for (int i = 0; i < K; ++i)
{
RGB temp;
file >> temp.r >> temp.g >> temp.b;
palette.push_back (temp);
}
}
file.close();
}
int main (int argc, char *argv[])
{
surfaceTranslate.x = surfaceTranslate.y = surfaceTranslate.z = toY.x = toY.y = toY.z = up.x = up.z = 0;
up.y = 1;
camera.x = camera.y = camera.z = 100;
readFile (argv[1]);
updateControl();
glutInit (&argc,argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition (50, 50);
glutInitWindowSize (800, 800);
main_window = glutCreateWindow ("Transformation Mode");
glutDisplayFunc (display);
glutKeyboardFunc (keyboardEvent);
glutMouseFunc (mouseEvent);
glutMotionFunc (changeDirection);
initialDisplay();
glutMainLoop();
}
You're missing the call to glutSwapBuffers() at the end of your display() function. This is needed to display the frame when using double buffered rendering.