Skip to content

Instantly share code, notes, and snippets.

@mfilipelino
Last active November 13, 2024 17:41
Show Gist options
  • Save mfilipelino/11240714 to your computer and use it in GitHub Desktop.
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.
#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