반응형

http://gogorchg.tistory.com/entry/Android-%ED%94%84%EB%A0%88%EC%9E%84-%EC%86%8D%EB%8F%84-%EC%A1%B0%EC%A0%88





쓰레드를 조절할 때, postDelay를 이용해서 프레임 속도를 조절하는데요.

Opengl을 사용할 경우 라이브러리 자체내에서 스레드를 돌리기 때문에

프레임 속도를 조절하기가 힘든 경우가 있었습니다.

그래서 이같은 소스가를 사용하는데요.

private static long targetFrameInterval = 1000L / 30L;  // 프레임 속도 30
private long frame = 30L;

// 스레드 콜백 함수 (무한 반복 하는 함수)
public synchronized void onDrawFrame(GL10 gl) {

// 프레임 처음 시간 설정

long frameStartTime = System.currentTimeMillis();

//.. 뭔가 뿌려주기 위한 소스 등등.

// 프레임 시간을 넘기면 그 시간 만큼 정지

long frameEndTime = System.currentTimeMillis();

long delta = frameEndTime - frameStartTime;

if (targetFrameInterval - delta > frame) {

try {

Thread.sleep(targetFrameInterval - delta);

} catch (InterruptedException e) {}

}
 


 저두 구글링을 통해서 알아낸 겁니다.

알았다기 보단 퍼 온거죠..^^;;; 

사이트를 잊어버려서.. 결국 이렇게 올렸다는..헤헤 

출처: http://gogorchg.tistory.com/entry/Android-%ED%94%84%EB%A0%88%EC%9E%84-%EC%86%8D%EB%8F%84-%EC%A1%B0%EC%A0%88 [항상 초심으로]

반응형

'CS > OpenGL' 카테고리의 다른 글

[OpenGL] 공부순서  (0) 2016.12.26
[OpenGL] FBO 관련 사이트  (0) 2016.12.21
[OpenGL]glReadPixels로 픽셀값을 읽어 glDrawPixels로 그리기  (0) 2016.12.21
[OpenGL] Frambe buffer object(FBO)  (1) 2016.12.20
[OpenGL] 텍스쳐 예제  (0) 2016.12.01
반응형

http://m.blog.naver.com/dnib/220581936320

반응형
반응형

1.

http://wanochoi.com/?p=1019


2.

http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/


3

FBO를 이용한 Render To Texture 구현

http://blog.daum.net/aero2k/53


4.

네이버 3D카페

http://cafe.naver.com/gld3d/181



5.

glPixelRead Example

http://www.lighthouse3d.com/tutorials/opengl-selection-tutorial/



6.

glPixelRead

https://www.khronos.org/opengles/sdk/docs/man3/html/glReadPixels.xhtml




반응형

'CS > OpenGL' 카테고리의 다른 글

[OpenGL] 쓰레드 속도조절  (0) 2017.01.04
[OpenGL] 공부순서  (0) 2016.12.26
[OpenGL]glReadPixels로 픽셀값을 읽어 glDrawPixels로 그리기  (0) 2016.12.21
[OpenGL] Frambe buffer object(FBO)  (1) 2016.12.20
[OpenGL] 텍스쳐 예제  (0) 2016.12.01
반응형

// 배열 동적할당 
 BYTE *oimagedata = (BYTE*)malloc(sW*sH*3); 
 BYTE *nimagedata = (BYTE*)malloc(sW*sH*3); 

 glReadPixels(0, 0, sW, sH, GL_RGB, GL_UNSIGNED_BYTE, oimagedata);


// 이미지 플립
 for(int j = 0 ; j< sH ; j++){
  for(int i = 0; i < sW ; i++){
   nimagedata[j*sW*3 + i*3 + 0] = oimagedata[j*sW*3 + (sW-i)*3 + 0];
   nimagedata[j*sW*3 + i*3 + 1] = oimagedata[j*sW*3 + (sW-i)*3 + 1];
   nimagedata[j*sW*3 + i*3 + 2] = oimagedata[j*sW*3 + (sW-i)*3 + 2];
  }
 }

 glDrawPixels(sW, sH, GL_RGB, GL_UNSIGNED_BYTE, nimagedata);
 
// 배열 해제
 
 free(oimagedata);
 free(nimagedata);



반응형

'CS > OpenGL' 카테고리의 다른 글

[OpenGL] 쓰레드 속도조절  (0) 2017.01.04
[OpenGL] 공부순서  (0) 2016.12.26
[OpenGL] FBO 관련 사이트  (0) 2016.12.21
[OpenGL] Frambe buffer object(FBO)  (1) 2016.12.20
[OpenGL] 텍스쳐 예제  (0) 2016.12.01
반응형

출처 : http://wanochoi.com/?p=1019


Framebuffer는 rendering의 최종 결과가 기록되는 buffer들의 집합이다.
OpenGL context가 생성되면서 기본적으로 하나의 framebuffer를 생성하여 사용하는데,
이러한 default framebuffer를 window-system-provided framebuffer라고 부른다.
반면, 필요 시 임의의 framebuffer를 동적으로 생성하여 사용하는 것이 가능한데,
이렇게 생성된 framebuffer를 application-created framebuffer라고 하며,
일반적으로 framebuffer object (FBO)라고 한다.
FBO는 display 외의 목적으로도 많이 사용된다.
Buffer란 OpenGL이 관리하는 memory 영역을 말한다. (buffer=array=image)
이러한 의미로 보면 FBO는 사실 엄밀히 말해서 buffer는 아니다.
(사실 aggregator의 개념에 더 가깝다.)

FBO는 하나 또는 다수의 buffer들이 attach되어 있는 형태로 존재한다.
(여러 개의 array들에 대한 pointer들을 member로 가지는 구조체(struct)와 같은 개념.)
Default framebuffer에는 color, depth, stencil, accumulation의 용도로 사용되는 buffer들이 attach될 수 있지만, FBO에는 accumulation을 제외한 color, depth, stencil의 용도로 사용되는 buffer들이 attach될 수 있다.
하나의 FBO에는 다수의 attachment point들이 존재하며, 각각의 attachment point마다 하나의 buffer가 attach될 수 있다.
하나의 FBO는 n개(system 마다 다름)의 color attachment points와 각각 한 개씩의 depth attachment point, stencil attachment point를 가진다.
(GL_COLOR_ATTACHMENT0, …, GL_COLOR_ATTACHMENTn, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT)
하나의 FBO에는 최소한 한 개의 color buffer가 attach되어야 한다.
여러 개의 color attachment points를 가지고 있는 이유는 동시에 여러 개의 color buffer에 rendering이 가능하기 때문인데, 이러한 기법을 multiple render targets (MRT)라고 부른다.
Framebuffer attachable buffer는 크게 두 가지 type이 있다.
1. texture object  2. renderbuffer object
Texture object가 render target으로 설정되어 rendering이 수행되는 것을 render-to-texture,
RBO가 render target으로 설정되어 rendering 작업이 수행되는 것을 offscreen rendering이라고 한다.
기본적으로 RBO에 rendering 작업이 완료되었다고 해도 GPU memory 상에만 존재할 뿐 화면에는 보여지지 않기 때문이다.
Texture란 보통의 경우 3D model의 표면을 장식해주는 image의 역할을 수행하지만, 이 외에도 다양한 data를 저장하기 위해 사용될 수 있다.
즉, texture는 GPU에서 사용되는 bulk data를 저장하는 용도로 쓰인다.
(bulk data란 여러 가지 용도로 사용되는 data를 말함.)
Texture는 1D, 2D, 3D 등의 형태로 사용이 가능하며, shader 내에서 값을 읽어서 사용하는 것이 가능하다.
Texture는 GPU memory 상에 독립적으로 동적 할당되어 자유롭게 사용이 가능하지만, RBO는 반드시 FBO에 attach되어 사용되어야 한다.
RBO는 texture와는 달리 반드시 2D 형태로만 사용되어야 하고, 단 한 개의 image 만을 가질 수 있다. (texture에서처럼 mipmaps 사용이 불가능함.)
RBO에 저장된 rendering 결과는 glReadPixels(), glDrawPixels(), glCopyPixels()와 같은 함수들을 이용해서 읽고 쓰는 것이 가능하긴 하지만, shader 내에서는 값을 읽어오는 것이 불가능하므로 texture source 등의 용도로 사용할 수 없다. 만약 shader 내에서 특정 image의 값을 읽어올 필요가 있다면 texture object로 만들어서 사용해야 한다.
만약 shader에서 값을 읽어서 사용하지 않는다면 성능상 texture object 보다는 RBO type을 사용하는 것이 더 좋다.
보통의 경우 depth test가 필요할 경우 depth buffer를 RBO type으로 생한한 후 해당 FBO의 GL_DEPTH_ATTACHMENT에 attach해서 사용하지만, 만약 fragment shader에서 post processing을 수행할 때 depth 값이 필요하다면 texture object type으로 생성한 후 해당 FBO의 GL_DEPTH_ATTACHMENT에 attach해서 사용해야 한다.
Texture object를 생성하는 방법은 일반적으로 texture를 사용하는 경우와 동일하다.
다만 image data를 load하여 연결해줄 필요가 없으므로 glTexImage2D() 함수에서 맨 마지막 인자에는 NULL을 써주면 된다.

다음은 FBO를 한 개 생성한 후, depth buffer로 사용될 texture object를 생성하여 attach하는 예제이다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// framebuffer object
GLuint fboId;
glGenFramebuffers( 1, &fboId );
glBindFramebuffer( GL_FRAMEBUFFER, fboId );
 
// texture buffer object to be used for depth buffer
GLuint depthTexId;
glGenTextures( 1, &depthTexId );
glBindTexture( GL_TEXTURE_2D, depthTexId );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL );
 
// attachment
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE2D, depthTexId, 0 );


다음은 FBO를 한 개 생성한 후, depth buffer로 사용될 renderbuffer object를 생성하여 attach하는 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
// framebuffer object
GLuint fboId;
glGenFramebuffers( 1, &fboId );
glBindFramebuffer( GL_FRAMEBUFFER, fboId );
 
// renderbuffer object to be used for depth buffer
GLuint depthRboId;
glGenRenderbuffers( 1, &depthRboId );
glBindRenderBuffer( GL_RENDERBUFFER, depthRboId );
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height );
 
// attachment
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRboId );


반응형

'CS > OpenGL' 카테고리의 다른 글

[OpenGL] 쓰레드 속도조절  (0) 2017.01.04
[OpenGL] 공부순서  (0) 2016.12.26
[OpenGL] FBO 관련 사이트  (0) 2016.12.21
[OpenGL]glReadPixels로 픽셀값을 읽어 glDrawPixels로 그리기  (0) 2016.12.21
[OpenGL] 텍스쳐 예제  (0) 2016.12.01
반응형

1.


한번 전반적인 flow를 따라 가면서 텍스처를 익혀보도록 해야겠다.



먼저 텍스처를 불러오는것부터!!

(그림에서 텍스처를 가져오는것을 목표로 함)


1)


 final int[] textureObjectIds = new int[1];

 glGenTextures(1, textureObjectIds, 0);


=> 텍스처를 생성하고! 그것의 아이디를 textureObjectIds에 넣는다.




2)

glBindTexture(GL_TEXTURE_2D,textureObjectIds[0]);


=> GL_TEXTURE_2D 속성을 가진 텍스처를 위에서 생성한 textureObjectIds와 바인딩시킨다.



3)

 //setup MipMap

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);

=>텍스처 확대와 축소의 방법으로 Mipmap을 사용하는데, 이를 설정하고!




4)

 texImage2D(GL_TEXTURE_2D, 0 , bitmap, 0);


=> 제일 중요해보이는데, 위에서 만든 텍스쳐에다가 bitmap데이터를 이어주기!!!!!!!!!!

    이때 bitmap데이터는 openGL이 읽을수 있도록 디코딩된 상태여야 한다.




5)

  bitmap.recycle();

  glGenerateMipmap(GL_TEXTURE_2D);



   //바인딩 해제

  glBindTexture(GL_TEXTURE_2D,0);


=> 그림데이터를 바인딩해줬으니, 더이상 필요가 없다. 그래서 recycle로 해제

     그리고 밉맵을 설정하고,  텍스쳐의 바인딩도 해제 시킨다.




여기까지가 전반적인 textureHelper의 역할이다.

다음으로는 렌더링 과정이 필요하다.

여기에서 사용한 텍스쳐도 결국에는 쉐이더와 이어지게 되어있다.

렌더링 과정에서는 이를 쉐이더에 전달하고 그 결과를 받고, 화면에 뿌리는 전반적인 작업을 한다고 보면된다.

쉐이더는 두가지로 나뉘는데, 버텍스쉐이더와 프래그먼트 쉐이더 이다.




uniform mat4 u_Matrix;

attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;

varying vec2 v_TextureCoordinates;

void main()
{
v_TextureCoordinates = a_TextureCoordinates;
gl_Position = u_Matrix * a_Position;
}


위는 버텍스 쉐이더의 모습인데, 

u_Matrix는 관점매트릭스로 해당 좌표에 관한 것을 설명할때 사용한다. (uniform 형태)

그리고 attribute가 2개인데. 한개는 버텍스데이터를 넣는것과

나머지 한개는 텍스쳐좌표를 넣는거다!


a_TextureCoordinates 속성 -> varying으로 바로 출력해서, 프래그먼트 쉐이더에서 이 버텍스 위치에다 텍스쳐를 그릴수 있게 해주는 역할을 한다.


a_Position은 뭐... 테이블좌표를 나타내는것...!!!




precision mediump float;

uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;

void main()
{
gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}

위에꺼는 프래그먼트 쉐이더의 내용이다.

varying은 버텍스쉐이더에서의 입력값이고, 텍스쳐의 위치값을 가지고 있음.

그리고 uniform으로 설정된 sampler2D가 진짜 bitmap의 데이터인데,

이를 texture2D에 넣어서. 프래그먼트를 출력을 한다.




그러면 이 쉐이더의 속성과 유니폼을 어떻게 연결시키는지 알아보자.



// Shader program

protected final int program;

protected ShaderProgram(Context context, int vertexShaderResourceId, int fragmentShaderResourceId){


//Compile the shaders and link the program.

program = ShaderHelper.buildProgram(TextResourceReader.readTextFileFromResource(

                context, vertexShaderResourceId),

                TextResourceReader.readTextFileFromResource(

                        context, fragmentShaderResourceId));

}



먼저 쉐이더를 builProgram(->만든 매서드)를 통해서 컴파일과 프로그램 링크시킨다.

이는 쉐이더 항목에서 배운것이다.

그런 다음에 uniform과 attribute 위치를 가져온다.



//Uniform constants

protected static final String U_MATRIX = "u_Matrix";

protected static final String U_TEXTURE_UNIT = "u_TextureUnit";


//Attribute constants

protected static final String A_POSITION = "a_Position";

protected static final String A_COLOR = "a_Color";

protected static final String A_TEXTURE_COORDINATES = "a_TextureCoordinates";


//Retrieve uniform locations for the shader program.

uMatrixLocation = glGetUniformLocation(program, U_MATRIX);

uTextureUnitLocation = glGetUniformLocation(program, U_TEXTURE_UNIT);


//Retrieve attribute locations for the shader program.

aPositionLocation = glGetAttribLocation(program, A_POSITION);

aTextureCoordinatesLocation = glGetAttribLocation(program, A_TEXTURE_COORDINATES);



유니폼과 속성의 위치를 가지고 오면...

이제는 거기다가 데이터를 집어넣는 일을 해야된다.


먼저 유니폼데이터부터 하고,

그다음에 속성데이터를 넣고.

그다음에 그리면 된다.



//Pass the matrix into the shader program.
glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);

// Set the active texture unit to texture unit 0.
//유닛0 텍스처를 활성화해라!!!
glActiveTexture(GL_TEXTURE0);

//Bind the texture to this unit.
//텍스처를 유닛과 연결!!
glBindTexture(GL_TEXTURE_2D, textureId);

//Tell the texture uniform sampler to use this texture in the shader by
//telling it to read from texture unit 0.
//sampler에 0번 유닛을 넣어라!!
glUniform1i(uTextureUnitLocation,0);



위에 정점 쉐이더에서 말하기를  uniform 데이터가 한개인데, 

그게 uMatrixLocation 이다. 

glUniformMatrix4fv 안에 matrix 데이터를 집어넣는다.


그다음부터는 프로그먼트 쉐이더의 텍스처를 입히는것과 관련된 내용이다.


glActiveTexture(GL_TEXTURE0)으로 0번 텍스처를 활성화 시키고.

이를 glBindTexture를 통해서 유닛과 연결을 시킨다.

glUniform1l을 통해서 텍스처 유닛0번을 uTextureUniLocation에 있는 텍스처에다가 넣는다는 의미이다.


그런뒤에 draw를 하게되면 해당 모습이 그려지게 된다.


public void draw(){
glDrawArrays(GL_TRIANGLE_FAN, 0 ,6);
}



텍스쳐에 대한 전반적인 흐름을 쭈욱 살펴보았다.

다시 한번 처음부터 쭈욱 따라가서 해당부분에 대한 감을 익혔으면 한다.




반응형

'CS > OpenGL' 카테고리의 다른 글

[OpenGL] 쓰레드 속도조절  (0) 2017.01.04
[OpenGL] 공부순서  (0) 2016.12.26
[OpenGL] FBO 관련 사이트  (0) 2016.12.21
[OpenGL]glReadPixels로 픽셀값을 읽어 glDrawPixels로 그리기  (0) 2016.12.21
[OpenGL] Frambe buffer object(FBO)  (1) 2016.12.20

+ Recent posts