//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "OknoGL.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
}
//---------------------------------------------------------------------------

bool TForm1::UstalFormatPikseli(HDC uchwytDC) const
{
	PIXELFORMATDESCRIPTOR opisFormatuPikseli;
	ZeroMemory(&opisFormatuPikseli,sizeof(opisFormatuPikseli));
	opisFormatuPikseli.nVersion=1;
	opisFormatuPikseli.dwFlags=PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; //w oknie, podwojne buforowanie
	opisFormatuPikseli.iPixelType=PFD_TYPE_RGBA; //typ koloru RGB
	opisFormatuPikseli.cColorBits=32; //jakosc kolorów 4 bajty
	opisFormatuPikseli.cDepthBits=16; //glebokosc bufora Z (z-buffer)
	opisFormatuPikseli.iLayerType=PFD_MAIN_PLANE;
	int formatPikseli=ChoosePixelFormat(uchwytDC,&opisFormatuPikseli);
	if (formatPikseli==0) return false;
	if (!SetPixelFormat(uchwytDC,formatPikseli,&opisFormatuPikseli)) return false;
	return true;
}

bool TForm1::InitWGL(HWND uchwytOkna)
{
	uchwytDC = ::GetDC(Handle);
	if (!UstalFormatPikseli(uchwytDC)) return false; //Utworzenie kontekstu renderowania i uczynienie go aktywnym
	uchwytRC = wglCreateContext(uchwytDC);
	if (uchwytRC==NULL) return false;
	if (!wglMakeCurrent(uchwytDC, uchwytRC)) return false;
	return true;
}

void TForm1::UsunWGL()
{
	wglMakeCurrent(NULL,NULL);
	wglDeleteContext(uchwytRC);
	::ReleaseDC(Handle,uchwytDC);
}

#include <gl.h>

void TForm1::UstawienieSceny(bool rzutowanieIzometryczne)
{
	glViewport(0,0,ClientWidth,ClientHeight); //okno OpenGL = wnetrze formy (domyslnie)

	//ustawienie punktu projekcji
	glMatrixMode(GL_PROJECTION); //przełączenie na macierz projekcji
	glLoadIdentity();
	//left,right,bottom,top,znear,zfar (clipping)
	float wsp=ClientHeight/(float)ClientWidth;
   if(!rzutowanieIzometryczne)
		//left,right,bottom,top,znear,zfar (clipping)
		//mnozenie macierzy rzutowania przez macierz perspektywy - ustalanie frustum
		glFrustum(-0.1, 0.1, wsp*-0.1, wsp*0.1, 0.3, 100.0);
	else
		glOrtho(-3, 3, wsp*-3, wsp*3, 0.3, 100.0);
	glMatrixMode(GL_MODELVIEW); //powrót do macierzy widoku modelu
	glEnable(GL_DEPTH_TEST); //z-buffer aktywny = ukrywanie niewidocznych powierzchni
}

void TForm1::RysujScene()
{
	const float x0=1.0;
	const float y0=1.0;
	const float z0=1.0;

	//Przygotowanie bufora
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //czysci bufory
	glLoadIdentity(); //macierz model-widok = macierz jednostkowa
	glTranslatef(0.0, 0.0, -10.0); //odsuniecie calosci o 10

	//Rysowanie trojkata
	glBegin(GL_TRIANGLES);
	//ustalanie trzech wierzcholkow trojkata (werteksow (x,y,z))
	//(0,0,z) jest mniej wiecej w srodku ekranu
	glVertex3f(-x0, -y0, z0); //dolny lewy
	glVertex3f(x0, -y0, z0); //dolny prawy
	glVertex3f(0, y0, z0); //gorny
	//koniec rysowania figury
	glEnd();

	//Z bufora na ekran
	SwapBuffers(uchwytDC);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   InitWGL(Handle);
   UstawienieSceny();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
   UsunWGL();   
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
   UstawienieSceny();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
   RysujScene();
   ValidateRect(Handle,NULL);
}
//---------------------------------------------------------------------------
