This question already has an answer here:
Compilation error with bresenham line algorithm?
(1 answer)
Closed 6 years ago.
Errors while compiling:
redefinition of 'y1' as different kind of symbol float x1 = 0, y1 = 0, x2 = 0, y2 = 0;
non-object type 'double (double)' is not assignable
y1 = 240-y;
no matching function for call to 'drawPixel'
drawPixel( x1, y1 );
no matching function for call to 'dda'
dda( x1, y1, x2, y2 );
Code:
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <iostream>
using namespace std;
#include <cstdlib>
#include <cmath>
//defining constants
#define MAX_WIDTH 640
#define MAX_HEIGHT 480
int flag = 1;
float x1 = 0, y1 = 0, x2 = 0, y2 = 0;
//method for drawing the pixel
void drawPixel( int x, int y ){
glBegin( GL_POINTS );
//setting the pointer color
glColor3f( 1.0, 1.0, 1.0 );
glVertex2i( x, y );
glEnd();
glFlush();
}
//display callback function
void display(){
glClear( GL_COLOR_BUFFER_BIT );
gluLookAt( 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 1.0, 0.0 );
/*
glBegin( GL_POINTS );
//setting the pointer color
glColor3f( 1.0, 1.0, 1.0 );
glVertex2i( 0, 0 );
glVertex2i( 10, 0 );
glEnd();
*/
glFlush();
}
//catching keyboard events
void keyboardEvent( unsigned char c, int x, int y ){
if( c == 27 ){
exit(0);
}
}
//dda implementation
void dda( float m1 , float n1 , float m2 , float n2 ){
float slope , Dx , Dy;
float dx , dy , length;
int i = 1;
dx = dy = length = 0.0;
slope = Dx = Dy = 0.0;
dx = m2 - m1;
dy = n2 - n1;
slope = dy/dx; //slope
cout << m1 << "\t" << n1 << "\t" << m2 << "\t" << n2 << endl;
length = (dx >= dy)?dx:dy ;
cout << length<< endl;
Dx = dx/length;
Dy = dy/length;
drawPixel( round(m1), round(n1) );
cout << m1 << m2 << endl;
for( ; i <= length ; i++ ){
m1 = m1 + Dx;
n1 = n1 + Dy;
drawPixel( round(m1), round(n1) );
cout << m1 << m2 << endl;
}
}
//catching mouse click events
void mouseEvent( int button, int state, int x, int y ){
//checking if the mouse button is clicked or not using state para.
if( state == GLUT_DOWN ){
if( button == GLUT_LEFT_BUTTON && flag == 1 ){
x1 = 320-x;
y1 = 240-y;
drawPixel( x1, y1 );
flag++;
}
else if( button == GLUT_LEFT_BUTTON && flag == 2 ){
x2 = 320-x;
y2 = 240-y;
drawPixel( x2, y2 );
flag++;
}
else if( button == GLUT_RIGHT_BUTTON && flag > 2 ){
drawPixel( 320-x, 240-y );
cout << x1 << "\t" << y1 << "\t" << x2 << "\t" << y2 << endl;
dda( x1, y1, x2, y2 );
}
}
}
//adjusting window when it is moved or resized
void reshape( int w, int h ){
glViewport( 0, 0, w, h );
}
//initialising the window at startup
void initialise(){
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glPointSize( 5 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( -320, 320, -240, 240 );
}
int main( int argc, char **argv ){
//initialising the glut library
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize( MAX_WIDTH, MAX_HEIGHT );
glutInitWindowPosition( 100, 100 );
glutCreateWindow("DDA Assignment");
//calling normal functions
initialise();
//registering callback functions
glutDisplayFunc( display );
glutKeyboardFunc( keyboardEvent );
glutMouseFunc( mouseEvent );
glutReshapeFunc( reshape );
glutMainLoop();
return 0;
}
If you compile this on POSIX, you will end up with <math.h> (and cmath) declaring functions with the name y0, y1 and yn, which will totally conflict with any global variable of the same name.
Since you explicitely tagged this question as c++14, you should also tell your compile to use that standard by using
g++ -std=c++14
(or any other appropriate version of the standard), which will also prevent the libc headers from declaring functions which are not in that standard.
Related
I am implementing the Bresenham algorithm, and I am pretty certain that my implementation is correct, but the screen is still blank, I think I'm using OpenGL wrong.
This is my full program. I am using nupengl.core.0.1.0.1 if it helps
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
#include <fstream>
#include <math.h>
#define Round(a) (int)(a+0.5)
#define max(a,b) (a>b)?a:b
using namespace std;
/*truct vectors = {
vector
}*/
void init(void) {
glClearColor(1.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
class Shape {
public:
virtual void Draw() = 0;
};
class lineBressenham : public Shape {
int x1, y1, x2, y2;
public:
lineBressenham(int a1, int b1, int a2, int b2) {
x1 = a1;
y1 = b1;
x2 = a2;
y2 = b2;
}
void Draw() {
int dx = x2 - x1;
int dy = y2 - y1;
int x = x1;
int y = y1;
int p = 2 * dy - dx;
glBegin(GL_POINTS);
while (x < x2) {
if (p >= 0) {
glVertex2i(x, y);
y = y + 1;
p = p + 2 * dy - 2 * dx;
}
else {
glVertex2i(x, y);
p = p + 2 * dy;
}
x = x + 1;
}
glEnd();
}
};
void displayWindow(void) {
ifstream infile;
glClear(GL_COLOR_BUFFER_BIT); // settings for buffer.
glColor3f(0.0, 0.0, 0.0);
glPointSize(3.0);
while (!infile.eof()) {
int a;
int x1 = 3, y1 = 4, x2 = 7, y2 = 9;
Shape* shape;
shape = new lineBressenham(x1, y1, x2, y2);
shape->Draw();
glutSwapBuffers();
//glFlush(); // draw everything in input, buffer in one time.
}
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500); // window size
glutInitWindowPosition(0, 0); // distance from the top-left screen
glutCreateWindow("Show the window"); // message displayed on top bar window
glewInit();
if (glewIsSupported("GL_VERSION_3_3")) {
std::cout << " GLEW Version is 3.3\n ";
}
else {
std::cout << "GLEW 3.3 not supported\n ";
}
glutDisplayFunc(displayWindow);
init();
glutMainLoop();
return 0;
}
I fixed it. The problem was I did not initialize the gluOrtho2D and glMatrixMode. The full code is
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
#include <fstream>
#include <math.h>
GLsizei windows_witdh = 800;
GLsizei windows_height = 600;
class lineBressenham {
int x1, y1, x2, y2;
public:
lineBressenham(int a1, int b1, int a2, int b2) {
x1 = a1;
y1 = b1;
x2 = a2;
y2 = b2;
}
void Draw() {
int dx = x2 - x1;
int dy = y2 - y1;
int x = x1;
int y = y1;
int p = 2 * dy - dx;
glBegin(GL_POINTS);
while (x < x2) {
if (p >= 0) {
glVertex2i(x, y);
y = y + 1;
p = p + 2 * dy - 2 * dx;
}
else {
glVertex2i(x, y);
p = p + 2 * dy;
}
x = x + 1;
}
glEnd();
}
};
void displayWindow(void) {
glClear(GL_COLOR_BUFFER_BIT); // settings for buffer.
glColor3f(1.0, 0.3, 0.7);
glPointSize(1.0);
int x1 = 30, y1 = 40, x2 = 700, y2 = 300;
lineBressenham *shape = new lineBressenham(x1, y1, x2, y2);;
shape->Draw();
glutSwapBuffers();
glFlush();
}
void init() {
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, windows_witdh, windows_height, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500); // window size
glutInitWindowPosition(0, 0); // distance from the top-left screen
glutCreateWindow("Bressenham"); // message displayed on top bar window
glLoadIdentity();
init();
if (glewIsSupported("GL_VERSION_3_3")) {
std::cout << " GLEW Version is 3.3\n ";
}
else {
std::cout << "GLEW 3.3 not supported\n ";
}
glutDisplayFunc(displayWindow);
glutMainLoop();
return 0;
}
I have just tried to run the Bresenham function which draws a line from 2 vertexes, but only the white screen of GLUT appear, there is no line at all. Here is my source code, can anybody help me?
#include <math.h>
#include <windows.h>
#include <GL/glut.h>
#include <GL/gl.h>
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 500.0, 0.0, 500.0);
}
void Bresenham(int x1, int y1, int x2, int y2) {
int Dx = abs(x2 - x1);
int Dy = abs(y2 - y1);
int p = 2 * Dy - Dx;
int c1 = 2 * Dy;
int c2 = 2 * (Dy - Dx);
int x = x1;
int y = y1;
int x_unit = 1, y_unit = 1;
glVertex2d(x, y);
while (x != x2) {
if (p<0) p += c1;
else {
p += c2;
y += y_unit;
}
x += x_unit;
glVertex2d(x, y);
}
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
Bresenham(50, 150, 300, 200);
glEnd();
glFlush();
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(50, 50);
glutCreateWindow("Line");
init();
int x1=50, y1=150, x2=300, y2=200;
glutDisplayFunc(display);
glutMainLoop();
return EXIT_SUCCESS;
}
Make sure your background color doesn't match your drawing color. Kinda hard to see white-on-white :)
Drawing the line in red works on my machine:
#include <GL/glut.h>
void Bresenham(int x1, int y1, int x2, int y2)
{
int Dx = abs(x2 - x1);
int Dy = abs(y2 - y1);
int p = 2 * Dy - Dx;
int c1 = 2 * Dy;
int c2 = 2 * (Dy - Dx);
int x = x1;
int y = y1;
int x_unit = 1, y_unit = 1;
glVertex2d(x, y);
while (x != x2)
{
if (p<0)
p += c1;
else
{
p += c2;
y += y_unit;
}
x += x_unit;
glVertex2d(x, y);
}
}
void display(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 500.0, 0.0, 500.0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_POLYGON);
glColor3ub( 255, 0, 0 );
Bresenham(50, 150, 300, 200);
glEnd();
glutSwapBuffers();
}
int main(int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutCreateWindow("Line");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Firstly thanks for giving your time.This is one of question which has a lot of answers but it does not work, here I am trying to take an example and let's see if we can solve this and maybe someone will get benefited again in future.
So the problem is we have glreadpixel() calling on a point on a circle, which is drawn by bresenham function.
But the thing is its not even giving any value than 0,0,0 for RGB on changing the background colour of the window.
Here is the big code, enjoy experimenting. I have tried everything. By the way, I am developing n macOS (OpenGL is hardware independent )
using namespace std;
#include <GLUT/glut.h>
#include <iostream>
#include <vector>
#include <CoreGraphics/CoreGraphics.h>
int r = 40;
int flag = 0;
int cordinates [50][3]=
{
{50, 50} , //0 station
{400, 450} , //1 station
{750, 250} //2 station
};
int matrix[50][50] = {
{0,1,1},
{1,0,1},
{1,1,0}
};
int trains[50][50] = {
{3,4,0,1,999},
{11,1,1,2,999},
{0,0,0,999}
};
int x,y;
int *x1, *y3, x2, y2;
int xx,yy,xxx,yyy,p,q,vertexcount,counter;
int xinc,xinc3,i,j,system_time,flag1,time_chekcer_cnt,dda =0;
char buf3[12],buf[12];
float tempx0,tempy0,tempx1,tempy1;
int train0 = 999 ;int start0,speed0,next0,nextx0,nexty0,final0 = 999 ;//999 signifies invalid
int train1 ,start1, speed1,next1,nextx1,nexty1,final1 = 999 ;//999 signifies invalid
int train2 ,start2, speed2,next2,final2 = 999 ;//999 signifies invalid
void init2D()
{
glClearColor(0,0,0,0.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D (0.0, 900.0, 0.0, 900.0);
}
;
void bresenham_circle(const int h, const int k,const int r)
{
int x=0,y=r,p=(3-(2*r));
do{
//Read pixel
unsigned char pixelub[3];
// glReadPixels(<#GLint x#>, <#GLint y#>, <#GLsizei width#>, <#GLsizei height#>, <#GLenum format#>, <#GLenum type#>, <#GLvoid *pixels#>)
glPointSize(1);
//draw two points
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POINTS);
glVertex2i((h+x),(k+y));
glEnd();
//color detection start
glReadPixels
(
(h+x),(k+y),
1, 1,
GLUT_RGB, GL_UNSIGNED_BYTE, &pixelub
);
//print
cout <<"reading pixel : "<<(h+x)<<" "<<(k+y);
printf("r: %u g: %u b: %u\n", pixelub[0], pixelub[1], pixelub[2]);
cout << endl;
//end
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POINTS);
glVertex2i((h+y),(k+x));
glEnd();
glBegin(GL_POINTS);
glVertex2i((h+y),(k-x));
glEnd();
glBegin(GL_POINTS);
glVertex2i((h+x),(k-y));
glEnd();
glBegin(GL_POINTS);
glVertex2i((h-x),(k-y));
glEnd();
glBegin(GL_POINTS);
glVertex2i((h-y),(k-x));
glEnd();
glBegin(GL_POINTS);
glVertex2i((h-y),(k+x));
glEnd();
glBegin(GL_POINTS);
glVertex2i((h-x),(k+y));
glEnd();
x++;
if(p<0){
p+= ((4*x)+6);
}else {
y--;
p+=(4*(x-y)+10);
}
}
while (x<=y);
}
void drawBitmapText(char *string,float x,float y,float z)
{
char *c;
glRasterPos3f(x, y,z);
for (c=string; *c != NULL; c++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
}
}
void systemtime(){
sprintf(buf, "%d", system_time); // puts string into buffer
printf("%s\n", buf);
sprintf(buf3, "%d", system_time-1); // puts string into buffer
if(system_time >1){
glColor3f(1.0, 1.0, 1.0);
drawBitmapText(buf3,200,200,0);
glColor3f(0.0, 1.0, 0.0);
drawBitmapText(buf,200,200,0);
system_time =system_time+1;
}else {
drawBitmapText(buf,200,200,0);
system_time =system_time+1;
}
};
void draw_pixel(int x, int y){
glPointSize(5);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POINTS);
cout << "\n THIS IS PRINTING X and Y :"<<x<<" & "<<y<<endl;
glVertex2i(x, y);
glEnd();
glFlush();
}
//bresenham ..... i vant DDA
void draw_dda( float *x0, float *y0, int x1, int y1,int speed) {
//cout << "\n LOOPING FOR START CORDIANTES : X0 and Y0 "<<*x0<<*y0<<endl;
int dx = x1 - *x0;
int dy = y1 - *y0;
//GLfloat x1 = p1.x; GLfloat y1 = p1.y;
GLfloat step = 0;
if(abs(dx) > abs(dy)) {
step = abs(dx);
} else {
step = abs(dy);
}
GLfloat xInc = dx/step;
GLfloat yInc = dy/step;
for (int speed_count = 0 ; speed_count < speed ; speed_count++){
glPointSize(5);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POINTS);
//cout << "\n THIS IS PRINTING X and Y :"<<xInc<<" & "<<yInc<<endl;
glVertex2i(*x0, *y0);
glEnd();
int cy1 = *y0;
int cx1 = *x0;
//cout << "\n calling bresenham";
glColor3f(1.0, 1.0, 1.0);
bresenham_circle(cx1, cy1, r);
//cout << " \n" <<cx1<<" "<<cy1<<" "<<r;
while (flag != 1){
r--;
//cout <<"\n r is "<<r<<endl;
if (r == 0){
flag = 1;
}
}
r =40;flag= 0;
*x0 = *x0+xInc;
*y0 = *y0+yInc;
glColor3f(1.0, 0.0, 0.0);
int cy = *y0;
int cx = *x0;
//cout << "\n calling bresenham";
bresenham_circle(cx, cy, r);
//cout << " \n" <<cx<<" "<<cy<<" "<<r;
while (flag != 1){
r--;
//cout <<"\n r is "<<r<<endl;
if (r == 0){
flag = 1;
}
}
r =40;flag= 0;
//cout << "\n THIS IS PRINTING X and Y :"<<xInc<<" & "<<yInc<<endl;
}
}
void drawline(float *x0, float *y0, int x1, int y1)
{ cout << "\n LOOPING FOR START CORDIANTES : ("<<*x0<<","<<*y0<<") To ("<<x1<<","<<y1<<")"<<endl;
int dx, dy, p, x, y;
dx=x1-*x0;
dy=y1-*y0;
x=*x0;
y=*y0;
p=2*dy-dx;
//cout << "X and X1 "<<x<<x1<<endl;
if (x<x1)
{
if(p>=0)
{
draw_pixel(x,y);
//cout << ">>>>>. Y INCREMENTED >>>>> "<<y<<endl;
y=y+1;
p=p+2*dy-2*dx;
}
else
{ //cout << "\n >>>>>NOT Y INCREMENTED >>>>> "<<y<<endl;
draw_pixel(x,y);
//cout << "X and Y "<<x<<y<<endl;
p=p+2*dy;
}
x=x+1;
}
*x0=x;
*y0=y;
//cout << "\n X "<<x<<" and Y "<<y<<endl;
//cout << "\n X0 "<<*x0<<" and Y0 "<<*y0<<endl;
}
void display_ndots()
{glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5);
glColor3f(1.0, 0.0, 0.0);
//draw two points
glBegin(GL_POINTS);
for(int i = 0; i < 10; i++)
{ xx = cordinates[i][0];
yy = cordinates[i][1];
glVertex2i(xx,yy);
//printf("%i",xx);
}
glEnd();
glColor3f(0.0, 1.0, 0.0);
//draw a line
glLineWidth(3);
glBegin(GL_LINES);
for(counter = 0 ; counter < 3 ; counter ++){
for (p = 0 ; p < 3 ; p ++){
for (q = 0 ; q < 3 ; q ++){
if( matrix[p][q] == 1){
xx = cordinates[p][0];
yy = cordinates[p][1];
xxx = cordinates[q][0];
yyy = cordinates[q][1];
glVertex2i(xx,yy);
glVertex2i(xxx,yyy);
}
}
}
}
glEnd();
systemtime();
time_chekcer_cnt = 0;
for(time_chekcer_cnt = 0 ; time_chekcer_cnt <10 ; time_chekcer_cnt ++){
if (system_time == trains[time_chekcer_cnt][0]){
switch (time_chekcer_cnt)
{
case 0: printf("Trian number %i have been started server time is %i \n",time_chekcer_cnt,system_time);
/*Initializing Train Data*/
train0 = time_chekcer_cnt;
speed0 = trains[time_chekcer_cnt][1];
start0 = trains[time_chekcer_cnt][2];
cout<<"\n >>>>>>>>>>>>>"<<start0<<endl;
tempx0 = cordinates[start0][0];
tempy0 = cordinates[start0][1];
next0 = trains[time_chekcer_cnt][3];
nextx0 = cordinates[next0][0];
nexty0 = cordinates[next0][1];
;
i=0;
while (trains[time_chekcer_cnt][i] != 999) {
i = i+1;
}
final0 = trains[time_chekcer_cnt][i-1];//999 signifies invalid
printf("\nfinal station is %i \n",final0);
//tempx01 = cordinates[start0][0]+10;
//tempy01 = cordinates[start0][1];
break;
case 1:
printf("Trian number %i have been started server time is %i \n",time_chekcer_cnt,system_time);
/*Initializing Train Data*/
train1 = time_chekcer_cnt;
speed1 = trains[time_chekcer_cnt][1];
start1 = trains[time_chekcer_cnt][2];
cout<<"\n >>>>>>>>>>>>>"<<start0<<endl;
tempx1 = cordinates[start0][0];
tempy1 = cordinates[start0][1];
next1 = trains[time_chekcer_cnt][3];
nextx1 = cordinates[next0][0];
nexty1 = cordinates[next0][1];
;
i=0;
while (trains[time_chekcer_cnt][i] != 999) {
i = i+1;
}
final1 = trains[time_chekcer_cnt][i-1];//999 signifies invalid
printf("\nfinal station is %i \n",final0);
break;
//default: // code to be executed if n doesn't match any cases
}
}
}
if (train0 != 999){
glColor3f(1.0, 1.0, 0.0);
draw_dda( &tempx0, &tempy0 ,nextx0, nexty0,speed0);
cout << "Draving from corinates ("<<tempx0<<","<<tempy0<<") To ("<<nextx0<<","<<nexty0<<")"<<endl;
}
if (train1 != 999){
glColor3f(1.0, 1.0, 0.0);
/// cout << "original x and y are "<<nextx0<<" & "<<nexty0;
draw_dda( &tempx1, &tempy1 ,nextx1, nexty1,speed1);
cout << "Draving from corinates ("<<tempx0<<","<<tempy0<<") To ("<<nextx0<<","<<nexty0<<")"<<endl;
// drawline( &tempx0, &tempy0 ,nextx0, nexty0);
//draw_dda( &tempx01, &tempy01 ,nextx0+10, nexty0);
// cout<<"After call by reference it is :"<<nextx0<<" & "<<nexty0;
}
/*bresenham_circle(100, 100, r);
while (flag != 1){
r--;
cout <<"\n r is "<<r<<endl;
if (r == 0){
flag = 1;
}
}*/
glFlush();
glGetError();
}
void timlycall (int unused) {
glutPostRedisplay();
glutTimerFunc(1000, timlycall, 0);
}
int main(int argc,char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (900, 900);
glutInitWindowPosition (0, 0);
glutCreateWindow ("points and lines");
init2D();
glutDisplayFunc(display_ndots);
//glutDisplayFunc(init2D);
glutTimerFunc(0, timlycall, 0);
glutMainLoop();
return 0;
}
Please not macos have library GLUT but windows have GL
Update 1.0
OK folks we have made some progress :
Using GLUT_RGB in glreadpixel() gives error code 1280 i.e. detected
by method BDL have provided. Which stands for incorrect enumeration ,
so use GL_RGB inside glreadpixel()
Now one more interesting thing we have to tackle, i.e now GlReadPixel
is giving r:255 g: 255 b: 255 as output , i.e background color
instead of color that must be yellow , because we are calling the
function on point which lies on the circle that too after its
painted.
You are passing a wrong enumeration to glReadPixels. GLUT_RGB is not the same as GL_RGB and may thus not be used for this function.
This would have been reported as a GL_INVALID_ENUM error by glGetError(), but the error code is never checked. You should use something like:
GLenum error = glGetError();
if (error != GL_NO_ERROR)
std::cout << "OpenGL error: " << error << std::endl;
I am trying to call a function, only when "spacebar" is pressed. Its key code is 32.
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <cmath>
#include <iostream>
#include <string.h>
using namespace std;
GLuint window, View1;
void Display_Mid_Ellipse()
{
double xc=0.0, yc=0.0, rx=140.0, ry=200.0;
double rxSq = rx * rx;
double rySq = ry * ry;
double x = 0, y = ry, p;
double px = 0, py = 2 * rxSq * y;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f( 1 ,0, 0);
glBegin(GL_POINTS);
glVertex2d(xc+x,yc-y);
glVertex2d(xc-x,yc-y);
glVertex2d(xc-x,yc+y);
glEnd();
p = rySq - (rxSq * ry) + (0.25 * rxSq);
while (px < py)
{
x++;
px = px + 2 * rySq;
if (p < 0)
p = p + rySq + px;
else
{
y--;
py = py - 2 * rxSq;
p = p + rySq + px - py;
}
glBegin(GL_POINTS);
glVertex2d(xc+x,yc+y);
glVertex2d(xc+x,yc-y);
glVertex2d(xc-x,yc-y);
glVertex2d(xc-x,yc+y);
glEnd();
}
p = rySq*(x+0.5)*(x+0.5) + rxSq*(y-1)*(y-1) - rxSq*rySq;
while (y > 0)
{
y--;
py = py - 2 * rxSq;
if (p > 0)
p = p + rxSq - py;
else
{
x++;
px = px + 2 * rySq;
p = p + rxSq - py + px;
}
glBegin(GL_POINTS);
glVertex2d(xc+x,yc+y);
glVertex2d(xc+x,yc-y);
glVertex2d(xc-x,yc-y);
glVertex2d(xc-x,yc+y);
glEnd();
glFlush();
}
} //end_MIDPOINT_ELLIPSE
void init () {
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.3,0.3,0.3,0.7);
gluOrtho2D(-500.0,500.0,-500.0,500.0);
}
void View1Display()
{
glutSetWindow(View1);
gluOrtho2D(-500.0,500.0,-500.0,500.0);
Display_Mid_Ellipse();
}
void Display()
{
glutSetWindow(window);
glClear(GL_COLOR_BUFFER_BIT);
//View1Display();
}
void keyFunc(unsigned char ch, int x, int y){
if(ch==32){
View1Display();
}
}
int main (int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(750, 750);
glutInitWindowPosition(0, 0);
window=glutCreateWindow("Circle and ellipse");
init();
View1 = glutCreateSubWindow(window,20,40, 340,340);
glutDisplayFunc(Display);
glutKeyboardFunc(keyFunc);
glutMainLoop();
return 0;
}
When i call the same View1Display from the Display() function, it works well.
I'm confused. I have tried the alternatives I could but could not find a solution. Please help.
Thanks
Callbacks are registered for the active window (creating a window implicitly activates it) so you can register separate display callbacks for the toplevel window and your subwindow.
Don't call your subwindow display function from the keyboard callback. Toggle a shared variable & use glutPostWindowRedisplay() to force a redraw instead.
If you're going to use GLUT_SINGLE make sure to glFlush() to force updates out to the framebuffer.
All together:
#include <GL/glut.h>
#include <cmath>
using namespace std;
void Display_Mid_Ellipse()
{
double xc = 0.0, yc = 0.0, rx = 140.0, ry = 200.0;
double rxSq = rx * rx;
double rySq = ry * ry;
double x = 0, y = ry, p;
double px = 0, py = 2 * rxSq * y;
glClear( GL_COLOR_BUFFER_BIT );
glColor3f( 1, 0, 0 );
glBegin( GL_POINTS );
glVertex2d( xc + x, yc - y );
glVertex2d( xc - x, yc - y );
glVertex2d( xc - x, yc + y );
glEnd();
p = rySq - ( rxSq * ry ) + ( 0.25 * rxSq );
while( px < py )
{
x++;
px = px + 2 * rySq;
if( p < 0 )
p = p + rySq + px;
else
{
y--;
py = py - 2 * rxSq;
p = p + rySq + px - py;
}
glBegin( GL_POINTS );
glVertex2d( xc + x, yc + y );
glVertex2d( xc + x, yc - y );
glVertex2d( xc - x, yc - y );
glVertex2d( xc - x, yc + y );
glEnd();
}
p = rySq*( x + 0.5 )*( x + 0.5 ) + rxSq*( y - 1 )*( y - 1 ) - rxSq*rySq;
while( y > 0 )
{
y--;
py = py - 2 * rxSq;
if( p > 0 )
p = p + rxSq - py;
else
{
x++;
px = px + 2 * rySq;
p = p + rxSq - py + px;
}
glBegin( GL_POINTS );
glVertex2d( xc + x, yc + y );
glVertex2d( xc + x, yc - y );
glVertex2d( xc - x, yc - y );
glVertex2d( xc - x, yc + y );
glEnd();
glFlush();
}
} //end_MIDPOINT_ELLIPSE
bool displayEllipse = false;
void View1Display()
{
glClearColor( 0.3, 0.3, 0.3, 0.7 );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( -500.0, 500.0, -500.0, 500.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
if( displayEllipse )
Display_Mid_Ellipse();
glFlush();
}
void Display()
{
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
glFlush();
}
GLuint window;
GLuint View1;
void keyFunc( unsigned char ch, int x, int y )
{
if( ch == 32 )
{
displayEllipse = !displayEllipse;
glutPostWindowRedisplay( View1 );
}
}
int main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize( 750, 750 );
glutInitWindowPosition( 0, 0 );
window = glutCreateWindow( "Circle and ellipse" );
glutDisplayFunc( Display );
glutKeyboardFunc( keyFunc );
View1 = glutCreateSubWindow( window, 20, 40, 340, 340 );
glutDisplayFunc( View1Display );
glutMainLoop();
return 0;
}
I try in 3D but i am a beginner, so i try do with 2D first and value of z = 0. I have an array of points with values random in array points[] using std::vector. I have functions Distance(...) and CaculateF(...) to caculate new value for points[] and store in array pnew[]. I need draw points[] and move them to the value of pnew[], but i only know drawing random points in array points[] first, i can't move them exactly to values in pnew[]. Can anybody help me?!
#include<stdlib.h>
#include<glut.h>
#include<iostream>
#include<conio.h>
#include<math.h>
#include<omp.h>
#include<time.h>
#include<Windows.h>
#include<vector>
using namespace std;
struct Point
{
float x, y , z;
float vx, vy, vz;
unsigned long m;
unsigned char r, g, b, a;
};
vector< Point > points, pnew;
void animation_points( int value )
{
// move all points left each frame
for( size_t i = 0; i < points.size(); ++i )
{
points[i].x -= 1;
// wrap point around if it's moved off
// the edge of our 100x100 area
if( points[i].x < -50 )
{
points[i].x = 100 + points[i].x;
}
}
glutPostRedisplay();
glutTimerFunc(30, animation_points, 1);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50, 50, -50, 50, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// draw
glColor3ub( 255, 255, 255 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
glVertexPointer( 2, GL_FLOAT, sizeof(Point), &points[0].x );
glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(Point), &points[0].r );
glPointSize( 3.0 );
glDrawArrays( GL_POINTS, 0, points.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
}
//Distance between i and j
float Distance(float x1,float y1, float z1, float x2, float y2, float z2)
{
return (sqrt(pow(x1-x2,2) + pow(y1-y2,2) + pow(z1-z2,2)));
}
//Value of F on Ox, Oy, Oz
Point CalculateF(double d, Point a, Point b, int dt)
{
Point F;
float vnewx, vnewy, vnewz, xnew , ynew, znew;
float G = 6.6742*pow(10,-11);
float Fx = (G*a.m*b.m/pow(d,2)*(a.x-b.x)/d);
float Fy = (G*a.m*b.m/pow(d,2)*(a.y-b.y)/d);
float Fz = (G*a.m*b.m/pow(d,2)*(a.z-b.z)/d);
vnewx = a.vx + Fx*dt/a.m;
vnewy = a.vy + Fy*dt/a.m;
vnewz = a.vz + Fz*dt/a.m;
xnew = a.x + a.x*dt;
ynew = a.y + a.y*dt;
znew = a.z + a.z*dt;
F.x = xnew;
F.y = ynew;
F.z = znew;
F.vx = vnewx;
F.vy = vnewy;
F.vz = vnewz;
F.m = a.m;
return F;
}
int main(int argc, char **argv)
{
// begin
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(640,480);
glutCreateWindow("N - body");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
// animation points
//glutTimerFunc(30, animation_points, 1);
////
int n, t;
cout<<"\n Number of body: ";
cin>>n;
// move after time t
cout<<"\n\n Time: ";
cin>>t;
t *= 3600;
// random points
for( int i = 0; i < n; ++i )
{
Point pt;
pt.x = -50 + (rand() % 100);
pt.y = -50 + (rand() % 100);
pt.z = 0;
pt.r = rand() % 255;
pt.g = rand() % 255;
pt.b = rand() % 255;
pt.a = 255;
points.push_back(pt);
}
glutMainLoop();
float d;
//#pragma omp parallel default(shared) private(i,j)
for (int i = 0 ; i < n ; i++)
{
//#pragma omp for schedule(static)
for (int j = 0 ; j < n ; j++)
{
d = Distance(points[i].x, points[i].y,points[i].z, points[j].x, points[j].y, points[j].z);
if (d!=0)
points[i] = CalculateF(d,points[i], points[j], t);
}
pnew.push_back(points[i]);
}
return 0;
}
You need to store the initial and the target positions of your points in arrays, then interpolate between them in the rendering code. To do that, you determine how much time has passed, compute a double lambda in the range 0.0 to 1.0 from the time, then draw the points at the position p_start + lambda * (p_target - p_start).