5 Stimmen

Textur auf den Würfel anwenden, unterschiedliche Textur auf jeder Seite des Würfels

Ich versuche, verschiedene Textur auf Würfel mit Shadern mit samplerCube und textureCube anzuwenden.

Aber ich bin nicht in der Lage, Textur auf Gesichtern des Würfels gezeichnet bekommen nur einzelne Farbe erscheint.

Screenshots der Ausgabe

Unten ist mein Shader-Code:

Vertex-Shader

String strVShader = "attribute vec4 a_position;" +
            "uniform mat4 u_VPMatrix;" +
            "attribute vec3 a_normal;" +
            "varying vec3 v_normal;" +
            "void main()" +
            "{" +
                "gl_Position = u_VPMatrix * a_position;" +
                "v_normal = a_normal;" +
            "}";

Fragment-Shader

String strFShader = "precision mediump float;" +
            "uniform samplerCube u_texId;" +
            "varying vec3 v_normal;" +
            "void main()" +
            "{" +
                "gl_FragColor = textureCube(u_texId, v_normal);" +
            "}";

Würfel Definition

float[] cube = {
        2,2,2, -2,2,2, -2,-2,2, 2,-2,2, //0-1-2-3 front
        2,2,2, 2,-2,2,  2,-2,-2, 2,2,-2,//0-3-4-5 right
        2,-2,-2, -2,-2,-2, -2,2,-2, 2,2,-2,//4-7-6-5 back
        -2,2,2, -2,2,-2, -2,-2,-2, -2,-2,2,//1-6-7-2 left
        2,2,2, 2,2,-2, -2,2,-2, -2,2,2, //top
        2,-2,2, -2,-2,2, -2,-2,-2, 2,-2,-2,//bottom
    };

short[] indeces = {0,1,2, 0,2,3,
            4,5,6, 4,6,7,
            8,9,10, 8,10,11,
            12,13,14, 12,14,15,
            16,17,18, 16,18,19,
            20,21,22, 20,22,23,
            };

float[] normals = {
                  0, 0, 1,   0, 0, 1,   0, 0, 1,   0, 0, 1,     //front
                   1, 0, 0,   1, 0, 0,   1, 0, 0,   1, 0, 0,     // right
                   0, 0,-1,   0, 0,-1,   0, 0,-1,   0, 0,-1,     //back
                   -1, 0, 0,  -1, 0, 0,  -1, 0, 0,  -1, 0, 0,     // left
                   0, 1, 0,   0, 1, 0,   0, 1, 0,   0, 1, 0,     //  top                  
                   0,-1, 0,   0,-1, 0,   0,-1, 0,   0,-1, 0,     // bottom

     }; 

OnDrawFrame

public void onDrawFrame(GL10 arg0) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        GLES20.glUseProgram(iProgId);
        cubeBuffer.position(0);
        GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, cubeBuffer);
        GLES20.glEnableVertexAttribArray(iPosition);

        GLES20.glVertexAttribPointer(iNormal, 3, GLES20.GL_FLOAT, false, 0, normBuffer);
        GLES20.glEnableVertexAttribArray(iNormal);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, iTexId);
        GLES20.glUniform1i(iTexLoc, 0);

        Matrix.setIdentityM(m_fIdentity, 0);
        Matrix.rotateM(m_fIdentity, 0, -xAngle, 0, 1, 0);
        Matrix.rotateM(m_fIdentity, 0, -yAngle, 1, 0, 0);
        Matrix.multiplyMM(m_fVPMatrix, 0, m_fViewMatrix, 0, m_fIdentity, 0);
        Matrix.multiplyMM(m_fVPMatrix, 0, m_fProjMatrix, 0, m_fVPMatrix, 0);
        GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, m_fVPMatrix, 0);

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
    }

Code für Würfelkarten erstellen

public int CreateCubeTexture()
    {
            ByteBuffer fcbuffer = null;

            int[] cubeTex = new int[1];

            GLES20.glGenTextures(1, cubeTex, 0);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP,cubeTex[0]);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
            Bitmap img = null;
            img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick1);
            fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4);

            img.copyPixelsToBuffer(fcbuffer);
            fcbuffer.position(0);
            Log.d("alpha",""+img.hasAlpha());
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight() , 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer);
            fcbuffer = null;
            img.recycle();

            img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick2);
            fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4);
            img.copyPixelsToBuffer(fcbuffer);
            fcbuffer.position(0);
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer);
            fcbuffer = null;
            img.recycle();

            img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick3);
            fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4);
            img.copyPixelsToBuffer(fcbuffer);
            fcbuffer.position(0);
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer);
            fcbuffer = null;
            img.recycle();

            img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick4);
            fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4);
            img.copyPixelsToBuffer(fcbuffer);
            fcbuffer.position(0);
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer);
            fcbuffer = null;
            img.recycle();

            img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick5);
            fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4);
            img.copyPixelsToBuffer(fcbuffer);
            fcbuffer.position(0);
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GLES20.GL_RGBA,img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer);
            fcbuffer = null;
            img.recycle();

            img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick6);
            fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4);
            img.copyPixelsToBuffer(fcbuffer);
            fcbuffer.position(0);
            GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer);
            fcbuffer = null;
            img.recycle();

            GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_CUBE_MAP);

            return cubeTex[0];
    }

Ich kann nicht verstehen, wo ich einen Fehler mache.

Wenn Sie den vollständigen Code sehen wollen.

Lösung:

Verwendung derselben Würfelzeichnungskoordinaten für Texturkoordinaten

Vielen Dank an alle

CODE Link

4voto

Face Bloke Punkte 446

Obwohl die Frage nun gelöst ist, möchte ich eine Erklärung dafür anbieten, warum die Verwendung anderer Koordinaten tatsächlich geholfen hat (weil das oben fehlt).

Als ich zum ersten Mal Cube-Mapping implementierte, hatte ich den gleichen Fehler, weil ich nicht wusste, wie Cube-Maps funktionieren. Cube-Map ist intern ein Satz von 6 2D-Texturen, die auf sechs Seiten eines Würfels angeordnet sind. Vom mathematischen Standpunkt aus betrachtet, definiert sie eine Lookup-Funktion, deren Argument 3D ist Richtung und die Ausgabe ist eine RGBA-Farbe.

Dies ist wichtig, da im obigen Beispiel das Argument für die Suche normal war. Normal ist eine Richtung, die korrekt ist. Aber die Normale ist auch über die gesamte Fläche des Würfels konstant (außer bei der Berechnung von Normalen im Stil von Smooth Shading, was nicht der Fall war). Wenn die Normale (Eingabe für die Suche) konstant ist, bedeutet das natürlich, dass auch die Ausgabe (Farbe) konstant sein muss. Mein Missverständnis war, dass ich annahm, dass OpenGL irgendwie beides berücksichtigen würde Position und Richtung aber das ist leider nicht der Fall.

Das Interessante in diesem speziellen Fall ist, dass man entweder cubeMap(position) oder cubeMap(position + direction) verwenden kann und ein ganz ähnliches Ergebnis erhält. Das liegt an einer weiteren wichtigen Eigenschaft von CubeMaps: Die Eingaberichtung wird zunächst normalisiert (die Länge auf 1 geändert, ohne die Richtung zu ändern), bevor die Farbe aus der Textur ausgelesen wird. Dies wurde auf älteren Grafikkarten verwendet, um eine schnelle Vektor-Normalisierung zu berechnen, indem eine spezielle Cube-Map-Textur verwendet wurde (weil die Berechnung der Quadratwurzel im Shader langsamer war als die Textur-Lookup).

Ein letzter Gedanke zu Würfeln - cube-map ist nicht der richtige Weg, um jeder Fläche eines Würfels eine andere Textur zuzuweisen. Es funktioniert für eine einfache Fälle, aber es wäre schwer, es praktisch zu machen, z. B. in einem Spiel, weil I) die Anzahl der Kombinationen von verschiedenen Texturen auf einem Würfel würde wahrscheinlich unnötig viele Texturen erfordern und II), weil diese Art, Textur Wiederholung kann nicht verwendet werden.

0voto

rama Punkte 1

Sie müssen devDept.DataSet.dll in Ihrer Anwendung hinzufügen und auf Ihr Objekt anwenden:

string brickMatName = "Wall bricks";
viewportLayout1.Materials.Add(brickMatName, new Material(devDept.DataSet.DataSet.GetBricks()));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X