Entrar
Últimos assuntos
» Problemas com a caixa de diálogo, ela é pequena e as letras não cabem dentropor Rukasu777 Ontem à(s) 18:10
» Problemas com particulas
por RastaMaan Dom 12 maio 2024, 17:03
» Problema ao entrar por uma porta e voltar por ela
por aminaro Seg 06 maio 2024, 10:08
» Alguém aqui já ganha dinheiro com seus games?
por theguitarmester Ter 30 Abr 2024, 11:43
» Colisões não funcionando
por theguitarmester Ter 30 Abr 2024, 10:16
» Como ajustar velocidade de cada frame da animação no game maker
por pequetux Sex 26 Abr 2024, 16:45
» Preciso de ajuda
por AftonDuGrau Dom 21 Abr 2024, 20:18
» Como faz o evento drawn GUI, não se repetir?
por aminaro Sex 19 Abr 2024, 20:30
» PROBLEMAS COM FÍSICAS DE ÁGUA
por aminaro Ter 16 Abr 2024, 10:07
» Retorno da GMBR!!!
por Ralphed Sex 12 Abr 2024, 22:45
» JOGADOR PARANDO NO AR QUANDO ATACA
por aminaro Qua 10 Abr 2024, 13:51
» Problemas com texto interativo
por Kaaru72 Dom 07 Abr 2024, 11:31
» Erro escondido e indecifrável
por dev_gabize.azv Qui 04 Abr 2024, 10:11
» Mudar cor de apenas uma palavra
por Ralphed Sáb 30 Mar 2024, 00:39
» Procuro Programador de game maker
por Wou Sex 15 Mar 2024, 10:27
» Mod APK
por gamerainha Qua 13 Mar 2024, 06:30
» Aceito pedidos de sprites (Com exemplos meus)
por Sevilha Qua 28 Fev 2024, 12:17
» Inventário simples
por Isquilo_Roedor Qui 22 Fev 2024, 15:18
» Problemas na programaçnao de inimigo [jogo DOOM LIKE]
por Black Mirror Dom 11 Fev 2024, 13:34
» ANDROID MULTI TOUCH
por DiegoBr Dom 04 Fev 2024, 12:13
» Servidor de Discord do fórum?
por Lighter Sáb 27 Jan 2024, 17:18
» Save e Load Json
por Klinton Rodrigues Qui 25 Jan 2024, 11:12
» Colisão com mais de um objeto
por aminaro Seg 22 Jan 2024, 15:02
» Oi sou novo aqui
por Thiago Silveira Alexandre Sáb 20 Jan 2024, 20:55
» Como acessar conteudo comprado no marketplace
por macmilam Sex 19 Jan 2024, 07:42
[Delphi]Renderizando o OpenGL em um TPanel
3 participantes
Página 1 de 1
[Delphi]Renderizando o OpenGL em um TPanel
Renderizando o OpenGL em um TPanel
Bem-vindo(a), vou encinar como renderizar o OpenGL em um TPanel no formulário.
Aqui está o resultado final:
Requerimento para o tutorial:
Delphi 7 ou superior (deve funcionar com o Delphi 5 e 6 tambem).
Saber o básico de Delphi, como usar os eventos dos componentes e etc.
Agora vamos ao tutorial.
Primeiro adicione um TPanel no formulário (O Panel está localizado na aba de componentes Startand), e mude o valor da propiedade Aling para alClient.Deixe o nome como está: Panel1.
Declare nas uses a unit OpenGL que já vem incluso no delphi.
- Código:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, OpenGL;
type
TForm1 = class(TForm)
...
Em private adicione o seguinte codigo:
- Código:
rc : HGLRC; //Contexto de renderização OpenGL
dc : HDC; //Contexto de Dispositivo (Device Contex)
ElapsedTime, AppStart, LastTime : DWord;
procedure glDraw;
procedure Idle(Sender: TObject; var Done: Boolean);
Agora depois de:
var
Form1: TForm1;
implementation
{$R *.dfm}
Adicione o codigo:
- Código:
procedure TForm1.glDraw;
begin
end;
procedure Tform1.Idle(Sender: TObject; var Done: Boolean);
begin
end;
procedure glInit();
begin
end;
Deiche assim por enquanto...
No evento OnCreate do formulário deixe-o assim:
- Código:
procedure TForm1.FormCreate(Sender: TObject);
var pfd : TPIXELFORMATDESCRIPTOR;
pf : Integer;
begin
Form1.Caption:='Renderizando o OpenGL em um TPanel';
//OpenGL initialisieren
dc:=GetDC(Panel1.Handle);
//PixelFormat
pfd.nSize:=sizeof(pfd);
pfd.nVersion:=1;
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER or 0;
pfd.iPixelType:=PFD_TYPE_RGBA; //PFD_TYPE_RGBA e PFD_TYPEINDEX
pfd.cColorBits:=32;
pf :=ChoosePixelFormat(dc, @pfd); //Returns format that most closely matches above pixel format
SetPixelFormat(dc, pf, @pfd);
rc :=wglCreateContext(dc); //Rendering Context = window-glCreateContext
wglMakeCurrent(dc,rc); //Make the DC (Form1) the rendering Context
//Initialist GL environment variables
glInit;
Panel1Resize(sender); //sets up the perspective
AppStart :=GetTickCount();
//when the app has spare time, render the GL scene
Application.OnIdle := Idle;
end;
No evento OnDestroy do formulário deixe-o assim:
- Código:
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0,0);
wglDeleteContext(rc);
end;
Agora no Panel1, use o evento OnResize e deixe-o assim:
- Código:
procedure TForm1.Panel1Resize(Sender: TObject);
begin
glViewport(0, 0, Panel1.Width, Panel1.Height); //Define a viewport para a janela OpenGL
glMatrixMode(GL_PROJECTION); //Altera o modo Matrix para Projeção
glLoadIdentity(); //Reseta o visualizador (view)
gluPerspective(45.0, Panel1.Width/Panel1.Height, 1.0, 500.0); //Faz os cálculos de perspectiva. Último valor = profundidade de corte máxima
glMatrixMode(GL_MODELVIEW); //Volta para a matriz de modelagem
end;
Até agora o nosso código está assim:
- Código:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, OpenGL;
type
TForm1 = class(TForm)
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Panel1Resize(Sender: TObject);
private
{ Private declarations }
rc : HGLRC; //Contexto de renderização OpenGL
dc : HDC; //Contexto de Dispositivo (Device Contex)
ElapsedTime, AppStart, LastTime : DWord;
procedure glDraw;
procedure Idle(Sender: TObject; var Done: Boolean);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.glDraw;
begin
end;
procedure Tform1.Idle(Sender: TObject; var Done: Boolean);
begin
end;
procedure glInit();
begin
end;
procedure TForm1.FormCreate(Sender: TObject);
var pfd : TPIXELFORMATDESCRIPTOR;
pf : Integer;
begin
Form1.Caption:='Renderizando o OpenGL em um TPanel';
//OpenGL initialisieren
dc:=GetDC(Panel1.Handle);
//PixelFormat
pfd.nSize:=sizeof(pfd);
pfd.nVersion:=1;
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER or 0;
pfd.iPixelType:=PFD_TYPE_RGBA; //PFD_TYPE_RGBA e PFD_TYPEINDEX
pfd.cColorBits:=32;
pf :=ChoosePixelFormat(dc, @pfd); //Returns format that most closely matches above pixel format
SetPixelFormat(dc, pf, @pfd);
rc :=wglCreateContext(dc); //Rendering Context = window-glCreateContext
wglMakeCurrent(dc,rc); //Make the DC (Form1) the rendering Context
//Initialist GL environment variables
glInit;
Panel1Resize(sender); //sets up the perspective
AppStart :=GetTickCount();
//when the app has spare time, render the GL scene
Application.OnIdle := Idle;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0,0);
wglDeleteContext(rc);
end;
procedure TForm1.Panel1Resize(Sender: TObject);
begin
glViewport(0, 0, Panel1.Width, Panel1.Height); //Define a viewport para a janela OpenGL
glMatrixMode(GL_PROJECTION); //Altera o modo Matrix para Projeção
glLoadIdentity(); //Reseta o visualizador (view)
gluPerspective(45.0, Panel1.Width/Panel1.Height, 1.0, 500.0); //Faz os cálculos de perspectiva. Último valor = profundidade de corte máxima
glMatrixMode(GL_MODELVIEW); //Volta para a matriz de modelagem
end;
end.
- Código:
procedure glInit();
begin
glClearColor(0.0, 0.0, 0.0, 0.0); //Fundo preto
glShadeModel(GL_SMOOTH); //Permite sombreamento de cor lisa
glClearDepth(1.0); //Setup do Buffer de profundidade
glEnable(GL_DEPTH_TEST); //Habilitar buffer de profundidade
glDepthFunc(GL_LESS); //O tipo de teste de profundidade a fazer
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Calculos de perspectiva
end;
Volte ao Idle e substitua-o por este código:
- Código:
procedure Tform1.Idle(Sender: TObject; var Done: Boolean);
begin
Done := FALSE;
LastTime :=ElapsedTime;
ElapsedTime :=GetTickCount() - AppStart; //Calcula o tempo decorrido
ElapsedTime :=(LastTime + ElapsedTime) DIV 2; //Média-lo para movimentos mais suaves
glDraw(); //Desenha a cena
SwapBuffers(DC); //Mostra a cena
end;
Volte ao glDraw() e substitua-o por este código:
- Código:
procedure TForm1.glDraw;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //Limpa a tela e o buffer de profundidade
glLoadIdentity(); //Reseta o visualizador (view)
//Position
OpenGL.gluLookAt(-5, 0, 10, 0, 0, 0, 0, 1, 0); //Configura a camêra
//X Y Z
glTranslatef(0, 0, 0); //Posiciona as unidades para desenhar o objeto na posição 0 0 0
glColor3f(255, 0, 0); //Define uma cor antes de desenhar o objeto
glRotatef(ElapsedTime/3, 0, 1, 0); //Rotaciona o cubo constantemente
//Desenhar o cubo
glBegin(GL_QUADS);
//Face frontal
glNormal3f( 0.0, 0.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
//Face traseira
glNormal3f( 0.0, 0.0,-1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
//Face superior (top)
glNormal3f( 0.0, 1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
//Face inferior (buttom)
glNormal3f( 0.0,-1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
//Face direita
glNormal3f( 1.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
//Face esquerda
glNormal3f(-1.0, 0.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glEnd();
end;
Ele é responssável por desenhar toda a cena a cada frame (quadro).
Pronto, agora é só salvar, compilar e testar.
Código fonte completo:
- Código:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, OpenGL;
type
TForm1 = class(TForm)
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Panel1Resize(Sender: TObject);
private
{ Private declarations }
rc : HGLRC; //Contexto de renderização OpenGL
dc : HDC; //Contexto de Dispositivo (Device Contex)
ElapsedTime, AppStart, LastTime : DWord;
procedure glDraw;
procedure Idle(Sender: TObject; var Done: Boolean);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.glDraw;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //Limpa a tela e o buffer de profundidade
glLoadIdentity(); //Reseta o visualizador (view)
//Position
OpenGL.gluLookAt(-5, 0, 10, 0, 0, 0, 0, 1, 0); //Configura a camêra
//X Y Z
glTranslatef(0, 0, 0); //Posiciona as unidades para desenhar o objeto na posição 0 0 0
glColor3f(255, 0, 0); //Define uma cor antes de desenhar o objeto
glRotatef(ElapsedTime/3, 0, 1, 0); //Rotaciona o cubo constantemente
//Desenhar o cubo
glBegin(GL_QUADS);
//Face frontal
glNormal3f( 0.0, 0.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
//Face traseira
glNormal3f( 0.0, 0.0,-1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
//Face superior (top)
glNormal3f( 0.0, 1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
//Face inferior (buttom)
glNormal3f( 0.0,-1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
//Face direita
glNormal3f( 1.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
//Face esquerda
glNormal3f(-1.0, 0.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glEnd();
end;
procedure Tform1.Idle(Sender: TObject; var Done: Boolean);
begin
Done := FALSE;
LastTime :=ElapsedTime;
ElapsedTime :=GetTickCount() - AppStart; //Calcula o tempo decorrido
ElapsedTime :=(LastTime + ElapsedTime) DIV 2; //Média-lo para movimentos mais suaves
glDraw(); //Desenha a cena
SwapBuffers(DC); //Mostra a cena
end;
procedure glInit();
begin
glClearColor(0.0, 0.0, 0.0, 0.0); //Fundo preto
glShadeModel(GL_SMOOTH); //Permite sombreamento de cor lisa
glClearDepth(1.0); //Setup do Buffer de profundidade
glEnable(GL_DEPTH_TEST); //Habilitar buffer de profundidade
glDepthFunc(GL_LESS); //O tipo de teste de profundidade a fazer
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Calculos de perspectiva
end;
procedure TForm1.FormCreate(Sender: TObject);
var pfd : TPIXELFORMATDESCRIPTOR;
pf : Integer;
begin
Form1.Caption:='Renderizando o OpenGL em um TPanel';
//OpenGL initialisieren
dc:=GetDC(Panel1.Handle);
//PixelFormat
pfd.nSize:=sizeof(pfd);
pfd.nVersion:=1;
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER or 0;
pfd.iPixelType:=PFD_TYPE_RGBA; //PFD_TYPE_RGBA e PFD_TYPEINDEX
pfd.cColorBits:=32;
pf :=ChoosePixelFormat(dc, @pfd); //Returns format that most closely matches above pixel format
SetPixelFormat(dc, pf, @pfd);
rc :=wglCreateContext(dc); //Rendering Context = window-glCreateContext
wglMakeCurrent(dc,rc); //Make the DC (Form1) the rendering Context
//Initialist GL environment variables
glInit;
Panel1Resize(sender); //sets up the perspective
AppStart :=GetTickCount();
//when the app has spare time, render the GL scene
Application.OnIdle := Idle;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0,0);
wglDeleteContext(rc);
end;
procedure TForm1.Panel1Resize(Sender: TObject);
begin
glViewport(0, 0, Panel1.Width, Panel1.Height); //Define a viewport para a janela OpenGL
glMatrixMode(GL_PROJECTION); //Altera o modo Matrix para Projeção
glLoadIdentity(); //Reseta o visualizador (view)
gluPerspective(45.0, Panel1.Width/Panel1.Height, 1.0, 500.0); //Faz os cálculos de perspectiva. Último valor = profundidade de corte máxima
glMatrixMode(GL_MODELVIEW); //Volta para a matriz de modelagem
end;
end.
Tutorial criado por leandrohackerx.
A maioria dos códigos que eu usei aprendi na internet.
Créditos abaixo:
www.sulaco.co.za pelos tutoriais e exemplos de OpenGL.
LeandroDaher- Data de inscrição : 13/05/2010
Reputação : 3
Número de Mensagens : 357
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Delphi]Renderizando o OpenGL em um TPanel
Vlw, obrigado por compartilhar, apesar de que poucos usarão isso em delphi, visto que o fórum é mais voltado para game maker, mais conhecimento nunca é demais né, sabendo que o game maker também é feito em delphi, é bom saber como as coisas funcionam internamente.
Klior- Data de inscrição : 07/03/2010
Reputação : 13
Número de Mensagens : 426
Prêmios :
x 0 x 1 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Plataformas :- Game Maker 8.0 ou 8.1
- C#
- Javascript
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos
|
|