Page 1 of 1

A basic Tracing Function for OpenGL

PostPosted: Fri Sep 18, 2020 2:30 pm
by hbyte
With the task of creating a Harry Plotter - download source at https://github.com/housebyte/HarryPlotter for Windows instead of Linux, ive been tinkering at OpenGL to use as the renderer instead of Xwindows X11 library used by the Harry Plotter. After some frantic research about buffering Ive finally got a trace that works heres my shifty 'first go at it' code in C++. Enjoy:

(Hope it might help anyone wishing to do a data trace for windows from their Algo.)

Code: Select all
/* Include Files */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <GL/freeglut.h>
#ifdef _MSC_VER
/* DUMP MEMORY LEAKS */
#include <crtdbg.h>
#endif

int trace_index;                     /* index of trace */
double red_position[2][3];                  /* X,Y,Z of red trace*/
double xcen = 0.0, ycen = 0.0, zcen = 0.0 ;   /* Coordinates of the point looked at */

int endofindex = 0;
double lines[300][3];
int numlines = 0;


The above is just the headers and the arrays for storing the trace which gets sent to the buffer using the following functions:

Code: Select all
void draw_line2buffer(double position[2][3]){

/*if end of screen reached*/
if(position[1][0]==endofindex){
   numlines=1;
   lines[0][1] = position[0][1];
   lines[0][0] = position[0][0];
   
   lines[1][1] = position[1][1];
   lines[1][0] = position[1][0];
}else{
   
   numlines+=1;
   
   lines[numlines-1][1] = position[0][1];
   lines[numlines-1][0] = position[0][0];
   
   lines[numlines][1] = position[1][1];
   lines[numlines][0] = position[1][0];
   
   
}


glNewList(2,GL_COMPILE);
glBegin ( GL_LINES ) ;
glColor3f(1.0,0.0,0.0);

for(int i=1;i<numlines;i++){
   
glVertex3d ( lines[i-1][0], lines[i-1][1], 0.0 ) ;
glVertex3d ( lines[i][0], lines[i][1], 0.0 ) ;   

printf("Position:%f , %f \n",lines[i-1][0],lines[i-1][1]);
printf("**************************************************\n");
printf("Position:%f , %f \n",lines[i][0],lines[i][1]);
 
}
glEnd () ;

printf("End of buffer*************************************\n");

glEndList();
}



Thats the buffer having been written to now the display function for writing to the window followed by the timer which kicks out the data continously to the red_points array:

Code: Select all
void display ( void )
{
      
  glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;

//glCallList( 1 );  :- you can call multiple lists from the buffer!! means Multiple traces
//glColor3d (1.0,0.0,0.0);
//glCallList( 1 );
glCallList( 2 );
 
  glColor3d ( 1.0, 1.0, 0.0 ) ;  /* White */
  /* Draw some axes */
  glBegin ( GL_LINES ) ;
  glVertex3d ( 1.0, 0.0, 0.0 ) ;
  glVertex3d ( -1.0, 0.0, 0.0 ) ;
 
  glVertex3d ( 0.0, 1.0, 0.0 ) ; /*Y coord*/
  glVertex3d ( 0.0, -1.0, 0.0 ) ;
 
 glEnd () ;
 
 glutSwapBuffers( );
 glFlush( );
 
}



And the timer function:

Code: Select all
void timer(int value){

/* Make your data come in here */
double x = ((double)trace_index);
double y = sin(x);
double z = 0;

Sleep(10);
   
/* Set the next timed callback */
glutTimerFunc ( 30, timer, 0 ) ;
   
/*set the last data as the first*/
for(int i=0;i<3;i++){
red_position[0][i]   = red_position[1][i];
}

red_position[1][0] = x/100;
red_position[1][1] = y;
red_position[1][2] = z;

/*reset the index when trace gets to the end of screen*/
if(trace_index>100){
trace_index=0;}else{
trace_index = trace_index+1;
}

draw_sphere2(red_position);
draw_line2buffer(red_position);

glutPostRedisplay () ;

}



And tie it all together with some initializing and a GlutMainloop:

Code: Select all
int main ( int argc, char *argv[] )
{
  int pargc = argc ;
 
  /* Initialize the array */
  srand ( 1023 ) ;
  for(int i=0;i<3;i++){
  red_position[1][i] = 0;
            }
  trace_index = 0;

  /* Set up the OpenGL parameters */
  glEnable ( GL_DEPTH_TEST ) ;
  glClearColor ( 0.0, 0.0, 0.0, 0.0 ) ;
  glClearDepth ( 1.0 ) ;

  /* Initialize GLUT */
  glutInitWindowSize ( 600, 600 ) ;
  glutInit ( &pargc, argv ) ;
  glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;

  /* Create the window */
  glutCreateWindow ( "Harry Plotter" ) ;
 
  glutDisplayFunc ( display ) ;
  //glutReshapeFunc ( reshape ) ; - Not used (not really what its for!!)
  glutTimerFunc   ( 30, timer, 0  ) ;
    /* Enter the GLUT main loop */
  glutMainLoop () ;

#ifdef _MSC_VER
  /* DUMP MEMORY LEAK INFORMATION */
  _CrtDumpMemoryLeaks () ;
#endif

  return 0 ;
 
}


I think that nailed it. I am sure there are other methods but this will do for me.
With Mingw64 installed on Windows compile with g++ -o Trace Trace.cpp -lopengl32 -lfreeglut -lglu32

freeglut can be downloaded and placed in each of Mingw folders include/ bin/ system32/*dll lib/*lib

Sneak a peak @ Shepherds latest works DarkSide - Chapter 2 - The Watchers

Or Read Kromos now :

Image

Re: A basic Tracing Function for OpenGL

PostPosted: Fri Sep 18, 2020 3:38 pm
by hbyte
Heres one with a pulsating yellow orb which has its radius changing with the traced sin(x^2) function.

Code: Select all
/* Include Files */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <GL/freeglut.h>
#ifdef _MSC_VER
/* DUMP MEMORY LEAKS */
#include <crtdbg.h>
#endif

int trace_index;                     /* index of trace */
double red_position[2][3];                  /* X,Y,Z of red trace*/
double xcen = 0.0, ycen = 0.0, zcen = 0.0 ;   /* Coordinates of the point looked at */
GLuint   SphereList;
GLUquadricObj *qobj;

int endofindex = 0;
double lines[300][3];
int numlines = 0;
/*display , reshape and timer

timer receives tcp/ip data and produces a point array which is plotted through the display function

*/

void draw_line(double position[2][3]);
void display();
void reshape ( int width, int height );
void timer (int value);

/*Draw line between two points updated via timer*/

void draw_sphere2(double position[2][3]){
   
   
   
   gluQuadricDrawStyle(qobj, GLU_FILL);
  glNewList(1, GL_COMPILE);  /* create sphere display list */
  glColor3f( .9f, .9f, 0. );
  gluSphere(qobj, /* radius */ position[1][1]*8, /* slices */ 20,  /* stacks

                                                       */ 20);
  glEndList();
}

void draw_line2buffer(double position[2][3]){

/*if end of screen reached*/
if(position[1][0]==endofindex){
   numlines=1;
   lines[0][1] = 0;//position[0][1];
   lines[0][0] = 0;//position[0][0];
   
   lines[1][1] = 0;//position[1][1];
   lines[1][0] = 0;//position[1][0];
}else{
   
   numlines+=1;
   
   lines[numlines-1][1] = position[0][1];
   lines[numlines-1][0] = position[0][0];
   
   lines[numlines][1] = position[1][1];
   lines[numlines][0] = position[1][0];
   
   
}


glNewList(2,GL_COMPILE);
glBegin ( GL_LINES ) ;
glColor3f(1.0,0.0,0.0);

for(int i=1;i<numlines;i++){
   
glVertex3d ( lines[i-1][0], lines[i-1][1], 0.0 ) ;
glVertex3d ( lines[i][0], lines[i][1], 0.0 ) ;   

printf("Position:%f , %f \n",lines[i-1][0],lines[i-1][1]);
printf("**************************************************\n");
printf("Position:%f , %f \n",lines[i][0],lines[i][1]);
 
}
glEnd () ;

printf("End of buffer*************************************\n");

glEndList();
}



void display ( void )
{
      
  glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;

//glCallList( 1 );
//glColor3d (1.0,0.0,0.0);
glCallList( 1 );
glCallList( 2 );
 
  glColor3d ( 1.0, 1.0, 0.0 ) ;  /* White */
  /* Draw some axes */
  glBegin ( GL_LINES ) ;
  glVertex3d ( 1.0, 0.0, 0.0 ) ;
  glVertex3d ( -1.0, 0.0, 0.0 ) ;
 
  /*glVertex3d ( 0.0, 0.0, 0.0 ) ;
  glVertex3d ( -1.0, 0.0, 0.0 ) ;
  */
  glVertex3d ( 0.0, 1.0, 0.0 ) ; /*Y coord*/
  glVertex3d ( 0.0, -1.0, 0.0 ) ;
 
 glEnd () ;

 glutSwapBuffers( );
 glFlush( );
 
 
}


void reshape ( int width, int height )
{
  float ar;
  glViewport ( 0, 0, width, height ) ;
  glMatrixMode ( GL_PROJECTION ) ;
  glLoadIdentity () ;
  ar = (float) width / (float) height ;
  glFrustum ( -ar, ar, -1.0, 1.0, 10.0, 100.0 ) ;
  glMatrixMode ( GL_MODELVIEW ) ;
  glLoadIdentity () ;
  xcen = 0.0 ;
  ycen = 0.0 ;
  zcen = 0.0 ;
  glTranslated ( xcen, ycen, zcen - 50.0 ) ;
}

void wait (int seconds){

clock_t endwait;
endwait = clock() + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}

}

void timer(int value){


double x = ((double)trace_index);
double y = sin(pow(x,2));
double z = 0;

Sleep(10);
   
/* Set the next timed callback */
glutTimerFunc ( 30, timer, 0 ) ;
   
for(int i=0;i<3;i++){
red_position[0][i]   = red_position[1][i];
}

red_position[1][0] = x/100;
red_position[1][1] = y/15;
red_position[1][2] = z;


if(trace_index>100){
trace_index=0;}else{
trace_index = trace_index+1;
}

draw_sphere2(red_position);
draw_line2buffer(red_position);

glutPostRedisplay () ;

}

int main ( int argc, char *argv[] )
{
  int pargc = argc ;
  qobj = gluNewQuadric();
  /* Initialize the random number generator */
  srand ( 1023 ) ;
  for(int i=0;i<3;i++){
  red_position[1][i] = 0;
            }
  trace_index = 0;

  /* Set up the OpenGL parameters */
  glEnable ( GL_DEPTH_TEST ) ;
  glClearColor ( 0.0, 0.0, 0.0, 0.0 ) ;
  glClearDepth ( 1.0 ) ;

  /* Initialize GLUT */
  glutInitWindowSize ( 600, 600 ) ;
  glutInit ( &pargc, argv ) ;
  glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;


 

  /* Create the window */
  glutCreateWindow ( "Harry Plotter" ) ;
 
  glutDisplayFunc ( display ) ;
  //glutReshapeFunc ( reshape ) ;
  glutTimerFunc   ( 30, timer, 0  ) ;
    /* Enter the GLUT main loop */
  glutMainLoop () ;

#ifdef _MSC_VER
  /* DUMP MEMORY LEAK INFORMATION */
  _CrtDumpMemoryLeaks () ;
#endif

  return 0 ;
 
}


Image
Image