Showing posts with label Code. Show all posts
Showing posts with label Code. Show all posts

May 7, 2013

Kiểm tra 1 điểm có nằm trong đa giác lồi không


Đoạn code này khá hữu ích trong đồ họa máy tính, với chức năng kiểm tra xem 1 điểm có nằm trong 1 đa giác lồi hay không. Khá là ngắn và có thể áp dụng rộng rãi. Điển hình như dùng trong kĩ thuật tô màu, chọn 1 đối tượng hình ảnh ...

Chỉ có 7 dòng nhưng chứa đựng tinh túy của thuật toán và kỹ thuật sử dụng ngôn ngữ lập trình

Code nó đây

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
  int i, j, c = 0;
  for (i = 0, j = nvert-1; i < nvert; j = i++) {
    if ( ((verty[i]>testy) != (verty[j]>testy)) &&
     (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
       c = !c;
  }
  return c;
}

Giải thích

  • Danh sách tham số: nvert số đỉnh của đa giác. vertx - mảng chứa tọa độ x của các đỉnh trong đa giác. verty tương tự như vertx nhưng là tọa độ y. testx tọa độ x điểm cần kiểm tra. testy tọa độ y điểm cần kiểm tra
  • Giá trị trả về là kiểu int. 0 là điểm đó nằm ở ngoài, 1 là điểm đó ở trong đa giác

Nguồn: Link đây

May 4, 2013

Lập trình quản lý file trong nachos

Hướng dẫn quản lí tập tin trong nachos

Bài viết đang được hoàn thiện


Đề bài cho đồ án này: Link đây

Các bước để tạo system call đã được đề cập tại : đây . Các bạn có thể tham khảo để nhớ lại

Bước 1. Cấu hình cho bài tập

Đầu tiên ta tìm hiểu sơ về các lớp trong nachos liên quan đến quản lý file.

  • FileSystem. Địa chỉ: filesys/filesys.h. Lớp này để quản lý các hệ thống file. Trong lớp này có các phương thức hỗ trợ việc quản lý bao gồm: tạo, xóa, mở 1 file dựa vào tên file đó
  • OpenFile. Địa chỉ:filesys/openfile.h. Lớp này dùng để thực thi các phép toán (operator) trên 1 file, bao gồm đọc, ghi, lấy độ dài Phương thức Close 1 file chính là destructor của nó luôn.

Hiểu được cái đề.

  • Đề yêu cầu cùng 1 lúc quản lý được 10 file. Tức là đâu đó trong hệ thống phải có 1 cái mảng kiểu OpenFile chứa 10 phần tử. Dĩ nhiên nó không nằm trong exception method, vì nằm ở đó mảng này sẽ bị xóa và khởi tạo lại mỗi lần gọi. Chính xác hơn, ta sẽ đặt nó ở lớp FileSystem ở dạng public (cho dễ cài đặt, để private phải cài thêm cái getter/setter khá khó chịu). Mỗi giá trị của OpenFileID chính là chỉ mục (index) của biến đó trong mảng ta tạo ở trên. Ví dụ mảng đó là openf thì khi mở file openf[3] giá trị trả về của hàm OpenFile sẽ là 3. Và dĩ nhiên, stdin và stdoout chính là openf[0] và openf[1]
  • 2 bé stdin và stdoout được tạo và mở ngay trong constructor của FileSystem, nhờ đó nó luôn luôn tồn tại và không mất đi. Và khi viết systemcall ta chỉ cần kiểm tra index == 0 || index == 1 (chính là cái OpenFileID) là xong
  • Các thao tác đọc, viết, đóng đã có sẵn rồi, ta chỉ cần thêm phương thức Seek vào OpenFile class. Phương thức này được cài đặt bằng lệnh LSeek. Nếu chú ý các phương thức đọc và viết đã được cài sẵn thì có thể dễ dàng cài đặt phương thức này.
  • Về vấn đề console, khi người dùng yêu cầu các file stdin và stdout thì ta xử lý riêng rẽ ( 1 lệnh if thôi). Để kiểm tra xem user có gọi 2 file đó không thì chỉ cần check OpenFileID

Cài đặt

  • Lưu ý: trong FileSystem và OpenFile có 2 version riêng cho mỗi lớp, để đảm bảo an toàn, ta cũng cài đặt cả 2 version đó những thay đổi khi làm
  • Project đã chạy được: Link đây

Apr 14, 2013

Macro nho nhỏ hiện các thông báo.


Trong lúc viết đồ án về Chat Reference, mình gặp chút vấn đề về việc xuất các thông báo cho người dùng. Đồ án được thực hiện trên MFC và dùng hàm MessageBox , trong khi đó, lúc lập trình, mình lại thiết kế các module, tức phần bussiness lại thực hiện trên console, dùng hàm printf. Lúc chuyển qua MFC phải chuyển hết các hàm đó ... Vả lại mỗi lần viết hàm lại 1 lần viết chuỗi xuất ra, thành thử nhiều khi không nhất quán.

Macro này giúp giải quyết vấn đề nho nhỏ đó. Đúng ra thì 1 con trỏ hàm, cũng có thể làm được điều này. Nhưng mình lại thích làm trên macro hơn :)) =)). Một vấn đề trong con trỏ hàm là đôi khi các hàm mình cần dùng không cùng chung kiểu khai báo, và như vậy dùng con trỏ hàm sẽ không ổn. Đồng thời việc biến tấu cũng không được gọn.

#define MAX_BUFERROR 255
#define COMMAND_ERROR printf
#define NEWEXCEPTION(mess, code) { \
                        char err[MAX_BUFERROR]; \
                        sprintf(err,mess". CODE: %d.\n", code);\
                        COMMAND_ERROR (err);\
                        fflush(NULL);\
                        }

Chút chú thích cho cái này xíu:

  • MAX_BUFERROR: Độ dài chuỗi tối đã của thông báo
  • COMMAND_ERROR: Tên hàm thực hiện xuất ra chuỗi
  • Yêu cầu phải có thư viện stdio.h cho macro này

Apr 5, 2013

Hàm strtok và những rắc rối xung quanh


Thật bất ngờ và tình cờ vì phải đụng đến em này lúc train thi Thách Thức. Và cũng tò mò là vì sao em này có cách dùng lạ đến vậy. Nhưng trước tiên là một số thông tin hấp dẫn đã.

Cú pháp:


char* strtok ( char *str, const char *delimters); 
 
 

Công dụng: Tách chuỗi str thành các chuỗi con. Các kí tự ngăn cách được định nghĩa trong chuỗi delimters.

Tham số:

  • str: chuỗi cần tách.
  • delimters: chuỗi chứ các kí tự ngăn cách

Các sử dụng: để lấy từ phẩn từ sau khi được cắt bị kí tự phân chia. Ta sử dụng đoạn code sau:

pch = strtok (str," ,.-");
while (pch != NULL)
{
  // Phần tử lấy ra là pch pch
  // Xử lý các thao tác trên pch
 pch = strtok (NULL, " ,.-");
}
return 0;

Nhiều người sẽ thắc mắc: đoạn mã strtok(NULL, " ,.-") nghĩa là gì. Nguyên nhân là trong hàm strtok sẽ tạo 1 biến static là char* - ta tạm gọi là last. Ban đầu nó sẽ được gắn bằng NULL. Sau lần duyệt đầu tiên, last sẽ có giá trị là địa chỉ hiện thời của phần tử đã lấy được. Khi chạy đến hàm strtok thứ 2 nó kiểm tra tham số đầu vào có phải là NULL không. Nếu phải thì nó lấy địa chỉ của chuỗi đem cắt gắn bằng giá trị mà last đang giữ.

Tham khảo:

  1. Source code hàm strtok của Microsoft
  2. Source code hàm strtok của Apple.

Lưu ý: vì hàm này tạo 1 biến static tạm để giữ giá trị vừa cắt nên không dùng được cho xử lý đa nhiệm.

Mar 2, 2013

Cấu hình giao diện cho Eclipse trên Linux

Trong Linux, giao diện của Eclipse có phần bất tiện vì khoảng trắng giữa các icon khá lớn, khiến cho không gian trở nên nhỏ đi. Điều đó gây ra sự bất tiện lớn khi làm việc


Giải pháp cho vấn đề đó như sau:
  • Trong thư mục ~/ mở file .gtkrc-2.0 và chép đoạn mã sau:
    style "gtkcompact" {
     font_name="Sans 8"
     GtkButton::default_border={0,0,0,0}
     GtkButton::default_outside_border={0,0,0,0}
     GtkButtonBox::child_min_width=0
     GtkButtonBox::child_min_heigth=0
     GtkButtonBox::child_internal_pad_x=0
     GtkButtonBox::child_internal_pad_y=0
     GtkMenu::vertical-padding=1
     GtkMenuBar::internal_padding=0
     GtkMenuItem::horizontal_padding=4
     GtkToolbar::internal-padding=0
     GtkToolbar::space-size=0
     GtkOptionMenu::indicator_size=0
     GtkOptionMenu::indicator_spacing=0
     GtkPaned::handle_size=4
     GtkRange::trough_border=0
     GtkRange::stepper_spacing=0
     GtkScale::value_spacing=0
     GtkScrolledWindow::scrollbar_spacing=0
     GtkExpander::expander_size=10
     GtkExpander::expander_spacing=0
     GtkTreeView::vertical-separator=0
     GtkTreeView::horizontal-separator=0
     GtkTreeView::expander-size=8
     GtkTreeView::fixed-height-mode=TRUE
     GtkWidget::focus_padding=0
     }
    class "GtkWidget" style "gtkcompact"
    style "gtkcompactextra" {
     xthickness=0
     ythickness=0
    }
    class "GtkButton" style "gtkcompactextra"
    class "GtkToolbar" style "gtkcompactextra"
    class "GtkPaned" style "gtkcompactextra"
    
  • Lưu file này lại và mở lại Eclipse. Lưu ý: Các chương trình khác dùng giao diện gtk cũng bị ảnh hưởng
Kết quả thu được:

Về vấn đề autocomplete không hoạt động.Giải quyết: Nhấn Alt + W + P. Chọn C/C++ - Editor - Content Assist -- Advanced và tick chọn hết. Về vấn đề tooltip bị nền màu đen hoặc khung Proposals không nhìn được: chọn giao diện hệ thống khác ( gtk theme), hoặc phải cấu hình lại giao diện đó

Dec 19, 2012

Sự khác biệt về hàm main của C và C++

Thoạt đầu tưởng chừng như không có sự khác biệt giữa 2 ngôn ngữ với hàm 'main': hàm đặc biệt quan trọng trong chương trình. Nhưng thưc tế lại khác xíu.
Cho 2 đoạn mã sau.
Đoạn 1: Viết bằng c:
#include <stdio.h>
float main(int a, int b, int c)
{
    printf("Chao cac ban\n");
}
Đoạn 2: Viết bằng cpp:
#include <iostream>
using namespace std;
int main( int n, char x, float t) 
{
    cout << "Chao cac ban" <<endl;
    return 0;
}
Cả 2 đoạn mã điều chạy được, tuy nhiên nếu compile đoạn mã cpp sẽ dính 2 cái Warning. Còn đối với c thì không có gì. Điều thú vị hơn là nếu trong đoạn mã cpp ta thay đổi kiểu trả về của 'main' từ 'int' sang 'float' thì lại dính error.
Đây là lí do:
  • Trong C, nó chỉ yêu cầu tồn tại một hàm tên 'main', vậy là đủ, nó không quan tâm đến chuyện tham số đầu vào hay kết quả trả về.
  • Trong C++, nó khuyến cáo sử dụng 2 mẫu:
    int main(int argc, char** argv); // hoặc
    int main() //
Nếu không rơi vào 2 trường hợp này: thay đổi số lượng tham số sẽ gây warning, còn thay đổi kiểu trả về gây ra error.

Sep 23, 2012

Tản mạn về C

Bài toán: Viết chương trình tính diện tích một hình tam giác khi biết chiều cao và cạnh đáy.

#include <stdio.h>
int main() {
 float height, base, area;                    /* variables definition */
 /*input data*/
 
 printf(" Hight :");
 scanf("%f", &height);
 printf(" Base :");
 scanf("%f", &base);
 
 /*calculate the area of a triangle*/
 area = 0.5 * ( height * base);
 /*output result */
 printf(" The area of triangle = %f \n", area);
 return 0;
}

Một chương trình C bao gồm rất nhiều module, được gọi là các hàm (function). Một hàm bắt buộc phải có trong chương trình C là main . Các vấn đề về hàm sẽ được đề cập sau.
Trong chương trình này gồm 2 thành phần: chỉ thị tiền xử lý và hàm main. Trong hàm main là tập hợp các câu lệnh và phép toán. Chỉ thị tiền xử lý ( preprocessor) là các lệnh được thực thi trước khi mã nguồn được dịch, nhờ đó, ta có thể thay đổi mã nguồn một cách tự động. Công dụng của preprocessor bao gồm:

  • Gọi các thư viện chuẩn, các file header, ...
  • Định nghĩa các macro
  • Dịch có điều kiện. Ví dụ: Đối với HĐH Linux hệ thống sẽ compile source cách này, nhưng với Win thì lại khác.
  • Định nghĩa lỗi do người dùng xác định
Bàn luận một chút về hàm main . Như đã biết, hoặc giả nếu chưa biết thì bây giờ biết, một hàm trong C thường có cấu trúc sau:
[Kiểu trả về] < tên hàm >([Các đối số])
Dường như với mọi hàm, thì kiểu trả về và tên hàm là các thông số bắt buộc ( các đối số có thể có hoặc không). Tuy nhiên với C, thì hàm main không nhất thiết phải có giá trị trả về. Thực tế, trong C, ta có thể khai báo hàm main theo 4 cách phổ biến sau:

  • void main()
  • int main()
  • void main(int argc, char** argv)
  • int main(int argc, char** argv)
Các được khuyến khích nhất là int main( int argc, char** argv) . Còn vì sao được khuyến khích thì sẽ được chém sau.
Trong một chương trình, thì hàm main chỉ được gọi một và chỉ một lần .
Trong hầu hết các tài liệu thì main là một hàm không thể thiếu. Vậy có khi nào trong chương trình của C không có main? Câu trả lời là có. Đối với các môi trường freestanding ( freestanding environment) thì không bắt buộc phải có main. Khác với freestanding environment, hosted environment yêu cầu phải có hàm main .
Vậy hosted và freestanding environment là cái gì gì? Nó có ăn được không?
Trả lời:

  • Hosted environment là một môi trường không chỉ hỗ trợ đầy đủ cho ngôn ngữ lập trình ( cụ thể ở đây là C), mà còn cung cấp các thư viện chuẩn ( STL - Standard Template Library). Ví dụ: Hệ điều hành Windows, Linux.
  • Freestanding environment là môi trường chỉ đơn thuần hỗ trợ C về ngôn ngữ và trình dịch mà không có các thư viện chuẩn. Ví dụ: Các hệ thống nhúng, di động ...
Hàm printf có chức năng hiển thị ra thiết bị xuất chuẩn ( stdout), ở đây là màn hình, dòng chữ Height: và Base: . Hàm scanf có chức năng truyền dữ liệu đầu vào chuẩn ( stdin) theo format định sẵn vào các biến height và base. Các hàm này khá giống hàm Writeln, Readln trong Pascal. Những hàm này cũng rất thú vị, tuy nhiên có lẽ sẽ được đề cập trong I/O stream và các vấn đề xung quanh .

Jun 18, 2012

[Hỏi ngu]: Sự khác nhau giữa Null pointer và void pointer


Tập hợp những câu hỏi mà đôi lúc mình ngộ ra là mình đã hỏi rất ngu =)) .
Null pointer là một giá trị của con trỏ. Con trỏ có nhiều kiểu (int*, char*) và mỗi kiểu đó sẽ qui định giá trị null khác nhau: NULL có thể là 0, cũng có thể là '\0' …
Void pointer là một kiểu - kiểu void* - con trỏ này có thể trỏ đến bất kì kiểu nào.
Vậy nên: Null pointer là một giá trị, còn void pointer là một kiểu con trỏ:
Example:
Void *pa = NULL;
Một tham khảo khác:
Thông thường một null pointer trỏ đến:
  • Địa chỉ 0.
  • Trỏ đến địa chỉ không hợp lệ  cho người dùng truy cập ( như địa chỉ 0x00000000 …), nếu cố truy cập dữ liệu vào địa chỉ này sẽ gây ra lỗi.

May 12, 2012

Danh sách liên kết (Linked List)

Ngộ nhận ra bài này mình viết code rất dở, để khi nào rảnh sẽ edit lại. Danh sách liên kết có những ứng dụng rất thú vị

Hôm nay Kỹ Thuật Lập Trình được học danh sách liên kết, vì ở dưới chăm chú sửa cái code thực hành mà không bắt kịp vấn đề, dù những định nghĩa căn bản đều hiểu. Cần phải tìm hiểu nó một cách cụ thể.

1.Khái niệm: Danh sách liên kết (linked list) là một cấu trúc dữ liệu bao gồm một nhóm các nút (nodes) tao thành một chuỗi.  Thông thường mỗi nút gồm dữ liệu (data) ở nút đó và tham chiếu (reference) đến nút kế tiếp trong chuỗi.
Danh sách liên kết là một trong những cấu trúc dữ liệu đơn giản và phổ biến nhất.
(Nguồn: Wikipedia)
clip_image001
Ưu điểm:
  • Cung cấp giải pháp để chứa cấu trúc dữ liệu tuyến tính.
  • Dễ dàng thêm hoặc xóa các phần tử trong danh sách mà không cần phải cấp phát hoặc tổ chức lại trật tự của mảng.
  • Cấp phát bộ nhớ động
Nhược điểm:
  • Một danh sách liên kết đơn giản không cho phép truy cập ngẫu nhiên dữ liệu.
  • Chính vì lí do trên mà một số phép tính như tìm phần tử cuối cùng, xóa phần tử ngẫu nhiên hay chèn thêm, tìm kiếm có thể phải duyệt tất cả các phần tử.
Phân loại:
  • Danh sách tuyến tính (Linear list):
clip_image002
  • Danh sách vòng (circular list):
clip_image003
  • Danh sách liên kết đôi (Double list):
clip_image004
Cấu trúc:
clip_image005
Data: Thành phần chứa một hay nhiều biến dữ liệu.
Next ptr: Tham chiếu trỏ đến phần tử kế tiếp trong cấu trúc.
Head: biến tham chiếu trỏ đến phần tử đầu tiên của danh sách.
clip_image006

Struct LLnode {
DataType Data;
LLnode* next;
};
 
2.Các phép toán:
Cho cấu trúc đơn giản:
struct LLintNode {
int Data;
struct LLintNode* Next;
};
Đếm số phần tử của Linked List:
Duyệt từng phần tử rồi đếm, cho đến khi nào gặp phần tử cuối.


int LengthLL(LLNode* head) {
int length = 0;
while (head != NULL) {
++length;
head = head ->Next;
}
return length;
}
Thêm một phần tử vào cuối linked list:
Nếu danh sách rỗng, thêm nút vào head.
Ngược lại, tìm phần tử cuối cùng của danh sách rồi thêm nút mới vào Next của nút cuối cùng đó:


void AddLast(LLNode** head, int data) {
LLNode** tmp = head;
 
LLNode* NewNode;
NewNode = (LLNode*) malloc(sizeof(LLNode));
NewNode->Data = data;
NewNode->Next = NULL;
 
if ((*tmp) == NULL) {
(*tmp) = NewNode;
} else {
while ((*tmp)->Next !=NULL) {
tmp = &((*tmp)->Next);
}
(*tmp)->Next = NewNode;
}
}
 
Xóa phần tử cuối cùng:
Tìm phần tử cuối cùng của danh sách, rồi gán bằng NULL.


void RemoveLast(LLNode** head) {
    LLNode** tmp = head;
    if ((*tmp) !=NULL) {
        while ((*tmp)->Next != NULL) {
            tmp = &((*tmp)->Next);
        }
    }
    (*tmp) = NULL;
 
}
Thêm phần tử vào đầu danh sách:
clip_image007




void AddFirst(LLNode** head, int Data) {
    LLNode** tmp = head;
    LLNode* NewNode;
    
    NewNode = (LLNode*) malloc(sizeof(LLNode));
    NewNode->Data = Data;
    NewNode->Next = (*head);
    
    (*tmp) = NewNode;
 
}
Xóa phần tử đầu tiên:
Nếu danh sách khác rỗng, đưa phần tử Next lên phía trước.


void RemoveFirst(LLNode** head) {
    LLNode** tmp = head;
    if ((*tmp) != NULL) {
        (*tmp) = (*tmp)->Next;
    }
}
Tìm kiếm phần tử trong danh sách:


LLNode* FindNode(LLNode** head,LLNode* src) {
    LLNode** tmp = head;
    while ( src->Data != (*tmp)->Data) {
        tmp = &((*tmp)->Next);
    }
    return (*tmp);
 
}
Chèn thêm 1 phần tử sau phần tử currrent:


int InsertNode(LLNode** head, LLNode* current, LLNode* NewNode) {
    LLNode** tmp = head;
    while ((current != (*tmp)) && (*tmp != NULL)) {
        tmp = &((*tmp)->Next);
    }
    
    if (*tmp == NULL) {
        return 0;
    } else {
        NewNode->Next= current->Next;
        current->Next = NewNode;
        
        (*tmp) = current;
        return 1;
    }
        
 
}
Xóa phần tử bất kì biết trước dữ liệu:

int RemoveNode(LLNode** head, LLNode* current) {
    LLNode** tmp = head;
    while ((current != (*tmp)) && (*tmp != NULL)) {
        tmp = &((*tmp)->Next);
    }
    if (*tmp == NULL) {
        return 0;
    } else {
        (*tmp) = (*tmp)->Next;
        return 1;
    }
}
3.Tham khảo:

May 3, 2012

Vẽ các hình học cơ bản trong OpenGL.


Tạo một dự án Empty Project và thiết lập cài đặt dành cho glut và OpenGL. Có thể tham khảo tại đây.
Gõ (hoặc chép) đoạn code sau:
#include <iostream>
#include <gl\glut.h>
#include <gl\GL.h>
#include <gl\GLU.h>
 
void display() {
 
    glColor3f(1.0,1.0,0.0);
 
    glPointSize(10);
    glBegin(GL_POINTS);
        glVertex2f(50,100);
        glVertex2f(200,200);
    glEnd();
    glFlush();
}
int main(int argc, char** argv) {
    glutInit(&argc,argv);
    
 
    glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(500,500);
    glutCreateWindow("Ve");
    
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
 
    glOrtho(0.0,500,0.0,500,-1.0,1.0);
 
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

Phần #include: để nhập các thư viện, file header để sử dụng các hàm glut, OpenGL.

Nghiên cứu các hàm được gọi trong Main() trước:


  • glutInit(int* pargc,char **argv): Khởi tạo thông số cho cửa sổ của glut. Các tham số pargc và argv được lấy từ hàm main().
  • Các hàm về thiết lập cửa sổ màn hình:

    • glutInitDisplayMode(int mode): thiết lập chế độ màu, buffer cho màn hình.

Danh sách các thiết lập:

GLUT_RGBA: thiết lâp cho chế độ màn hình RGBA.

GLUT_RGB: tương tự GLUT_RGBA.

GLUT_INDEX: thiết lập chế độ màu mặc định.

GLUT_SINGLE: thiết lập chế độ màn hình buffer đơn.

GLUT_DOUBLE: thiết lập chế độ màn hình buffer đôi.

GLUT_ACCUM: thiết lập chế độ accumulation buffer.

GLUT_ALPHA: thiết lập chế độ đối tương anpha cho buffer màu.

GLUT_DEPTH: thiết lập cho depth buffer.

GLUT_STENCIL: thiết lập cho stencil buffer.

GLUT_MULTISAMPLE: thiết lập cho multisampling.

GLUT_STEREO: thiết lập chế độ stereo.

GLUT_LUMINANCE: thiết lập cho chế độ màu "luminance".

Sử dụng toán tử OR để kết hợp các chế độ màu, buffer với nhau.


  • glutInitWindowPosition(int x, int y): tọa độ cửa sổ màn hình.
  • glutInitWindowSize(int x, int y): thiết lập kích thước cửa sổ màn hình.
  • glutCreateWindow(char* title): tạo cửa sổ màn hình với tiêu đề là title.


  • glClearColor(Glclampf red, Glclampf green, Glclampf blue, Glclampf alpha): thiết lập chế độ màu mới cho toàn bộ ứng dụng.
  • glClear(int mode): GL_COLOR_BUFFER_BIT: thông số để thiết lập cho màu sắc. Còn một số thiết lập nữa sẽ được đề cập sau.
  • glOrtho(...): thiết lập tầm nhìn trực giao, sẽ được nói chi tiết trong bài về phép biến trong OpenGL.


  • glutDisplayFunc(void (*f)(void)): gọi hàm để thực hiện việc vẽ khi cửa sổ màn hình hiển thị. Trong ví dụ này là gọi hàm display.
  • glutMainLoop(): Lặp đi lặp lại các hàm callback - sẽ đề cập sau - đến khi nao cửa sổ đóng lại.

Trong hàm display:


  • glColor3f( red, green, blue ): thiết lập màu sắc cho đối tượng sắp vẽ.
  • glPointSize(float size): kích thước điểm ảnh.
  • glBegin(int mode): gồm các thông số và minh họa phía dưới:

clip_image001


  • glEnd():kết thúc quá trình vẽ.
  • glFlush(): đưa dữ liệu từ bộ nhớ tạm và màn hình.