Ir ao conteúdo
  • Cadastre-se

Posts recomendados

Pseudo 3D


 


Olá a todos. Falarei a respeito de algo interessante na programação, o pseudo 3D. O Pseudo 3D é um método utilizado para renderização de um ambiente com uma sensação de profundidade (eixo Z) porém o efeito é apenas ilusão.


Este método de renderização era utilizado em muitos jogos antigos como por exemplo, os jogos de corrida onde a pista da corrida parecia ter uma profundidade.


curves1.png


 


 


Existem tipos parecidos de renderização como o "Mode 7" onde a renderização já possui mais recursos como por exemplo, a Rotação.


Mode_7_Test-0000.png


 


Gostaria de falar a respeito com o pessoal do forum, para pedir se alguém possui algum material explicativo ou algum tutorial onde ensine o básico sobre esta renderização.


Bem bacana ter conhecimento para ver como na realidade funciona o openGL por baixo dos panos. 


 


Sei que deve existir uma lógica bem básica para isto e quero aprender, para assim, programar algo em JAVA. 


 


Gostaria também de saber se existe um nome específico para este tipo de renderização.


 


Código:


Podemos utilizar uma simples JFrame em java, criar um Thread, más a lógica para que possamos gerar este eixo Z, e movimentar as faixas geradas para dar impressão 3D é o que preciso.


O assunto é um pouco complicado para ser encontrado na internet, más o que achei foi o conteúdo deste site, porém ainda sim é um tanto complexo a explicação.


http://www.extentofthejam.com/pseudo/


 


Se puderem disponibilizar algo básico em java com esta lógica utilizada ajudará muito.


 


 


Evolução:


Tentei reproduzir um efeito simples em Pseudo3D da mesma forma utilizar para estes jogos antigos. Obtive o seguinte resultado:


GxTAY5b.gif



package pseudo3d;

/**
*
* @author Vinicius
*/
public class Pseudo3D {

public static void main(String[] args) {

new Tela();

}
}


package pseudo3d;

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

/**
*
* @author Vinicius
*/
public class Tela extends JFrame implements Runnable, KeyListener{

//Constantes - Tamanho
public static final int LARGURA = 800;
public static final int ALTURA = 600;
public static final int CENTRO_LARGURA = LARGURA / 2;
public static final int CENTRO_ALTURA = ALTURA / 2;

//Constantes - Evento
public static final int PARADO = 0;
public static final int CIMA = 1;
public static final int BAIXO = 2;
public static final int ESQUERDA = 3;
public static final int DIREITA = 4;

//Atributos - Imagem
private BufferedImage imagem;
private Graphics grafico;
private Render3D render3D;

//Atributos - Evento
private int evento = PARADO;
private int deslocamentoX = 0, deslocamentoZ = 0;

/*
* Construtor
*/
public Tela()
{
this.setTitle("Pseudo-3D v1.0");
this.setSize(LARGURA, ALTURA);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.addKeyListener(this);
this.setVisible(true);

this.imagem = new BufferedImage(LARGURA, ALTURA, BufferedImage.TYPE_INT_RGB);
this.grafico = this.imagem.getGraphics();

new Thread(this).start();
}

/**
* Calcular fps do sistema.
* <p>
* <code>long tempo = System.currentTimeMillis(); </code>
* <p>
* <code>while(System.currentTimeMillis() - tempo < 30);</code>
*/
public void fps()
{
long tempo = System.currentTimeMillis();

while(System.currentTimeMillis() - tempo < 30);

//System.out.println("fps: " + (System.currentTimeMillis() - tempo));
}

/**
* Verificar evento de movimentação.
* Irá realizar validação de limite.
*/
private void evento()
{
switch(this.evento)
{
case CIMA: this.deslocamentoZ++; break;
case ESQUERDA: this.deslocamentoX-= 40; break;
case DIREITA: this.deslocamentoX+= 40; break;
}

if(deslocamentoZ > 5)
{
deslocamentoZ = 0;
}
}

@[member=override]
public void run()
{
this.render3D = new Render3D(this);

while(true)
{
this.fps();

this.render3D.renderTeto(deslocamentoZ);
this.render3D.renderPiso(deslocamentoZ);
this.render3D.renderProfundidadeTeto(deslocamentoX);
this.render3D.renderProfundidadePiso(deslocamentoX);

this.repaint();

this.evento();
}
}

@[member=override]
public void keyTyped(KeyEvent e)
{
}

@[member=override]
public void keyPressed(KeyEvent e)
{
switch(e.getKeyCode())
{
case KeyEvent.VK_UP: this.evento = CIMA; break;
case KeyEvent.VK_DOWN: this.evento = BAIXO; break;
case KeyEvent.VK_LEFT: this.evento = ESQUERDA; break;
case KeyEvent.VK_RIGHT: this.evento = DIREITA; break;
}
}

@[member=override]
public void keyReleased(KeyEvent e)
{
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:
case KeyEvent.VK_DOWN:
case KeyEvent.VK_LEFT:
case KeyEvent.VK_RIGHT:
this.evento = PARADO; break;
}
}

@[member=override]
public void paint(Graphics g)
{
g.drawImage(this.imagem, 0, 0, this);
}

/*
* Get e Set
*/
public BufferedImage getImagem() {
return imagem;
}

public void setImagem(BufferedImage imagem) {
this.imagem = imagem;
}

public Graphics getGrafico() {
return grafico;
}

public void setGrafico(Graphics grafico) {
this.grafico = grafico;
}
}



package pseudo3d;

import java.awt.Color;

/**
*
* @author Vinicius
*/
public class Render3D {

//Atributos - Imagem
private Tela tela;

/**
* Construtor da classe. Passar uma tela para que seja renderizado
* as linhas bidimensionais.
* @param tela
*/
public Render3D(Tela tela)
{
this.tela = tela;
}

/**
* Renderizar Teto na tela em perpectiva. Passar como parâmetro o deslocamento.
* Passar 0 como valor do parâmetro para não fornecer deslocamento.
* <p>
* Utilizará variável "Z" para calcular a profundidade
* @param deslocamento
*/
public void renderTeto(int deslocamento)
{
int z = 2 + deslocamento;

for(int i = this.tela.CENTRO_ALTURA; i >= 0; i--)
{
if(i == (this.tela.CENTRO_ALTURA - z))
{
this.tela.getGrafico().setColor(Color.BLACK);
z *= 2;
}
else
{
this.tela.getGrafico().setColor(Color.GRAY);
}

this.tela.getGrafico().drawLine(0, i, this.tela.LARGURA, i);
}
}

/**
* Renderizar Piso na tela em perpectiva. Passar como parâmetro o deslocamento.
* Passar 0 como valor do parâmetro para não fornecer deslocamento.
* <p>
* Utilizará variável "Z" para calcular a profundidade
* @param deslocamento
*/
public void renderPiso(int deslocamento)
{
int z = 2 + deslocamento;

for(int i = this.tela.CENTRO_ALTURA; i < this.tela.ALTURA; i++)
{
if(i == (this.tela.CENTRO_ALTURA + z))
{
this.tela.getGrafico().setColor(Color.BLACK);
z *= 2;
}
else
{
this.tela.getGrafico().setColor(Color.DARK_GRAY);
}

this.tela.getGrafico().drawLine(0, i, this.tela.LARGURA, i);
}
}

/**
* Renderizar profundidade do Teto na tela em perpectiva. Passar como parâmetro o deslocamento.
* Passar 0 como valor do parâmetro para não fornecer deslocamento.
* <p>
* Utilizará variável "Z" para calcular a profundidade
* @param deslocamento
*/
public void renderProfundidadeTeto(int deslocamento)
{
this.tela.getGrafico().setColor(Color.BLACK);

for(int i = (this.tela.ALTURA * this.tela.LARGURA) * -1; i < (this.tela.LARGURA * this.tela.ALTURA); i++)
{
if((i + deslocamento) % 600 == 0)
{
this.tela.getGrafico().drawLine(i, 0, this.tela.CENTRO_LARGURA, this.tela.CENTRO_ALTURA);
}
}
}

/**
* Renderizar profundidade do Piso na tela em perpectiva. Passar como parâmetro o deslocamento.
* Passar 0 como valor do parâmetro para não fornecer deslocamento.
* <p>
* Utilizará variável "Z" para calcular a profundidade
* @param deslocamento
*/
public void renderProfundidadePiso(int deslocamento)
{
this.tela.getGrafico().setColor(Color.BLACK);

for(int i = (this.tela.ALTURA * this.tela.LARGURA) * -1; i < (this.tela.LARGURA * this.tela.ALTURA); i++)
{
if((i + deslocamento) % 600 == 0)
{
this.tela.getGrafico().drawLine(i, this.tela.ALTURA, this.tela.CENTRO_LARGURA, this.tela.CENTRO_ALTURA);
}
}
}
}


Obs:


Já fiz uma postagem no fórum referente a técnicas de renderização em 3D utilizando Ray Casting, e o que encontrei na internet foi um tutorial super complexo. Procurei até demais para encontrar uma simples classe java que me ajudasse a aprender, com um código básico, simples e muito melhor que o código complexo.


Estou aqui para solicitar algo básico e se puderem ajudar :rolleyes:  estarei grato. 


 


 


Demonstração:


Este app foi desenvolvido por um gringo. Feito em javascript, e por possuir muitos recursos, não ficou bom para ter uma noção e sim, bom para se perder no código.


http://codeincomplete.com/projects/racer/v1.straight.html


Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!