Jump to content

  • Log In with Google      Sign In   
  • Create Account


Snake 3D why does this work?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 jammasterz   Members   -  Reputation: 104

Like
0Likes
Like

Posted 06 December 2013 - 04:53 PM

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)?



Sponsor:

#2 jammasterz   Members   -  Reputation: 104

Like
0Likes
Like

Posted 11 December 2013 - 01:46 PM

Or maybe somebody has a better way of doing this?



#3 Sponji   Members   -  Reputation: 1225

Like
1Likes
Like

Posted 12 December 2013 - 01:19 AM

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.


Edited by Sponji, 12 December 2013 - 01:19 AM.

Derp

#4 arka80   Members   -  Reputation: 799

Like
0Likes
Like

Posted 18 December 2013 - 11:24 AM

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






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS