OpenGL - glClear() not clearing... possibly

I’m trying to animate a quad in 2D space that has a texture applied to it, but its as if its not clearing (glClear is DEFINITELY being called before each render) or maybe its making a new quad each time, I don’t know.

anyway, instead of a moving square, I get this:

here is my run() method:

private void run() {
		isRunning = true;

		int frames = 0;
		long frameCounter = 0;

		final double frameTime = 1.0 / FRAME_CAP;

		long lastTime = Time.getTime();
		double unprocessedTime = 0;

		while (isRunning) {

			boolean render = false;

			long startTime = Time.getTime();
			long passedTime = startTime - lastTime;
			lastTime = startTime;

			unprocessedTime += passedTime / (double) Time.SECOND;
			frameCounter += passedTime;

			while (unprocessedTime > frameTime) {
				render = true;
				unprocessedTime -= frameTime;

				if (Window.isCloseRequested()) {
					stop();
				}

				Time.setDelta(frameTime);
				Input.update();

				game.input(); // IMPORTANT
				game.update(); // IMPORTANT

				if (frameCounter >= Time.SECOND) {
					System.out.println(frames);
					frames = 0;
					frameCounter = 0;
				}
			}

			if (render) {
				render(); // IMPORTANT
				frames++;
			} else {
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

		cleanUp();
	}

here is my RenderUtil class, which contains static methods such as clearScreen() and initGraphics():

public static void clearScreen(){
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER); //Although it is 2D, I might want to add some depth later on ;)
	}
	
	public static void initGraphics(int WIDTH, int HEIGHT){
		glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
		
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
		glMatrixMode(GL_MODELVIEW);
		glEnable(GL_TEXTURE_2D);
	}
	
	public static String getOpenGLVersion(){
		return glGetString(GL_VERSION);
	}

and here is what I do in render():

private void render() {
		clearScreen();
		game.render();
		Window.render(); // quite simply, Display.update();

	}

this is a part of my Game class


public void render(){
		sprite.render();
	}
	
	public void update(){
		if (Input.getKey(Input.KEY_A)){
			sprite.setPos(sprite.getPos().getX() - 0.25f, sprite.getPos().getY());
		}
		if (Input.getKey(Input.KEY_D)){
			sprite.setPos(sprite.getPos().getX() + 0.25f, sprite.getPos().getY());
		}
		if (Input.getKey(Input.KEY_S)){
			sprite.setPos(sprite.getPos().getX(), sprite.getPos().getY() - 0.25f);
		}
		if (Input.getKey(Input.KEY_W)){
			sprite.setPos(sprite.getPos().getX(), sprite.getPos().getY() + 0.25f);
		}

And crucially, the actual rendering, the Sprite class.


private Vector2f pos;
	private int size;
	
	//which animation the sprite has
	private int i;
	private int j;
	
	private Texture texture;
	
	public Sprite(String name, int size){
		i = 0;
		j = 0;
		this.size = size;
		pos = new Vector2f(0,0);
		
		try{
			texture = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/" + name + ".png")));
		} catch (IOException e){
			e.printStackTrace();
		}
		
	}
	
	public void render(){
		
                //IMPORTANT
                //should I be doing glBegin --coordinate stuff-- glEnd every render()? 

		texture.bind();
		
		glBegin(GL_QUADS);

                // this is just a bit of square math to determine which tile of a spritesheet the quad should display.
		
			//BL
			glTexCoord2f(i * 0.25f, (j+1) * 0.25f);
//			glTexCoord2f(0, 1); of the tile
			glVertex2f(pos.getX(), pos.getY());
			//BR
			glTexCoord2f((i+1) * 0.25f, (j+1) * 0.25f);
//			glTexCoord2f(1,1); of the tile
			glVertex2f(pos.getX() + size, pos.getY());
			//TR
			glTexCoord2f((i+1) * 0.25f, j * 0.25f);
//			glTexCoord2f(1,0); of the tile
			glVertex2f(pos.getX() + size, pos.getY() + size);
			//TL
			glTexCoord2f(i * 0.25f, j * 0.25f);
//			glTexCoord2f(0,0); of the tile
			glVertex2f(pos.getX(), pos.getY() + size);
			
		glEnd();

	}
	
	public Vector2f getPos(){
		return pos;
	}
	
	public void setPos(Vector2f r){
		pos = r;
	}
	
	public void setPos(float x, float y){
		pos.setX(x);
		pos.setY(y);
	}

	public int getI() {
		return i;
	}

	public void setI(int i) {
		this.i = i;
	}

	public int getJ() {
		return j;
	}

	public void setJ(int j) {
		this.j = j;
	}

so when rendering my “sprite” should I be doing glBegin --coordinates-- glEnd every render cycle? Does this create an entirely new quad as well as the old one? that’s the only possible problem that I can see.

Yes, unless you’re using display lists (which upload the data once to the GPU), the you will need to call glBegin and end every frame. The other thing you could do, which would probably be better to do, would be to use glTranslatef and move your vertices instead of creating a new quad every frame.

right, I didn’t think about that, I made my own Vector engine you see, so I thought I would relate my own vectors to that ^ current system. But unless I want to do a lot of background openGL work, I think that would be a good idea XD.

Does removing GL_DEPTH_BUFFER from your clear call fix it?

it does! Why would that be? I know its not atm. but it might be necessary in the future to use 3D space.

EDIT: is it because I’m using glVertex2f in a depth space? If I used glVertex3f with any old z component this wouldn’t have happened would it?

Just taking a stab in the dark but clearing the buffer bit sorts the geometry along the Z axis, so maybe OpenGL thought that you were drawing those 2D quads on top of each other and wanted to sort them? If you look, the quad drawn most recently overlaps the quad drawn before it. But I don’t know!

I think I know why. You could try looking for error after you clear GL_DEPTH_BUFFER. I think it gives you an error. The argument is invalid probably. What you should be doing is

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

The problem was with him clearing the depth buffer in the first place. I don’t of any reason why you would need a depth buffer for “true” 2D (I.E. not isometric or 2.5D)

Damn, it took 6 posts for someone to notice it was GL_DEPTH_BUFFER_BIT not GL_DEPTH_BUFFER. One is used for a bit-field and the other is a standalone name. That’s how tricky OpenGL is :slight_smile:

Anyway, that error caused your glClear call to fail. You were never actually clearing the screen :wink:

Moral of the story is: make sure you check OpenGL for errors. You would have picked up on this much sooner.

Edit: But don’t feel bad. The actual mistake you made was minor and you are far from alone with not checking for OpenGL errors.