=================================
=================================
=================================
출처: http://gogorchg.tistory.com/entry/Android-ColorMask-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
[ Android ] ColorMask 사용하기
| 나의 플랫폼/안드로이드 2011/09/06 13:48
Posted by GsBOB
글로우 효과를 내거나 이미지에 발광 효과를 줄려고 할 때
사용하면 괜찮을 것 같아서 이렇게 글을 남깁니다.
Opengl es 같은 경우 자체적으로 diffuse(범위) 빛 효과 값을 이용하여
글로우 효과를 표현하기도 하는 것 같은데요..
만약 랜더링 되지 않은 그냥 bitmap 파일을 글로우 효과를 낼려면..
어쩔수 없이 bitmap 자체를 변경 시켜줘야 한다는 게
몇일 간 조사한 저의 결과 였습니다.
bitmap변경은 다음과 같이 이용하였습니다.
// bitmap 소스를 받아온다.
Bitmap tmpbitmap = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.raw.lightmap));
tmpbitmap = Bitmap.createScaledBitmap(tmpbitmap, 256, 256, true);
Paint paint = new Paint();
int textureIndex = 0;
// 50개의 텍스처를 초기화 했습니다.
for(float contrast = 0.0f ; textureIndex < 50 ; contrast += 0.1f,textureIndex++){
// 컬러 매트릭스 생성
ColorMatrix cm = new ColorMatrix();
// 컬러 캐트릭스를 적용 시킨 비트맵을 그릴 팔레트Bitmap
Bitmap paletBmp = Bitmap.createBitmap(tmpbitmap.getWidth(), tmpbitmap.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(paletBmp);
// contrast값이 높아 질수록 밝아진다. ( 글로우 효과일 경우 보이는 부분이 줄어드는 효과를 볼 수 있죠.)
setContrastScaleOnly(cm, contrast);
// 컬러 필터로 적용
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.save();
canvas.drawBitmap(tmpbitmap, 0,0, paint);
canvas.restore();
mLightMapTexId[textureIndex] = loadTexture(paletBmp);
}
tmpbitmap.recycle();
tmpbitmap = null;
아마 글로우 효과를 내는데 제가 잘못 생각할 수도 있을 것 같네요..
혹시 다른 의견이나~~
괜찮은 생각 있으신 분~~~ 특히 Opengl es 2.0을 이용하는 방법이면
더욱 환영입니다.^^
=================================
=================================
=================================
출처: http://gogorchg.tistory.com/entry/Android-Opengl-es-Blur%ED%9A%A8%EA%B3%BC
[ Android Opengl es ] Blur효과
아직 실험해보지는 않았다.
이것도 역시 Bitmap의 컬러값을 이용하여,변경하는 함수이다.
function BlurHorizontal (source, dest, radius) {
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
total = 0
for (kx = -radius; kx <= radius; ++kx)
total += source(x + kx, y)
dest(x, y) = total / (radius * 2 + 1)
}
}
}
function BlurVertical (source, dest, radius) {
for (x = 0; x < width; ++x) {
for (y = 0; y < height; ++y) {
total = 0
for (ky = -radius; ky <= radius; ++ky)
total += source(x, y + ky)
dest(x, y) = total / (radius * 2 + 1)
}
}
}
function Blur (source, dest, radius) {
BlurHorizontal(source, temp, radius)
BlurVertical(temp, dest, radius)
}
출처 : http://www.blackpawn.com/texts/blur/default.html
중요한 건 , 모든 연산이 CPU에서 하기 때문에.
매번 블러를 적용시킬려고 하면, 속도가 현저하게 저하되는 것을 느낄 수 있을 것 같다.
먼가 Opengl es 내적으로 GPU를 이용하는 방법을 빨리 찾아야 할 것 같다.
어렵다 정말...^^;;;
=================================
=================================
=================================
출처: http://gogorchg.tistory.com/entry/Android-Opengl-es-20-Blur-%ED%9A%A8%EA%B3%BC
드뎌!!!! Blur효과를 냈습니다.
아마 이런 것 가지고 하시는 분들 계시겠지만, 저한테는 너무 기분 좋은 일이네요.^^
이 효과를 내고 싶어도... 낼 수가 없었던 지금까지의 고생이 오늘 해결 되었네요.
Opengl es 2.0으로 했구요.
FrameShader 소스 부분의 컬러 값을 변경하면 됩니다.
String fShaderStr =
"precision mediump float; \n" +
"varying vec2 v_texCoord; \n" + // 이건 texture index 배열이죠. DrawElement에서 사용
"uniform sampler2D s_lightMap; \n" + // 이미지 텍스쳐 입니다.
"uniform float u_blurAmount; \n" + // Blur을 먹이기 위해 Object간의 간격을 조절
"uniform int u_blurFlag; \n" + // 테스트를 위해 Blur 먹인 것과 아닌 것을 구분하는 Flag
"void main() \n" +
"{ \n" +
" \n" +
" vec4 lightColor; \n" +
" \n" +
" highp vec4 color = vec4(0,0,0,1); \n" + // 색깔을 받을 변수
// Blur를 가우스 공식에 의해 변경을 시켜주는 거지요.
" if ( u_blurFlag == "+ENABLE_BLUR+"){ \n " +
" highp vec2 gaussFilter[7]; \n" +
" gaussFilter[0] = vec2(-3.0, 0.015625); \n" +
" gaussFilter[1] = vec2(-2.0, 0.09375); \n" +
" gaussFilter[2] = vec2(-1.0, 0.234375); \n" +
" gaussFilter[3] = vec2(0.0, 0.3125); \n" +
" gaussFilter[4] = vec2(1.0, 0.234375); \n" +
" gaussFilter[5] = vec2(2.0, 0.09375); \n" +
" gaussFilter[6] = vec2(3.0, 0.015625); \n" +
" \n" +
" highp float blurSize = u_blurAmount * 1.0; \n" +
" \n" +
" for( int i = 0; i < 7; i++ ) \n" +
" color += texture2D( s_lightMap, vec2( v_texCoord.x+gaussFilter[i].x*blurSize, v_texCoord.y+gaussFilter[i].x*blurSize ) )*gaussFilter[i].y; \n" +
" }else{ \n " +
" color = texture2D( s_lightMap, v_texCoord ); \n" +
" } \n" +
" gl_FragColor = color ; \n" +
"} \n";
결과 화면:
위 쪽은 기본 이미지.
밑 쪽은 Blur 값을 넣은 이미지 입니다.
blurAmount를 0.01f로 줬을 때 나오는 결과구요.
더 주게 되면 Blur Object가 더욱 벌어져서 이상하게 보여버립니다.
이렇게요^^
왠지 오늘 너무 행복한 하루 네요~~^^
더 궁금한 거 있으시면 댓글 달아주세요 ㅎ
모두 추운 날씨 몸 조심하시고
즐코딩하세요~ ㅎ
=================================
=================================
=================================
[ Android Opengl es 2.0 ] glDrawArrays 와 glDrawElements 사용법
여러 소스를 보다 보면,
glDrawArrays를 사용하거나, glDrawElements를 사용하기도 합니다.
그래서, 저 같은 경우는 이해하기 쉬운 glDrawArrays를 많이 사용했는데요.
// Vertex 배열을 만듬.
private final float[] mVerticesData =
{
0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f,
};
// Vertex Buffer에 포인터를 설정한다.
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);
// Vertex 속성을 허용한다.
GLES20.glEnableVertexAttribArray(0);
// Vertex의 포인터 갯수 만큼만 그린다. ( 0부터 18 )
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mVerticesData.length/3);
이렇게 Vertex만 잡아주면 쉽게 그릴 수 있는게 glDrawArrays이구요.
만약, 한 구역 내에서 여러 모양의 형태로 그리고 싶을 경우가 있을 때 , glDrawElements를 사용하는데요.
이 때 필요한 것이 Indices 배열입니다.
// Vertex 배열을 만듬.
private final float[] mVerticesData =
{
0.0f, 0.0f, 0.0f, // Vertex 0
-0.5f, 0.5f, 0.0f,// Vertex 1
0.5f, 0.5f, 0.0f, // Vertex 2
1.0f, 0.0f, 0.0f, // Vertex 3
0.5f, -0.5f, 0.0f,// Vertex 4
-0.5f, -0.5f, 0.0f,// Vertex 5
-1.0f, 0.0f, 0.0f,// Vertex 6
};
// Indice 배열을 만듬.
private final short[] mIndicesData = {
0,2,1, // 삼각형 1
0,3,2,// 삼각형 2
0,4,3,// 삼각형 3
0,5,4,// 삼각형 4
0,6,5,// 삼각형 5
0,1,6,// 삼각형 6
};
// Vertex Buffer에 포인터를 설정한다.
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);
// Vertex 속성을 허용한다.
GLES20.glEnableVertexAttribArray(0);
// Indices 갯수만큼 설정.
GLES20.glDrawElements(GLES20.GL_TRIANGLE_FAN, mIndicesData.length,
GLES20.GL_UNSIGNED_SHORT, mIndices);
Vertex의 위치 를 보여드린 그림입니다.
각각 안에 삼각형이 6개가 그려지죠.
3각형을 그릴 포인트를 Indices 배열에 지정한 것입니다.
이 그림의 주소따라
mIndicesData 안에 값들 대로 그려보십시요.
아~~~ 하실 껍니다.^^
참고>
glDrawElements를 할 경우, 여러 Object를 연결 시키고자 할때,
Vertex는 많아도 indices로 연결을 시켜주면 되니 사용하기 편하다고 하네요..^^
=================================
=================================
=================================
[Android Opengl es 2.0 ] VBO(VertexArray Buffer Object ) 관련해서
이번에 이해하게된 함수는
glGenBuffers, glBindBuffer,glBufferData 이 세 함수입니다.
이 함수에는 다음과 같은 코드로 Vertex 배열을 Opengl Buffer에 저장을 시켜서
Handle Number를 이용하여 사용을 하는데요.
// Buffer 생성 공간을 2군데 만든다.
GLES20.glGenBuffers(2, vObjId);
// Buffer 공간에서 첫번째와 연결
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vObjId.get(0));
// 연결된 첫번째 공간에 Static형태로 Vertex데이터를 저장 한다.
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, mVerticesData.length * 4, mVertices,
GLES20.GL_STATIC_DRAW);
// 한 번 읽을 때마다 , float 4바이트를 3개씩 읽게 된다. ( ex> 0.0f,0.0f,0.0f )
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);
// 속성 적용을 허용한다.
GLES20.glEnableVertexAttribArray(0);
전 코드를 만들면서 생각에 큰 오류가 있었습니다.
바로 위 glGenBuffers라는 함수는
여러 Object에 대한 형태를 지정해 놓으면,
Handle Number를 통하여 Object 모양을 바꿀 수 있을 줄 알았습니다.
하지만!!!!!
glGenBuffers는 한 Object에 대한 여러 Attribute을 지정하는 것이었습니다.
즉, 한 Object에 한해서 밖에 생성이 안된다는 이야기입니다.
구글링을 해본 결과 얻은 결론은 Opengl es 버전이 아닌,
또는 안드로이드가 아니고 iOS내에 Opengl es 버전에는
glGenVertexArrays ( Opengl )
glGenVertexArraysOES ( iOS Opengl )
위 함수를 통하여 여러 Object를 Buffer에 지정할 수가 있는 것 같습니다.
우선, 제가 테스트해 본 결과로는 안드로이드에서 Buffer 여러 Object를 지정해 놓는 것은
힘들어 보이네요...
혹시 이 의견에 반발이 있으신 분은 주저 말고 댓글 달아주세요!!!
이게 100% 맞다고 할 수 없지 않습니까??^^
=================================
=================================
=================================
[ Android Opengl es 2.0 ] Vertex배열을 이용하여 간단한 도형 만들기
안녕하세요.
이번엔 Vertex배열을 이용하여 제가 그린 그림을 보여드릴려고 합니다.
private final float[] mVerticesData =
{
0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f,
};
위와 같이 하게 되면 정육각형이 구해집니다.
먼저 결과 화면을 보여드리겠습니다.
Vertex로직은 다음과 같습니다.
public void onTouchEvent(MotionEvent event){
switch(event.getAction()){
case MotionEvent.ACTION_UP:
if(drawType == GLES20.GL_TRIANGLES){
drawType = GLES20.GL_LINE_LOOP;
}else{
drawType = GLES20.GL_TRIANGLES;
}
break;
}
}
그릴 때 마다 drawType을 변형 시켜서, Touch를 할 경우에
선일 경우에는 꽉 채우는 형태로,
꽉 채워져 있으면 선으로 그려보았습니다.
중요한 부분이 vertex의 순서를 잘못 하면 다음과 같은 결과가 날 수 있다는 것이지요.
GL_LINE_LOOP일 경우는 저희가 예전 놀이로 많이 했던,
연필을 때지 않고 선 그리기 형태로 선을 계속 그린다고
생각하시면 됩니다.
이렇게 Vertex를 공책이나 연습장에 생각해서 그려보신 후,
이제 VertexShader에 적용을 시켜야하는데요.
[ mVerticesBuffer가 사용되기 전에 적용]
mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mVertices.put(mVerticesData).position(0);
[ Drawing 하는 함수에서]
// Vertex 값은 시작이 0이요, 3단위씩 끊어져 있소, 값은 Float형태요.
// Float일 경우 false로 하지만, 만약 다른 데이터 형식일 때 true로 하면 normalize가 된다고 책있네요.
// 3단위로 읽고, 0만큼 건너 뛰겠소. (나중에 Vertex배열에 여러가지를 겸해서 설정할 수도 있습니다.)
// mVertices라는 ByteBuffer를 가지고 그리시요.
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);
GLES20.glEnableVertexAttribArray(0);
// 배열형태를 그립니다.
// 총 배열의 Column 수는 18개 입니다.
// 3단위씩 18개로 되어있죠.
GLES20.glDrawArrays(drawType, 0, 18);
이렇게 간단하게 육각형을 그리는 연습을 해보았습니다.
이제 먼가 움직여도 보고 이것 저것 해볼려고 합니다.
Opengl es 1.0은 해봤는데.
먼가 2.0에서는 개발자에게 대한 자유도가 더 올라간 듯한 느낌도 들고,
이해하기가 더 복잡해 진것 같기도 하고..
아무튼!!!
공부해서 이해가 될 때 마다 글을 남겨둘까 합니다.
이 글이 많은 사람들에게 도움이 되면 좋겠습니다.
=================================
=================================
=================================
[ Android ] Opengl에서 glDrawElements함수로 그릴 떄 주의점
전 glDrawArray함수를 많이 사용하는데요.
폴라곤을 이용하여 텍스처를 입힐 때에는 glDrawElements함수를 사용하는 게 훨 편하고
속도면에서도 낫더라구요.
그런데 기존에 사용했던 glDrawArray함수와 glDrawElements함수를 사용할 때
준비해야할 점들이 다릅니다.
glDrawArray함수는 vertex 좌표만 있어도 표현이 가능하죠. ( 다른 Normal등 부수적인 것을 제외 )
하지만, glDrawElements함수에서는 vertex만큼 중요한 좌표가 두가지가 있죠.
바로!!! vertex포인터를 하게 될 좌표와 텍스처 포인터를 할 좌표!!
이 두가지를 확실하게 해주지 않으면 죽을 때까지 원하는 모양을 보실수 없으십니다.
먼저 , 텍스처 포인터를 할 때
위와 같이 두 포인터가 합쳐서 1을 표현해야만 합니다.
저 윗 그림을 배열로 표시하면
{
0.0 , 0.0
0.5 , 0.0
1.0 , 0.0
0.0 , 0.5
0.5 , 0.5
1.0 , 0.5
0.0 , 1.0
0.5 , 1.0
1.0 , 1.0
}
함수는 다음과 같습니다. 참고하세요.^^ : Java에서 테스트 한 거라 ㅎㅎ
private static void texturePoint(){
int i = 0;
float delta_x = 1.0f / (float)(3-1);
float delta_y = 1.0f / (float)(3-1);
for (int y = 0; y < 3; y++)
for (int x = 0; x < 3; x++)
{
System.out.println((float)x * delta_x + " , " + (float)y * delta_y);
i += 2;
}
}
그 다음은 Vertex포인트 입니다.
똑같은 위 그림을 표현하면 배열이 다음과 같구요.
0 , 1 , 4 , 0 , 3 , 4
1 , 2 , 5 , 1 , 4 , 5
3 , 4 , 7, 3 , 6 , 7
4 , 5 , 8, 4 , 7 , 8
소스는 다음과 같습니다.
private static void vertexPoint() {
int i = 0;
for (int y = 0; y < (3 - 1); y++) {
for (int x = 0; x < (3 - 1); x++) {
int n = (y * 3) + x;
System.out.println((byte) n + " , " + (byte)(n + 1) + " , " + (byte)(n + 1 + 3));
System.out.println((byte) n + " , " + (byte)(n + 1 + 3 - 1) + " , " + (byte)(n + 1 + 3));
i += 6;
}
}
}
저두 이걸로 조금 씩 텍스처의 개념이 이해가 되어 가고, DrawElements를 사용하는데 자신감이 생겼네요^^
어려움을 직면했을 때 포기말고 끝까지 해봅시다.!!!
도움이 되었으면 좋겠네요.. 화이팅!!
아!!! 지금 숫자 3은 가로 세로의 포인트 갯수가 각각 3개인 것입니다.^^
=================================
=================================
=================================
'스마트기기개발관련 > OpenGL (그래픽, 게임)' 카테고리의 다른 글
android 안드로이드 NDK에서 C++ STL 사용 과련 (0) | 2020.09.18 |
---|---|
안드로이드 android NDK jni 폴더안에 폴더를 만들어 빌드해보기 관련 (0) | 2020.09.18 |
안드로이드 Android ndk 오픈지엘 OpenGL ES LoadTexture 관련 (0) | 2020.09.18 |
안드로이드 android ndk 디버그 하는법 관련 (0) | 2020.09.18 |
안드로이드 오픈지엘 OpenGL ES 2.0 매핑 투영 카메라 관련 (0) | 2014.06.11 |