2003/09/05 04:28:35
[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$GLDoubleBuffer.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 is 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$GLDoubleBuffer::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$GLDoubleBuffer::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$GLDoubleBuffer::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$GLDoubleBuffer::fillRect(jint x1, jint y1, jint x2, jint y2,jint color) {
100     activateContext();
101     setColor(color);
102     glBegin(GL_QUADS); 
103         glVertex3f(x1,y2,0.0f );
104         glVertex3f(x2,y2,0.0f );
105         glVertex3f(x2,y1,0.0f );
106         glVertex3f(x1,y1,0.0f );
107     glEnd();
108 }
109
110 void OpenGL$GLDoubleBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
111     //fprintf(stderr,"setClip: %d %d %d %d\n",x1,y1,x2,y2);
112     if(x1==0 && y1==0 && x2==width && y2==height) {
113         if(glScissorEnabled) {
114             activateContext();
115             glDisable(GL_SCISSOR_TEST);
116             glScissorEnabled = false;
117         }
118         return;
119     }
120     activateContext();
121     if(!glScissorEnabled) {
122         glEnable(GL_SCISSOR_TEST);
123         glScissorEnabled = true;
124     }
125     if((x1 >= x2) || (y1 >= y2))
126         glScissor(0,0,0,0);
127     else
128         glScissor(x1,height-y2,x2-x1,y2-y1);
129     checkGLError();
130 }
131
132 void OpenGL$GLDoubleBuffer::resetClip() {
133     activateContext();
134     if(glScissorEnabled) {
135         glDisable(GL_SCISSOR_TEST);
136         glScissorEnabled = false;
137     }    
138 }
139
140 void OpenGL$RectGLPicture::natInit(JArray<jint> *data_) {
141     unsigned char *buf;
142     int i,j;
143     int size = width*height;
144     jint *data = elements(data_);
145     buf = new unsigned char[size*4];
146     GLuint tex;
147
148     for(i=0,j=0;i<size;i++,j+=4) {
149         jint pixel = data[i];
150         buf[j+0] = (pixel >> 16) & 0xff;
151         buf[j+1] = (pixel >>  8) & 0xff;
152         buf[j+2] = (pixel >>  0) & 0xff;
153         buf[j+3] = (pixel >> 24) & 0xff;
154     }
155     
156     gl->activateSharedContext();
157     glEnable(GL_TEXTURE_RECTANGLE_EXT);
158     glGenTextures(1,&tex);
159     glBindTexture(GL_TEXTURE_RECTANGLE_EXT,tex);
160     glPixelStorei(GL_PACK_ALIGNMENT,1);
161     glTexImage2D(GL_TEXTURE_RECTANGLE_EXT,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
162     delete buf;
163
164     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
165     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
166     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
167     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
168
169     glDisable(GL_TEXTURE_RECTANGLE_EXT);
170     checkGLError();
171   
172     textureName = (jint)tex;
173 }
174
175 void OpenGL$RectGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) { 
176     glColor4f(1.0f,1.0f,1.0f,1.0f);
177     glEnable(GL_TEXTURE_RECTANGLE_EXT);
178     glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);    
179     glBegin(GL_QUADS); 
180         glTexCoord2i (sx1, sy1   );
181         glVertex3i   (dx1, dy1, 0);   
182         glTexCoord2i (sx2, sy1   ); 
183         glVertex3i   (dx2, dy1, 0);
184         glTexCoord2i (sx2, sy2   ); 
185         glVertex3i   (dx2, dy2, 0);
186         glTexCoord2i (sx1, sy2   );
187         glVertex3i   (dx1, dy2, 0);
188     glEnd();
189     glDisable(GL_TEXTURE_RECTANGLE_EXT);
190     checkGLError();
191
192 }
193
194 void OpenGL::natDeleteTexture(jint tex_) {
195     activateSharedContext();
196     GLuint tex = (GLuint) tex_;
197     glDeleteTextures(1,&tex);
198 }
199
200 void OpenGL$SquareGLPicture::natInit(JArray<jint> *data_) {
201     unsigned char *buf;
202     int row,col,p;
203     jint *data = elements(data_);
204     buf = new unsigned char[texWidth*texHeight*4];
205     GLuint tex;
206
207     p=0;
208     for(row=0;row<height;row++) {
209         for(col=0;col<width;col++) {
210             jint pixel = data[row*width+col];
211             buf[p+0] = (pixel >> 16) & 0xff;
212             buf[p+1] = (pixel >>  8) & 0xff;
213             buf[p+2] = (pixel >>  0) & 0xff;
214             buf[p+3] = (pixel >> 24) & 0xff;
215             p+=4;
216         }
217         for(;col < texWidth;col++,p+=4)
218             buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
219     }
220     for(;row < texHeight;row++) 
221         for(col=0;col<texWidth;col++,p+=4)
222             buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
223     
224     gl->activateSharedContext();
225     glEnable(GL_TEXTURE_2D);
226     glGenTextures(1,&tex);
227     glBindTexture(GL_TEXTURE_2D,tex);
228     glPixelStorei(GL_PACK_ALIGNMENT,1);
229     glTexImage2D(GL_TEXTURE_2D,0,4,texWidth,texHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
230     checkGLError();    
231     delete buf;
232
233     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
234     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
235     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
236     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
237
238     glDisable(GL_TEXTURE_2D);
239     checkGLError();
240   
241     textureName = (jint)tex;
242 }
243
244 void OpenGL$SquareGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) {
245     float tx1,ty1,tx2,ty2; // normalized texture coords
246     tx1 = (float) sx1 / (float) texWidth;
247     ty1 = (float) sy1 / (float) texHeight;
248     tx2 = (float) sx2 / (float) texWidth;
249     ty2 = (float) sy2 / (float) texHeight;
250
251     glColor4f(1.0f,1.0f,1.0f,1.0f);
252     glEnable(GL_TEXTURE_2D);
253     glBindTexture(GL_TEXTURE_2D, textureName);    
254     checkGLError();
255     glBegin(GL_QUADS); 
256         glTexCoord2f (tx1, ty1   );
257         glVertex3i   (dx1, dy1, 0);
258         glTexCoord2f (tx2, ty1   ); 
259         glVertex3i   (dx2, dy1, 0);
260         glTexCoord2f (tx2, ty2   ); 
261         glVertex3i   (dx2, dy2, 0);
262         glTexCoord2f (tx1, ty2   );
263         glVertex3i   (dx1, dy2, 0);
264     glEnd();
265     glDisable(GL_TEXTURE_2D);
266     checkGLError();
267 }
268
269 } } } // end org::xwt::plat