1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the GNU General Public License version 2 ("the License").
3 // You may not use this file except in compliance with the License.
5 // Author: Brian Alliet
7 // IMPROVMENT: use alpha testing? might be faster
9 #include <org/ibex/plat/OpenGL.h>
10 #include <org/ibex/plat/OpenGL$GLPixelBuffer.h>
11 #include <org/ibex/plat/OpenGL$GLPicture.h>
12 #include <org/ibex/plat/OpenGL$RectGLPicture.h>
13 #include <org/ibex/plat/OpenGL$SquareGLPicture.h>
14 #include <org/ibex/plat/OpenGL$MosaicGLPicture.h>
16 #include <java/lang/Error.h>
19 #include <OpenGL/gl.h>
20 #include <OpenGL/glu.h>
21 #include <OpenGL/glext.h>
23 #warning I am not sure if these are correct
31 #define min(a,b) ((a)<(b)?(a):(b))
32 #define max(a,b) ((a)>(b)?(a):(b))
34 namespace org { namespace ibex { namespace plat {
36 #define checkGLError() checkGLError2(__FILE__,__LINE__)
37 static void checkGLError2(const char *file,int line) {
38 GLenum err = glGetError();
39 if(err == GL_NO_ERROR) return;
41 fprintf(stderr,"%s:%d: GL Error: %s",file,line,(char *) gluErrorString(err));
45 void OpenGL::natInit() {
48 activateSharedContext();
49 s = glGetString(GL_EXTENSIONS);
50 rectangularTextures = (jboolean) gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle",s);
51 glGetIntegerv(GL_MAX_TEXTURE_SIZE,&i);
52 maxTexSize = (jint) i;
53 if(rectangularTextures) {
54 glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT,&i);
55 maxRectTexSize = (jint) i;
57 s = glGetString(GL_VENDOR);
58 vendor = JvNewStringLatin1(s==0 ? "" : (char*)s);
59 s = glGetString(GL_RENDERER);
60 renderer = JvNewStringLatin1(s==0 ? "" : (char*)s);
61 s = glGetString(GL_VERSION);
62 version = JvNewStringLatin1(s==0 ? "" : (char*)s);
65 void OpenGL$GLPixelBuffer::drawableInit(jint width, jint height) {
66 glClearColor (0.3f, 0.7f, 1.0f, 1.0f);
68 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
69 glShadeModel(GL_SMOOTH);
71 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
73 glViewport(0,0,width,height);
74 glMatrixMode(GL_PROJECTION);
76 glOrtho(0,width,height,0,-1,1);
77 // CHECKME: This causes textures to be blurry, but something like this
78 // (but not this) might be required to draw straight lines
79 //glMatrixMode(GL_MODELVIEW);
81 //glTranslatef(0.375, 0.375, 0.0);
86 void OpenGL$GLPixelBuffer::setColor(jint argb) {
87 float alpha = ((argb >> 24) & 0xff) / 255.0;
88 float red = ((argb >> 16) & 0xff) / 255.0;
89 float green = ((argb >> 8) & 0xff) / 255.0;
90 float blue = ((argb >> 0) & 0xff) / 255.0;
91 glColor4f(red,green,blue,alpha);
94 void OpenGL$GLPixelBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, jint x4, jint y2, jint color) {
98 glVertex3f(x1,y1,0.0f );
99 glVertex3f(x3,y2,0.0f );
100 glVertex3f(x4,y2,0.0f );
101 glVertex3f(x2,y1,0.0f );
105 void OpenGL$GLPixelBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
106 //fprintf(stderr,"setClip: %d %d %d %d\n",x1,y1,x2,y2);
107 if(x1==0 && y1==0 && x2==width && y2==height) {
108 if(glScissorEnabled) {
110 glDisable(GL_SCISSOR_TEST);
111 glScissorEnabled = false;
116 if(!glScissorEnabled) {
117 glEnable(GL_SCISSOR_TEST);
118 glScissorEnabled = true;
120 if((x1 >= x2) || (y1 >= y2))
123 glScissor(x1,height-y2,x2-x1,y2-y1);
127 void OpenGL$GLPixelBuffer::resetClip() {
129 if(glScissorEnabled) {
130 glDisable(GL_SCISSOR_TEST);
131 glScissorEnabled = false;
135 // FEATURE: Eliminate duplicate code in RectGLPicture and SquareGLPicture
136 void OpenGL$RectGLPicture::natInit(Object *data_, jboolean alphaOnly) {
139 int size = width*height;
143 jbyte *data = elements((JArray<jbyte> *)data_);
144 buf = (unsigned char *) data;
146 jint *data = elements((JArray<jint> *)data_);
147 buf = new unsigned char[size*4];
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;
157 gl->activateSharedContext();
158 glEnable(GL_TEXTURE_RECTANGLE_EXT);
159 glGenTextures(1,&tex);
160 glBindTexture(GL_TEXTURE_RECTANGLE_EXT,tex);
161 glPixelStorei(GL_PACK_ALIGNMENT,1);
163 GL_TEXTURE_RECTANGLE_EXT,0,
164 alphaOnly ? GL_ALPHA : GL_RGBA,width,height,0,
165 alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
169 if(gl->glVersion >= 1.2) {
170 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
171 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
172 glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
173 glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
175 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
176 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
179 glDisable(GL_TEXTURE_RECTANGLE_EXT);
182 textureName = (jint)tex;
185 void OpenGL$RectGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
188 cx2 = min(cx2, dx + width);
189 cy2 = min(cy2, dy + height);
190 if (cy2 <= cy1 || cx2 <= cx1) return;
191 glEnable(GL_TEXTURE_RECTANGLE_EXT);
192 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
194 glTexCoord2i (cx1 - dx, cy1 - dy );
195 glVertex3i (cx1, cy1, 0);
196 glTexCoord2i (cx2 - dx, cy1 - dy );
197 glVertex3i (cx2, cy1, 0);
198 glTexCoord2i (cx2 - dx, cy2 - dy );
199 glVertex3i (cx2, cy2, 0);
200 glTexCoord2i (cx1 - dx, cy2 - dy );
201 glVertex3i (cx1, cy2, 0);
203 glDisable(GL_TEXTURE_RECTANGLE_EXT);
207 void OpenGL::natDeleteTexture(jint tex_) {
208 activateSharedContext();
209 GLuint tex = (GLuint) tex_;
210 glDeleteTextures(1,&tex);
213 void OpenGL$SquareGLPicture::natInit(Object *data_, jboolean alphaOnly) {
219 jbyte *data = elements((JArray<jbyte>*) data_);
220 if(texWidth == width && texHeight == height) {
221 buf = (unsigned char*) data;
223 buf = new unsigned char[texWidth*texHeight];
225 for(row=0;row<height;row++) {
226 for(col=0;col<width;col++)
227 buf[p++] = data[row*width+col];
228 for(;col<texWidth;col++)
231 for(;row<texHeight;row++)
232 for(col=0;col<texWidth;col++)
236 jint *data = elements((JArray<jint>*) data_);
237 buf = new unsigned char[texWidth*texHeight*4];
239 for(row=0;row<height;row++) {
240 for(col=0;col<width;col++) {
241 jint pixel = data[row*width+col];
242 buf[p+0] = (pixel >> 16) & 0xff;
243 buf[p+1] = (pixel >> 8) & 0xff;
244 buf[p+2] = (pixel >> 0) & 0xff;
245 buf[p+3] = (pixel >> 24) & 0xff;
248 for(;col < texWidth;col++,p+=4)
249 buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
251 for(;row < texHeight;row++)
252 for(col=0;col<texWidth;col++,p+=4)
253 buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
256 gl->activateSharedContext();
257 glEnable(GL_TEXTURE_2D);
258 glGenTextures(1,&tex);
259 glBindTexture(GL_TEXTURE_2D,tex);
260 glPixelStorei(GL_PACK_ALIGNMENT,1);
261 glTexImage2D(GL_TEXTURE_2D,0,alphaOnly ? GL_ALPHA : GL_RGBA,texWidth,texHeight,0,alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
263 if(!alphaOnly || width != texWidth || height != texHeight) delete buf;
265 if(gl->glVersion >= 1.2) {
266 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
267 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
268 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
269 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
271 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
272 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
275 glDisable(GL_TEXTURE_2D);
278 textureName = (jint)tex;
281 void OpenGL$SquareGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
284 cx2 = min(cx2, dx + width);
285 cy2 = min(cy2, dy + height);
286 if (cy2 <= cy1 || cx2 <= cx1) return;
287 float tx1 = (float) (cx1 - dx) / (float) texWidth;
288 float ty1 = (float) (cy1 - dy) / (float) texHeight;
289 float tx2 = (float) (cx2 - dx) / (float) texWidth;
290 float ty2 = (float) (cy2 - dy) / (float) texHeight;
291 glEnable(GL_TEXTURE_2D);
292 glBindTexture(GL_TEXTURE_2D, textureName);
295 glTexCoord2f (tx1, ty1 );
296 glVertex3i (cx1, cy1, 0);
297 glTexCoord2f (tx2, ty1 );
298 glVertex3i (cx2, cy1, 0);
299 glTexCoord2f (tx2, ty2 );
300 glVertex3i (cx2, cy2, 0);
301 glTexCoord2f (tx1, ty2 );
302 glVertex3i (cx1, cy2, 0);
304 glDisable(GL_TEXTURE_2D);
308 } } } // end org::ibex::plat