How to make a simple fog effect in OpenGL ?

Ok, I’ve just implemented the fog effect while studying OpenGL, so I’m going to show you guys how to do it.

In order to test the effect, you must have object in 3d space. Here mine is a 2×2 texture
(I create a simple 2×2 texture and then mapping it to the 4-vertex square)

texture

My vertex shader file:

// Vertex shader
attribute vec3 a_position;
attribute vec2 a_uv;

uniform mat4 u_projection;
uniform mat4 u_view;
uniform mat4 u_model;

varying vec3 v_position;
varying vec2 v_uv;

void main()
{
vec4 positionTmp = vec4 ( a_position, 1.0 );

v_position = ( u_model * positionTmp ).xyz;
v_uv = a_uv;

gl_Position = u_projection * u_view * u_model * positionTmp;
}

My fragment shader file:

// Fragment shader
precision mediump float;

uniform sampler2D u_texture;
uniform vec4 u_fogColor;
uniform vec4 u_eyePos;
uniform float u_fogMaxDist;
uniform float u_fogMinDist;

varying vec3 v_position;
varying vec2 v_uv;

float eyeDist;

float computeLinearFactor()
{
float factor;

factor = ( u_fogMaxDist - eyeDist ) /
( u_fogMaxDist - u_fogMinDist );
factor = clamp ( factor, 0.0, 1.0 );

return factor;
}
void main()
{
eyeDist = distance ( v_position, u_eyePos );

float factor = computeLinearFactor();
vec4 fogColor = fogFactor * u_fogColor;
vec4 baseColor = texture2D ( u_texture, v_uv );

gl_FragColor = baseColor * fogFactor +
fogColor * ( 1.0 - fogFactor );

Result ( my u_fogColor is red):
texture_fog

Advertisements

Setting environment for NDK ( Cài đặt môi trường cho NDK)


Các công cụ cần thiết
1. Android ndk: https://developer.android.com/ndk/downloads/index.html#Downloads
2. Android sdk: https://developer.android.com/sdk/index.html (Kéo xuống SDK tools only)
3. Apache ant: http://ant.apache.org/
4. Jdk 1.6 trở lên: http://www.oracle.com/technetwork/java/javase/downloads/index.html

Cài đặt Environment Variable
Thêm đường dẫn vào path variable:
<android-ndk_path>;
<apache-ant_path>\bin;
<android-sdk_path>\tools;
<android-sdk_path>\platform-tools;
<jdk_path>\bin

Build ứng dụng mẫu <android-ndk_path>\samples\hello-jni
Step 1: Tạo file build.xml
+ Mở cmd:
root-disk <enter>
cd <android-ndk_path>\samples\hello-jni <enter>
<android-sdk_path>\tools\android update project -t <target-id> -p <android-ndk_path>\samples\hello-jni -s <enter>

Untitled

Untitled

Chú ý: target-id là id tương ứng của từng phiên bản android đã được cài đặt trong SDK, để xem chi tiết, type lệnh sau trong cmd:
<android-sdk_path>\tools\android list targets

Step 2: Tạo file *.so
*.so (Share object file): là file giúp Java có thể đọc được code C++ được dạng trong chúng
+ Mở cmd:
root-disk <enter>
cd <android-ndk_path>\samples\hello-jni <enter>
<android-ndk_path>\ndk-build.cmd <enter>

Untitled

Untitled

Step 3: Build file apk
+ Mở cmd:
root-disk <enter>
cd <android-ndk_path>\samples\hello-jni <enter>
<apache-ant_path>\bin\ant.bat debug<enter>

Chờ khoảng 5s, nếu xuất hiện dòng BUILD SUCCESSFUL thì bạn đã thành công. File apk sẽ được lưu trong thư mục bin của project. Cấu trúc của thư mục bin này cũng giống với cấu trúc của 1 file apk thông thường khi decompile

Chú ý: Đến bước này nếu bị lỗi đường dẫn của SDK không đúng, bạn hãy tìm tới file local.properties trong thư mục <android-ndk_path>\samples\hello-jni, và edit lại đường dẫn của SDK tại biến sdk.dir

Step 4: Chạy thử file apk trên android device
Kéo thả file apk vào genymotion

Untitled
Hello JNI !

Happy coding ! 🙂

Giải đáp những câu phỏng vấn C/C++ của John Sonmez


Đây là những câu hỏi rất hay tớ đọc được trong bài viết Tại sao C/C++ không còn là sự lựa chọn cho bạn nữa ? của John Sonmez, do vinacode dịch. Để giải đáp được những câu hỏi này cần có kiến thức khá vững về C/C++ và nó luôn thôi thúc tớ đi tìm câu trả lời, nhưng không phải trả lời theo kiểu search google và chép đáp án vào, mà tớ muốn bản thân tớ ( và các bạn cũng vậy) phải tiếp xúc với kiến thức trong câu hỏi đó đủ nhiều và có một sự mạch lạc trong tư duy khi giải thích lại nó.

Ok, ko dài dòng nữa, đây là danh sách:

1. Có bao nhiêu cách để khởi tạo một kiểu dữ liệu nguyên thủy trong C++ và đó là những cách nào?

Hiện tại mình có thể nêu ra 3 cách:
int var_1; <- Khởi tạo biến var_1 với giá trị mặc định do môi trường quyết định
int var_1(4); <- Khởi tạo biến var_1 với giá trị được truyền vào
int var_1(var_2); <- Khởi tạo biến var_1 với giá trị của var_2 (copy constructor)
Update:
int var_1 = 4; <- implicit cast
int var_1{4}; <- inintializer list

2. Tại sao bạn nên khai báo một hàm hủy là ảo (virtual) ?

Giả sử có class Parent và class Child kế thừa từ Parent. Ta định nghĩa con trỏ:
Parent * p = new Child();
Lúc này để tạo ra Child(), thì Parent() phải được tạo ra trước. Khi chúng ta delete p, thì cả 2 đối tượng này cũng phải được gọi Destructor.
Vậy nếu không khai báo virtual cho hàm Destructor của Parent, thì chỉ Destructor của Parent được gọi, đối tượng Child() vẫn còn đó
3. Nó có nghĩa gì khi nói rằng C++ hỗ trợ overloading (nạp chồng)?
4. Nêu ra một số ví dụ về overloading trong C++?
5. Khái niệm name mangling trong C++ có nghĩa là gì và tại sao nó lại được sử dụng?
6. Một lớp trừu tượng cơ sở (abstract base) có nghĩa là gì?
7. RTTI có nghĩa là gì?
8. Làm thế nào để bạn có thể truy cập một biến mà nó bị “che khuất” bởi một biến khác có cùng tên?

Có thể sử dụng namespace: đưa 2 biến cùng tên đó vào 2 namespace khác nhau, bạn có 2 biến cùng tên var:
namespace ns1 { int var;}
namespace ns2 { int var;}
Cách truy cập:
ns1::var = 6;
ns2::var = 9;

Cũng có thể dùng class và struct nhưng cách đó khá thô thiển vì phải tạo nên thể hiện của class và struct

Update: Trường hợp biến local bị che khuất bởi biến global có cùng tên, có thể sử dụng toán tử truy cập phạm vi :: để gọi biến global

int x;
int func()
{
int x;
x = 3;    // local
::x = 3; // global
}

9. Khái niệm namespace có nghĩa là gì và làm thế nào để sử dụng nó?

Mới gặp ngay ở câu 8 :))
namespace theo như cách dịch thì là “không gian tên”, tớ cũng chẳng biết dịch như thế nào cho đúng, chỉ biết là nó được dùng để phân loại, gom các đối tượng vào thành một nhóm. Cách dùng như sau:
namespace <name> { // declare or define }
Ví dụ: Tớ có một namespace tên nsmath, và trong namespace này tớ sẽ khai báo một biến distance, một hàm Add và một class Point chẳng hạn

namespace nsmath
</span><span class="text_exposed_show">{
float distance;
float Add(float a, float b);
class Point;
}


Bạn có thể chỉ khai báo propotype như thế, và định nghĩa các hàm và class bên ngoài (như class):

float nsmath::Add(float a, float b) { // add a to b }
class nsmath::Point { // construct };


10. Điểm khác nhau giữa một lớp và một cấu trúc (struct) trong C++ là gì, và so sánh với ngôn ngữ C thì như thế nào?

Điểm khác nhau duy nhất giữa class và struct trong C++ đó là, những thuộc tính của class nếu để mặc định thì nó là private, của struct là public.
So sánh với ngôn ngữ C: ?

11. Khái niệm template là gì? Làm thế nào để sử dụng chúng ?
12. Một hàm tạo sao chép (copy constructor) có nghĩa là gì và khi nào thì nó được sử dụng, đặc biệt là khi so sánh với toán tử =
13. Điểm khác nhau giữa một sao chép “shallow” và “deep” là gì?

14. Hằng toán tử (const operator) nghĩa là gì và nó được sử dụng như thế nào?
15. Điểm khác nhau giữa truyền tham chiếu, truyền tham trị, và truyền bởi con trỏ trong C++ là gì?
16. Khi nào thì nên và khi nào thì không nên trả về một giá trị bởi tham chiếu trong C++?
17. Điểm khác nhau giữa một biến tạo ra trên ngăn xếp (stack) và một biến tạo ra trên heap là gì?

Biến trên stack tự giải phóng khi ra khỏi khối lệnh ( block )
Biến trên heap phải dùng free() ( C ) hoặc delete ( C++ ) để giải phóng


18. Làm thế nào để bạn giải phóng bộ nhớ đã cấp phát động cho một mảng?
19. Đa kế thừa là gì? Khi nào thì nó nên được sử dụng?
20. Một hàm ảo thuần túy (pure virtual) là gì?
21. Từ khóa mutable có ý nghĩa gì?
22. Từ khóa volatile có ý nghĩa gì?
23. Khái niệm STL có nghĩa là gì?
24. Khái niệm Vector có nghĩa là gì?

Vector là một cấu trúc dữ liệu được xây dựng sẵn trong C++

25. Cái gì được chứa strong phần header <algorithms>?
26. Điểm khác nhau giữa ‪#‎include‬ <iostream.h> và #include <iostream> là gì?

iostream.h là thư viện cũ, được thay thế bởi iostream từ C++ 98.
iostream.h được khai báo toàn cục, còn iostream được khai báo cục bộ
Thêm cái nữa đó là nếu #include <iostream.h> thì không cần phải thông báo sử dụng namespace std, nhưng #include <iostream> thì cần

27. Điểm khác nhau giữa “++i” and “i++” là gì?

++i: cộng i lên 1 trước rồi thực hiện phép toán
i++: thực hiện phép toán trước rồi cộng i lên 1
28. Ước lượng short circuit có nghĩa là gì? Nó được sử dụng như thế nào? Tại sao việc sử dụng nó có thể gây nguy hiểm?
29. Toán tử ‘,’ có ý nghĩa gì?
30. Toán tử tam nguyên có nghĩa là gì? Cách sử dụng nó như thế nào?
31. Hàm hằng thành viên (const member) có nghĩa là gì và nó được sử dụng như thế nào?
32. Làm thế nào để sử dụng try/catch trong C++?
33. Tại sao bạn đừng bao giờ ném ra một ngoại lệ trong một hàm hủy?
34. Từ khóa explicit có ý nghĩa gì?

Từ khoá explicit đặt trước Constructor một tham số của một class, thì đối tượng của class này không thể tạo ra bằng implicit cast

class A {
public:
explicit A ( int data ) { // ... }
}
int main() {
A a ( 3 );    // RIGHT
A a = 3;     // WRONG

35. Đâu là cách đúng để thực thi một ép kiểu trong C++?
36. Khái niệm inline có nghĩa là gì?