Hi ,
I am working on implementing a line clipping algorithm by cohen -sutherland.The below code is using Open GL.
Could somebody look at it and let me know how to fix these errors ive cleaned up most of it but not successful yet.
The code :
--------------------------
----------
----------
-----
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct point {
int x ;
int y ; } ;
struct segment {
point pi ;
point pf ; } ;
struct rectangle {
point sg ;
point id ; } ;
static int aff = 0 ;
static segment s = { -5,0,5,0 } ;
static int p1 = 1 ;
void traceSegment(int xi,int yi,int xf,int yf,float *c) {
glColor3fv(c) ;
glBegin(GL_LINES) ;
glVertex2f((float) xi,(float) yi) ;
glVertex2f((float) xf,(float) yf) ;
glEnd() ;
}
void pixel(int x,int y,float *c) {
glColor3fv(c) ;
glBegin(GL_QUADS) ;
glVertex2f(x-0.5F,y-0.5F) ;
glVertex2f(x-0.5F,y+0.5F) ;
glVertex2f(x+0.5F,y+0.5F) ;
glVertex2f(x+0.5F,y-0.5F) ;
glEnd() ;
}
void line(int xi,int yi,int xf,int yf,float *c) {
int dx,dy,i,xinc,yinc,cumul,x,
y ;
x = xi ;
y = yi ;
dx = xf - xi ;
dy = yf - yi ;
xinc = ( dx > 0 ) ? 1 : -1 ;
yinc = ( dy > 0 ) ? 1 : -1 ;
dx = abs(dx) ;
dy = abs(dy) ;
pixel(x,y,c) ;
if ( dx > dy ) {
cumul = dx / 2 ;
for ( i = 1 ; i <= dx ; i++ ) {
x += xinc ;
cumul += dy ;
if (cumul >= dx) {
cumul -= dx ;
y += yinc ; }
pixel(x,y,c) ; } }
else {
cumul = dy / 2 ;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc ;
cumul += dx ;
if ( cumul >= dy ) {
cumul -= dy ;
x += xinc ; }
pixel(x,y,c) ; } }
}
void traceRectangle(rectangle *r,float *c) {
line(r->id.x,r->id.y,r->id
.x,r->sg.y
,c) ;
line(r->id.x,r->sg.y,r->sg
.x,r->sg.y
,c) ;
line(r->id.x,r->id.y,r->sg
.x,r->id.y
,c) ;
line(r->sg.x,r->id.y,r->sg
.x,r->sg.y
,c) ;
}
int code(point *p,rectangle *r) {
int c ;
if ( p->x < r->sg.x )
c = 1 ;
else
c = 0 ;
if ( p->x > r->id.x )
c += 2 ;
if ( p->y < r->sg.y )
c += 4 ;
if ( p->y > r->id.y )
c += 8 ;
return(c) ;
}
int code_nul(int c) {
return(c == 0) ;
}
int pas1commun(int c1,int c2) {
return((c1&c2) == 0) ;
}
int code0(int c) {
return(c&1) ;
}
int code1(int c) {
return(c&2) ;
}
int code2(int c) {
return(c&4) ;
}
int code3(int c) {
return(c&8) ;
}
int intersection(int ai,int bi,int af,int bf,int val) {
int res = 0 ;
if ( af-ai != 0 )
res =(int) (bi +(double) (val-ai) / (af-ai) * (bf-bi)) ;
else
res = 32767 ;
return(res) ;
}
void clipperSegment(rectangle *r,segment *s,float *c) {
segment se = *s ;
int c1,c2 ;
point p ;
c1 = code(&s->pi,r) ;
c2 = code(&s->pf,r) ;
while ( ( !code_nul(c1) || !code_nul(c2) ) && ( pas1commun(c1,c2) ) ) {
if ( code_nul(c1) ) {
p = s->pi ;
s->pi = s->pf ;
s->pf = p ;
c1 = c2 ; }
if ( code0(c1) ) {
s->pi.y = intersection(s->pi.x,s->pi
.y,s->pf.x
,s->pf.y,r
->sg.x) ;
s->pi.x = r->sg.x ; }
else
if ( code1(c1) ) {
s->pi.y = intersection(s->pi.x,s->pi
.y,s->pf.x
,s->pf.y,r
->id.x) ;
s->pi.x = r->id.x ; }
else
if ( code2(c1) ) {
s->pi.x = intersection(s->pi.y,s->pi
.x,s->pf.y
,s->pf.x,r
->sg.y) ;
s->pi.y = r->sg.y ; }
else
if ( code3(c1) ) {
s->pi.x = intersection(s->pi.y,s->pi
.x,s->pf.y
,s->pf.x,r
->id.y) ;
s->pi.y = r->id.y ; }
c1 = code(&s->pi,r) ;
c2 = code(&s->pf,r) ; }
if ( code_nul(c1) && code_nul(c2) )
line(s->pi.x,s->pi.y,s->pf
.x,s->pf.y
,c) ;
*s = se ;
}
void CALLBACK display() {
float black[] = { 0.0F,0.0F,0.0F,1.0F };
float red[] = { 1.0F,0.0F,0.0F,1.0F };
float white[] = { 0.0F,1.0F,0.0F,1.0F };
float blue[] = { 0.0F,0.0F,1.0F,1.0F } ;
float orange[] = { 1.0F,1.0F,0.0F,1.0F };
float cyan[] = { 0.0F,1.0F,1.0F,1.0F };
float magenta[] = { 1.0F,0.0F,1.0F,1.0F };
float green[] = { 1.0F,1.0F,1.0F,1.0F };
rectangle r = { -17,-13,16,11 } ;
segment s1 = { -20,-18,6,1 } ;
segment s2 = { -25,3,13,18 } ;
segment s3 = { 23,13,27,-17 } ;
segment s4 = { 13,8,-11,3 } ;
segment s5 = { 23,-9,11,-18 } ;
segment s6 = { 16,-7,16,19 } ;
segment s7 = { -6,-13,9,-13 } ;
glClear(GL_COLOR_BUFFER_BI
T|GL_DEPTH
_BUFFER_BI
T);
glPushMatrix();
switch ( aff) {
case 0 : traceRectangle(&r,blue) ;
line(s1.pi.x,s1.pi.y,s1.pf
.x,s1.pf.y
,white) ;
line(s2.pi.x,s2.pi.y,s2.pf
.x,s2.pf.y
,red) ;
line(s3.pi.x,s3.pi.y,s3.pf
.x,s3.pf.y
,orange) ;
line(s4.pi.x,s4.pi.y,s4.pf
.x,s4.pf.y
,black) ;
line(s5.pi.x,s5.pi.y,s5.pf
.x,s5.pf.y
,green) ;
line(s6.pi.x,s6.pi.y,s6.pf
.x,s6.pf.y
,cyan) ;
line(s7.pi.x,s7.pi.y,s7.pf
.x,s7.pf.y
,magenta) ;
break ;
case 1 : traceRectangle(&r,blue) ;
clipperSegment(&r,&s1,whit
e) ;
clipperSegment(&r,&s2,red)
;
clipperSegment(&r,&s3,oran
ge) ;
clipperSegment(&r,&s4,blac
k) ;
clipperSegment(&r,&s5,gree
n) ;
clipperSegment(&r,&s6,cyan
) ;
clipperSegment(&r,&s7,mage
nta) ;
break ;
case 2 : traceRectangle(&r,blue) ;
clipperSegment(&r,&s,red) ;
pixel(s.pi.x,s.pi.y,orange
) ;
pixel(s.pf.x,s.pf.y,orange
) ;
break ; }
glPopMatrix();
glFlush();
auxSwapBuffers() ;
}
void CALLBACK reshape(int w,int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION
);
glLoadIdentity();
glOrtho(-30.0,30.0,-20.0,2
0.0,-40.0,
40.0);
glMatrixMode(GL_MODELVIEW)
;
glLoadIdentity();
}
void CALLBACK auxKeyReturn() {
aff++ ;
if ( aff == 3 )
aff = 0 ;
}
void CALLBACK auxKeyEspace() {
p1 = !p1 ;
}
void CALLBACK auxKeyUp() {
if ( p1 ) {
s.pi.y++ ;
if ( s.pi.y > 20 )
s.pi.y = 20 ; }
else {
s.pf.y++ ;
if ( s.pf.y > 20 )
s.pf.y = 20 ; }
}
void CALLBACK auxKeyDown() {
if ( p1 ) {
s.pi.y-- ;
if ( s.pi.y < -20 )
s.pi.y = -20 ; }
else {
s.pf.y-- ;
if ( s.pf.y < -20 )
s.pf.y = -20 ; }
}
void CALLBACK auxKeyRight() {
if ( p1 ) {
s.pi.x++ ;
if ( s.pi.x > 30 )
s.pi.x = 30 ; }
else {
s.pf.x++ ;
if ( s.pf.x > 30 )
s.pf.x = 30 ; }
}
void CALLBACK auxKeyLeft() {
if ( p1 ) {
s.pi.x-- ;
if ( s.pi.x < -30 )
s.pi.x = -30 ; }
else {
s.pf.x-- ;
if ( s.pf.x < -30 )
s.pf.x = -30 ; }
}
void CALLBACK init() {
glShadeModel(GL_SMOOTH);
glClearColor(0.8F,0.8F,0.8
F,1.0F);
}
void main(void) {
auxInitDisplayMode(AUX_DOU
BLE|AUX_RG
BA|AUX_DEP
TH);
auxInitPosition (0,0,300,200);
auxInitWindow("Clipping For Cohen-Sutherland") ;
init();
auxKeyFunc(AUX_RETURN,auxK
eyReturn) ;
auxKeyFunc(AUX_SPACE,auxKe
yEspace) ;
auxKeyFunc(AUX_UP,auxKeyUp
) ;
auxKeyFunc(AUX_DOWN,auxKey
Down) ;
auxKeyFunc(AUX_LEFT,auxKey
Left) ;
auxKeyFunc(AUX_RIGHT,auxKe
yRight) ;
auxReshapeFunc(reshape);
auxMainLoop(display);
}