Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java JNI ja C/C++

Sivun loppuun

kpzpt [04.09.2009 00:39:27]

#

Hei!

Tarvitsee oppia Java JNI lukemaan C/C++ koodia.

Ei myöskään tässä tarvitse koko APIa opetella,
tarvitsen ainoastaan OpenGL kutsut.

Onkos Ohjelmointiputkassa JNI taitajia ??

Yritin googleta mutta en löytänyt tutoriaaleja Linuxilleni.

//----

Kiitos,,

Jackal von ÖRF [04.09.2009 00:44:20]

#

Jos pelkkää OpenGL:ää tarvitset, niin käytä JOGL tai LWJGL -kirjastoa.

kpzpt [04.09.2009 02:04:43]

#

Heh!

Juuri nuo molemmat ovat syynä miksi tarvitsen oppia JNI käyttöä.

Eli, JOGL on yli megan paketti ja LWJGL on yli 400k kun poistaa Open Audio Libraryn.

Tarvitsen ainoastaan perus tekstureitten käsittelyt Java projekteihini.

Peli Demo -> http://temp432123.dy.fi/Pelit
Rakentuva Sivustoni -> http://temp432123.dy.fi

Tuohon yllä olevaan, JOGL kanssa kun tein tuota niin oli yli 1.2 megan paketti.
LWJGL kanssa onnistuin pääsemään alle 400k, mutta, molemmat sisältävät aivan
liikaa sellaista mitä en tarvitse.

yritän päästä alle 60k-70k OpenGL kutsujen kanssa.

//----

Kiitos,,

Metabolix [04.09.2009 09:33:16]

#

Yksi hyvä syy jättää homma sikseen: Natiivi kirjasto vastaa natiivia ohjelmaa, eli joka käyttöjärjestelmä ja prosessori vaatii erillisen kirjaston. Omaa kirjastoasi et luultavasti saa käännettyä kuin yhdelle tai parille järjestelmälle. Rajoittaisit siis käyttäjäkuntaasi. JOGL löytyy valmiiksi jo monelle järjestelmälle, ja joku sinua taitavampi huolehtii sen yhteensopivuudesta.

Tässä on hyvin selkeä ohje.

maka78 [04.09.2009 10:57:48]

#

No JNI:n käyttö on loppu pelissä aika simppeliä:
Tässä SUN:in tutoriaali aiheesta:
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html

Eli lyhyesti java luokkaan tehdään native avainsanalla niiden metodien rungot jotka halutaan tehdä C++:lla, samaan tapaan kuin interface:issä.

tämän jälkeen luokka käännetään javac:illa. Jonka jälkeen luokasta luodaan header-file C++:aa varten komennolla:
javah -jni LuokanNimi

Sitten tehdään C++:lla DLL-rojekti(windows)tai so-projekti(Linux) johon liitetään tuo javah:illa luotu header-tiedosto ja toteutetaan header:issä kuvatut metodit.
Sit käännetään ja tuo valmis DLL tai so liitetään java paketin mukaan.

Eli C++:lla tehdyissä metodeissa kutsut sitten niitä varsinaisia OpenGL-kutsuja.

Mut itsekin käyttäisin valmiita kirjastoja, ellei sitten rojekti ihan oikeesti muuta vaadi.

Tuolta Sun:in sivuilta pitäis löytyä esimerkki myös Linukalle (muistaakseni)

Blaze [04.09.2009 13:22:30]

#

Kannattaa myös huomata, että natiivikoodin ajaminen appletista vaatii sen, että applet on digitaalisesti allekirjoitettu ("signed applet"). Käyttäjä saa silmilleen pelottavannäkösiä vahvistusdialogeja ja siinä, missä tavalliset appletit leikkivät kiltisti hiekkalaatikossaan, näillä signedeillä on valta vaikka poistaa kaikki käyttäjän tiedostot. Tietoturvastaan kiinnostuneet siis jättävät moiset ajamatta.

kpzpt [04.09.2009 14:46:03]

#

Hmm!

Olen kyllä käynyt kaikki nuo pointit lävitse, ennen päätöstäni kokeilla
omaa OpenGL JNI kirjastoa.

En usko että joudun kovinkaan paljoa työtä näkemään eri koneille tehtävien
kirjastojen kanssa, linux ja windows menevät varmanakin melkein identtisinä,
Mac on vähän kysymysmerkkinä.

Signeeraus on ainoa huono asia projektissa.
Ja signeeraus on vielä kyllä yksin se paras syy käyttää Java2D:tä koko projektissani.
Mutta kokeilen nyt kuitenkin omaa pientä OpenGL kirjastoa, kiitos kun autatte ihan alkuun, jotta saan sitten itse ison rullan pyörimään ja rakennettua nämä omat kirjastoni.

----

Minulla on nyt tuo JNI HelloWorld testissä, Linux Ubuntussa.
Ohjelmani valittaa seuraavaa ->

Minä käytän Netbeans IDE 6.7.1 editoria, ja olen run parametreihin asettanut
-Djava.library.path=/home/munnimi/

Java Source.

package ekaclass;

class HelloWorld
{

     private native void print();

     public static void main(String[] args)
     {
         new HelloWorld().print();
         System.out.println("HelloWorld!");
     }

     static
     {
        System.loadLibrary("libEkaSO.SO");
     }
 }

C++ source.

 #include <jni.h>
 #include <stdio.h>
 #include "ekaclass_HelloWorld.h"

 JNIEXPORT void JNICALL
 Java_HelloWorld_print(JNIEnv *env, jobject obj)
 {
     printf("Hello World!\n");
     return;
 }

C++ header.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class ekaclass_HelloWorld */

#ifndef _Included_ekaclass_HelloWorld
#define _Included_ekaclass_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     ekaclass_HelloWorld
 * Method:    print
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_ekaclass_HelloWorld_print
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
Exception in thread "main" java.lang.UnsatisfiedLinkError: no libEkaSO.SO in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1709)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1028)
        at ekaclass.HelloWorld.<clinit>(Unknown Source)
Could not find the main class: ekaclass.HelloWorld.  Program will exit.
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

Myöskin komentoriviltä käynnistys aiheuttaa saman virheilmoituksen,
vaikka käytän -Djava.library.path=/home/munnimi/ optiota.

//----

Kiitos,,

Metabolix [04.09.2009 15:01:48]

#

Funktiosi nimi on väärin. Näethän jo otsikkotiedostosta, että sen pitäisi olla Java_ekaclass_HelloWorld_print. Oletko kääntänyt C++-koodisi oikealla tavalla .so-tiedostoksi? Myös kirjainkoolla on väliä, eli .so kuuluisi kirjoittaa pienellä sekä Java-koodissa että C++:n käännöskomennossa.

kpzpt [04.09.2009 17:10:45]

#

Ok!

Onnistuin vihdoin helloworld demon kanssa, nyt olisi tarkoitus opetella JNI OpenGL kera hieman.

Tässä olisi RedBook demo joka pitäisi laittaa Java Canvakseen ->

Itse demo toimi hienosti Ubuntussani NetBeans IDE 6.7.1 kanssa.

Nyt olisi tarkoitus muuttaa demoa niin että sitä voi kutsua Javasta käsin.
Onkos Ohjelmointiputkassa JNI taitajia, tarvitsen ainoastaan nämä perus asiat
jotta sitten voin soveltaa kaikkia OpenGL käskyjä Javan kanssa.

Kuinka tämänkaltaiset demot saa piirtymään Java Canvakseen ??

( Yritän siis rakentaa alle 25-80 ?? kiloisen (.JAR) OpenGL kirjaston Java projektiini )

/*
 * File:   main.cpp
 * Author: jtapio
 *
 * Created on 4. syyskuuta 2009, 16:46
 */
/*
 * Copyright (c) 1993-1997, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED
 * Permission to use, copy, modify, and distribute this software for
 * any purpose and without fee is hereby granted, provided that the above
 * copyright notice appear in all copies and that both the copyright notice
 * and this permission notice appear in supporting documentation, and that
 * the name of Silicon Graphics, Inc. not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission.
 *
 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
 * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * US Government Users Restricted Rights
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
 * clause at DFARS 252.227-7013 and/or in similar or successor
 * clauses in the FAR or the DOD or NASA FAR Supplement.
 * Unpublished-- rights reserved under the copyright laws of the
 * United States.  Contractor/manufacturer is Silicon Graphics,
 * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
 *
 * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
 */

/*
 *  aapoly.c
 *  This program draws filled polygons with antialiased
 *  edges.  The special GL_SRC_ALPHA_SATURATE blending
 *  function is used.
 *  Pressing the 't' key turns the antialiasing on and off.
 */
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

GLboolean polySmooth = GL_TRUE;

static void init(void)
{
   glCullFace (GL_BACK);
   glEnable (GL_CULL_FACE);
   glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);
   glClearColor (0.0, 0.0, 0.0, 0.0);
}

#define NFACE 6
#define NVERT 8
void drawCube(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1,
        GLdouble z0, GLdouble z1)
{
   static GLfloat v[8][3];
   static GLfloat c[8][4] = {
      {0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 1.0},
      {0.0, 1.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 1.0},
      {0.0, 0.0, 1.0, 1.0}, {1.0, 0.0, 1.0, 1.0},
      {0.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}
   };

/*  indices of front, top, left, bottom, right, back faces  */
   static GLubyte indices[NFACE][4] = {
      {4, 5, 6, 7}, {2, 3, 7, 6}, {0, 4, 7, 3},
      {0, 1, 5, 4}, {1, 5, 6, 2}, {0, 3, 2, 1}
   };

   v[0][0] = v[3][0] = v[4][0] = v[7][0] = x0;
   v[1][0] = v[2][0] = v[5][0] = v[6][0] = x1;
   v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
   v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
   v[0][2] = v[1][2] = v[2][2] = v[3][2] = z0;
   v[4][2] = v[5][2] = v[6][2] = v[7][2] = z1;

#ifdef GL_VERSION_1_1
   glEnableClientState (GL_VERTEX_ARRAY);
   glEnableClientState (GL_COLOR_ARRAY);
   glVertexPointer (3, GL_FLOAT, 0, v);
   glColorPointer (4, GL_FLOAT, 0, c);
   glDrawElements (GL_QUADS, NFACE*4, GL_UNSIGNED_BYTE, indices);
   glDisableClientState (GL_VERTEX_ARRAY);
   glDisableClientState (GL_COLOR_ARRAY);
#else
   printf ("If this is GL Version 1.0, ");
   printf ("vertex arrays are not supported.\n");
   exit(1);
#endif
}

/*  Note:  polygons must be drawn from front to back
 *  for proper blending.
 */
void display(void)
{
   if (polySmooth) {
      glClear (GL_COLOR_BUFFER_BIT);
      glEnable (GL_BLEND);
      glEnable (GL_POLYGON_SMOOTH);
      glDisable (GL_DEPTH_TEST);
   }
   else {
      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glDisable (GL_BLEND);
      glDisable (GL_POLYGON_SMOOTH);
      glEnable (GL_DEPTH_TEST);
   }

   glPushMatrix ();
      glTranslatef (0.0, 0.0, -8.0);
      glRotatef (30.0, 1.0, 0.0, 0.0);
      glRotatef (60.0, 0.0, 1.0, 0.0);
      drawCube(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);
   glPopMatrix ();

   glFlush ();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(30.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 't':
      case 'T':
         polySmooth = !polySmooth;
         glutPostRedisplay();
         break;
      case 27:
         exit(0);  /*  Escape key  */
         break;
      default:
         break;
   }
}

/*  Main Loop
 */
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB
                        | GLUT_ALPHA | GLUT_DEPTH);
   glutInitWindowSize(200, 200);
   glutCreateWindow(argv[0]);
   init ();
   glutReshapeFunc (reshape);
   glutKeyboardFunc (keyboard);
   glutDisplayFunc (display);
   glutMainLoop();
   return 0;
}

//----

Kiitos,,

vehkis91 [04.09.2009 17:46:53]

#

Mitä ominaisuuksia siitä OGL:stä sää oikeen tarviit?

EDIT, hitto tollahan se lukikin. Eli tarviit textuureiden latauksen, ogl:n alustuksen ja piirron?

kpzpt [04.09.2009 18:21:44]

#

Hei!

Tarvitsen OpenGL alustuksen Java Canvakseen, lisänä tarvitsen muutaman perus OpenGL toiminnan canvakseen esimerkiksi.

Kiva jos löytyisi tarvittavaa taitoa ??

( edit. )
Itse kuvien lataus voi hoitua ihan Javalla, siirrän vain sitten jo käsitellyt kuvat Array muodossa C++ OpenGL GLUT:tiin muodostumaan tekstureiksi.

( edit2. )
Lisänä tarvitsen hieman ymmärrystä rakenteeseen.
Eli, kuinka tämän kaltainen Java <-> C++ hyppely kannattaa rakentaa.

//----

Kiitos,,


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta