// IMPROVMENT: use alpha testing? might be faster
#include <org/xwt/plat/OpenGL.h>
-#include <org/xwt/plat/OpenGL$GLDoubleBuffer.h>
+#include <org/xwt/plat/OpenGL$GLPixelBuffer.h>
#include <org/xwt/plat/OpenGL$GLPicture.h>
#include <org/xwt/plat/OpenGL$RectGLPicture.h>
#include <org/xwt/plat/OpenGL$SquareGLPicture.h>
#include <OpenGL/glu.h>
#include <OpenGL/glext.h>
#else
-#warning I am not sure if these is correct
+#warning I am not sure if these are correct
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glext.h>
#include <stdio.h>
+#define min(a,b) (a<b?a:b)
+
namespace org { namespace xwt { namespace plat {
#define checkGLError() checkGLError2(__FILE__,__LINE__)
version = JvNewStringLatin1(s==0 ? "" : (char*)s);
}
-void OpenGL$GLDoubleBuffer::drawableInit(jint width, jint height) {
+void OpenGL$GLPixelBuffer::drawableInit(jint width, jint height) {
glClearColor (0.3f, 0.7f, 1.0f, 1.0f);
glClearDepth( 0.0f );
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
checkGLError();
}
-void OpenGL$GLDoubleBuffer::setColor(jint argb) {
+void OpenGL$GLPixelBuffer::setColor(jint argb) {
float alpha = ((argb >> 24) & 0xff) / 255.0;
float red = ((argb >> 16) & 0xff) / 255.0;
float green = ((argb >> 8) & 0xff) / 255.0;
glColor4f(red,green,blue,alpha);
}
-void OpenGL$GLDoubleBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, jint x4, jint y2, jint color) {
+void OpenGL$GLPixelBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, jint x4, jint y2, jint color) {
activateContext();
setColor(color);
- glBegin(GL_QUADS);
+ glBegin(GL_QUADS); {
glVertex3f(x1,y1,0.0f );
glVertex3f(x3,y2,0.0f );
glVertex3f(x4,y2,0.0f );
glVertex3f(x2,y1,0.0f );
- glEnd();
-}
-
-void OpenGL$GLDoubleBuffer::fillRect(jint x1, jint y1, jint x2, jint y2,jint color) {
- activateContext();
- setColor(color);
- glBegin(GL_QUADS);
- glVertex3f(x1,y2,0.0f );
- glVertex3f(x2,y2,0.0f );
- glVertex3f(x2,y1,0.0f );
- glVertex3f(x1,y1,0.0f );
- glEnd();
+ } glEnd();
}
-void OpenGL$GLDoubleBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
+void OpenGL$GLPixelBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
//fprintf(stderr,"setClip: %d %d %d %d\n",x1,y1,x2,y2);
if(x1==0 && y1==0 && x2==width && y2==height) {
if(glScissorEnabled) {
checkGLError();
}
-void OpenGL$GLDoubleBuffer::resetClip() {
+void OpenGL$GLPixelBuffer::resetClip() {
activateContext();
if(glScissorEnabled) {
glDisable(GL_SCISSOR_TEST);
}
}
-void OpenGL$RectGLPicture::natInit(JArray<jint> *data_) {
+// FEATURE: Eliminate duplicate code in RectGLPicture and SquareGLPicture
+void OpenGL$RectGLPicture::natInit(Object *data_, jboolean alphaOnly) {
unsigned char *buf;
int i,j;
int size = width*height;
- jint *data = elements(data_);
- buf = new unsigned char[size*4];
GLuint tex;
- for(i=0,j=0;i<size;i++,j+=4) {
- jint pixel = data[i];
- buf[j+0] = (pixel >> 16) & 0xff;
- buf[j+1] = (pixel >> 8) & 0xff;
- buf[j+2] = (pixel >> 0) & 0xff;
- buf[j+3] = (pixel >> 24) & 0xff;
+ if(alphaOnly) {
+ jbyte *data = elements((JArray<jbyte> *)data_);
+ buf = (unsigned char *) data;
+ } else {
+ jint *data = elements((JArray<jint> *)data_);
+ buf = new unsigned char[size*4];
+ for(i=0,j=0;i<size;i++,j+=4) {
+ jint pixel = data[i];
+ buf[j+0] = (pixel >> 16) & 0xff;
+ buf[j+1] = (pixel >> 8) & 0xff;
+ buf[j+2] = (pixel >> 0) & 0xff;
+ buf[j+3] = (pixel >> 24) & 0xff;
+ }
}
gl->activateSharedContext();
glGenTextures(1,&tex);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT,tex);
glPixelStorei(GL_PACK_ALIGNMENT,1);
- glTexImage2D(GL_TEXTURE_RECTANGLE_EXT,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
- delete buf;
+ glTexImage2D(
+ GL_TEXTURE_RECTANGLE_EXT,0,
+ alphaOnly ? GL_ALPHA : GL_RGBA,width,height,0,
+ alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
+ if(!alphaOnly)
+ delete buf;
- // FIXME: enable linear filtering for opengl 1.2
- glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
- glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ if(gl->glVersion >= 1.2) {
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ }
- /*glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
-
glDisable(GL_TEXTURE_RECTANGLE_EXT);
checkGLError();
textureName = (jint)tex;
}
-void OpenGL$RectGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) {
- glColor4f(1.0f,1.0f,1.0f,1.0f);
+void OpenGL$RectGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
+ cx2 = min(cx2, dx + width);
+ cy2 = min(cx2, dy + height);
+ if (cy2 <= cy1 || cx2 <= cx1) return;
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
- glBegin(GL_QUADS);
- glTexCoord2i (sx1, sy1 );
- glVertex3i (dx1, dy1, 0);
- glTexCoord2i (sx2, sy1 );
- glVertex3i (dx2, dy1, 0);
- glTexCoord2i (sx2, sy2 );
- glVertex3i (dx2, dy2, 0);
- glTexCoord2i (sx1, sy2 );
- glVertex3i (dx1, dy2, 0);
- glEnd();
+ glBegin(GL_QUADS); {
+ glTexCoord2i (cx1 - dx, cy1 - dy );
+ glVertex3i (cx1, cy1, 0);
+ glTexCoord2i (cx2 - dx, cy1 - dy );
+ glVertex3i (cx2, cy1, 0);
+ glTexCoord2i (cx2 - dx, cy2 - dy );
+ glVertex3i (cx2, cy2, 0);
+ glTexCoord2i (cx1 - dx, cy2 - dy );
+ glVertex3i (cx1, cy2, 0);
+ } glEnd();
glDisable(GL_TEXTURE_RECTANGLE_EXT);
checkGLError();
-
}
void OpenGL::natDeleteTexture(jint tex_) {
glDeleteTextures(1,&tex);
}
-void OpenGL$SquareGLPicture::natInit(JArray<jint> *data_) {
+void OpenGL$SquareGLPicture::natInit(Object *data_, jboolean alphaOnly) {
unsigned char *buf;
int row,col,p;
- jint *data = elements(data_);
- buf = new unsigned char[texWidth*texHeight*4];
GLuint tex;
- p=0;
- for(row=0;row<height;row++) {
- for(col=0;col<width;col++) {
- jint pixel = data[row*width+col];
- buf[p+0] = (pixel >> 16) & 0xff;
- buf[p+1] = (pixel >> 8) & 0xff;
- buf[p+2] = (pixel >> 0) & 0xff;
- buf[p+3] = (pixel >> 24) & 0xff;
- p+=4;
+ if(alphaOnly) {
+ jbyte *data = elements((JArray<jbyte>*) data_);
+ if(texWidth == width && texHeight == height) {
+ buf = (unsigned char*) data;
+ } else {
+ buf = new unsigned char[texWidth*texHeight];
+ p=0;
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++)
+ buf[p++] = data[row*width+col];
+ for(;col<texWidth;col++)
+ buf[p++] = 0;
+ }
+ for(;row<texHeight;row++)
+ for(col=0;col<texWidth;col++)
+ buf[p++] = 0;
}
- for(;col < texWidth;col++,p+=4)
- buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
+ } else {
+ jint *data = elements((JArray<jint>*) data_);
+ buf = new unsigned char[texWidth*texHeight*4];
+ p=0;
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ jint pixel = data[row*width+col];
+ buf[p+0] = (pixel >> 16) & 0xff;
+ buf[p+1] = (pixel >> 8) & 0xff;
+ buf[p+2] = (pixel >> 0) & 0xff;
+ buf[p+3] = (pixel >> 24) & 0xff;
+ p+=4;
+ }
+ for(;col < texWidth;col++,p+=4)
+ buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
+ }
+ for(;row < texHeight;row++)
+ for(col=0;col<texWidth;col++,p+=4)
+ buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
}
- for(;row < texHeight;row++)
- for(col=0;col<texWidth;col++,p+=4)
- buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
gl->activateSharedContext();
glEnable(GL_TEXTURE_2D);
glGenTextures(1,&tex);
glBindTexture(GL_TEXTURE_2D,tex);
glPixelStorei(GL_PACK_ALIGNMENT,1);
- glTexImage2D(GL_TEXTURE_2D,0,4,texWidth,texHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
+ glTexImage2D(GL_TEXTURE_2D,0,alphaOnly ? GL_ALPHA : GL_RGBA,texWidth,texHeight,0,alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
checkGLError();
- delete buf;
+ if(!alphaOnly || width != texWidth || height != texHeight) delete buf;
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
- /*glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
+ if(gl->glVersion >= 1.2) {
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ }
glDisable(GL_TEXTURE_2D);
checkGLError();
textureName = (jint)tex;
}
-void OpenGL$SquareGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) {
- float tx1,ty1,tx2,ty2; // normalized texture coords
- tx1 = (float) sx1 / (float) texWidth;
- ty1 = (float) sy1 / (float) texHeight;
- tx2 = (float) sx2 / (float) texWidth;
- ty2 = (float) sy2 / (float) texHeight;
-
- glColor4f(1.0f,1.0f,1.0f,1.0f);
+void OpenGL$SquareGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
+ cx2 = min(cx2, dx + width);
+ cy2 = min(cx2, dy + height);
+ if (cy2 <= cy1 || cx2 <= cx1) return;
+ float tx1 = (float) (cx1 - dx) / (float) texWidth;
+ float ty1 = (float) (cy1 - dy) / (float) texHeight;
+ float tx2 = (float) (cx2 - dx) / (float) texWidth;
+ float ty2 = (float) (cy2 - dy) / (float) texHeight;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureName);
checkGLError();
- glBegin(GL_QUADS);
- glTexCoord2f (tx1, ty1 );
- glVertex3i (dx1, dy1, 0);
- glTexCoord2f (tx2, ty1 );
- glVertex3i (dx2, dy1, 0);
- glTexCoord2f (tx2, ty2 );
- glVertex3i (dx2, dy2, 0);
- glTexCoord2f (tx1, ty2 );
- glVertex3i (dx1, dy2, 0);
- glEnd();
+ glBegin(GL_QUADS); {
+ glTexCoord2f (tx1, ty1 );
+ glVertex3i (cx1, cy1, 0);
+ glTexCoord2f (tx2, ty1 );
+ glVertex3i (cx2, cy1, 0);
+ glTexCoord2f (tx2, ty2 );
+ glVertex3i (cx2, cy2, 0);
+ glTexCoord2f (tx1, ty2 );
+ glVertex3i (cx1, cy2, 0);
+ } glEnd();
glDisable(GL_TEXTURE_2D);
checkGLError();
}