1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL]
2 // Author: Brian Alliet
4 // IMPROVMENT: use alpha testing? might be faster
6 #include <org/xwt/plat/OpenGL.h>
7 #include <org/xwt/plat/OpenGL$GLPixelBuffer.h>
8 #include <org/xwt/plat/OpenGL$GLPicture.h>
9 #include <org/xwt/plat/OpenGL$RectGLPicture.h>
10 #include <org/xwt/plat/OpenGL$SquareGLPicture.h>
11 #include <org/xwt/plat/OpenGL$MosaicGLPicture.h>
13 #include <java/lang/Error.h>
16 #include <OpenGL/gl.h>
17 #include <OpenGL/glu.h>
18 #include <OpenGL/glext.h>
20 #warning I am not sure if these are correct
28 #define min(a,b) ((a)<(b)?(a):(b))
29 #define max(a,b) ((a)>(b)?(a):(b))
31 namespace org { namespace xwt { namespace plat {
33 #define checkGLError() checkGLError2(__FILE__,__LINE__)
34 static void checkGLError2(const char *file,int line) {
35 GLenum err = glGetError();
36 if(err == GL_NO_ERROR) return;
38 fprintf(stderr,"%s:%d: GL Error: %s",file,line,(char *) gluErrorString(err));
42 void OpenGL::natInit() {
45 activateSharedContext();
46 s = glGetString(GL_EXTENSIONS);
47 rectangularTextures = (jboolean) gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle",s);
48 glGetIntegerv(GL_MAX_TEXTURE_SIZE,&i);
49 maxTexSize = (jint) i;
50 if(rectangularTextures) {
51 glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT,&i);
52 maxRectTexSize = (jint) i;
54 s = glGetString(GL_VENDOR);
55 vendor = JvNewStringLatin1(s==0 ? "" : (char*)s);
56 s = glGetString(GL_RENDERER);
57 renderer = JvNewStringLatin1(s==0 ? "" : (char*)s);
58 s = glGetString(GL_VERSION);
59 version = JvNewStringLatin1(s==0 ? "" : (char*)s);
62 void OpenGL$GLPixelBuffer::drawableInit(jint width, jint height) {
63 glClearColor (0.3f, 0.7f, 1.0f, 1.0f);
65 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
66 glShadeModel(GL_SMOOTH);
68 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
70 glViewport(0,0,width,height);
71 glMatrixMode(GL_PROJECTION);
73 glOrtho(0,width,height,0,-1,1);
74 // CHECKME: This causes textures to be blurry, but something like this
75 // (but not this) might be required to draw straight lines
76 //glMatrixMode(GL_MODELVIEW);
78 //glTranslatef(0.375, 0.375, 0.0);
83 void OpenGL$GLPixelBuffer::setColor(jint argb) {
84 float alpha = ((argb >> 24) & 0xff) / 255.0;
85 float red = ((argb >> 16) & 0xff) / 255.0;
86 float green = ((argb >> 8) & 0xff) / 255.0;
87 float blue = ((argb >> 0) & 0xff) / 255.0;
88 glColor4f(red,green,blue,alpha);
91 void OpenGL$GLPixelBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, jint x4, jint y2, jint color) {
95 glVertex3f(x1,y1,0.0f );
96 glVertex3f(x3,y2,0.0f );
97 glVertex3f(x4,y2,0.0f );
98 glVertex3f(x2,y1,0.0f );
102 void OpenGL$GLPixelBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
103 //fprintf(stderr,"setClip: %d %d %d %d\n",x1,y1,x2,y2);
104 if(x1==0 && y1==0 && x2==width && y2==height) {
105 if(glScissorEnabled) {
107 glDisable(GL_SCISSOR_TEST);
108 glScissorEnabled = false;
113 if(!glScissorEnabled) {
114 glEnable(GL_SCISSOR_TEST);
115 glScissorEnabled = true;
117 if((x1 >= x2) || (y1 >= y2))
120 glScissor(x1,height-y2,x2-x1,y2-y1);
124 void OpenGL$GLPixelBuffer::resetClip() {
126 if(glScissorEnabled) {
127 glDisable(GL_SCISSOR_TEST);
128 glScissorEnabled = false;
132 // FEATURE: Eliminate duplicate code in RectGLPicture and SquareGLPicture
133 void OpenGL$RectGLPicture::natInit(Object *data_, jboolean alphaOnly) {
136 int size = width*height;
140 jbyte *data = elements((JArray<jbyte> *)data_);
141 buf = (unsigned char *) data;
143 jint *data = elements((JArray<jint> *)data_);
144 buf = new unsigned char[size*4];
145 for(i=0,j=0;i<size;i++,j+=4) {
146 jint pixel = data[i];
147 buf[j+0] = (pixel >> 16) & 0xff;
148 buf[j+1] = (pixel >> 8) & 0xff;
149 buf[j+2] = (pixel >> 0) & 0xff;
150 buf[j+3] = (pixel >> 24) & 0xff;
154 gl->activateSharedContext();
155 glEnable(GL_TEXTURE_RECTANGLE_EXT);
156 glGenTextures(1,&tex);
157 glBindTexture(GL_TEXTURE_RECTANGLE_EXT,tex);
158 glPixelStorei(GL_PACK_ALIGNMENT,1);
160 GL_TEXTURE_RECTANGLE_EXT,0,
161 alphaOnly ? GL_ALPHA : GL_RGBA,width,height,0,
162 alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
166 if(gl->glVersion >= 1.2) {
167 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
168 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
169 glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
170 glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
172 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
173 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
176 glDisable(GL_TEXTURE_RECTANGLE_EXT);
179 textureName = (jint)tex;
182 void OpenGL$RectGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
185 cx2 = min(cx2, dx + width);
186 cy2 = min(cy2, dy + height);
187 if (cy2 <= cy1 || cx2 <= cx1) return;
188 glEnable(GL_TEXTURE_RECTANGLE_EXT);
189 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
191 glTexCoord2i (cx1 - dx, cy1 - dy );
192 glVertex3i (cx1, cy1, 0);
193 glTexCoord2i (cx2 - dx, cy1 - dy );
194 glVertex3i (cx2, cy1, 0);
195 glTexCoord2i (cx2 - dx, cy2 - dy );
196 glVertex3i (cx2, cy2, 0);
197 glTexCoord2i (cx1 - dx, cy2 - dy );
198 glVertex3i (cx1, cy2, 0);
200 glDisable(GL_TEXTURE_RECTANGLE_EXT);
204 void OpenGL::natDeleteTexture(jint tex_) {
205 activateSharedContext();
206 GLuint tex = (GLuint) tex_;
207 glDeleteTextures(1,&tex);
210 void OpenGL$SquareGLPicture::natInit(Object *data_, jboolean alphaOnly) {
216 jbyte *data = elements((JArray<jbyte>*) data_);
217 if(texWidth == width && texHeight == height) {
218 buf = (unsigned char*) data;
220 buf = new unsigned char[texWidth*texHeight];
222 for(row=0;row<height;row++) {
223 for(col=0;col<width;col++)
224 buf[p++] = data[row*width+col];
225 for(;col<texWidth;col++)
228 for(;row<texHeight;row++)
229 for(col=0;col<texWidth;col++)
233 jint *data = elements((JArray<jint>*) data_);
234 buf = new unsigned char[texWidth*texHeight*4];
236 for(row=0;row<height;row++) {
237 for(col=0;col<width;col++) {
238 jint pixel = data[row*width+col];
239 buf[p+0] = (pixel >> 16) & 0xff;
240 buf[p+1] = (pixel >> 8) & 0xff;
241 buf[p+2] = (pixel >> 0) & 0xff;
242 buf[p+3] = (pixel >> 24) & 0xff;
245 for(;col < texWidth;col++,p+=4)
246 buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
248 for(;row < texHeight;row++)
249 for(col=0;col<texWidth;col++,p+=4)
250 buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
253 gl->activateSharedContext();
254 glEnable(GL_TEXTURE_2D);
255 glGenTextures(1,&tex);
256 glBindTexture(GL_TEXTURE_2D,tex);
257 glPixelStorei(GL_PACK_ALIGNMENT,1);
258 glTexImage2D(GL_TEXTURE_2D,0,alphaOnly ? GL_ALPHA : GL_RGBA,texWidth,texHeight,0,alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
260 if(!alphaOnly || width != texWidth || height != texHeight) delete buf;
262 if(gl->glVersion >= 1.2) {
263 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
264 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
265 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
266 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
268 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
269 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
272 glDisable(GL_TEXTURE_2D);
275 textureName = (jint)tex;
278 void OpenGL$SquareGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
281 cx2 = min(cx2, dx + width);
282 cy2 = min(cy2, dy + height);
283 if (cy2 <= cy1 || cx2 <= cx1) return;
284 float tx1 = (float) (cx1 - dx) / (float) texWidth;
285 float ty1 = (float) (cy1 - dy) / (float) texHeight;
286 float tx2 = (float) (cx2 - dx) / (float) texWidth;
287 float ty2 = (float) (cy2 - dy) / (float) texHeight;
288 glEnable(GL_TEXTURE_2D);
289 glBindTexture(GL_TEXTURE_2D, textureName);
292 glTexCoord2f (tx1, ty1 );
293 glVertex3i (cx1, cy1, 0);
294 glTexCoord2f (tx2, ty1 );
295 glVertex3i (cx2, cy1, 0);
296 glTexCoord2f (tx2, ty2 );
297 glVertex3i (cx2, cy2, 0);
298 glTexCoord2f (tx1, ty2 );
299 glVertex3i (cx1, cy2, 0);
301 glDisable(GL_TEXTURE_2D);
305 } } } // end org::xwt::plat