i am working on a program which draws polygons according to user inputs.
I have problems with drawing triangles using GL_TRIANGLE. I used the same code below to draw square and it worked well. Hovewer, if i want to draw only one triangle it does not work.
Can anyone help me?
public class Triangle extends Shape{
private FloatBuffer vertexBuffer;
private FloatBuffer _colorBuffer;
private ShortBuffer indexBuffer;
private float vertices[] = {
-0.5f, -0.5f, 0.5f, // 0
0.5f, -0.5f, 0.5f, // 1
0f, -0.5f, -0.5f, // 2
};
private short[] indices = { 0, 2, 1 };
float[] colors = {1f, 1f, 0f, 1f };
public Triangle() {
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
_colorBuffer = cbb.asFloatBuffer();
_colorBuffer.put(colors);
_colorBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
}
edit:
i call my Triangle class from here, maybe i have made mistake here
public class OpenGLRenderer implements Renderer {
String name;
ArrayList myArr ;
private float angle, x,y,z;
public OpenGLRenderer(String nm ) {
name =nm;
myArr = new ArrayList<Shape>();
x=0;
y=0;
z=-3;
}
@Override
public void onDrawFrame(GL10 gl) {
//clear the screen and depth buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(x, y, z);
for (Shape t : myArr)
{
if (t instanceof Rectangle)
{
// gl.glTranslatef(0, 0, -4);
((Rectangle )t).draw(gl);
}
if (t instanceof Square)
{ //gl.glTranslatef(0, 1, 0);
((Square )t).draw(gl);}
if (t instanceof Pyramid){
((Pyramid)t).draw(gl);
if (t instanceof Triangle){
((Triangle)t).draw(gl);
}
if (t instanceof Line){
((Line)t).draw(gl);
}
}
}//for
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity(); //reset the projection matrix
GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,
0.1f, 100.0f); //calculate the aspect ratio of window
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//set the bg as black
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glShadeModel(GL10.GL_SMOOTH);
//depth buffer setup
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
public void addshape(Shape s)
{y=y+0.1f;
myArr.add(s);
}
}
First, Martin is correct about the
colorsarray. It needs to have a color (4 values in your case) for every vertex (so 12 values at all).Next, at the moment your triangle lies inside the x-z-plane and as you don’t make any changes to the modelview matrix (except translating along the z-axis), you should just see a line, if any, (think of a sheet of paper viewed from the side).
But your real problem is your draw loop. I guess you’re not only new to OpenGL, but also to Java and object oriented programming in general. This whole design is complete rubbish. That’s what virtual functions are for in object oriented code. Just let each shape implement its correct
drawmethod. So the only thing you need to do isGiven that
Shapehas an abstractdrawmethod, that the other subclasses implement. But this is more of a design flaw. The actual error is, that the braces of theifs are broken. At the moment the triangle is only drawn, iftis an instance ofPyramidand ofTriangle, sodrawis never called for triangles (and also for lines).