71870c7de1e150eb98d726d8a095c00454d3a76a
[org.ibex.core.git] / src / org / xwt / plat / OpenGL.cc
1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL]
2 // Author: Brian Alliet
3
4 // IMPROVMENT: use alpha testing? might be faster
5
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>
12
13 #include <java/lang/Error.h>
14
15 #ifdef __APPLE__
16 #include <OpenGL/gl.h>
17 #include <OpenGL/glu.h>
18 #include <OpenGL/glext.h>
19 #else
20 #warning I am not sure if these are correct
21 #include <gl/gl.h>
22 #include <gl/glu.h>
23 #include <gl/glext.h>
24 #endif
25
26 #include <stdio.h>
27
28 namespace org { namespace xwt { namespace plat {
29
30 #define checkGLError() checkGLError2(__FILE__,__LINE__)
31 static void checkGLError2(const char *file,int line) {
32     GLenum err = glGetError();
33     if(err == GL_NO_ERROR) return;
34
35     fprintf(stderr,"%s:%d: GL Error: %s",file,line,(char *) gluErrorString(err));
36     exit(EXIT_FAILURE);
37 }
38
39 void OpenGL::natInit() {
40     GLint i;
41     const GLubyte *s;
42     activateSharedContext();
43     s = glGetString(GL_EXTENSIONS);
44     rectangularTextures = (jboolean) gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle",s);
45     glGetIntegerv(GL_MAX_TEXTURE_SIZE,&i);
46     maxTexSize = (jint) i;
47     if(rectangularTextures) {
48         glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT,&i);
49         maxRectTexSize = (jint) i;
50     }
51     s = glGetString(GL_VENDOR);
52     vendor = JvNewStringLatin1(s==0 ? "" : (char*)s);
53     s = glGetString(GL_RENDERER);
54     renderer = JvNewStringLatin1(s==0 ? "" : (char*)s);
55     s = glGetString(GL_VERSION);
56     version = JvNewStringLatin1(s==0 ? "" : (char*)s);
57 }
58
59 void OpenGL$GLPixelBuffer::drawableInit(jint width, jint height) {
60     glClearColor (0.3f, 0.7f, 1.0f, 1.0f);
61     glClearDepth( 0.0f );
62     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
63     glShadeModel(GL_SMOOTH);
64     glEnable(GL_BLEND);
65     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
66
67     glViewport(0,0,width,height);
68     glMatrixMode(GL_PROJECTION);
69     glLoadIdentity(); 
70     glOrtho(0,width,height,0,-1,1);
71     // CHECKME: This causes textures to be blurry, but something like this
72     // (but not this) might be required to draw straight lines   
73     //glMatrixMode(GL_MODELVIEW);
74     //glLoadIdentity(); 
75     //glTranslatef(0.375, 0.375, 0.0);    
76     
77     checkGLError();
78 }
79
80 void OpenGL$GLPixelBuffer::setColor(jint argb) {
81     float alpha = ((argb >> 24) & 0xff) / 255.0;
82     float red   = ((argb >> 16) & 0xff) / 255.0;
83     float green = ((argb >>  8) & 0xff) / 255.0;
84     float blue  = ((argb >>  0) & 0xff) / 255.0;
85     glColor4f(red,green,blue,alpha);
86 }
87
88 void OpenGL$GLPixelBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, jint x4, jint y2, jint color) {
89     activateContext();
90     setColor(color);
91     glBegin(GL_QUADS); 
92         glVertex3f(x1,y1,0.0f );   
93         glVertex3f(x3,y2,0.0f );  
94         glVertex3f(x4,y2,0.0f ); 
95         glVertex3f(x2,y1,0.0f ); 
96     glEnd();
97 }
98
99 void OpenGL$GLPixelBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
100     //fprintf(stderr,"setClip: %d %d %d %d\n",x1,y1,x2,y2);
101     if(x1==0 && y1==0 && x2==width && y2==height) {
102         if(glScissorEnabled) {
103             activateContext();
104             glDisable(GL_SCISSOR_TEST);
105             glScissorEnabled = false;
106         }
107         return;
108     }
109     activateContext();
110     if(!glScissorEnabled) {
111         glEnable(GL_SCISSOR_TEST);
112         glScissorEnabled = true;
113     }
114     if((x1 >= x2) || (y1 >= y2))
115         glScissor(0,0,0,0);
116     else
117         glScissor(x1,height-y2,x2-x1,y2-y1);
118     checkGLError();
119 }
120
121 void OpenGL$GLPixelBuffer::resetClip() {
122     activateContext();
123     if(glScissorEnabled) {
124         glDisable(GL_SCISSOR_TEST);
125         glScissorEnabled = false;
126     }    
127 }
128
129 void OpenGL$RectGLPicture::natInit(JArray<jint> *data_) {
130     unsigned char *buf;
131     int i,j;
132     int size = width*height;
133     jint *data = elements(data_);
134     buf = new unsigned char[size*4];
135     GLuint tex;
136
137     for(i=0,j=0;i<size;i++,j+=4) {
138         jint pixel = data[i];
139         buf[j+0] = (pixel >> 16) & 0xff;
140         buf[j+1] = (pixel >>  8) & 0xff;
141         buf[j+2] = (pixel >>  0) & 0xff;
142         buf[j+3] = (pixel >> 24) & 0xff;
143     }
144     
145     gl->activateSharedContext();
146     glEnable(GL_TEXTURE_RECTANGLE_EXT);
147     glGenTextures(1,&tex);
148     glBindTexture(GL_TEXTURE_RECTANGLE_EXT,tex);
149     glPixelStorei(GL_PACK_ALIGNMENT,1);
150     glTexImage2D(GL_TEXTURE_RECTANGLE_EXT,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
151     delete buf;
152
153     // FIXME: enable linear filtering for opengl 1.2
154     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
155     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
156     
157     /*glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
158     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
159     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
160     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
161
162     glDisable(GL_TEXTURE_RECTANGLE_EXT);
163     checkGLError();
164   
165     textureName = (jint)tex;
166 }
167
168 void OpenGL$RectGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) { 
169     if (gl->hasRectangularTextures()) {
170         glColor4f(1.0f,1.0f,1.0f,1.0f);
171         glEnable(GL_TEXTURE_RECTANGLE_EXT);
172         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);    
173         glBegin(GL_QUADS); 
174         glTexCoord2i (sx1, sy1   );
175         glVertex3i   (dx1, dy1, 0);   
176         glTexCoord2i (sx2, sy1   ); 
177         glVertex3i   (dx2, dy1, 0);
178         glTexCoord2i (sx2, sy2   ); 
179         glVertex3i   (dx2, dy2, 0);
180         glTexCoord2i (sx1, sy2   );
181         glVertex3i   (dx1, dy2, 0);
182         glEnd();
183         glDisable(GL_TEXTURE_RECTANGLE_EXT);
184         checkGLError();
185     } else {
186         float tx1,ty1,tx2,ty2; // normalized texture coords
187         tx1 = (float) sx1 / (float) width;
188         ty1 = (float) sy1 / (float) height;
189         tx2 = (float) sx2 / (float) width;
190         ty2 = (float) sy2 / (float) height;
191
192         glColor4f(1.0f,1.0f,1.0f,1.0f);
193         glEnable(GL_TEXTURE_2D);
194         glBindTexture(GL_TEXTURE_2D, textureName);    
195         checkGLError();
196         glBegin(GL_QUADS); 
197             glTexCoord2f (tx1, ty1   );
198             glVertex3i   (dx1, dy1, 0);
199             glTexCoord2f (tx2, ty1   ); 
200             glVertex3i   (dx2, dy1, 0);
201             glTexCoord2f (tx2, ty2   ); 
202             glVertex3i   (dx2, dy2, 0);
203             glTexCoord2f (tx1, ty2   );
204             glVertex3i   (dx1, dy2, 0);
205         glEnd();
206         glDisable(GL_TEXTURE_2D);
207         checkGLError();
208     }
209 }
210
211 void OpenGL::natDeleteTexture(jint tex_) {
212     activateSharedContext();
213     GLuint tex = (GLuint) tex_;
214     glDeleteTextures(1,&tex);
215 }
216
217 void OpenGL$SquareGLPicture::natInit(JArray<jint> *data_) {
218     unsigned char *buf;
219     int row,col,p;
220     jint *data = elements(data_);
221     buf = new unsigned char[texWidth*texHeight*4];
222     GLuint tex;
223
224     p=0;
225     for(row=0;row<height;row++) {
226         for(col=0;col<width;col++) {
227             jint pixel = data[row*width+col];
228             buf[p+0] = (pixel >> 16) & 0xff;
229             buf[p+1] = (pixel >>  8) & 0xff;
230             buf[p+2] = (pixel >>  0) & 0xff;
231             buf[p+3] = (pixel >> 24) & 0xff;
232             p+=4;
233         }
234         for(;col < texWidth;col++,p+=4)
235             buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
236     }
237     for(;row < texHeight;row++) 
238         for(col=0;col<texWidth;col++,p+=4)
239             buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
240     
241     gl->activateSharedContext();
242     glEnable(GL_TEXTURE_2D);
243     glGenTextures(1,&tex);
244     glBindTexture(GL_TEXTURE_2D,tex);
245     glPixelStorei(GL_PACK_ALIGNMENT,1);
246     glTexImage2D(GL_TEXTURE_2D,0,4,texWidth,texHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
247     checkGLError();    
248     delete buf;
249
250     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
251     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
252     /*glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
253     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
254     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
255     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
256
257     glDisable(GL_TEXTURE_2D);
258     checkGLError();
259   
260     textureName = (jint)tex;
261 }
262
263 void OpenGL$SquareGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) {
264     float tx1,ty1,tx2,ty2; // normalized texture coords
265     tx1 = (float) sx1 / (float) texWidth;
266     ty1 = (float) sy1 / (float) texHeight;
267     tx2 = (float) sx2 / (float) texWidth;
268     ty2 = (float) sy2 / (float) texHeight;
269
270     glColor4f(1.0f,1.0f,1.0f,1.0f);
271     glEnable(GL_TEXTURE_2D);
272     glBindTexture(GL_TEXTURE_2D, textureName);    
273     checkGLError();
274     glBegin(GL_QUADS); 
275         glTexCoord2f (tx1, ty1   );
276         glVertex3i   (dx1, dy1, 0);
277         glTexCoord2f (tx2, ty1   ); 
278         glVertex3i   (dx2, dy1, 0);
279         glTexCoord2f (tx2, ty2   ); 
280         glVertex3i   (dx2, dy2, 0);
281         glTexCoord2f (tx1, ty2   );
282         glVertex3i   (dx1, dy2, 0);
283     glEnd();
284     glDisable(GL_TEXTURE_2D);
285     checkGLError();
286 }
287
288 } } } // end org::xwt::plat