I am new to OpenGL programming.I have made a rotating cube with different images on different faces of the cube..i want to set background for the Screen..Any help will be appreciated..
Draw a textured quad covering the whole viewport. To do this, switch the projection and modelview to identity and disable depth testing. With projection and modelview being identity vertex coordinates [-1 … 1] will cover the whole viewport. In code:
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat tex_quad[16] = {
/* x, y, s, t */
-1, -1, 0, 0,
1, -1, 1, 0,
1, 1, 1, 1,
-1, 1, 0, 1
};
glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*4, &tex_quad[0]);
glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*4, &tex_quad[2]);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, background_image_texture_ID);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_TEXTURE_2D);
In my project all code of creation GLSurfaceView looks like:
glSurfaceView = ...
glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
glSurfaceView.setBackgroundResource(R.drawable.my_background);
glSurfaceView.setZOrderOnTop(true);
glSurfaceView.setRenderer(...);
glSurfaceView.setRenderMode(...);
NOTE: Do not use
_glSurfaceView.setBackgroundDrawable(this.getResources().getDrawable(R.drawable.my_background));
I wasted a few days on it.
And do not call
gl.glClearColor(...)
in
Renderer.onDrawFrame
I think the OP wants to turn his code into an android live wallpaper.
#Sumit : if I'm right you should do your due dilligence: http://developer.android.com/resources/articles/live-wallpapers.html
If I'm wrong, then please be more precise in your question.
Related
I want to use booth SDL and gles 1 on Android using a native activity.
SDL offers a function to create an OpenGL-context( SDL_GL_CreateContext ).
Clearing the screen and swapping the buffer works, but every draw-attempt fails.
To make sure, that i made nothing wrong, i made the drawing-attempt as small as possible.
Here is the small sample.
// creating OpengGL-context [...]
while (true) // basic mainloop
{
// set viewport and projectionmatrix
glViewport(0, 0, engine->getWidth(), engine->getHeight()); // width and height in pixels
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrthof(-1, 1, 1, -1, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
//draw shape
GLfloat vertices[] = {1,0,0, 0,1,0, -1,0,0};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
}
// free memory [...]
The problem is now that nothing is drawn. But my OpenGL-context is valid.
Any help would be appreciated :)
Thanks
Edit:
I actually forgot to force OpenGL 1, using
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
To add some lightning to my OpenGL ES20 cube, I need to calculate the normals for each plane. I've found a "tutorial" on lightning, but they simply hard-coded the normals into the cube, which appears to me as not the best option, since it seems limited?
So my approach to the cube is as follows:
private float[] mVertices = {
-1, -1, -1, // bottom left
1, -1, -1, // bottom right back
1, 1, -1, // top right
-1, 1, -1, // top left
-1, -1, 1, // bottom left
1, -1, 1, // bottom right front
1, 1, 1, // top right
-1, 1, 1 // top left
};
private float[] mColors = {
0.6f, 0f, 0.6f,
0.6f, 0f, 0.6f,
0.6f, 0f, 0.6f,
0.6f, 0f, 0.6f,
0.8f, 0f, 0.6f,
0.8f, 0f, 0.6f,
0.8f, 0f, 0.6f,
0.8f, 0f, 0.6f
};
private float[] mNormal = new float[?]; ?
private short[] mIndices = {
0, 4, 5,
0, 5, 1,
1, 5, 6,
1, 6, 2,
2, 6, 7,
2, 7, 3,
3, 7, 4,
3, 4, 0,
4, 7, 6,
4, 6, 5,
3, 0, 1,
3, 1, 2
};
i.e. i have all 8 vertices defined as well as indices, on how to combine them to triangles.
To get the normal matrix, I've read that I am supposed to invert the matrix, then transpose it. So I've tried this:
float[] mTempMatrix = new float[mVertices.length];
Matrix.invertM(mTempMatrix, 0, mVertices, 0);
Matrix.transposeM(mNormal, 0, mTempMatrix, 0);
But this is always filled with zeros, and my cube stays black. How example am I supposed to calculate the normal matrix? Should it be something with the model matrix? If yes, where am I supposed to do this, since the only place they are really combined is in the shader? Is there another way to do this which would be more appropriate?
The issue you are facing is that you share vertices between cube faces. The normal is a vector that points othogonal to the plane of the surface.
Consider the top/right/front vertex as an example (that you share with the front, right and top faces).
When used on the front face, the normal needs to point towards you as 0, 0, 1
When used on the right face, the normal needs to point to the right as 1, 0, 0
When used on the top face, the normal needs to point up as 0, 1, 0
So how to reconcile that?
You could set the normal for the vertex to point out from the corner, e.g. as 0.707, 0.707, 0.707. That'll most likely give you an interesting lighting effect on the corner but is probably not what you're after.
The other solution is not to re-use the vertices between faces. So you'll need 24 (4 per side) instead of 8. You'll then have 3 versions of each vertex but each one of those now belongs to just one face, hence you can set the normal vector as perpendicular to that face. You'll also be able to set the color for just that face as well since you'll no longer be sharing the vertex with other faces.
I'm trying to work on some OpenGL stuff. What I've got up to now is a viewport, in which I'm drawing some imaginary "borders" by using GL_LINES. It looks like this, with setLookAt set as follows:
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 5, 0, 0, 0, 0, 1, 0);
My frustum is set: Matrix.frustumM(mProjectionMatrix, 0, -2, 2, -2, 2, 1, 11); so I'm positioned somewhere inside the "cube".
Now what I'm trying to achieve is let the user look around. I'm capturing onTouchEvents, passing any movement in x/y direction to the renderer. What I'm doing next is rotating all lines drawn by the specific angle I received from the touch listener.
It then looks like this:
So the cube is not rotated around the viewer or the eye-center, but instead around some point that I don't know where it's coming from.
My problem is: how can I rotate the object around the viewer's center/position? Do I have to rotate the mViewMatrix which comes from setLookAtM? If yes, simply by using Matrix.setRotateM(mViewMatrix, ...)?
The Line's drawing method looks like this:
public void draw(float[] mViewMatrix, float[] mProjectionMatrix) {
Matrix.multiplyMM(mViewProjectionMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
GLES20.glUseProgram(iProgId);
lineBuffer.position(0);
GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, lineBuffer);
GLES20.glEnableVertexAttribArray(iPosition);
colorBuffer.position(0);
GLES20.glVertexAttribPointer(iColor, 3, GLES20.GL_FLOAT, false, 0, colorBuffer);
GLES20.glEnableVertexAttribArray(iColor);
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.rotateM(mModelMatrix, 0, rotX, 1, 0, 0);
Matrix.rotateM(mModelMatrix, 0, -rotY, 0, 1, 0);
Matrix.setIdentityM(mViewProjectionMatrix, 0);
Matrix.multiplyMM(mViewProjectionMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
//GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, mMVPMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewProjectionMatrix, 0);
GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, mMVPMatrix, 0);
//GLES20.glDrawElements(GLES20.GL_LINES, mVertices.length/2, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
GLES20.glDrawArrays(GLES20.GL_LINES, 0, mVertices.length / 2);
}
look at function takes 3 vertices, eye position, target position and up vector. Basically it generates a matrix that moves scene around to render scene like you are looking from eye position to target position. In your example your is at 0,0,0 and looks at 5, 0, 0 (so you are looking at +x direction and up is defined as 0, 1, 0 (higher y value means object will be at top of window.)
Instead of using those constants, first define a camera position.
float cameraX, cameraY, cameraY;
it is harder to work with target vectors, so instead use an angle that defines which direction you are looking at
float angle;
and to calculate targetVector use this angle.
float targetX = cameraX + cos(angle);
float targetY = cameraY;
float targetZ = cameraZ + sin(angle);
Now to move camera around, you have to modify cameraX-Y-Z. If you want to move forward you should move your camera towards to target vector. For example to move 10 unit forward.
targetX += cos(angle)*10;
targetY += sin(angle)*10;
You also need to recalculate target vector since target position also should move.
If you want to move backwards, use -= operator instead. If you want to move sides then you have to add or remove angle PI/2 in those calculations.
To rotate camera around just increase/decrease angle and recalculate target vector.
This is a very basic camera and you won't be able to look up or down. You have to use pitch/yaw camera to be able to look up and down.
I am trying to display a texture on a square using opengl es 1 using the ndk.
I am using this "hacks" to load a png from the apk : http://www.anddev.org/ndk_opengl_-_loading_resources_and_assets_from_native_code-t11978.html
This seems to work fine.
When i want to apply the texture to my quad, the texture seems to be duplicate.
After some research i think the problem is coming from my rendering code :
//the order is correct even if it is not in the numeric order
GLfloat vertexBuffer[] = {
_vertices[0].x, _vertices[0].y,
_vertices[3].x, _vertices[3].y,
_vertices[1].x, _vertices[1].y,
_vertices[2].x, _vertices[2].y,
};
GLfloat texCoords[] = {
0.0, 1.0, // left-bottom
1.0, 1.0, // right-bottom
0.0, 0.0, // left-top
1.0, 0.0 // right-top
};
glBindTexture(GL_TEXTURE_2D, _texture->getTexture());
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, 0);
The problem was definitly is the png loading function.
I add a test to check if the image contain an alpha channel using the libpng :
bool hasAlpha;
switch (info_ptr->color_type) {
case PNG_COLOR_TYPE_RGBA:
hasAlpha = true;
break;
case PNG_COLOR_TYPE_RGB:
hasAlpha = false;
break;
default:
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
zip_fclose(file);
return TEXTURE_LOAD_ERROR;
}
And i changed the glTexImage2D parameters "internalformat" and "format":
glTexImage2D(GL_TEXTURE_2D, 0, hasAlpha ? GL_RGBA : GL_RGB, width, height, 0, hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*) image_data);
I am trying to write code that will cycle between rendering an animation and rendering a heads up display. The animation works, however I am having difficulty switching between the animation's projection matrix and another orthographic projection matrix for the HUD.
The main loop runs as follows:
init();
while (isAnimationRunning) {
drawAnimation();
drawHUD();
}
And the initialization of the surface is:
void init(){
glEnableClientState(GL10.GL_VERTEX_ARRAY);
glClearColor(1, 1, 1, 1);
glMatrixMode(GL11.GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, windowWidth, windowHeight);
GLU.gluPerspective(gl11, 45.0f, windowWidth / windowHeight, 0.1f, 100.0f);
}
And the code for the animation rendering
void drawAnimation() {
glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL10.GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(gl11, x, y, zoom, x, y, 0, 0, 1, 0);
drawAnimationTextures();
}
And the code for the HUD rendering
void drawHUD(){
glMatrixMode(GL10.GL_MODELVIEW);
glPushMatrix();
// IF THIS LINE IS REMOVED THE ANIMATION DISPLAYS BUT NOT THE HUD
glLoadIdentity();
glClear(GL10.GL_COLOR_BUFFER_BIT);
GLU.gluLookAt(gl11, 0, 0, 2, 0, 0, 0, 0, 1, 0);
glMatrixMode(GL10.GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
GLU.gluPerspective(gl11, 45, aspectRatio, 0.1f, 100.0f);
glOrthof(-aspectRatio, aspectRatio, -1, 1, -4, 4);
drawHUDTexture();
glPopMatrix();
glMatrixMode(GL10.GL_MODELVIEW);
glPopMatrix();
}
The screen is blank when this code is implemented. Any ideas what the problem might be?
////////////////////////
void drawTexture(float x, float y, float z, float sizeX, float sizeY,...){
glEnable(GL10.GL_TEXTURE_2D);
glPushMatrix();
bindTexture(texture);
glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
glFrontFace(GL10.GL_CW);
glColor4f(RGB[0], RGB[1], RGB[2], alpha);
glTranslatef(x, y, z);
glScalef(sizeX, sizeY, sizeZ);
glVertexPointer(3, GL10.GL_FLOAT, 0, squareVertexBuffer);
glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
}
Why are you clearing the framebuffer in both routines? You should call it once only in your top level loop. If the animation appears when you comment out the loadidentity but still have the glclear there I am puzzled.
It looks like the hud overwrites the whole screen, make it semi transparent to check this, it may be so large you're just seeing a small part of it.
plus your hud code is setting up a perspective view, then an ortho view - which one do you want?