OpenGL ES 텍 스 처 상세 설명

14323 단어 OpenGLES무늬.
앞에서 배 운 기술 을 사용 하면 OpenGL ES 를 이용 하여 입체 도형 을 구축 할 수 있 고 정점 착색 기와 필름 착색 기 를 통 해 다양한 변화 와 빛 등 효 과 를 가 져 와 3 차원 효 과 를 더욱 진실 하 게 만 들 수 있 습 니 다.실제로 저 는 3D 게임 이 훨씬 아름 다운 것 을 많이 보 았 습 니 다.그것 은 여러 가지 아름 다운 이미지 가 사람들 에 게 많은 시각 적 향 연 을 가 져 다 주 었 기 때 문 입 니 다.이 글 은 앞의 기초 위 에서 물체 의 표면 스티커 를 추가 하여 물 체 를 더욱 보기 좋게 한다.
텍 스 처 개념
무늬 는 이미지 사진 이나 일련의 데 이 터 를 나타 내 는데 무늬 를 사용 하면 물 체 를 더 많은 디 테 일 로 사용 할 수 있다.OpenGL ES 2.0 에는 2 차원 텍 스 처 와 큐 브 텍 스 처 두 가지 스티커 가 있다.
모든 2 차원 무늬 는 많은 작은 무늬 요소 로 구성 되 어 있 으 며,필름 과 픽 셀 과 유사 하 며,무늬 를 사용 하 는 가장 간단 한 방식 은 바로 하나의 이미지 에서 데 이 터 를 직접 불 러 오 는 것 이다.OpenGL 에서 텍 스 처 이미지 의 왼쪽 하단 을 stst 좌표(0.0,0.0)로 지정 하고 오른쪽 상단 은 stst 좌표(1.0,1.0)로 지정 하지만 1.0 이 넘 는 좌표 도 허용 되 며,이 구간 이외 의 텍 스 처 는 읽 을 때 텍 스 처 스 트 레 칭 모드 로 결정 된다.
OpenGL ES 2.0 은 정사각형 일 필 요 는 없 지만,각 차원 은 2 의 멱 이 어야 한다.
안 드 로 이 드 에서 사용 하 는 OpenGL ES 의 텍 스 처 좌 표 는 공식 텍 스 처 좌표 시스템 과 달리 안 드 로 이 드 에서 공식 텍 스 처 좌표 시스템 을 사용 해 얻 은 결 과 는 반대 이 고 왼쪽 상단 은 stst 좌표(0.0,0.0)점,오른쪽 하단 은 stst 좌표(1.0,1.0)점 이다.
2 차원 무늬 맵 의 원리

무늬 를 사용 하 는 것 은 무늬 그림 에서 샘플링 을 하 는 것 이기 때문에 선택 한 무늬 좌 표를 정점 착색 기 에 입 히 고 플러그 인 을 통 해 조각 원 착색 기 에서 무늬 그림 에서 지정 한 위치 에서 샘플링 하면 된다.무늬 그림 의 데 이 터 는 조각 원 플러그 인 을 통 해 무늬 단원 이 지정 한 것 을 전달 해 야 한다.
텍 스 처 대상 과 텍 스 처 로드
무늬 대상 을 만 들 고 렌 더 링 에 필요 한 무늬 데 이 터 를 저장 합 니 다.예 를 들 어 이미지 데이터,필터 모드,포장 모드 등 입 니 다.텍 스 처 대상 생 성 함수 만 들 기

public static native void glGenTextures(
    int n, //              
    int[] textures, //       ID   
    int offset
  );
텍 스 처 대상 이 프로그램 에서 더 이상 사용 되 지 않 을 때 삭제 해 야 합 니 다.

public static native void glDeleteTextures(
    int n, //           
    int[] textures, //         ID   
    int offset
  );
텍 스 처 대상 의 ID 는 glGenTextures 에서 만들어 져 야 하 며,텍 스 처 ID 가 생 성 되면 텍 스 처 대상 을 연결 해 야 후속 작업 을 계속 할 수 있 습 니 다.후속 작업 은 바 인 딩 된 텍 스 처 대상 에 영향 을 줍 니 다.텍 스 처 가 특정한 텍 스 처 목표 에 연결 되면 삭제 하기 전에 바 인 딩 상 태 를 유지 합 니 다.

public static native void glBindTexture(
    int target, //           GL_TEXTURE_2D   GL_TEXTURE_CUBE_MAP
    int texture //         ID
  );
어떤 텍 스 처 유닛 활성화

public static native void glActiveTexture(
    int texture //         
  );
이 두 함수 에 대한 이해:그래 픽 카드 에는 N 개의 텍 스 처 유닛(GLTEXTURE0,GL_TEXTURE1,GL_TEXTURE 2...)각 텍 스 처 셀 에는 텍 스 처 대상(targetTexture1D,targetTexture2D,targetTexture3D,targetTextureCube...)이 많이 저장 되 어 있 으 며 OpenGL ES 2.0 은 targetTexture2D 와 targetTextureCube 만 지원 하 는 것 으로 보인다.
텍 스 처 유닛 Texture Unit 의 정 의 는 다음 과 같 습 니 다.

struct TextureUnit
{
  GLuint targetTexture1D;
  GLuint targetTexture2D;
  GLuint targetTexture3D;
  GLuint targetTextureCube;
  ...
};
glActiveTexture 함 수 는 현재 활동 하 는 텍 스 처 유닛 을 설정 하 는 것 입 니 다.

TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS]
GLuint currentTextureUnit = 0;
// ...
void glActiveTexture(GLenum textureUnit)
{
  currentTextureUnit = textureUnit - GL_TEXTURE0 ;
}
glBindTexture 함 수 는 현재 활동 하 는 텍 스 처 유닛 에 텍 스 처 대상 ID 를 부여 하 는 대상 텍 스 처 입 니 다.

void glBindTexture(GLenum textureTarget, GLuint textureObject)
{
  TextureUnit *texUnit = &textureUnits[currentTextureUnit];
  switch(textureTarget)
  {
  case GL_TEXTURE_1D: texUnit->targetTexture1D = textureObject; break;
  case GL_TEXTURE_2D: texUnit->targetTexture2D = textureObject; break;
  case GL_TEXTURE_3D: texUnit->targetTexture3D = textureObject; break;
  case GL_TEXTURE_CUBEMAP: texUnit->targetTextureCube = textureObject; break;
  }
}
그림 의 텍 스 처 데 이 터 를 가 져 옵 니 다.

public static void texImage2D(int target, //   GL_TEXTURE_2D
               int level, //                ,        , level  0。
               Bitmap bitmap,
               int border //   ,    0 
               )
다른 텍 스 처 옵션 의 설정 은 glTexParameterf 시리즈 함 수 를 사용 합 니 다.

public static native void glTexParameterf(
    int target, 
    int pname, //      ,   GL_TEXTURE_MAG_FILTER,GL_TEXTURE_MIN_FILTER,GL_TEXTURE_WRAP_S,GL_TEXTURE_WRAP_T
    float param //       
  );
텍 스 처 적용 예
앞의 입방체 의 각 면 에 한 장의 그림 을 무늬 스티커 로 사용 합 니 다.효과 그림(이 무늬 그림 은 어느 선생님 이 었 죠?)

Rectangle.java

public class Rectangle {
  private FloatBuffer mVertexBuffer;
  private int mProgram;
  private int mPositionHandle;
  private int muMVPMatrixHandle;
  private int mColorHandle;
  private int muMMatrixHandle;
  private int muLightLocationHandle;
  private int mTextureCoordHandle;
  private int textureId;
  private int muTextureHandle;

  private Context mContext;
  public Rectangle(Context context) {
    this.mContext = context;
    initVetexData();
  }

  public void initVetexData() {
    float vertices[] = new float[] {
        //              
        //  
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        -1, 1, 1, 1,0,0,0, 0.0f, 0.0f,
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        -1, 1, 1, 1,0,0,0, 0.0f, 0.0f,
        -1,-1, 1, 1,0,0,0, 0.0f, 1.0f,
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        -1,-1, 1, 1,0,0,0, 0.0f, 1.0f,
        1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //  
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        1, 1,-1, 1,0,0,0, 1.0f, 0.0f,
        1,-1,-1, 1,0,0,0,  0.0f, 0.0f,
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        1,-1,-1, 1,0,0,0,  0.0f, 0.0f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        -1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        1, 1,-1, 1,0,0,0, 1.0f, 0.0f,
        //  
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        -1, 1,-1, 1,0,0,0, 0.0f, 0.0f,
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1,-1, 1,0,0,0, 0.0f, 0.0f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        -1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //  
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //  
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        1, 1,-1, 1,0,0,0,  0.0f, 0.0f,
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1,-1, 1,0,0,0,  0.0f, 0.0f,
        -1, 1,-1, 1,0,0,0, 0.0f, 1.0f,
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1, 1, 1, 1,0,0,0, 1.0f, 1.0f,
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1, 1, 1,0,0,0, 1.0f, 1.0f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //  
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1, 1, 1,0,0,0, 1.0f, 0.0f,
        -1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        1,-1,-1, 1,0,0,0, 1.0f, 1.0f,
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1,-1, 1,0,0,0, 1.0f, 1.0f,
        1,-1, 1, 1,0,0,0, 1.0f, 0.0f
      };
    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    mVertexBuffer = vbb.asFloatBuffer();
    mVertexBuffer.put(vertices);
    mVertexBuffer.position(0);

    int vertexShader = loaderShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    int fragmentShader = loaderShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

    mProgram = GLES20.glCreateProgram();
    GLES20.glAttachShader(mProgram, vertexShader);
    GLES20.glAttachShader(mProgram, fragmentShader);
    GLES20.glLinkProgram(mProgram);

    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
    mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
    mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");

    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
    muLightLocationHandle = GLES20.glGetUniformLocation(mProgram, "uLightLocation");
    muTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture");
    initTexture();
  }

  //      
  public void initTexture() {
    int [] textures = new int[1];
    GLES20.glGenTextures(1, textures, 0);
    textureId = textures[0];
    //       ,       0     
    //GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    //      ID            0  GL_TEXTURE_2D  
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
    //                      
    //           
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);
    //           
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
    //         st         ,              1      
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);

    Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.texture);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
    //           ,    
    bitmap.recycle();
  }

  public void draw() {
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 12*6);
  }

  public void setValue(float[] mvpMatrix, float[] mMatrix) {
    GLES20.glUseProgram(mProgram);
    mVertexBuffer.position(0);
    GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, (4+3+2) * 4, mVertexBuffer);
    mVertexBuffer.position(3);
    GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, (4+3+2) * 4, mVertexBuffer);
    mVertexBuffer.position(7);
    GLES20.glVertexAttribPointer(mTextureCoordHandle, 2, GLES20.GL_FLOAT, false, (4+3+2) * 4, mVertexBuffer);
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glEnableVertexAttribArray(mColorHandle);
    GLES20.glEnableVertexAttribArray(mTextureCoordHandle);

    GLES20.glUniform3f(muLightLocationHandle, 0, 0, 20);
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mvpMatrix, 0);
    GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, mMatrix, 0);
    //         0        
    GLES20.glUniform1i(muTextureHandle, 0);
  }

  private int loaderShader(int type, String shaderCode) {
    int shader = GLES20.glCreateShader(type);
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);
    return shader;
  }

  private String vertexShaderCode = "uniform mat4 uMVPMatrix;"
      + "attribute vec2 aTextureCoord;"
      + "varying vec2 vTextureCoord;"
      + "uniform mat4 uMMatrix;"
      + "uniform vec3 uLightLocation;"
      + "attribute vec4 aColor;"
      + "varying vec4 vColor;" 
      + "varying vec4 vDiffuse;"
      + "attribute vec3 aPosition;"
      + "void main(){" 
      + "vec3 normalVectorOrigin = aPosition;"
      + "vec3 normalVector = normalize((uMMatrix*vec4(normalVectorOrigin,1)).xyz);"
      + "vec3 vectorLight = normalize(uLightLocation - (uMMatrix * vec4(aPosition,1)).xyz);"
      + "float factor = max(0.0, dot(normalVector, vectorLight));"
      + "vDiffuse = factor*vec4(1,1,1,1.0);"
      + "gl_Position = uMVPMatrix * vec4(aPosition,1);"
      + "vColor = aColor;"
      + "vTextureCoord = aTextureCoord;" //             ,           
      + "}";

  private String fragmentShaderCode = "precision mediump float;"
      + "uniform sampler2D uTexture;" //   uniform         , java               
      + "varying vec2 vTextureCoord;"
      + "varying vec4 vColor;"
      + "varying vec4 vDiffuse;"
      + "void main(){"
      + "gl_FragColor = (vColor*vDiffuse + vColor*vec4(0.6,0.6,0.6,1))*texture2D(uTexture, vTextureCoord);" //              ,texture2D        
      + "}";
}

주의해 야 할 것 은 들 어 오 는 정점 일 때 배열 에 정점,색상,무늬 좌표 가 포함 되 어 있 기 때문에 ByteBuffer 의 position 방법 으로 포 지 셔 닝 해 야 합 니 다.
코드 다운로드
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기