Biến đổi và hiển thị trong OpenGL

Một phần của tài liệu Bài giảng kỹ thuật Đồ họa và thực tại Ảo it32 Đại học mở hà nội (Trang 103 - 109)

Bài 6 KỸ THUẬT LẬP TRÌNH XỬ LÝ ĐỒ HỌA VỚI THƯ VIỆN OPENGL

6.3. Biến đổi và hiển thị trong OpenGL

Trong thư viện JOGL, các phép xử lý đồ họa đều được lập trình sẵn thông qua các hàm gồm:

Đối với việc hiển thị, có các hàm xư lý sau:

Kỹ thuật đồ họa và Thực tại ảo - Bài 6 Trang 7 Trước hết, cần tạo đối tượng hỗ trợ phép chiếu là GLU bằng lệnh GLU.createGLU với tham số là đối tượng GL2.

Lệnh Ý nghĩa

GLU  = GLU.createGLU( GL2  ); Tạo đối tượng xử lý hiển thị

.gluPerspective( fovy, aspect, zNear, zFar ); Chiếu phối cảnh

*.glFrustum( left, right, top, bottom ); Vùng quan sát/chiếu

*.glViewport( x, y, width, height ); Khung nhìn

*.glOrtho( left, right, bottom, top, near, far); Chiếu song song

.gluLookAt( eX,eY,eZ, cX,cY,cZ, uX,uY,uZ ); Đặt điểm/hướng nhìn

Lệnh Ý nghĩa

*.glRotatef( a,x,y,z ); Quay với góc ‘a’ và trục quay là véc-tơ (x,y,z)

*.glTranslatef( dx, dy, dz ); Dịch chuyển theo bước thay đổi dx,dy,dz

*.glScalef( sx,sy,sz ); Co giãn theo tỷ lệ (sx,sy,sz)

*.glLoadIdentity(); Nạp ma trận đơn vị để tính toán các phép biến đổi Đối xứng qua Ox, Oy, Oz bằng ‘glScalef’ với sx,sy,sz là giá trị âm (-1).

Co giãn tại chỗ: (1) chuyển đến gốc; (2) co giãn; (3) chuyển ngược về.

Kỹ thuật đồ họa và Thực tại ảo - Bài 6 Trang 8 Lập trình một chương trình để vẽ hình chóp tam giác và thực hiện các phép xử lý như quay, tịnh tiến, co dãn cũng như phép chiếu đối với hình đó.

import java.awt.Dimension;

import java.awt.EventQueue;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.border.EmptyBorder;

import javax.swing.JLabel;

import javax.swing.JTextField;

import javax.swing.JButton;

import com.jogamp.opengl.GL2;

import com.jogamp.opengl.GLAutoDrawable;

import com.jogamp.opengl.GLEventListener;

import com.jogamp.opengl.awt.GLJPanel;

import com.jogamp.opengl.glu.GLU;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

import java.awt.Color;

public class transf_view3d extends JFrame

implements GLEventListener{

float arot=40, xrot=0, yrot=0.7f, zrot=0.5f,

xtra=-0.7f, ytra=0.5f, ztra=0,

xsca=0.3f, ysca=0.7f, zsca=0;

Kỹ thuật đồ họa và Thực tại ảo - Bài 6 Trang 9 private GLJPanel drawable = new GLJPanel();

public transf_view3d() {

setTitle("Biến đổi & hiển thị ");

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

drawable.setPreferredSize(new Dimension(500,300));

drawable.addGLEventListener(this);

setContentPane(drawable);

pack();

setVisible(true);

}

float X[]={-0.5f, 0.0f, 0.3f, 0.0f};

float Y[]={-0.5f, 0.5f, -0.5f, 0.0f};

float Z[]={ 0.0f, 0.0f, 0.5f, 1.0f};

int E[][]={{0,1},{1,2},{2,0},{0,3},{1,3},{2,3}};

void veTDT(GL2 g){

GLU gu=GLU.createGLU(g);

g.glMatrixMode(GL2.GL_PROJECTION);

g.glLoadIdentity(); gu.gluPerspective(60.0, 4.0/3.0, 0, 40);

g.glMatrixMode(GL2.GL_MODELVIEW);

g.glLoadIdentity(); gu.gluLookAt(-1, -1, 1, 0, 0, 0, 0, 1, 0);

g.glPushMatrix();

g.glTranslatef(-0.8f, -0.8f, 0);

g.glLineWidth(1);

g.glBegin(GL2.GL_LINES);

g.glColor3f(1.0f, 1.0f, 1.0f);

Kỹ thuật đồ họa và Thực tại ảo - Bài 6 Trang 10 g.glVertex3f(0, 0, 0); g.glVertex3f(0.5f, 0, 0);

g.glVertex3f(0, 0, 0); g.glVertex3f(0, 0.5f, 0);

g.glVertex3f(0, 0, 0); g.glVertex3f(0, 0, 0.5f);

g.glEnd();

g.glFlush();

g.glPopMatrix();

}

void veCTG(GL2 g, int k,float a,float x,float y,float z) {

g.glPushMatrix();

if(k==2) g.glRotatef(a, x, y, z);

else if(k==3) g.glTranslatef(x, y, z);

else if(k==4) g.glScalef(x, y, z);

g.glLineWidth(3);

g.glBegin(GL2.GL_LINES);

for(int i=0;i<E.length;i++){

float re=1.0f/(i+1), gr=1.0f/(i+1), bl=1-1.0f/(i+1);

g.glColor3f(re, gr, bl);

g.glVertex3f(X[E[i][0]], Y[E[i][0]], Z[E[i][0]]);

g.glVertex3f(X[E[i][1]], Y[E[i][1]], Z[E[i][1]]);

}

g.glEnd();

g.glFlush();

g.glPopMatrix();

}

@Override

public void display(GLAutoDrawable arg0) {

GL2 g=arg0.getGL().getGL2();

Kỹ thuật đồ họa và Thực tại ảo - Bài 6 Trang 11 veTDT(g);

veCTG(g,1,0,0,0,0);

veCTG(g,2,arot,xrot,yrot,zrot);

veCTG(g,3,0,xtra,ytra,ztra);

veCTG(g,4,0,xsca,ysca,zsca);

}

public static void main(String[] args) {

new transf_view3d();

}

public void dispose(GLAutoDrawable arg0){}

public void init(GLAutoDrawable arg0){}

public void reshape(GLAutoDrawable a0,int a1,int a2,int a3,int a4){}

}

Các tham số xử lý được khai báo bởi các biến gồm:

arot = 40 độ là góc quay, xrot=0, yrot=0.7, zrot=0.5 xác định véc-tơ trục quay.

xtra=-0.7, ytra=0.5, ztra=0 xác định bước tịnh tiến hình.

xsca=0.3, ysca=0.7, zsca=0 xác định tỷ lệ co giãn hình.

Hàm tạo của lớp chương trình kế thừa Jframe làm cửa sổ được lập trình như trong ví

dụ trước.

Tiếp theo, khai báo các biến tọa độ của hình là các mảng X[], Y[] và Z[] tại các dòng 39,40,41. Ở dòng 42 khai báo mảng E chứa 6 cạnh của hình, mỗi cạnh gồm 2 đỉnh tương ứng với tọa độ ở các mảng X,Y,Z ở trên. Như đã biết, đây là mô hình wire-frame của hình

vẽ.

Từ dòng 44 đến 60 lập trình một hàm để vẽ hình chóp tam giác có tên veCTG, hàm này có các tham số đối tượng vẽ GL2, k để quy định phép xử lý trước khi vẽ hay không, x,y,z là các tham số tương ứng với phép xử lý của k.

Kỹ thuật đồ họa và Thực tại ảo - Bài 6 Trang 12 Trong hàm gồm, dòng 45 là lệnh glPushMatrix để lưu giữ ma trận xử lý tính toán vào stack, dòng 46 đến 48 để kiểm tra tham số k và thực hiện lệnh xử lý tương ứng với k=2 sẽ quay, k=3 sẽ tịnh tiến và k=4 sẽ co giãn.

Dòng 49 quy định độ rộng nét vẽ là 3 và dòng 50 là bắt đầu vẽ với chế độ vẽ là các đoạn thẳng nối bởi cặp điểm.

Dòng 51 đến 56 là lệnh lặp for để vẽ 6 cạnh của hình, màu của mỗi cạnh được thay đổi và xác định bởi dòng 52, dòng 53 để đặt màu vẽ và hai dòng 54, 55 để quy định tọa độ cặp đỉnh vẽ 1 cạnh.

Sau khi vẽ xong, cần khôi phục lại ma trận tính toán bằng lệnh glPopMatrix ở dòng

59 để xử lý vẽ lần sau.

Hàm display thực hiện lấy đối tượng vẽ kiểu GL2 ở dòng 64, dòng 65 đến 68 gọi hàm “veCTG” để vẽ hình chóp tam giác theo các trường hợp. Dòng 65 truyền tham số k

là 1 để không xử lý biến đổi trước khi vẽ (tức vẽ đúng tọa độ đã khai báo), dòng 66 truyền

k là 2 với các tham số arot, xrot, yrot, zrot để thực hiện quay hình, dòng 67 truyền k là 3 với các tham số xtra, ytra, ztra để tịnh tiến hình, dòng 68 truyền k là 4 với các tham số xsca, ysca, zsca để co giãn hình.

Cuối cùng hàm main chứa lệnh tạo đối tượng cửa sổ để chạy chương trình. Các hàm khác như init, dispose, reshape không sử dụng đến và để rỗng.

Thông thường, theo mặc định, cửa sổ quan sát khi vẽ chứa mặt phẳng hệ trục tọa độ Oxy, còn trục Oz là vuông góc với màn hình với chiêu tăng dần từ sau ra trước. Có thể thay đổi bằng cách thực hiện phép chiếu và đặt điểm quan sát ở một vị trí khác tùy ý. Trong chương trình trên, đoạn lệnh tô viền màu đỏ là để thực hiện công việc này, và kết quả là ảnh màn hình phía dưới. Trong đoạn đó, trước hết phải tạo đối tượng GLU bằng lệnh createGLU, sau đó gọi ma trận thực hiện phép chiếu bằng lệnh glMatrixMode với tham số GL2.GL_PROJECTION, khởi tạo ma trận chiếu là đơn vị và thực hiện phép chiếu bằng lệnh gluPerspective với tham số 60 là góc rộng của vùng nhìn, tỷ lệ khung nhìn là 4/3, giới hạn gần là 1 và xa là 40. Tiếp theo gọi ma trận mô hình quan sát bằng lệnh glMatrixMode với tham số GL2.GL_MODELVIEW, khởi tạo ma trận này là đơn vị

và thực hiện đặt điểm quan sát bằng lệnh gluLookAt với tham số tọa độ điểm nhìn là (-1,- 1,1), điểm nhìn tới gốc tọa độ và hướng lên của mắt nhìn đi qua điểm (0,1,0).

Một phần của tài liệu Bài giảng kỹ thuật Đồ họa và thực tại Ảo it32 Đại học mở hà nội (Trang 103 - 109)

Tải bản đầy đủ (PDF)

(146 trang)