Snake 3D why does this work?

Started by
2 comments, last by arka80 10 years, 4 months ago

Hello. After some time i have noticed that the rendering method i use is not to handy nor easy to understand

Instead of moving the entire world to the camera i would like the camera to move around instead.

This is my first game and its very early in development(you can only steer the snake now :D).

Here are functions i use to render the world:


  public void render() {
        this.clearScreen();
        this.renderGrid();
        this.rederSnake();
    }
    private void clearScreen(){
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0f, 0f, 0f, 0f);
        glLoadIdentity();
    }
    private void renderGrid(){
        //set up the camera
        glTranslatef(0, 0, -35);
        glRotatef(35, 1f, 0f, 0f);
        //rotate the snake and the camera
        glRotated(snakeRotationAngle, 0, 1f, 0);
        glTranslatef(-(level.getSnake().getPosX() * squareSize + (squareSize/2)), 0, (level.getSnake().getPosZ() * squareSize - (squareSize/2)));
        //render the grid
        glColor3f(0.5f, 0f, 0.5f);
        glBegin(GL11.GL_QUADS);
            for(int j = 0; j<level.getGrid().getzSize();j++){
                for(int i = 0; i<level.getGrid().getxSize();i++){
                    glVertex3f(i * squareSize + squareBorder,0,-(j+1) * squareSize + squareBorder);
                    glVertex3f(i * squareSize + squareBorder,0,-j * squareSize - squareBorder);
                    glVertex3f((i+1) * squareSize - squareBorder,0,-j * squareSize - squareBorder);
                    glVertex3f((i+1) * squareSize - squareBorder,0,-(j+1) * squareSize + squareBorder);
                }
            }
        glEnd();
    }
    private void rederSnake(){
        glLoadIdentity();
        glTranslatef(-squareSize/2, -squareSize/2, -20);
        glRotatef(35, 1, 0, 0);
        this.rotation += 6;
        if (rotation % 360 == 0)
            rotation = rotation %360;
        glTranslatef(squareSize/2, 0, -1.5f);
        glRotatef(rotation, 0f, 0f, 1f);
        glTranslatef(0f, 0f, -1.5f);
 
 
        glBegin(GL11.GL_TRIANGLES);
            GL11.glColor3f(0f,0.13333333f,0.4f);//royal blue 5
            GL11.glVertex3f(headXCoords[0], headYCoords[0], -0.5f);
            GL11.glVertex3f(headXCoords[1], headYCoords[1], -0.5f);
            GL11.glVertex3f(0, 0, -3.5f);
 
 
            GL11.glColor3f(0.152941f,0.250980f,0.5450980f);//royal blue 4
            GL11.glVertex3f(headXCoords[1], headYCoords[1], -0.5f);
            GL11.glVertex3f(headXCoords[2], headYCoords[2], -0.5f);
            GL11.glVertex3f(0, 0, -3.5f);
 
 
            GL11.glColor3f(0.22745098f,0.3725490196f,0.80392156863f);//royal blue 3
            GL11.glVertex3f(headXCoords[2], headYCoords[2], -0.5f);
            GL11.glVertex3f(headXCoords[3], headYCoords[3], -0.5f);
            GL11.glVertex3f(0, 0, -3.5f);
 
 
            GL11.glColor3f(0.282352941f,0.462745098f,1f);//royal blue 1
            GL11.glVertex3f(headXCoords[3], headYCoords[3], -0.5f);
            GL11.glVertex3f(headXCoords[4], headYCoords[4], -0.5f);
            GL11.glVertex3f(0, 0, -3.5f);    
 
 
            GL11.glColor3f(0.25490196f,0.4117647f,1f);//royal blue
            GL11.glVertex3f(headXCoords[4], headYCoords[4], -0.5f);
            GL11.glVertex3f(headXCoords[5], headYCoords[5], -0.5f);
            GL11.glVertex3f(0, 0, -3.5f);
 
 
            GL11.glColor3f(0,0,1f);// blue
            GL11.glVertex3f(headXCoords[5], headYCoords[5], -0.5f);
            GL11.glVertex3f(headXCoords[0], headYCoords[0], -0.5f);
            GL11.glVertex3f(0, 0, -3.5f);
        GL11.glEnd();
    }

I am aware that there is better way of sending the vertices, but i feel like doing it this way for now.

So i have modified this code and i deleted all the rotations and translation from around the functions and i added a new one that does the camera steering:


//everything is drawn on x and z axes, so y is the height.
private void setUpCamera(){
   glRotatef(45, 1, 0, 0);
   //rotation 45 degrees around the x axis
   glRotatef(snakeRotationAngle, 0, 1, 0);
   //rotation n degrees around the y axis(player steering)
   glTranslatef(-squareSize * this.level.getSnake().getPosX() - squareSize/2 + squareBorde   r, -25, squareSize * this.level.getSnake().getPosZ() - 25);
   //I translate the snake to the center of a square and to its position.
} 

My question is: if im rotating the camera 45 degrees, and afterwards i move away from 0,0,0 by posX and posZ, the camera should be in the air looking at the grid at 45 degrees angle on height (simplified posZ = 0) posX * tan(45).

Why does this code work? And why do i have to translate the camera 25 up to see something(i got this after some trial and error)?

Advertisement

Or maybe somebody has a better way of doing this?

I would use real matrices instead of playing around with OpenGL's functions to modify the current matrix. It makes code much more cleaner and helps you later with newer OpenGL versions where you don't have those functions.

I would set the camera like this:


mat4 camera_transform = translate(snake.position) * rotate_x(angle) * translate(0, 0, distance);

Now the camera should be looking at the snake's position with the specified angle and distance.

Take the inverse of it to get the view matrix:


mat4 view_matrix = inverse(camera_transform);

And rendering could be done like this then:


// Load projection matrix
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(projection_matrix);

// Load view matrix
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(view_matrix);

// Render an apple
glPushMatrix();
glMultMatrixf(apple.transform);
render(apple);
glPopMatrix();

Hope this helps.

Derp

I'm a bit rusty at opengl, but I think with glRotate without push/pop you are rotating the whole world, not only the camera, hence your strange camera behaviour

This topic is closed to new replies.

Advertisement