2012-11-26 4 views
0

여섯면 (예 : 상자)에 같은 질감의 큐브를 성공적으로 표시했지만 스카이 박스를 만들려고합니다 (각면마다 6 가지 텍스처 1 개). 스카이 박스는 모든면에서 흰색 만 표시합니다. 각 텍스처는 크레이트 큐브에서 작동하므로 텍스처가 괜찮습니다 (생각합니다.) 여기에 내 코드와 일부 스크린 샷이 있습니다.Android OpengGL 여러 텍스처가 표시되지 않음

TexturedCube 클래스

package com.dissertation.dnativeapp; 

import java.io.IOException; 
import java.io.InputStream; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import javax.microedition.khronos.opengles.GL10; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLUtils; 
import android.util.Log; 
/* 
* A cube with texture. 
* Define the vertices for only one representative face. 
* Render the cube by translating and rotating the face. 
*/ 
public class TexturedCube { 
    private static final String TAG = "texcube"; 
    private FloatBuffer vertexBuffer; // Buffer for vertex-array 
    private FloatBuffer texBuffer; // Buffer for texture-coords-array (NEW) 

    private float[] vertices = { // Vertices for a face 
     -1.0f, -1.0f, 0.0f, // 0. left-bottom-front 
     1.0f, -1.0f, 0.0f, // 1. right-bottom-front 
     -1.0f, 1.0f, 0.0f, // 2. left-top-front 
     1.0f, 1.0f, 0.0f // 3. right-top-front 
    }; 

    float[] texCoords = { // Texture coords for the above face (NEW) 
     0.0f, 1.0f, // A. left-bottom (NEW) 
     1.0f, 1.0f, // B. right-bottom (NEW) 
     0.0f, 0.0f, // C. left-top (NEW) 
     1.0f, 0.0f // D. right-top (NEW) 
    }; 
    int[] textureIDs = new int[1]; // Array for 1 texture-ID (NEW) 

    // Constructor - Set up the buffers 
    public TexturedCube() { 
     // Setup vertex-array buffer. Vertices in float. An float has 4 bytes 
     ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); 
     vbb.order(ByteOrder.nativeOrder()); // Use native byte order 
     vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float 
     vertexBuffer.put(vertices);   // Copy data into buffer 
     vertexBuffer.position(0);   // Rewind 

     // Setup texture-coords-array buffer, in float. An float has 4 bytes (NEW) 
     ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4); 
     tbb.order(ByteOrder.nativeOrder()); 
     texBuffer = tbb.asFloatBuffer(); 
     texBuffer.put(texCoords); 
     texBuffer.position(0); 
    } 

    // Draw the shape 
    public void draw(GL10 gl) { 
     gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise orientation 
     gl.glEnable(GL10.GL_CULL_FACE); // Enable cull face 
     gl.glCullFace(GL10.GL_BACK); // Cull the back face (don't display) 

     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
     gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Enable texture-coords-array (NEW) 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); // Define texture-coords buffer (NEW) 

     // front 
     gl.glPushMatrix(); 
     gl.glTranslatef(0.0f, 0.0f, 1.0f); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glPopMatrix(); 

     // left 
     gl.glPushMatrix(); 
     gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f); 
     gl.glTranslatef(0.0f, 0.0f, 1.0f); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glPopMatrix(); 

     // back 
     gl.glPushMatrix(); 
     gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f); 
     gl.glTranslatef(0.0f, 0.0f, 1.0f); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glPopMatrix(); 

     // right 
     gl.glPushMatrix(); 
     gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); 
     gl.glTranslatef(0.0f, 0.0f, 1.0f); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glPopMatrix(); 

     // top 
     gl.glPushMatrix(); 
     gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f); 
     gl.glTranslatef(0.0f, 0.0f, 1.0f); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glPopMatrix(); 

     // bottom 
     gl.glPushMatrix(); 
     gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f); 
     gl.glTranslatef(0.0f, 0.0f, 1.0f); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glPopMatrix(); 

     gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Disable texture-coords-array (NEW) 
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glDisable(GL10.GL_CULL_FACE); 
    } 

    // Load an image into GL texture 
    public void loadTexture(GL10 gl, Context context) { 
     gl.glGenTextures(1, textureIDs, 0); // Generate texture-ID array 
     Log.d(TAG, "gen number = " + textureIDs[0]); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); // Bind to texture ID 
     // Set up texture filters 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 

     // Construct an input stream to texture image "res\drawable\nehe.png" 
     InputStream istream = context.getResources().openRawResource(R.drawable.crate); 
     Bitmap bitmap; 
     try { 
     // Read and decode input as bitmap 
     bitmap = BitmapFactory.decodeStream(istream); 
     } finally { 
     try { 
      istream.close(); 
     } catch(IOException e) { } 
     } 

     // Build Texture from loaded bitmap for the currently-bind texture ID 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
     bitmap.recycle(); 
    } 
} 

스카이 박스 클래스

package com.dissertation.dnativeapp; 

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import javax.microedition.khronos.opengles.GL10; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLUtils; 
import android.util.Log; 
/* 
* A photo cube with 6 pictures (textures) on its 6 faces. 
*/ 
public class SkyBox { 
    private static final String TAG = "skybox"; 
    private FloatBuffer vertexBuffer; // Vertex Buffer 
    private FloatBuffer texBuffer;  // Texture Coords Buffer 

    private int numFaces = 6; 
    private int[] imageFileIDs = { // Image file IDs 
     R.drawable.front3, 
     R.drawable.left3, 
     R.drawable.back3, 
     R.drawable.right3, 
     R.drawable.top3, 
     R.drawable.bot3 
    }; 
    private int[] textureIDs = new int[numFaces]; 
    private Bitmap[] bitmap = new Bitmap[numFaces]; 
    private float cubeHalfSize = 1.2f; 

    // Constructor - Set up the vertex buffer 
    public SkyBox(Context context) { 
     // Allocate vertex buffer. An float has 4 bytes 
     ByteBuffer vbb = ByteBuffer.allocateDirect(12 * 4 * numFaces); 
     vbb.order(ByteOrder.nativeOrder()); 
     vertexBuffer = vbb.asFloatBuffer(); 

     // Read images. Find the aspect ratio and adjust the vertices accordingly. 
     for (int face = 0; face < numFaces; face++) { 
     bitmap[face] = BitmapFactory.decodeStream(
       context.getResources().openRawResource(imageFileIDs[face])); 
     int imgWidth = bitmap[face].getWidth(); 
     int imgHeight = bitmap[face].getHeight(); 
     float faceWidth = 2.0f; 
     float faceHeight = 2.0f; 
     // Adjust for aspect ratio 
     if (imgWidth > imgHeight) { 
      faceHeight = faceHeight * imgHeight/imgWidth; 
     } else { 
      faceWidth = faceWidth * imgWidth/imgHeight; 
     } 
     float faceLeft = -faceWidth/2; 
     float faceRight = -faceLeft; 
     float faceTop = faceHeight/2; 
     float faceBottom = -faceTop; 

     // Define the vertices for this face 
     float[] vertices = { 
      faceLeft, faceBottom, 0.0f, // 0. left-bottom-front 
      faceRight, faceBottom, 0.0f, // 1. right-bottom-front 
      faceLeft, faceTop, 0.0f, // 2. left-top-front 
      faceRight, faceTop, 0.0f, // 3. right-top-front 
     }; 
     vertexBuffer.put(vertices); // Populate 
     } 
     vertexBuffer.position(0); // Rewind 

     // Allocate texture buffer. An float has 4 bytes. Repeat for 6 faces. 
     float[] texCoords = { 
     0.0f, 1.0f, // A. left-bottom 
     1.0f, 1.0f, // B. right-bottom 
     0.0f, 0.0f, // C. left-top 
     1.0f, 0.0f // D. right-top 
     }; 
     ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4 * numFaces); 
     tbb.order(ByteOrder.nativeOrder()); 
     texBuffer = tbb.asFloatBuffer(); 
     for (int face = 0; face < numFaces; face++) { 
     texBuffer.put(texCoords); 
     } 
     texBuffer.position(0); // Rewind 
    } 

    // Render the shape 
    public void draw(GL10 gl) { 
     gl.glFrontFace(GL10.GL_CCW); 

     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); 

     // front 
     gl.glPushMatrix(); 
     gl.glTranslatef(0f, 0f, cubeHalfSize); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 
     gl.glPopMatrix(); 

     // left 
     gl.glPushMatrix(); 
     gl.glRotatef(270.0f, 0f, 1f, 0f); 
     gl.glTranslatef(0f, 0f, cubeHalfSize); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[1]); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4); 
     gl.glPopMatrix(); 

     // back 
     gl.glPushMatrix(); 
     gl.glRotatef(180.0f, 0f, 1f, 0f); 
     gl.glTranslatef(0f, 0f, cubeHalfSize); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[2]); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4); 
     gl.glPopMatrix(); 

     // right 
     gl.glPushMatrix(); 
     gl.glRotatef(90.0f, 0f, 1f, 0f); 
     gl.glTranslatef(0f, 0f, cubeHalfSize); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[3]); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4); 
     gl.glPopMatrix(); 

     // top 
     gl.glPushMatrix(); 
     gl.glRotatef(270.0f, 1f, 0f, 0f); 
     gl.glTranslatef(0f, 0f, cubeHalfSize); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[4]); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4); 
     gl.glPopMatrix(); 

     // bottom 
     gl.glPushMatrix(); 
     gl.glRotatef(90.0f, 1f, 0f, 0f); 
     gl.glTranslatef(0f, 0f, cubeHalfSize); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[5]); 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4); 
     gl.glPopMatrix(); 

     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
    } 

    // Load images into 6 GL textures 
    public void loadTexture(GL10 gl) { 
     gl.glGenTextures(6, textureIDs, 0); // Generate texture-ID array for 6 IDs 

     Log.d(TAG, "gen number = " + textureIDs[0]); 
     // Generate OpenGL texture images 
     for (int face = 0; face < numFaces; face++) { 
      Log.d(TAG, "gen number " + face + " = " + textureIDs[face]); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[face]); 
     // Build Texture from loaded bitmap for the currently-bind texture ID 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0); 
     bitmap[face].recycle(); 
     } 
    } 
} 

MyGLRenderer

package com.dissertation.dnativeapp; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 
import android.content.Context; 
import android.opengl.GLSurfaceView; 
import android.opengl.GLU; 
import android.util.Log; 

import com.dissertation.dnativeapp.GVariables; 

public class MyGLRenderer implements GLSurfaceView.Renderer { 

    private static final String TAG = "render"; 
    private Context context; // Application context needed to read image (NEW) 
    private TexturedCube cube; 
    private Cube cube1; 
    private SkyBox skybox; 
    private int scene; 
    private int number; 

// For controlling cube's z-position, x and y angles and speeds (NEW) 
    float angleX = 0; 
    float angleY = 0; 
    float speedX = 0; 
    float speedY = 0; 
    float z = -6.0f;  

    // Constructor 
    public MyGLRenderer(Context context) { 
     this.context = context; // Get the application context (NEW) 
     cube = new TexturedCube(); 
     cube1 = new Cube(); 
     skybox = new SkyBox(context); 
     //get scene value 
     scene = GVariables.getScene(); 
    } 

    // Call back when the surface is first created or re-created. 

    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set color's clear-value to black 
     gl.glClearDepthf(1.0f);   // Set depth's clear-value to farthest 
     gl.glEnable(GL10.GL_DEPTH_TEST); // Enables depth-buffer for hidden surface removal 
     gl.glDepthFunc(GL10.GL_LEQUAL); // The type of depth testing to do 
     gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); // nice perspective view 
     gl.glShadeModel(GL10.GL_SMOOTH); // Enable smooth shading of color 
     gl.glDisable(GL10.GL_DITHER);  // Disable dithering for better performance 

     if(scene == 1) 
     { 
      // Setup Texture, each time the surface is created (NEW) 
      cube.loadTexture(gl, context); // Load image into Texture (NEW) 
     } 
     if(scene == 2) 
     { 
      skybox.loadTexture(gl); 
     } 
      gl.glEnable(GL10.GL_TEXTURE_2D); // Enable texture (NEW) 

    } 

    // Call back after onSurfaceCreated() or whenever the window's size changes. 

    public void onSurfaceChanged(GL10 gl, int width, int height) { 
      if (height == 0) height = 1; // To prevent divide by zero 
      float aspect = (float)width/height; 

      // Set the viewport (display area) to cover the entire window 
      gl.glViewport(0, 0, width, height); 

      // Setup perspective projection, with aspect ratio matches viewport 
      gl.glMatrixMode(GL10.GL_PROJECTION); // Select projection matrix 
      gl.glLoadIdentity();     // Reset projection matrix 
      // Use perspective projection 
      GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.f); 

      gl.glMatrixMode(GL10.GL_MODELVIEW); // Select model-view matrix 
      gl.glLoadIdentity();     // Reset 

      // You OpenGL|ES display re-sizing code here 
      // ...... 
     } 

    // Call back to draw the current frame. 

    public void onDrawFrame(GL10 gl) { 

     //get number of objects 
     Log.d(TAG, "getting number"); 
     number = GVariables.getNumberOfObjects(); 
     Log.d(TAG, "number got"); 
     // Clear color and depth buffers 
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

     if(scene == 1) 
     { 
     for(int i = 0; i < number; i++) 
     { 
       // ----- Render the Cube ----- 
       gl.glLoadIdentity();     // Reset the current model-view matrix 
       gl.glTranslatef((-3 + (3*i)), 0.0f, z); // Translate into the screen 
       gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f); // Rotate (NEW) 
       gl.glRotatef(angleY, 0.0f, 1.0f, 0.0f); // Rotate (NEW) 
       gl.glScalef(0.8f, 0.8f, 0.8f); 
       cube.draw(gl); 
      } 
     } 
     if(scene == 0) 
     { 
      for(int i = 0; i < number; i++) 
      { 
       gl.glLoadIdentity(); 
       gl.glTranslatef((-3 + (3*i)), 0.0f, z); 
       gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f); // Rotate (NEW) 
       gl.glRotatef(angleY, 0.0f, 1.0f, 0.0f); // Rotate (NEW) 
       gl.glScalef(0.8f, 0.8f, 0.8f); 
       cube1.draw(gl); 
      } 
     } 
     if(scene == 2) 
     { 
      gl.glLoadIdentity(); 
      gl.glTranslatef(0.0f, 0.0f, z); 
      gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f); // Rotate (NEW) 
      gl.glRotatef(angleY, 0.0f, 1.0f, 0.0f); // Rotate (NEW) 
      gl.glScalef(1.0f, 1.0f, 1.0f); 
      skybox.draw(gl); 
     } 

     // Update the rotational angle after each refresh (NEW) 
     angleX += speedX; 
     angleY += speedY; 
    } 
} 

하고 필요한 경우 MainActivity

01 (나무 상자 등의 하나) 23,492,928,324,251,356,587,303,210

나는 스카이 박스 내가 너무 특정하지만 당신이 설정 텍스처에 대한 매개 변수가 누락되어있을 수 있습니다 아니다

답변

2

에 대한 이미지 만 흰색 얼굴을 게시하지 못할 -edit : 당신의

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 

을 "에 대한 "(모든"bind "호출 후에) 텍스처를 만들 때 반복됩니다.

어쨌든이 내용을 읽으려면 너무 많은 코드를 게시했습니다 ...

+0

왜 이러한 매개 변수가 필요합니까? 설명해 주시겠습니까? 감사. – bickster

+1

텍스쳐 데이터가 렌더 버퍼에 일대일로 적용되지 않을 때 (예를 들어, 10x10 텍스처는 렌더링 버퍼의 20x20 부분으로 그려 질 것입니다) 동작 할 때 OpenGL에게 어떻게 동작하는지 알려주는 것이 필요합니다. 나는 기본값이 무엇인지 전혀 몰라. 당신이 일대일로 그림을 그리는 경우에는 이것을 건너 뛸 수 있지만 시도하지는 않았을 것입니다. –

관련 문제