UTNianos

Versión completa: OpenGL - OpenCV - Linux
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Páginas: 1 2
Bueno, me puse a investigar un poco esta fusión de tecnologías... Y la verdad me costo un poco poder usar la imagen capturada de una webcam como textura (aunque una vez que di en el clavo, me di cuenta que era una pelotudez), y como por lo menos a mi me costo, comparto el codigo boludo...
Spoiler: Mostrar




#include <stdio.h>
#include <stdlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/keysym.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"

CvCapture* capture = NULL;
/* stuff about our window grouped together */
typedef struct {
Display *dpy;
int screen;
Window win;
GLXContext ctx;
XSetWindowAttributes attr;
Bool fs;
XF86VidModeModeInfo deskMode;
int x, y;
unsigned int width, height;
unsigned int depth;
} GLWindow;

typedef struct {
int width;
int height;
unsigned char *data;
} textureImage;

/* attributes for a single buffered visual in RGBA format with at least
* 4 bits per color and a 16 bit depth buffer */
static int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None};

/* attributes for a double buffered visual in RGBA format with at least
* 4 bits per color and a 16 bit depth buffer */
static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None };

GLWindow GLWin;
Bool done;
GLfloat rotX; /* X Rotation */
GLfloat rotY; /* Y Rotation */
GLfloat rotZ; /* Z Rotation */

GLfloat zoom;
GLfloat xmove;
GLfloat ymove;
GLuint texture[1]; /* Storage For One Texture */

/* simple loader for 24bit bitmaps (data is in rgb-format) */
int loadBMP(char *filename, textureImage *texture)
{
FILE *file;
unsigned short int bfType;
long int bfOffBits;
short int biPlanes;
short int biBitCount;
long int biSizeImage;
int i;
unsigned char temp;
/* make sure the file is there and open it read-only (binary) */
if ((file = fopen(filename, "rb")) == NULL)
{

return 0;
}
if(!fread(&bfType, sizeof(short int), 1, file))
{

return 0;
}
/* check if file is a bitmap */
if (bfType != 19778)
{

return 0;
}
/* get the file size */
/* skip file size and reserved fields of bitmap file header */
fseek(file, 8, SEEK_CUR);
/* get the position of the actual bitmap data */
if (!fread(&bfOffBits, sizeof(long int), 1, file))
{

return 0;
}

/* skip size of bitmap info header */
fseek(file, 4, SEEK_CUR);
/* get the width of the bitmap */
fread(&texture->width, sizeof(int), 1, file);

/* get the height of the bitmap */
fread(&texture->height, sizeof(int), 1, file);

/* get the number of planes (must be set to 1) */
fread(&biPlanes, sizeof(short int), 1, file);
if (biPlanes != 1)
{

return 0;
}
/* get the number of bits per pixel */
if (!fread(&biBitCount, sizeof(short int), 1, file))
{

return 0;
}

if (biBitCount != 24)
{

return 0;
}
/* calculate the size of the image in bytes */
biSizeImage = texture->width * texture->height * 3;

texture->data = malloc(biSizeImage);
/* seek to the actual data */
fseek(file, bfOffBits, SEEK_SET);
if (!fread(texture->data, biSizeImage, 1, file))
{

return 0;
}
/* swap red and blue (bgr -> rgb) */
for (i = 0; i < biSizeImage; i += 3)
{
temp = texture->data[i];
texture->data[i] = texture->data[i + 2];
texture->data[i + 2] = temp;
}
return 1;
}

Bool loadGLTextures() /* Load Bitmaps And Convert To Textures */
{
Bool status;
textureImage *texti;

status = False;
texti = malloc(sizeof(textureImage));
if (loadBMP("Data/NeHe.bmp", texti))
{
status = True;
glGenTextures(1, &texture[0]); /* create the texture */
glBindTexture(GL_TEXTURE_2D, texture[0]);
/* actually generate the texture */
glTexImage2D(GL_TEXTURE_2D, 0, 3, texti->width, texti->height, 0,
GL_RGB, GL_UNSIGNED_BYTE, texti->data);
/* enable linear filtering */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
/* free the ram we used in our texture generation process */
if (texti)
{
if (texti->data)
free(texti->data);
free(texti);
}
return status;
}

/* function called when our window is resized (should only happen in window mode) */
void resizeGLScene(unsigned int width, unsigned int height)
{
if (height == 0) /* Prevent A Divide By Zero If The Window Is Too Small */
height = 1;
/* Reset The Current Viewport And Perspective Transformation */
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}

/* general OpenGL initialization function */
int initGL(GLvoid)
{
if (!loadGLTextures())
{
return False;
}
glEnable(GL_TEXTURE_2D); /* Enable Texture Mapping */
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
/* we use resizeGLScene once to set up our initial perspective */
resizeGLScene(GLWin.width, GLWin.height);
glFlush();
return True;
}
void textureFromCam()
{
/*numero de canales: 3 - ancho y alto: 640x480*/

static IplImage*imagen;
if (capture==NULL)
{
capture= cvCreateCameraCapture(0);
}
imagen = cvQueryFrame(capture);
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, imagen->width, imagen->height, 0,GL_BGR, GL_UNSIGNED_BYTE, imagen->imageData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glFlush();







}
/* Here goes our drawing code */
int drawGLScene(GLvoid)
{

textureFromCam();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef(xmove, ymove, zoom);

glRotatef(rotX, 1.0f, 0.0f, 0.0f); /* rotate on the X axis */
glRotatef(rotY, 0.0f, 1.0f, 0.0f); /* rotate on the Y axis */
glRotatef(rotZ, 0.0f, 0.0f, 1.0f); /* rotate on the Z axis */
glBindTexture(GL_TEXTURE_2D, texture[0]); /* select our texture */
glBegin(GL_QUADS);
/* front face */
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
/* back face */
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
/* right face */
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
/* left face */
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
/* top face */
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
/* bottom face */
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glEnd();
/* change the rotation angles */
rotX += 0.7f;
rotY += 0.5f;
rotZ += 0.8f;
glXSwapBuffers(GLWin.dpy, GLWin.win);
return True;
}

/* function to release/destroy our resources and restoring the old desktop */
GLvoid killGLWindow(GLvoid)
{
if (GLWin.ctx)
{
if (!glXMakeCurrent(GLWin.dpy, None, NULL))
{
printf("Could not release drawing context.\n");
}
glXDestroyContext(GLWin.dpy, GLWin.ctx);
GLWin.ctx = NULL;
}
/* switch back to original desktop resolution if we were in fs */
if (GLWin.fs)
{
XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
}
XCloseDisplay(GLWin.dpy);
}

/* this function creates our window and sets it up properly */
/* FIXME: bits is currently unused */
Bool createGLWindow(char* title, int width, int height, int bits,
Bool fullscreenflag)
{
XVisualInfo *vi;
Colormap cmap;
int dpyWidth, dpyHeight;
int i;
int glxMajorVersion, glxMinorVersion;
int vidModeMajorVersion, vidModeMinorVersion;
XF86VidModeModeInfo **modes;
int modeNum;
int bestMode;
Atom wmDelete;
Window winDummy;
unsigned int borderDummy;

GLWin.fs = fullscreenflag;
/* set best mode to current */
bestMode = 0;
/* get a connection */
GLWin.dpy = XOpenDisplay(0);
GLWin.screen = DefaultScreen(GLWin.dpy);
XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion,
&vidModeMinorVersion);


XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes);
/* save desktop-resolution before switching modes */
GLWin.deskMode = *modes[0];
/* look for mode with requested resolution */
for (i = 0; i < modeNum; i++)
{
if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
{
bestMode = i;
}
}
/* get an appropriate visual */
vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
if (vi == NULL)
{
vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);

}
else
{

}
glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);

/* create a GLX context */
GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
/* create a color map */
cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
vi->visual, AllocNone);
GLWin.attr.colormap = cmap;
GLWin.attr.border_pixel = 0;

if (GLWin.fs)
{
XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]);
XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
dpyWidth = modes[bestMode]->hdisplay;
dpyHeight = modes[bestMode]->vdisplay;
printf("Resolution de la pantallinhirilla: %dx%d\n", dpyWidth, dpyHeight);
XFree(modes);

/* create a fullscreen window */
GLWin.attr.override_redirect = True;
GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
StructureNotifyMask;
GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
&GLWin.attr);
XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0);
XMapRaised(GLWin.dpy, GLWin.win);
XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync,
GrabModeAsync, CurrentTime);
XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask,
GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
}
else
{
/* create a window in window mode*/
GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
StructureNotifyMask;
GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
/* only set window title and handle wm_delete_events if in windowed mode */
wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1);
XSetStandardProperties(GLWin.dpy, GLWin.win, title,
title, None, NULL, 0, NULL);
XMapRaised(GLWin.dpy, GLWin.win);
}
/* connect the glx-context to the window */
glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
&GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);

glXIsDirect(GLWin.dpy, GLWin.ctx);

if (!initGL())
{

return False;
}
return True;
}

void keyPressed(KeySym key)
{
switch (key)
{
case XK_Escape:
done = True;
break;
case XK_F1:
killGLWindow();
GLWin.fs = !GLWin.fs;
createGLWindow("FuckYeah", 640, 480, 24, GLWin.fs);
break;
case XK_F2:
zoom+=0.1f;
break;
case XK_F3:
zoom-=0.1f;
break;
case XK_F5:
xmove+=0.1f;
break;
case XK_F6:
xmove-=0.1f;
break;
case XK_F7:
ymove+=0.1f;
break;
case XK_F8:
ymove-=0.1f;
break;
}
}

int main(int argc, char **argv)
{

XEvent event;
KeySym key;

done = False;
/* default to fullscreen */
GLWin.fs = False;
zoom=0.0f;
xmove=0.0f;
ymove=0.0f;
if (!createGLWindow("FuckYeah true fucking death metal!", 800, 600, 24,
GLWin.fs))
{
done = True;
}
/* wait for events*/
while (!done)
{
/* handle the events in the queue */
while (XPending(GLWin.dpy) > 0)
{
XNextEvent(GLWin.dpy, &event);
switch (event.type)
{
case Expose:
if (event.xexpose.count != 0)
break;
drawGLScene();
break;
case ConfigureNotify:
/* call resizeGLScene only if our window-size changed */
if ((event.xconfigure.width != GLWin.width) ||
(event.xconfigure.height != GLWin.height))
{
GLWin.width = event.xconfigure.width;
GLWin.height = event.xconfigure.height;

resizeGLScene(event.xconfigure.width,
event.xconfigure.height);
}
break;
/* exit in case of a mouse button press */
case ButtonPress:
done = True;
break;
case KeyPress:
key = XLookupKeysym(&event.xkey, 0);
keyPressed(key);
break;
case ClientMessage:
if (*XGetAtomName(GLWin.dpy, event.xclient.message_type)
== *"WM_PROTOCOLS")
{

done = True;
}
break;
default:
break;
}
}
drawGLScene();
}
cvReleaseCapture(&capture);
killGLWindow();
return 0;
}



aca el codigo del make...



CC = gcc -Wall -pedantic -ansi `pkg-config --cflags --libs opencv`

all:
$(CC) lesson06.c -o lesson06 -L/usr/X11R6/lib -lGL -lGLU -lXxf86vm

clean:
@echo Cleaning up...
@rm lesson06
@echo Done.



y un video de como funca...






espero que le sea util a alguno =)

links de donde aprendi:

La web de nehe, con unos tutoriales de OpenGL multiplataformas excelentes!

La web de OpenCV
Jaja, muy bien!
Buenisimo,si se pudiera agradecer en esta sección, lo haría.
Lástima que el eclipse se niega a buildearme hasta el programa mas pelotudo (El "Hola Mundo" que viene de ejemplo...). Cuando averigue como hacerlo funcionar (venza la paja y se lo pregunte a algún ayudante de SSOO) le voy a dar mas bola (por ahora tengo que usar el gedit y es una patada en los huevos).
rulo, lo hice todo con el gedit yo xD

usa define, ifdef y sarasa para debugear con printf... y lista la torta JAJAJAJAJ

Imaginate la gente que programaba sobre tarjetas perforadas (?)
(13-08-2012 23:12)sebasthian777 escribió: [ -> ]rulo, lo hice todo con el gedit yo xD

Una vez que te acostumbras al eclipse,volver de ahí es como pasar de vuelta de C a PASCAL.
ONCE YOU GO BLACK YOU DON'T GO BACK.

Cita:usa define, ifdef y sarasa para debugear con printf... y lista la torta JAJAJAJAJ

GCC no me quire boludo, me compile un programa que se me traba antes de entrar a un ciclo while....al hacer la comparación.
Esto parece obra de Gates.

Cita:Imaginate la gente que programaba sobre tarjetas perforadas (?)

Eso no es nada, imaginate a la gente que programa en assembler,donde un X+Y son 5 lineas de código.
Aún peor...imaginate a la gente que programaba usando VI.
1) mucha gente sigue usando el VI, o mejor dicho ahora usan el VIM.
2) lo programe en gedit porque no pude hacer andar ni el entorno del QT ni el entorno del Eclipse =P jajaja
"fuck yeah true fucking metal"


no comments.
Cita:
Cita:Imaginate la gente que programaba sobre tarjetas perforadas (?)

Eso no es nada, imaginate a la gente que programa en assembler,donde un X+Y son 5 lineas de código.
Aún peor...imaginate a la gente que programaba usando VI.

no tenes idea de lo que decis rulo.

y a+b son tres lineas de codigo Evilmonkey
miguel Heart
debuggear con printf??

gdb señores, gdb!


cuando llegue a casa veo de compilarlo a ver que sale...
printf?
gdb?

Comprense un IDE.
(14-08-2012 10:54)Jarry escribió: [ -> ]debuggear con printf??

gdb señores, gdb!


cuando llegue a casa veo de compilarlo a ver que sale...

mmmm, te vas a tener que bajar el opencv jarry, sino te va a putear...
(para compilar los binarios, librerias y la mar en coche de opencv tardas aprox 4 horas XD)
no hay binariops precompilados para debian?
me mataste, la verdad me parece que no, pero nunca se sabe....
ahora si ya me pueden dar gracias por este thread (?)
Gracias sebas, por el .out de cada día.
Páginas: 1 2
URLs de referencia