430 likes | 637 Views
jogl. נכתב ע"י משה חדד. Previously ,on CG…. מעבר מקורדינטות עולם לקורדינטות מבט Projection הטלה אורתוגרפית הטלה פרספקטיבית OpenGL windows Glut פקודות openGL. היום. Jogl התקנה אובייקטים בסיסיים הגדרת סביבה בסיסית פקודות נוספות ב openGL. JOGL. jogl
E N D
jogl נכתב ע"י משה חדד
Previously ,on CG… • מעבר מקורדינטות עולם לקורדינטות מבט • Projection • הטלה אורתוגרפית • הטלה פרספקטיבית • OpenGL • windows • Glut • פקודות openGL
היום • Jogl • התקנה • אובייקטים בסיסיים • הגדרת סביבה בסיסית • פקודות נוספות ב openGL
JOGL • jogl • בראשית היה java3D וחושך על פני תהום, ויאמרו Sun Microsystems יהי jogl • Jogl היא ממשק ל-openGL עבור java שפותחה בשיתוף עם יוצרת openGLSGI • השימוש בפונקציות openGL נעשה בעזרת JNI java native interface • JNI מאפשרת שימוש בקוד c / c++ מתוך קוד java • Jogl משתמש בעצם בספריות openGL שכתובות ב- c • כמובן שעבור על סביבת עבודה נצטרך natives המתאימים לסביבה (מנטרל את הרב-סביבתיות של java )
JOGL • התקנת Jogl • ע"מ להתקין את הספריות יש להוריד מהאתר של jogl שני קבצים עיקריים • Jogl.jar – מכיל את הפקודות ב-java • jogl-natives-windows-i586.zip – מכיל את קבצי ה- dll המתאימים למערכת ההפעלה (windows במקרה שלנו ) • לינק לאתר https://jogl.dev.java.net/servlets/ProjectDocumentList • אפשר להוריד את הגרסה האחרונה של יוני 2009 • ניתן כמובן גם להוריד משם את javaDoc וגם קבצי demo
JOGL • התקנת Jogl • כזה ראה וקדש
JOGL • JSR-231-1.1.1a • קובץ jogl-1.1.1a-windows-i586.zip (בהנחה שיש לכם מעבד אינטל)
JOGL • את קובץ ה jar יש לשם בספריה C:\Program Files\Java\jre1.5.0_06\lib\ext • את קובץ ה-natives יש לפתוח ולהכניס את קבצי ה-dll לספריה • C:\Program Files\Java\jre1.5.0_06\bin • הערה • Jogl עברה פיתוחים רבים ושינויים רבים ,נכון לעכשיו היא התייצבה • בעקבות השינויים הנ"ל קוד ישן לא יעבוד עם הספריות החדשות • ניתן להבחין בין קוד ישן • הקוד הישן משתמש ב import net.java.games.jogl……… • הקוד החדש משתמש ב-import com.sun.opengl.util…… • אז אם אתם מחפשים דוגמאות באינטרנט תדאגו שהם יהיו מעודכנות
JOGL • אובייקטים בסיסיים • GLCanvas מתפקד כמו canvas (כלומר משטח עליו ניתן לצייר) • GLJPanel – מתפקד כמו Jpanel ,איטי יחסית ל GLCanvas • GLAutoDrawable- ממשק שמיישמים שני הרכיבים הנ"ל המאפשר • גישה לאובייקט GL (ומשם למתודות שלו) • מנגנון calbackGLEventListener לאירועים המתרחשים בתכנית • Init() , display() , reshape(), displayChanged() • GLCapabilities –מאפשר קבלת סט של פרמטרים עבור openGL (לא חובה לשימוש) • Animator-אובייקט שתפקידו העיקרי הוא לקבל GLCanvas ולקרוא למתודת ה-display() באופן סידרתי
JOGL • הגדרת סביבה בסיסית • import- נקרא לספריות של openGLול-awt • java.awt • javax.media.opengl • javax.media.opengl.glu.GLU • com.sun.opengl.util • ניישם מחלקה כ-GLEventListener • המחלקה תיישם את המתודות init() display וכו' • ניישם כמובן גם את הארועים עליהם אנחנו רוצים להגיב כלומר keylistener,mouselistener וכו' כך שיתווספו לנו המתודות המתאימות
JOGL public class Ex3 implements GLEventListener, KeyListener, MouseMotionListener { //the main class will implement the GLEventListener adding the init & display methods public static GLU glu; //static object GLU that will be init at the init() method public static void main(String[] args) { Frame f = new Frame("Ex3"); //create a frame GLCanvas canvas = new GLCanvas(); //create a GLCanvas canvas.addGLEventListener(new Ex3()); //add the ex3 as an event listener for GLCanvas events f.setSize(800, 640); final Animator animator = new Animator(canvas); //create animator class that gets the GLCanvas and calls it’s display methods sequentially f.add(canvas); //add the canvas to the frame f.addWindowListener(new WindowAdapter() { //create a window adapter the handle the window closing event publicvoid windowClosing(WindowEvent e) { new Thread(new Runnable() {//create a different thread that handles the animator closing and system exit to make sure the animator will be stopped before the system will exit publicvoid run() { animator.stop(); System.exit(0); } }).start(); } }); f.setVisible(true); //make the frame visible animator.start(); //start the animator } }
JOGL • Init() , display() וכו' • מקבלות אובייקט מסוג GLAutoDrawable ממנו אפשר לגשת לאובייקט GL • לפי ההוראות במדריך של jogl עדיף לקבל את GL בכל פעם במתודות מאשר להגדיר משתנה גלובלי שמותחל ב-init() • במתודת ה-init() נגדיר את כל ההגדרות הבסיסיות לסביבה של openGL • במתודת ה-display() נצייר את הסביבה שאנחנו רוצים • ע"מ לגשת לאובייקטים של GLU נגדיר מחלקה גלובלית GLU שמותחל ב-init() וכך ניגש למתודות ואובייקטים של GLU
JOGL public void init(GLAutoDrawable arg0) { GL gl = arg0.getGL(); // get the GL from the GLAutoDrawable gl.glEnable(GL.GL_NORMALIZE); //all the vecs wil benormalize gl.glEnable(GL.GL_CULL_FACE); //enable cull face gl.glEnable(GL.GL_DEPTH_TEST); //enable depth buffer gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //define the clear color toblack glu = new GLU(); //init the GLU object gl.glMatrixMode(GL.GL_PROJECTION); //switch to projection matrix gl.glLoadIdentity(); //init the matrix glu.gluPerspective(45.0f, 800 / 640, 1, 1000);//init the 3D perspective view }
yv xv zv near far JOGL glMatrixMode(GL_PROJECTION) ; glLoadIdentity(); gluPerspective(viewAngle,aspectRatio,n,f);
JOGL public void display(GLAutoDrawable arg0) { GL gl = arg0.getGL();//get the GL object gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); //clear the depth buffer and the color buffer gl.glMatrixMode(GL.GL_MODELVIEW); //switch to model matrix gl.glLoadIdentity(); //init the matrix glu.gluLookAt(eyeX,eyeY,eyeZ,cX,cY,cZ,upX,upY,upZ)); //set the camera view //draw things using openGL gl.glFlush(); //load the data to the bufffers }
OpenGL • OpenGL • glPushMatrix • דוחפת את המטריצה הנוכחית למחסנית • glPopMatrix • מחזירה את המטריצה האחרונה שנדחפה למחסנית • נשתמש בפונקציות הנ"ל כשנבנה אובייקט המורכב מכמה אובייקטים • נשתמש בנקודה אחת כנקודת מקור שממנה נבנה את כל האובייקט כולו gl.glCallList(Darw_CarBody); //call the CarBody polar display list gl.glPushMatrix(); //push the matrix to go back to 0,0 gl.glTranslatef(X,Y,Z); //translate to a new position gl.glRotatef(right_w, 0.0f, 1.0f, 0.0f); //rotate the wheel gl.glCallList(draw_wheel); //call the wheel display list gl.glPopMatrix(); //pop the matrix we back at where we were gl.glPushMatrix(); //push matrix again gl.glTranslatef(X1,Y1,Z1); //translate to a new position gl.glRotatef(right_w, 0.0f, 1.0f, 0.0f); //rotate the wheel gl.glCallList(draw_wheel); //call the wheel display list again gl.glPopMatrix(); //pop the matrix
Body System Front-Wheel System OpenGL • OpenGL
OpenGL • OpenGL • gluLookAt() • הפקודה הנ"ל נותנת לנו נקודת מבט על העולם (ממקמת את המצלמה במיקום מסויים) • מקבלת את הערכים הבאים מסוג double או GLdouble : • eyex,eyey,eyez זה המיקום של המצלמה • centerx,centery,centerz לאן המצלמה מסתכלת • upx ,upy upz ווקטור UP • הפקודה תבוא אחרי קריאה למטריצת המודלינג glMatrixMode(GL_MODELVIEW);
OpenGL • OpenGL • המצלמה • נוכל לשלוט בתזוזת המצלמה ע"י glLookAt • נגדיר את שלוש הנקודות כווקטורים • נשנה את הווקטורים בהתאם לצרכים שלנו • תזוזה קדימה אחורה • נחשב ווקטור בין מיקום המצלמה eye לבין centerdirection • תזוזה קדימה תתבצע בכיוון של הווקטור הנ"ל • eye+direction יקדם את eye בכיוון של direction • center+direction יקדם את center בכיוון של direction • אם נכפיל את direction בגודל כלשהו נקבל התקדמות מהירה יותר • אם נכפיל את direction במספר שלילי נקבל התקדמות אחורה
OpenGL • OpenGL • המצלמה • סיבוב המצלמה מסביב לאובייקט • המצלמה נמצא ב eye ומסתכלת על center נחשב ווקטור בניהם נקרא לו r • נקרא לזוית בין r לציר yβ • r*sin(β)=r_project • נראה לזוית בין r_project לציר x α • r_project*sin(α)=z • r_project*cos(α)=x • שליטה על הזויות תיתן לנו שליטה על מיקום המצלמה מסביב לאובייקט
OpenGL • OpenGL • המצלמה • מבט של המצלמה מסביב • ממש כמו מקודם יש לנו שתי זוויות אחת עם ציר Y ואחת עם Xβ ו α בהתאמה • הפעם מיקום ה eye ומיקום ה center התחלף • עכשיו בראשית יושב ה eye וה-center יושב היכן שהמצלמה מסתכלת • ע"י שינוי הזוויות אפשר לשלוט על מבט המצלמה
OpenGL • OpenGL • המצלמה • לא לשכוח להחזיר את המצלמה למקום שלה • בחישוב שלנו אנחנו משתמשים בווקטורים,ווקטורים יוצאים מהראשית,לכן אחרי שחישבנו היכן center נמצא חישבנו אותו יחסית לראשית וצריך למקום אותו יחסית ל eye כלומר לחבר בין שניהם center β up eye α
OpenGL • OpenGL • המצלמה • תנועה חלקה • לחיצה על החצים במקלדת תגרום למצלמה להמשיך ישר כל הזמן עד לשיחרור המקש • ע"מ לשלב לחיצה על כמה מקשים במקביל נבצע כמה דברים • בהנחה שיש לנו פונקצית תזוזת מצלמה move(amount) • בהנחה שיש לנו פונקציית סיבוב מצלמה rotate(r_amount) • קריאה לפונקציות הנ"ל תתבצע בפונקציית ה display ולא בפונקציית המקלדת, הקריאה תתבצע רק אם יש תזוזה במצלמה • הערכים amount ו r_amount ישונו לפי לחיצה על מקשי המקלדת • הערכים יאופסו ברגע ששיחררנו את מקשי המקלדת
OpenGL • OpenGL • המצלמה • תנועה חלקה • כשאר לוחצים על המקשים במקלדת public void keyPressed(KeyEvent arg0) { switch (arg0.getKeyCode()) { case 38: moveAmount = 0.01f; break; case 40: moveAmount =-0.01f; break; case 37: rotateAmount = 0.01f; break; . . . } }
OpenGL • OpenGL • המצלמה • תנועה חלקה הפונקציה שתטפל בשיחרור מקש public void keyReleased(KeyEvent arg0) { switch (arg0.getKeyCode()) { case 38: moveAmount = 0.0f; break; case 40: moveAmount = 0.0f; break; case 37: rotateAmount = 0.0f; break; case 39: rotateAmount = 0.0f; break; } }
OpenGL • אור וצבע • מראה האובייקט תלוי בכמה דברים • סוג פני השטח של האובייקט • מחוספס ,חלק ,משטח מראה וכו, • מיקום האור וסוגו • יחסית לעין • מיקום העין • יחסית לאור
OpenGL • אור וצבע • שלושה סוגי אור • Ambient • אור אחיד...האור המוחזר מכל עצם ומגיע מכל מקום בצורה אחידה. • Diffuse • הבהירות של העצם (בכל נקודה) ביחס למקור האור. (מחושב לפי הזווית בין קרן האור לבין הנורמל לנקודה) • Specular • הברק של העצם ביחס למקור האור (מחושב לפי הזווית בין קרן האור לבין הנורמל לנקודה)
OpenGL • אור וצבע • ע"מ להגדיר אור ב-OpenGL צריך להגדיר: • מיקום האור • סוג החומר של העצם • הנורמלים של הקודקודים • וכמובן צריך להודיע לOpenGL- שאנחנו נשתמש באור • gl.glEnable(GL_LIGHTING)
OpenGL • אור וצבע • OpenGL תומכת ב-8 מקורות אור • נאפשר כל מקור בנפרד ע"י glEnable(GL_LIGHTn) כאשר 07<n< • ונגדיר את המאפיינים של כל מקור ע"י • ווקטור ערכים float values[] = {0.0, 1.0, 0.0, 1.0}; gl.glLightfv(GL_LIGHT2,GL_DIFFUSE,values); • ערכים אפשרייםGL.GL_AMBIENT, GL.GL_DIFFUSE: GL.GL_SPECULAR ,GL.GL_POSITION
OpenGL • אור • דוגמה float color[4] = {0.0, 0.85, 0.0, 1.0}; float ambient[4] = {0.05, 0.05, 0.05, 1.0}; float position[4] = {0.0, 1.0, 1.0}; Init(GLAutoDrawable arg0){ GL gl = arg0.getGL(); gl.glEnable(GL_LIGHTING); gl.glEnable(GL_LIGHT0); } Display(GLAutoDrawable arg0){ GL gl = arg0.getGL(); gl.glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); gl.glLightfv(GL_LIGHT0, GL_DIFFUSE, color); gl.glLightfv(GL_LIGHT0, GL_SPECULAR, color); gl.glLightfv(GL_LIGHT0, GL_POSITION, position); }
OpenGL • אור • סוגי האור: • אור קבוע • אור הנע מסביב לאובייקט • אור הנע עם המצלמה
OpenGL • אור • אור קבוע • האור יוגדר לאחר הגדרת ה-Viewport כלומר לאחר gllookAt gl.glMatrixMode(GL_MODELVIEW) ; gl.glLookAt / any view transform gl.glLight(GL_POSITION/DIRECTION) gl.glRotate/glTranslate/glScale - on the objects.
OpenGL • אור • אור הנע מסביב לאובייקט • האור יוגדר בנפרד וללא קשר ל-Viewport gl.glMatrixMode(GL_MODELVIEW) ; gl.glLookAt / any view transform gl.glPushMatrix() ; gl.glTranslate() / glRotate() (for light pos and dir) gl.glLight(GL_POSITION/DIRECTION) gl.glPopMatrix() ; gl.glBegin() … gl.glEnd() // Draw the objects.
OpenGL • אור • אור הנע עם המצלמה • האור יוגדר לפני ה-Viewport כלומר לפני glLookAt gl.glMatrixMode(GL_MODELVIEW) ; gl.glLoadIdentity() ; gl.glLight(GL_POSITION/DIRECTION) gl.glLookAt / any view transform gl.glTranslate() / glRotate() (for objects) gl.glBegin() … glEnd() // Draw the objects.
OpenGL • אור • הגדרת חומרים • כדי לדעת את כמות האור המוחזר מהאובייקט עלינו להגדיר גם מאיזה סוג חומר הוא • הגדרת חומרים נעשית דומה מאוד להגדרת אור
OpenGL • אור • הגדרת חומרים • הגדרת חומר מוחלת על כל האובייקטים המצויירים עד אשר משנים את ההגדרה • נשתמש בפונקציה • gl.glMaterialfv(GL_FRONT, p_name, p);
OpenGL • אור • הגדרת חומרים • כפי שראינו בהרצאה כל חומר מחזיר את שלושת הסוגים של האור לכן גם כאן נגדיר את שלושת הסוגים • Ambient ו diffuse בדרך כלל הם אותו צבע • Specular מוגדר בדרך כלל בגוון של אפור (מתכתי)
OpenGL • אור • הגדרת חומרים • GL_SHININESS מגדיר את כמות הברק של האובייקט float m_color[4] = {0.0, 0.85, 0.0, 1.0}; float s_color[4] = {0.8, 0.8, 0.8, 1.0}; float shininess[1] = {120.0}; gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, m_color); gl.glMaterialfv(GL_FRONT, GL_SPECULAR, s_color); glMaterialfv(GL_FRONT, gl.GL_SHININESS, shininess);
OpenGL • אור • הגדרת חומרים • GL_FRONT אומר בעצם להגדיר את הפוליגונים רק בצד הקידמי שלהם • איך נדע מה הצד הקידמי ומה הצד האחורי? נגדיר • gl.glFrontFace(GLenum mode) קובע איך יוגדרו הצדדים • CCW-נגד כיוון השעון GL.GL_CCW • CW –עם כיוון השעון GL.GL_CW • אחרי ההגדרה הזאת סדר הכנסת הקודקודים קובע את הפנים והאחור
OpenGL • אור • הגדרת חומרים v1 v1 v3 v2 v2 v3 ClockWise CounterClockWise
OpenGL • אור • נורמלים • כדי לגעת איך האור מוחזר עלינו לדעת את מיקום האובייקט יחסית לאור לכן נצטרך להגדיר נורמל לכל קודקוד שאנחנו מגדירים • הגדרת נורמל מתבצעת בעזרת glNormal3f(x, y, z);
OpenGL • אור • נורמלים • הגדרת הנורמלים נעשית בעת הגדרת האובייקט • לפני שנקרא ל-gl.glVertex3f נקרא ל-gl.glNormal3f והקודקוד שיבוא אחריו יקבל את הנורמל • נורמל צריך להיות ווקטור היחידה לכן או שננרמל אותו לפני כן או שנגדיר ל openGL לנרמל את הווקטורים אוטומטית ע"י gl.glEnable(GL.GL_NORMALIZE);