Last active
November 13, 2024 17:41
-
-
Save mfilipelino/11240714 to your computer and use it in GitHub Desktop.
Paint Brush simples usando opengl e glut usando algoritmo bresenham para desenha linha, circulo e retangulo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef __APPLE__ | |
#include <GLUT/glut.h> | |
#else | |
#include <GL/gl.h> | |
#include <GL/glut.h> | |
#endif | |
#include <math.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define FIRST 0 | |
int SCREEN[2] = {800,800}; | |
// teclas do mouse | |
int mouse_x0; | |
int mouse_y0; | |
int mouse_x1; | |
int mouse_y1; | |
// estado dos clicks | |
int STATE = 0; | |
double RGB[3]; | |
int SIZE = 1; | |
char MODE; | |
double getX(int x){ | |
return (double) (x/(SCREEN[0]/2.0)) -1.0; | |
} | |
double getY(int y){ | |
return (double) -(y/(SCREEN[1]/2.0)) +1.0; | |
} | |
void wipeVertex(){ | |
//limpa os vertices do vetor de vertices | |
mouse_x0 = SCREEN[0]/2.0; | |
mouse_y0 = SCREEN[1]/2.0; | |
mouse_x1 = SCREEN[0]/2.0; | |
mouse_y1 = SCREEN[1]/2.0; | |
STATE = 0; | |
} | |
void setPixel(int x, int y){ | |
glBegin(GL_POINTS); | |
glVertex2f(getX(x), getY(y)); | |
glEnd(); | |
} | |
void Linha(int x0, int y0, int x1, int y1) { | |
int dx = abs(x1-x0); //diferenca absoluta entre xFinal e xInicial | |
int sx = x0<x1 ? 1 : -1; //modificador de sinal de x, denota se x cresce ou descresce | |
int dy = abs(y1-y0); //diferenca absoluta entre yFinal e yInicial | |
int sy = y0<y1 ? 1 : -1; //modificador de sinal de y, denota se y cresce ou descresce | |
int erro = (dx>dy ? dx : -dy)/2; //baseando-se na maior diferenca, define-se o erro inicial | |
int erroTemp; //erro de cada iteracao | |
while(true){ | |
setPixel(x0,y0); //imprime ponto | |
if ((x0==x1) && (y0==y1)) | |
break; //ponto final atingido, encerra algoritmo | |
erroTemp = erro; //atualiza erro | |
if (erroTemp > -dx) { | |
erro -= dy; //decrementa erro com a diferenca absoluta entre yFinal e yInicial | |
x0 += sx; //incrementa (ou decrementa) x | |
} | |
if (erroTemp < dy) { | |
erro += dx; //incrementa erro com a diferenca absoluta entre xFinal e xInicial | |
y0 += sy; //incrementa (ou decrementa) y | |
} | |
} | |
} | |
void Circulo(int xc, int yc, int r){ | |
int x = 0; | |
int y = r; | |
int p = 1 - r; | |
setPixel(xc + x, yc + y); | |
setPixel(xc - x, yc + y); | |
setPixel(xc + x, yc - y); | |
setPixel(xc - x, yc - y); | |
setPixel(xc + y, yc + x); | |
setPixel(xc - y, yc + x); | |
setPixel(xc + y, yc - x); | |
setPixel(xc - y, yc - x); | |
while(x < y){ | |
x++; | |
if(p < 0){ | |
p = p + 2*x + 1; | |
} | |
else{ | |
y--; | |
p = p + 2*(x-y) + 1; | |
} | |
setPixel(xc + x, yc + y); | |
setPixel(xc - x, yc + y); | |
setPixel(xc + x, yc - y); | |
setPixel(xc - x, yc - y); | |
setPixel(xc + y, yc + x); | |
setPixel(xc - y, yc + x); | |
setPixel(xc + y, yc - x); | |
setPixel(xc - y, yc - x); | |
} | |
// glEnd(); | |
} | |
void Retangulo( int x0, int y0, int x1, int y1){ | |
Linha(x0, y0, x1, y0); | |
Linha(x1, y0, x1, y1); | |
Linha(x1, y1, x0, y1); | |
Linha(x0, y0, x0, y1); | |
} | |
void Display(){ | |
int dist; | |
int static clean = 0; | |
//limpa a tela e os buffers | |
glClearColor(255, 255, 255, 0.0); | |
if( clean == 0){ // limpa tela na primeira execução | |
glClear(GL_COLOR_BUFFER_BIT); | |
clean++; | |
} | |
//define cor | |
glColor3f(RGB[0],RGB[1],RGB[2]); | |
//define espessura | |
glPointSize(SIZE); | |
//debug | |
// printf("COLOR=%g,%g,%g\n", RGB[0],RGB[1],RGB[2]); | |
// printf("SIZE=%d\n", SIZE); | |
// printf("MODE=%c\n", MODE); | |
//printf("VERTEX=%d/%d\n",VERTEX,VERTEX_COUNT); | |
if( STATE ){ | |
switch( MODE ){ | |
case 'C': | |
if( STATE == 2){ | |
dist = sqrt( pow (mouse_x1 - mouse_x0, 2) + pow (mouse_y1 - mouse_y0, 2)); | |
Circulo(mouse_x0, mouse_y0, dist); | |
STATE = 0; | |
} | |
break; | |
case 'R': | |
Linha(mouse_x0, mouse_y0, mouse_x1, mouse_y1); | |
break; | |
case 'B': | |
if( STATE == 2){ | |
Retangulo(mouse_x0, mouse_y0, mouse_x1, mouse_y1); | |
STATE = 0; | |
} | |
break; | |
} | |
} | |
printf("\n"); | |
glFlush(); | |
} | |
void Mouse(int button, int state, int x, int y) { | |
switch(button){ | |
case GLUT_LEFT_BUTTON: | |
if(state == GLUT_DOWN){ | |
if( STATE == FIRST ){ | |
mouse_x0 = x; | |
mouse_y0 = y; | |
mouse_x1 = x; | |
mouse_y1 = y; | |
STATE++; | |
}else if( STATE > 0){ | |
mouse_x0 = mouse_x1; | |
mouse_y0 = mouse_y1; | |
mouse_x1 = x; | |
mouse_y1 = y; | |
STATE++; | |
} | |
} | |
break; | |
case GLUT_MIDDLE_BUTTON: | |
if( state == GLUT_DOWN ) | |
wipeVertex(); | |
} | |
glutPostRedisplay(); | |
} | |
void KeyboardSpecial(int key, int x, int y){ | |
switch( key ){ | |
case GLUT_KEY_UP:{ | |
if( SIZE <= 10 ){ | |
SIZE++; | |
} | |
} | |
break; | |
case GLUT_KEY_DOWN:{ | |
if( SIZE >= 1 ){ | |
SIZE--; | |
} | |
} | |
break; | |
} | |
} | |
void Keyboard(unsigned char key, int x, int y) { | |
switch(key) { | |
case 'r': | |
case 'R':{ | |
MODE = 'R'; | |
wipeVertex(); | |
} | |
break; | |
case 'c': | |
case 'C':{ | |
MODE = 'C'; | |
wipeVertex(); | |
} | |
break; | |
case 'b': | |
case 'B':{ | |
MODE = 'B'; | |
wipeVertex(); | |
} | |
break; | |
case 'l': | |
case 'L':{ | |
glClear(GL_COLOR_BUFFER_BIT); | |
wipeVertex(); | |
} | |
break; | |
case '0': { | |
RGB[0] = 0.0; | |
RGB[1] = 0.0; | |
RGB[2] = 0.0; | |
} | |
break; | |
case '1': { | |
RGB[0] = 0.0; | |
RGB[1] = 1.0; | |
RGB[2] = 0.0; | |
} | |
break; | |
case '2': { | |
RGB[0] = 1.0; | |
RGB[1] = 0.0; | |
RGB[2] = 0.0; | |
} | |
break; | |
case '3': { | |
RGB[0] = 1.0; | |
RGB[1] = 1.0; | |
RGB[2] = 0.0; | |
} | |
break; | |
case '4': { | |
RGB[0] = 1.0; | |
RGB[1] = 0.0; | |
RGB[2] = 1.0; | |
} | |
break; | |
case '5': { | |
RGB[0] = 0.0; | |
RGB[1] = 1.0; | |
RGB[2] = 1.0; | |
} | |
break; | |
case '6': { | |
RGB[0] = 0.0; | |
RGB[1] = 0.0; | |
RGB[2] = 1.0; | |
} | |
break; | |
case '7': { | |
RGB[0] = 0.25; | |
RGB[1] = 0.5; | |
RGB[2] = 0.75; | |
} | |
break; | |
case '8': { | |
RGB[0] = 0.75; | |
RGB[1] = 0.25; | |
RGB[2] = 0.5; | |
} | |
break; | |
case '9': { | |
RGB[0] = 0.5; | |
RGB[1] = 0.75; | |
RGB[2] = 0.25; | |
} | |
break; | |
case 27: { | |
exit(0); | |
} | |
break; | |
} | |
glutPostRedisplay(); | |
} | |
int main(int argc, char *argv[]){ | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); | |
glutInitWindowPosition(0,0); | |
glutInitWindowSize(SCREEN[0],SCREEN[1]); | |
glutCreateWindow("OPENGL PAINT"); | |
glutDisplayFunc(Display); | |
glutMouseFunc(Mouse); | |
glutKeyboardFunc(Keyboard); | |
glutSpecialFunc(KeyboardSpecial); | |
Keyboard('0',0,0); //cor preta. | |
Keyboard('R',0,0); // reta | |
glutMainLoop(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment