Optymalizacja metody renderującej w OpenGL

0

Cześć. Pisałem już na podobne tematy kilka razy. Mam kilka rozwiązań, problem w tym że nie są one za ładne, przynajmniej dla mnie. A więc, chciałbym prosić o pomoc w doprowadzeniu tego kodu do porządku.

 
	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();
	}

Na początku od razu chciałbym powiedzieć, że wiem że to nie jest najefektywniejsza metoda renderowania. W przyszłości mam zamiar użyć funkcji które wysyłają całe tablice vertexów, ale nie zapoznałem się jeszcze wystarczająco z tym jak to zrobić w javie.

Pierwszy problem to obroty i tłumaczenia na początku obydwu funkcji. Wydaje mi się że jest ich za dużo i że da się to zrobić o wiele łatwiej. Ale to tylko moje przeczucie.

Drugi problem, ktory jest nieco poważniejszy to że kod nie do końca działa tak jak powinien. Koordynaty w head*Coords[] generowane są następująco:

 private void computeSnakeModel(){
		final float regulation = 0.5f;
		float theta = 2 * (float)Math.PI / 6;
		int radius = this.level.getSnake().getSize() * regulation;
		for (int i = 0; i < 6;i++){
			headXCoords[i] = (float) (Math.cos(theta * (i + 1)) * radius);
			headYCoords[i] = (float) (Math.sin(theta * (i + 1)) * radius);
		}
	}

Potem renderuje je na osi x i y i obracam na osi z w środku sześciokąta. Ale na ekranie wygląda to inaczej. Sześciokąt renderowany jest na osi x i z, a obracany na osi y. Czyli jakby całość była obrócona o 90 stopni w górę. Nie mam pojęcia co to powoduje.

0

Czy coś jest nie tak? Jeśli sa jakieś błędy albo jak czegoś nie da sie w temacie zrozumieć to moge to poprawic.

0

Cześć. Sorry za nekrofilię ale chyba lepsze to niż zakładanie nowego tematu na ten sam temat.

Po jakimś czasie zauważyłem że moja metoda renderowania nie jest zbyt wygodna ani łatwa do zrozumienia.
Zamiast przesuwać cały świat do kamery chciałbym żeby to kamera była ruchoma.

Usunąłem wszelkie translaty i rotaty z funkcji renderGrid i renderSnake i dodałem nową która zamiast tego wszystkiego steruje kamerą:

 
        //wszystko jest rysowane na osiach x i z. y to wysokosc.
	private void setUpCamera(){
		glRotatef(45, 1, 0, 0);
                //obracam o 45 stopni wokół osi x
		glRotatef(snakeRotationAngle, 0, 1, 0);
                //obracam o n stopni wokół y(czyli obracanie graczem)
		glTranslatef(-squareSize * this.level.getSnake().getPosX() - squareSize/2 + squareBorder, -25, squareSize * this.level.getSnake().getPosZ() - 25);
                //przesuwam na srodek kwadratu i do pozycji i na pozycje weza
	}

Moje pytanie: skoro obracam kamerę o 45 stopni, po czym odsuwam się od 0,0,0 o posX, posZ, kamera powinna wisieć w powietrzu patrząc na plansze pod katem 45 stopni na wysokości(upraszczając posZ = 0) posX * tan (45).
Dlaczego ten kod działa?

1 użytkowników online, w tym zalogowanych: 0, gości: 1