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]));
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.
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.