forked from enlightenment/efl
ewooo- gl routines for evas.. been working on them...... :)
SVN revision: 2969
This commit is contained in:
parent
83dff01c43
commit
b4a315b048
|
@ -20,6 +20,7 @@ libevas_la_SOURCES = \
|
|||
evas_bits.c \
|
||||
evas_callbacks.c \
|
||||
evas_events.c \
|
||||
evas_gl_routines.c \
|
||||
evas_gradient.c \
|
||||
evas_image.c \
|
||||
evas_line.c \
|
||||
|
@ -32,6 +33,6 @@ evas_render.c \
|
|||
evas_text.c \
|
||||
Evas.h
|
||||
|
||||
libevas_la_LIBADD = -lX11 -lXext -lttf -ldl -lm -lImlib2 -ldb $(LDFLAGS)
|
||||
libevas_la_LIBADD = -lX11 -lXext -lttf -ldl -lm -lImlib2 -ldb -lGL $(LDFLAGS)
|
||||
libevas_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
libevas_la_LDFLAGS = -version-info 0:1:0
|
||||
|
|
|
@ -0,0 +1,411 @@
|
|||
/* C library header files. */
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xmu/StdCmap.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include "Evas.h"
|
||||
|
||||
Display *disp;
|
||||
|
||||
static int __evas_gl_configuration[] =
|
||||
{
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
None
|
||||
};
|
||||
|
||||
/* imlib 2 opengl backend work - transfer imlib image between states */
|
||||
/* of being client-side data, a texture set (an WxH array of textutes */
|
||||
/* tiled - to work around maximum texture size limitation of opengl) and */
|
||||
/* a buffer (using a pixmap as a destination drawable so we can render */
|
||||
/* ofscreen) */
|
||||
|
||||
typedef struct _evas_gl_image Evas_GL_Image;
|
||||
typedef enum _evas_gl_image_state Evas_GL_Image_State;
|
||||
|
||||
enum _evas_gl_image_state
|
||||
{
|
||||
EVAS_STATE_DATA,
|
||||
EVAS_STATE_TEXTURE
|
||||
};
|
||||
|
||||
struct _evas_gl_image
|
||||
{
|
||||
Evas_GL_Image_State state;
|
||||
int w, h;
|
||||
/* data specific params */
|
||||
DATA32 *data;
|
||||
/* common GL params */
|
||||
GLXContext context;
|
||||
/* texture state specific params */
|
||||
struct _tex
|
||||
{
|
||||
int max_size;
|
||||
int w, h;
|
||||
int edge_w, edge_h;
|
||||
GLuint *textures;
|
||||
} texture;
|
||||
/* buffer specific params */
|
||||
struct _buf
|
||||
{
|
||||
Display *display;
|
||||
XVisualInfo *visual_info;
|
||||
Colormap colormap;
|
||||
Window window;
|
||||
} buffer;
|
||||
};
|
||||
|
||||
void
|
||||
__evas_gl_copy_image_rect_to_texture(Evas_GL_Image *im, int x, int y,
|
||||
int w, int h, int tw, int th,
|
||||
GLuint texture)
|
||||
{
|
||||
int tx, ty;
|
||||
DATA32 *data, *p1, *p2;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
data = malloc(tw * th * 4);
|
||||
for (ty = 0; ty < h; ty++)
|
||||
{
|
||||
p1 = im->data + ((y + ty) * im->w) + x;
|
||||
p2 = data + (ty * tw);
|
||||
for (tx = 0; tx < w; tx++)
|
||||
{
|
||||
*p2 =
|
||||
((*p1 & 0xff000000)) |
|
||||
((*p1 & 0x00ff0000) >> 16) |
|
||||
((*p1 & 0x0000ff00)) |
|
||||
((*p1 & 0x000000ff) << 16);
|
||||
p2++; p1++;
|
||||
}
|
||||
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void
|
||||
__evas_gl_move_state_data_to_texture(Evas_GL_Image *im)
|
||||
{
|
||||
int i, x, y;
|
||||
XSetWindowAttributes att;
|
||||
|
||||
if (!im->data) return;
|
||||
|
||||
im->texture.w = im->w / (im->texture.max_size - 2);
|
||||
if (im->w > ((im->texture.max_size - 2) * im->texture.w))
|
||||
{
|
||||
int shift = 0;
|
||||
|
||||
im->texture.edge_w = im->w - (im->texture.w * (im->texture.max_size - 2));
|
||||
while (im->texture.edge_w < (im->texture.max_size >> shift)) shift++;
|
||||
im->texture.edge_w = im->texture.max_size >> (shift - 1);
|
||||
im->texture.w++;
|
||||
}
|
||||
else
|
||||
im->texture.edge_w = im->texture.max_size;
|
||||
im->texture.h = im->h / (im->texture.max_size - 2);
|
||||
if (im->h > ((im->texture.max_size - 2) * im->texture.h))
|
||||
{
|
||||
int shift = 0;
|
||||
|
||||
im->texture.edge_h = im->h - (im->texture.h * (im->texture.max_size - 2));
|
||||
while (im->texture.edge_h < (im->texture.max_size >> shift)) shift++;
|
||||
im->texture.edge_h = im->texture.max_size >> (shift - 1);
|
||||
im->texture.h++;
|
||||
}
|
||||
else
|
||||
im->texture.edge_h = im->texture.max_size;
|
||||
|
||||
att.colormap = im->buffer.colormap;
|
||||
att.border_pixel = 0;
|
||||
att.event_mask = 0;
|
||||
im->buffer.window = XCreateWindow(im->buffer.display,
|
||||
RootWindow(disp, DefaultScreen(disp)),
|
||||
0, 0, 32, 32, 0,
|
||||
im->buffer.visual_info->depth,
|
||||
InputOutput,
|
||||
im->buffer.visual_info->visual,
|
||||
CWColormap | CWBorderPixel | CWEventMask,
|
||||
&att);
|
||||
im->texture.textures = malloc(sizeof(GLuint) * im->texture.w * im->texture.h);
|
||||
glXMakeCurrent(im->buffer.display, im->buffer.window, im->context);
|
||||
glGenTextures(im->texture.w * im->texture.h, im->texture.textures);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
for (i = 0, y = 0; y < im->texture.h; y++)
|
||||
{
|
||||
for (x = 0; x < im->texture.w; x++, i++)
|
||||
{
|
||||
int xx, yy, ww, hh, tw, th;
|
||||
|
||||
if (x == (im->texture.w - 1)) tw = im->texture.edge_w;
|
||||
else tw = im->texture.max_size;
|
||||
if (y == (im->texture.h - 1)) th = im->texture.edge_h;
|
||||
else th = im->texture.max_size;
|
||||
|
||||
if (x == 0) xx = 0;
|
||||
else xx = x * (im->texture.max_size - 2) - 1;
|
||||
if (x == (im->texture.w - 1)) ww = im->w - (x * (im->texture.max_size- 2));
|
||||
else ww = im->texture.max_size - 2;
|
||||
ww += 2;
|
||||
if (x == 0) ww--;
|
||||
if (x == (im->texture.w - 1)) ww--;
|
||||
|
||||
if (y == 0) yy = 0;
|
||||
else yy = y * (im->texture.max_size - 2) - 1;
|
||||
if (y == (im->texture.h - 1)) hh = im->h - (y * (im->texture.max_size- 2));
|
||||
else hh = im->texture.max_size - 2;
|
||||
hh += 2;
|
||||
if (y == 0) hh--;
|
||||
if (y == (im->texture.h - 1)) hh--;
|
||||
|
||||
__evas_gl_copy_image_rect_to_texture(im, xx, yy, ww, hh, tw, th,
|
||||
im->texture.textures[i]);
|
||||
}
|
||||
}
|
||||
/* done - set the actual image state to textured */
|
||||
im->state = EVAS_STATE_TEXTURE;
|
||||
}
|
||||
|
||||
void __evas_calc_tex_and_poly(Evas_GL_Image *im, int x, double *x1, double *x2,
|
||||
int *tx, int *txx, double *dtx, double *dtxx, int tw, int w, int edge)
|
||||
{
|
||||
if ((x == 0) && (tw > 1))
|
||||
{
|
||||
*tx = 0;
|
||||
*txx = im->texture.max_size - 2;
|
||||
*dtx = (double)*tx / (im->texture.max_size);
|
||||
*dtxx = (double)*txx / (im->texture.max_size);
|
||||
}
|
||||
else if (x < (tw - 1))
|
||||
{
|
||||
*tx = 1;
|
||||
*txx = im->texture.max_size - 1;
|
||||
*dtx = (double)*tx / (im->texture.max_size);
|
||||
*dtxx = (double)*txx / (im->texture.max_size);
|
||||
}
|
||||
else if ((x == 0) && (tw == 1))
|
||||
{
|
||||
*tx = 0;
|
||||
*txx = w - (x * (im->texture.max_size - 2));
|
||||
*dtx = (double)*tx / (double)edge;
|
||||
*dtxx = (double)*txx / (double)edge;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tx = 1;
|
||||
*txx = w - (x * (im->texture.max_size - 2));
|
||||
*dtx = (double)*tx / (double)edge;
|
||||
*dtxx = (double)*txx / (double)edge;
|
||||
}
|
||||
|
||||
if (x == 0)
|
||||
*x1 = 0.0;
|
||||
else
|
||||
*x1 = (double)(x * (im->texture.max_size - 2));
|
||||
|
||||
if (x < (tw - 1))
|
||||
*x2 = (double)((x + 1) * (im->texture.max_size - 2));
|
||||
else
|
||||
*x2 = (double)w;
|
||||
}
|
||||
|
||||
void __evas_gl_render_to_window(Evas_GL_Image *im,
|
||||
Display *disp, Window w, int win_w, int win_h,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h)
|
||||
{
|
||||
int x, y, i;
|
||||
double dx, dy, dw, dh;
|
||||
|
||||
if (im->state != EVAS_STATE_TEXTURE)
|
||||
__evas_gl_move_state_data_to_texture(im);
|
||||
glXMakeCurrent(disp, w, im->context);
|
||||
/*
|
||||
glClearColor(0.7, 0.7, 0.7, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
*/
|
||||
glEnable(GL_BLEND);
|
||||
glShadeModel(GL_FLAT);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
/* why doesnt scissor work ? */
|
||||
/*
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(dst_x, win_h - dst_y - 1, dst_w, dst_h);
|
||||
*/
|
||||
/* translate all poly coords in ints to normal X coord space */
|
||||
glViewport(0, 0, win_w, win_h);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, win_w, 0, win_h, -1, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glScalef(1, -1, 1);
|
||||
glTranslatef(0, -win_h, 0);
|
||||
/* project src and dst rects to overall dest rect */
|
||||
dw = (((double)dst_w * (double)im->w)/ (double)src_w);
|
||||
dx = (double)dst_x - (((double)dst_w * (double)src_x)/ (double)src_w);
|
||||
|
||||
dh = (((double)dst_h * (double)im->h)/ (double)src_h);
|
||||
dy = (double)dst_y - (((double)dst_h * (double)src_y)/ (double)src_h);
|
||||
for (y = 0, i = 0; y < im->texture.h; y++)
|
||||
{
|
||||
for (x = 0; x < im->texture.w; x++, i++)
|
||||
{
|
||||
int tx, ty, txx, tyy;
|
||||
double x1, y1, x2, y2;
|
||||
double dtx, dtxx, dty, dtyy;
|
||||
|
||||
|
||||
__evas_calc_tex_and_poly(im, x, &x1, &x2, &tx, &txx,
|
||||
&dtx, &dtxx,
|
||||
im->texture.w, im->w,
|
||||
im->texture.edge_w);
|
||||
__evas_calc_tex_and_poly(im, y, &y1, &y2, &ty, &tyy,
|
||||
&dty, &dtyy,
|
||||
im->texture.h, im->h,
|
||||
im->texture.edge_h);
|
||||
x1 = dx + ((x1 * dw) / (double)im->w);
|
||||
y1 = dy + ((y1 * dh) / (double)im->h);
|
||||
x2 = dx + ((x2 * dw) / (double)im->w);
|
||||
y2 = dy + ((y2 * dh) / (double)im->h);
|
||||
glBindTexture(GL_TEXTURE_2D, im->texture.textures[i]);
|
||||
glBegin(GL_POLYGON);
|
||||
glTexCoord2d(dtx, dty); glVertex2d(x1, y1);
|
||||
glTexCoord2d(dtxx, dty); glVertex2d(x2, y1);
|
||||
glTexCoord2d(dtxx, dtyy); glVertex2d(x2, y2);
|
||||
glTexCoord2d(dtx, dtyy); glVertex2d(x1, y2);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
glXSwapBuffers(im->buffer.display, w);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
Evas_GL_Image *
|
||||
__evas_gl_create_image(void)
|
||||
{
|
||||
Evas_GL_Image *im;
|
||||
|
||||
im = malloc(sizeof(Evas_GL_Image));
|
||||
memset(im, 0, sizeof(Evas_GL_Image));
|
||||
return im;
|
||||
}
|
||||
|
||||
static XVisualInfo *__evas_vi = NULL;
|
||||
static GLXContext __evas_gl_cx = 0;
|
||||
|
||||
int
|
||||
__evas_gl_capable(Display *disp)
|
||||
{
|
||||
int eb, evb;
|
||||
return glXQueryExtension(disp, &eb, &evb);
|
||||
}
|
||||
|
||||
Visual *
|
||||
__evas_gl_get_visual(Display *disp)
|
||||
{
|
||||
static Display *d = NULL;
|
||||
|
||||
if (d != disp)
|
||||
{
|
||||
d = disp;
|
||||
__evas_vi = glXChooseVisual(disp, DefaultScreen(disp), __evas_gl_configuration);
|
||||
}
|
||||
return __evas_vi->visual;
|
||||
}
|
||||
|
||||
Colormap
|
||||
__evas_gl_get_colormap(Display *disp)
|
||||
{
|
||||
static Display *d = NULL;
|
||||
static Colormap cmap = 0;
|
||||
|
||||
if (!__evas_vi) __evas_gl_get_visual(disp);
|
||||
if (d != disp)
|
||||
{
|
||||
d = disp;
|
||||
cmap = XCreateColormap(disp, RootWindow(disp, DefaultScreen(disp)), __evas_vi->visual, 0);
|
||||
}
|
||||
return cmap;
|
||||
}
|
||||
|
||||
void
|
||||
__evas_gl_init(Display *disp)
|
||||
{
|
||||
if (__evas_gl_cx) return;
|
||||
|
||||
if (!__evas_gl_capable(disp)) return;
|
||||
__evas_gl_get_visual(disp);
|
||||
/* direct rendering client */
|
||||
__evas_gl_cx = glXCreateContext(disp, __evas_vi, NULL, GL_TRUE);
|
||||
/* GLX indirect */
|
||||
/* __evas_gl_cx = glXCreateContext(disp, __evas_vi, NULL, GL_TRUE);*/
|
||||
}
|
||||
|
||||
Evas_GL_Image *
|
||||
__evas_gl_image_new_from_file(Display *disp, char *file)
|
||||
{
|
||||
Evas_GL_Image *im;
|
||||
Imlib_Image i;
|
||||
|
||||
i = imlib_load_image(file);
|
||||
if (!i) return NULL;
|
||||
imlib_context_set_image(i);
|
||||
im = __evas_gl_create_image();
|
||||
im->w = imlib_image_get_width();
|
||||
im->h = imlib_image_get_height();
|
||||
im->data = imlib_image_get_data();
|
||||
im->texture.max_size = 256;
|
||||
__evas_gl_init(disp);
|
||||
im->context = __evas_gl_cx;
|
||||
im->buffer.display = disp;
|
||||
im->buffer.colormap = __evas_gl_get_colormap(disp);
|
||||
im->buffer.visual_info = __evas_vi;
|
||||
return im;
|
||||
}
|
||||
|
||||
void
|
||||
__evas_sync(Display *disp)
|
||||
{
|
||||
glXWaitGL();
|
||||
XSync(disp, False);
|
||||
}
|
||||
|
||||
void
|
||||
__evas_flush_draw(Display *disp, Window win)
|
||||
{
|
||||
glXSwapBuffers(disp, win);
|
||||
}
|
||||
|
||||
void
|
||||
__evas_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
|
||||
int r, int g, int b, int a)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue