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 is correct
28 namespace org { namespace xwt { namespace plat {
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;
35 fprintf(stderr,"%s:%d: GL Error: %s",file,line,(char *) gluErrorString(err));
39 void OpenGL::natInit() {
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;
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);
59 void OpenGL$GLPixelBuffer::drawableInit(jint width, jint height) {
60 glClearColor (0.3f, 0.7f, 1.0f, 1.0f);
62 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
63 glShadeModel(GL_SMOOTH);
65 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
67 glViewport(0,0,width,height);
68 glMatrixMode(GL_PROJECTION);
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);
75 //glTranslatef(0.375, 0.375, 0.0);
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);
88 void OpenGL$GLPixelBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, jint x4, jint y2, jint color) {
92 glVertex3f(x1,y1,0.0f );
93 glVertex3f(x3,y2,0.0f );
94 glVertex3f(x4,y2,0.0f );
95 glVertex3f(x2,y1,0.0f );
99 void OpenGL$GLPixelBuffer::fillRect(jint x1, jint y1, jint x2, jint y2,jint color) {
103 glVertex3f(x1,y2,0.0f );
104 glVertex3f(x2,y2,0.0f );
105 glVertex3f(x2,y1,0.0f );
106 glVertex3f(x1,y1,0.0f );
110 void OpenGL$GLPixelBuffer::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) {
115 glDisable(GL_SCISSOR_TEST);
116 glScissorEnabled = false;
121 if(!glScissorEnabled) {
122 glEnable(GL_SCISSOR_TEST);
123 glScissorEnabled = true;
125 if((x1 >= x2) || (y1 >= y2))
128 glScissor(x1,height-y2,x2-x1,y2-y1);
132 void OpenGL$GLPixelBuffer::resetClip() {
134 if(glScissorEnabled) {
135 glDisable(GL_SCISSOR_TEST);
136 glScissorEnabled = false;
140 void OpenGL$RectGLPicture::natInit(JArray<jint> *data_) {
143 int size = width*height;
144 jint *data = elements(data_);
145 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;
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);
164 // FIXME: enable linear filtering for opengl 1.2
165 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
166 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
168 /*glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
169 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
170 glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
171 glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
173 glDisable(GL_TEXTURE_RECTANGLE_EXT);
176 textureName = (jint)tex;
179 void OpenGL$RectGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) {
180 if (gl->hasRectangularTextures()) {
181 glColor4f(1.0f,1.0f,1.0f,1.0f);
182 glEnable(GL_TEXTURE_RECTANGLE_EXT);
183 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
185 glTexCoord2i (sx1, sy1 );
186 glVertex3i (dx1, dy1, 0);
187 glTexCoord2i (sx2, sy1 );
188 glVertex3i (dx2, dy1, 0);
189 glTexCoord2i (sx2, sy2 );
190 glVertex3i (dx2, dy2, 0);
191 glTexCoord2i (sx1, sy2 );
192 glVertex3i (dx1, dy2, 0);
194 glDisable(GL_TEXTURE_RECTANGLE_EXT);
197 float tx1,ty1,tx2,ty2; // normalized texture coords
198 tx1 = (float) sx1 / (float) width;
199 ty1 = (float) sy1 / (float) height;
200 tx2 = (float) sx2 / (float) width;
201 ty2 = (float) sy2 / (float) height;
203 glColor4f(1.0f,1.0f,1.0f,1.0f);
204 glEnable(GL_TEXTURE_2D);
205 glBindTexture(GL_TEXTURE_2D, textureName);
208 glTexCoord2f (tx1, ty1 );
209 glVertex3i (dx1, dy1, 0);
210 glTexCoord2f (tx2, ty1 );
211 glVertex3i (dx2, dy1, 0);
212 glTexCoord2f (tx2, ty2 );
213 glVertex3i (dx2, dy2, 0);
214 glTexCoord2f (tx1, ty2 );
215 glVertex3i (dx1, dy2, 0);
217 glDisable(GL_TEXTURE_2D);
222 void OpenGL::natDeleteTexture(jint tex_) {
223 activateSharedContext();
224 GLuint tex = (GLuint) tex_;
225 glDeleteTextures(1,&tex);
228 void OpenGL$SquareGLPicture::natInit(JArray<jint> *data_) {
231 jint *data = elements(data_);
232 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;
252 gl->activateSharedContext();
253 glEnable(GL_TEXTURE_2D);
254 glGenTextures(1,&tex);
255 glBindTexture(GL_TEXTURE_2D,tex);
256 glPixelStorei(GL_PACK_ALIGNMENT,1);
257 glTexImage2D(GL_TEXTURE_2D,0,4,texWidth,texHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
261 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
262 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
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 glDisable(GL_TEXTURE_2D);
271 textureName = (jint)tex;
274 void OpenGL$SquareGLPicture::draw(jint dx1, jint dy1, jint dx2, jint dy2,jint sx1, jint sy1, jint sx2, jint sy2) {
275 float tx1,ty1,tx2,ty2; // normalized texture coords
276 tx1 = (float) sx1 / (float) texWidth;
277 ty1 = (float) sy1 / (float) texHeight;
278 tx2 = (float) sx2 / (float) texWidth;
279 ty2 = (float) sy2 / (float) texHeight;
281 glColor4f(1.0f,1.0f,1.0f,1.0f);
282 glEnable(GL_TEXTURE_2D);
283 glBindTexture(GL_TEXTURE_2D, textureName);
286 glTexCoord2f (tx1, ty1 );
287 glVertex3i (dx1, dy1, 0);
288 glTexCoord2f (tx2, ty1 );
289 glVertex3i (dx2, dy1, 0);
290 glTexCoord2f (tx2, ty2 );
291 glVertex3i (dx2, dy2, 0);
292 glTexCoord2f (tx1, ty2 );
293 glVertex3i (dx1, dy2, 0);
295 glDisable(GL_TEXTURE_2D);
299 } } } // end org::xwt::plat