I'm trying to render a cube and rotate it along it's Y axis using OpenGL ES 2.0, however the cube does not render as a cube but rather as some sort of very flat trapezium. A few images showing the odd behaviour:
I'm not exactly sure what is causing the strange behaviour. I am utilising the Pigs in a Blanket library for rendering on PS Vita.
These are my cube vertices. The first 3 values in each row are the vertex data, the last 2 values are for texture mapping
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
This is my initialization function. surface_width = 960
, surface_height = 544
and aspect = 1.764706
void TestScene::init(EGLint s_width, EGLint s_height)
{
surface_height = s_height;
surface_width = s_width;
model = glm::mat4(1.0f);
projection = glm::mat4(1.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
texture.load_texture("app0:assets/wall.jpg");
if (!shader.load_shaders("app0:shaders/vert.cg", "app0:shaders/frag.cg"))
sceKernelExitProcess(0);
}
This is my rendering function
void TestScene::render(EGLDisplay display, EGLSurface surface, double deltaTime)
{
glViewport(0, 0, surface_width, surface_height);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture.ID);
glUseProgram(shader.ID);
GLint mvpLoc = glGetUniformLocation(shader.ID, "mvp");
GLint position = glGetAttribLocation(shader.ID, "vPosition");
GLint texLoc = glGetAttribLocation(shader.ID, "vTexCoord");
GLfloat aspect = (GLfloat)surface_width/(GLfloat)surface_height;
projection = glm::perspective(glm::radians(camera.Zoom), aspect, 0.1f, 100.0f);
view = camera.GetViewMatrix();
model = glm::rotate(model, glm::radians(1.0f), glm::vec3(0.0f, -1.0f, 0.0f));
glm::mat4 mvp = projection * view * model;
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));
// Bind vertex positions
glEnableVertexAttribArray(position);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
// Bind texture positions
glEnableVertexAttribArray(texLoc);
glVertexAttribPointer(texLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(position);
glDisableVertexAttribArray(texLoc);
eglSwapBuffers(display, surface);
}
My cameras zoom value is 45.0f
and this is the GetViewMatrix method:
glm::mat4 Camera::GetViewMatrix()
{
return glm::lookAt(Position, Position + Front, Up);
}
and finally the shaders: vert.cg
void main
(
uniform float4x4 mvp,
float4 vPosition,
float2 vTexCoord: TEXCOORD0,
out float4 oPosition: POSITION,
out float2 fTexCoord: TEXCOORD
)
{
oPosition = mul(mvp, vPosition);
fTexCoord = vTexCoord;
};
frag.cg
float4 main
(
in float2 fTexCoord: TEXCOORD0,
uniform sampler2D texture1: TEXUNIT0
)
{
float4 col;
col = tex2D(texture1, fTexCoord);
return col;
}
I have a feeling it has something to do with my projection matrix but I'm not entirely sure. Any help is greatly appreciated, thank you
UPDATE:
If I update the near value in glm::perspective from 0.1f
to 1.0f
it produces a better looking but still false result, so I'm pretty sure the issue is in my projection matrix. What am I doing wrong here?
projection = glm::perspective(glm::radians(camera.Zoom), aspect, 0.1f, 100.0f);
becomes
projection = glm::perspective(glm::radians(camera.Zoom), aspect, 1.0f, 100.0f);
for the following results:
I've found the issue. I was multiplying the model view projection matrix incorrectly in the vert shader.
oPosition = mul(mvp, vPosition);
should be
oPosition = mul(vPosition, mvp);
this works with a near value of 0.1f
EDIT
Also the missing faces were due to incorrect winding order with my vertices. Here is a corrected set of vertices, they are in clockwise order glFrontFace(GL_CW);
GLfloat vertices[] = {
// Back face
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // Bottom-left
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // bottom-right
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // top-left
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // bottom-left
// Front face
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-left
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // top-right
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // bottom-right
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // top-right
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-left
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // top-left
// Left face
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-right
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-left
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-left
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-left
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-right
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-right
// Right face
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-left
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-right
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-right
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-left
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-left
// Bottom face
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // top-right
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // bottom-left
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, // top-left
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // bottom-left
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // top-right
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-right
// Top face
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // top-left
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // bottom-right
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // bottom-right
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, // bottom-left
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f // top-left
};