2003/10/16 05:39:20
[org.ibex.core.git] / src / org / xwt / plat / OpenGL.cc
index e307b45..5540c2d 100644 (file)
@@ -4,7 +4,7 @@
 // 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>
@@ -17,7 +17,7 @@
 #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>
@@ -56,7 +56,7 @@ void OpenGL::natInit() {
     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);
@@ -77,7 +77,7 @@ void OpenGL$GLDoubleBuffer::drawableInit(jint width, jint height) {
     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;
@@ -85,7 +85,7 @@ void OpenGL$GLDoubleBuffer::setColor(jint argb) {
     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); 
@@ -96,18 +96,7 @@ void OpenGL$GLDoubleBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, ji
     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();
-}
-
-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) {
@@ -129,7 +118,7 @@ void OpenGL$GLDoubleBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
     checkGLError();
 }
 
-void OpenGL$GLDoubleBuffer::resetClip() {
+void OpenGL$GLPixelBuffer::resetClip() {
     activateContext();
     if(glScissorEnabled) {
         glDisable(GL_SCISSOR_TEST);
@@ -137,20 +126,26 @@ void OpenGL$GLDoubleBuffer::resetClip() {
     }    
 }
 
-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();
@@ -158,18 +153,23 @@ void OpenGL$RectGLPicture::natInit(JArray<jint> *data_) {
     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();
   
@@ -177,11 +177,10 @@ void OpenGL$RectGLPicture::natInit(JArray<jint> *data_) {
 }
 
 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);
-    glEnable(GL_TEXTURE_RECTANGLE_EXT);
-    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);    
-    glBegin(GL_QUADS); 
-        glTexCoord2i (sx1, sy1   );
+       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);
@@ -189,10 +188,9 @@ void OpenGL$RectGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1,
         glVertex3i   (dx2, dy2, 0);
         glTexCoord2i (sx1, sy2   );
         glVertex3i   (dx1, dy2, 0);
-    glEnd();
-    glDisable(GL_TEXTURE_RECTANGLE_EXT);
-    checkGLError();
-
+       glEnd();
+       glDisable(GL_TEXTURE_RECTANGLE_EXT);
+       checkGLError();
 }
 
 void OpenGL::natDeleteTexture(jint tex_) {
@@ -201,45 +199,67 @@ 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();
@@ -254,7 +274,6 @@ void OpenGL$SquareGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx
     tx2 = (float) sx2 / (float) texWidth;
     ty2 = (float) sy2 / (float) texHeight;
 
-    glColor4f(1.0f,1.0f,1.0f,1.0f);
     glEnable(GL_TEXTURE_2D);
     glBindTexture(GL_TEXTURE_2D, textureName);    
     checkGLError();