1
\$\begingroup\$

At the moment I'm writing an Android OpenGL ES 2.0 game but now I get stuck on rendering a SkyBox. Here is my (a bit simplified) code for the SkyBox:

float vertices [] = {-1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1};
byte drawOrder[] = {1,3,0,0,3,2,4,6,5,5,6,7,0,2,4,4,2,6,5,7,1,1,7,3,5,1,4,4,1,0,6,2,7,7,2,3};

private final void bindTexture()
{
    int shaderTextureUnit = GLES20.glGetUniformLocation(shaderProgram, "u_TextureUnit");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, texture);
    GLES20.glUniform1i(shaderTextureUnit, 0);
}

public void draw(float[] viewMatrix) // viewMatrix = Camera = data array
{
    GLES20.glUseProgram(shaderProgram);
    bindTexture(); // Load Texture

    shaderPosition = GLES20.glGetAttribLocation(shaderProgram, "a_Position");
    shaderMatrix = GLES20.glGetUniformLocation(shaderProgram, "u_Matrix");

    // get handle to shape's transformation matrix
    GLES20.glUniformMatrix4fv(shaderMatrix, 1, false, vpMatrix, 0);

    // Prepare the triangle coordinate data
    GLES20.glEnableVertexAttribArray(shaderPosition);
    GLES20.glVertexAttribPointer(shaderPosition, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);

    // Draw the object to the screen GL_UNSIGNED_BYTE
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, orderBuffer.capacity(), GLES20.GL_UNSIGNED_BYTE, orderBuffer);
    GLES20.glDisableVertexAttribArray(shaderPosition); // Free the position in shader
}

I think this code should be perfect because I got it from an OpenGL for beginners book. My problem now is that it looks like this if I render the SkyBox to the screen. I initialize my Camera with this code and here you have also the code for my touch event. If my considerations are right this should produce a circle around the origin so I can see all sides of the SkyBox.

private float angle = 90;

Matrix.setLookAtM(data, 0,   0, 0, 0,   0, 0, -1,   0, 1, 0); // the viewMatrix
// Z+ out of screen     Z- in screen

public void onTouch()
{
    angle += 2;

    float s = (float) Math.sin(angle * Math.PI / 180);
    float c = (float) Math.cos(angle * Math.PI / 180);

    Matrix.setLookAtM(data, 0,   0, 0, 0,   c, 0, -s,   0, 1,  0); // the viewMatrix
}

The draw Method from the SkyBox is called with the data Matrix from the camera (ViewMatrix) and with disabled depthBuffer. Do you have any ideas why the SkyBox is rendered so strange? What is wrong with my code? Only to be sure that all is right with my shaders here is the code from them:

FragmentShader

precision mediump float; 

uniform samplerCube u_TextureUnit;
varying vec3 v_Position;

void main()                         
{
    gl_FragColor = textureCube(u_TextureUnit, v_Position);    
}

VertexShader

uniform mat4 u_Matrix;
attribute vec3 a_Position;  
varying vec3 v_Position;

void main()                    
{                                                 
    v_Position = a_Position;    
    v_Position.z = -v_Position.z; 

    gl_Position = u_Matrix * vec4(a_Position, 1.0);
    gl_Position = gl_Position.xyww;
}
\$\endgroup\$
1
+50
\$\begingroup\$

Im not entirely sure about this myself, but maybe your problem is that you dont have one. From the looks of it, your skybox is rotating correctly. Question now: I see you are initializing and uploading the view-matrix correctly, but what about the projection-matrix, i dont see that one. My guess is that your code is alright so far, but since you havent specified it (the projection), OpenGL defaults to some sort of orthogonal projection, which is why it looks so weird when rotating. Maybe that solves your problem. Regards, Daniel

EDIT: Try using the Matrix.perspectiveM() method and upload the returned matrix to your shader, then multiply it by the view-matrix before multiplying the product of both by your coordinate vector. That should fix your problem, in case you are still waiting for an answer.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Yes you are right. Thank you very mcuh. I rendered the cube only with the camera matix but of course I have to do it with the camProjection matrix. Now I have one more little question. Here I draw the SkyBox from the camera position (0|0|0) If I move the camera to let's say (0|6|-8) I see the cube from the outside. What do I have to do that I'm always 'in' the cube? \$\endgroup\$ – Cilenco Jan 25 '15 at 21:35
  • \$\begingroup\$ Well, that ones is relatively easy. For now, your skybox has a fixed position - but you want to make it "move" with the camera. Just make the vertices of the skybox relative to your camera position (add a constant vector - thats the distance to the cam - for each vertex of the skybox to your cam position), that will create the illusion of the boxe sides being infinitely far away from your cam. If youre unsure, there should be a lot of material online on this issue. Also, please mark my answer as the correct solution, so people dont need to answer to this anymore. \$\endgroup\$ – tubberd Jan 25 '15 at 23:29
  • \$\begingroup\$ Glad it solved your problem btw :D \$\endgroup\$ – tubberd Jan 25 '15 at 23:31
  • \$\begingroup\$ @Cilenco i have one question for you now: when or how is the bounty awarded? :P \$\endgroup\$ – tubberd Jan 26 '15 at 14:30
  • \$\begingroup\$ Since one hour. Sorry I can't give to you earlier. \$\endgroup\$ – Cilenco Jan 26 '15 at 17:22
0
\$\begingroup\$

Before all I can defenetly say , that disabling ZBuffer is bad idea due perfomance issues, and it looks like for me it is issue. 1) try enable Zbuffer!! 2) check your model,view and project matrices

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Okay thank you for your ideas. If I turn on the ZBuffer (ZBuffer is the same as depthBuffer?) the result on the screen does not change. All I do with the viewMatrix you can see in the question. My projectionMatrix looks okay in the debug mode and I do not have a modelMatrix for the skyBox because it is at position (0|0|0), has no rotation and no scale. So realy I call the draw method from above only with the viewMatrix. \$\endgroup\$ – Cilenco Jan 2 '15 at 21:29
  • \$\begingroup\$ try glEnable(GL_DEPTH_TEST); glDepthFunc ( GL_LEQUAL ); \$\endgroup\$ – Alexsey Shestacov Jan 3 '15 at 13:01
  • \$\begingroup\$ I'm sorry but this does not help too. Same result :/ \$\endgroup\$ – Cilenco Jan 4 '15 at 0:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.