PDA

View Full Version : OpenGL 3.x with Delphi



noeska
19-12-2009, 06:45 PM
With the dglOpenGL header up to date ( http://wiki.delphigl.com/index.php/dglOpenGL.pas/en ) and an delphi hello world example for OpenGL 3.x to be found. (i may have overlooked it).
I decided to write one using http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_(C%2B%2B/Win) as a guidance.

So here is the result:
http://www.noeska.net/downloads/OpenGL3xAPI.zip

Have fun with it. Of course feedback is welcome here.

WILL
19-12-2009, 07:35 PM
Very cool! Finally someone using OpenGL 3.x :D

noeska
28-12-2009, 09:39 AM
Finished some more examples from http://nopper.tv/opengl_3_2.html

Here are the examples in delphi: http://www.noeska.net/ogl3xexamples.zip

Bugs:
- i dont trust the cubemapping example, or it could be the tga reader flipping textures.
- the particle system does not work with the the shape textures due to in the fragment shader gl_PointCoord is always 0. But instead it shows red squares as points.

epiece
29-01-2010, 04:20 AM
Hi! What is better to use? Delphi X which is Direct X or Open GL? ... :)
Please Advise... Thanks...

chronozphere
29-01-2010, 08:25 AM
There is no "better" choice, just pick one and see if you like it. DelphiX is really nice for beginners because It has a lot of classes made for you. OpenGL doesn't have that, but its really powerfull too.

@Noeska: Great, I'll definitaly use those samples to make a new OGL 3.x engine. ;)

epiece
29-01-2010, 12:34 PM
:yes: thanks master :yes:
Can you advice me on what should I focus for?
I Love Delphi but most game are made of C++ , I hate OOP in C++ that's why I preferred to use Delphi with its PASCAL OOP. But I still want to focus on C++ because most game programming jobs are for C++ Developers.

Thanks 8)

Brainer
29-01-2010, 05:00 PM
If I may toss my ten cents: ;)

C++ is the most common programming language, but it doesn't matter it's the best there is. It's certain that if you're thinking about a job in professional game development, you have to focus on learning C++. I can say it's not the best choice for a beginner.

On the other hand, if you're ambitious enough, you can try and make a game yourself in Delphi and then look for a publisher. I'm not entirely sure, but you can use Steam as your distribution platform, too. The fact Delphi isn't as popular as C++ doesn't mean that you can't make a game/engine/decent commercial app in it! If you ask me, I believe that Delphi isn't worse than C++, it's even better. But it's one of the controversial topics, so maybe I'll stop adding fuel to the fire. ;)

If you are still uncertain which development API you should choose, I'd suggest OpenGL. It's fairly simple, the headers are available for Delphi, and it's easy to convert examples written in different programming languages, too. It's the best choice if you want your engine to be cross-platform.

Uff, I hope I dispelled your doubts. :)

NecroDOME
29-01-2010, 05:37 PM
@Chrono: You could make DelphiGL to counter the easy of DelphiX :) (srry for late reply, I just read the thread)

Brainer
30-01-2010, 06:32 AM
While reading OpenGL specs, I noticed this:


[...] Edge flags and fixed-function vertex processing - ColorPointer, EdgeFlag-
Pointer, FogCoordPointer, IndexPointer, NormalPointer, Secondary-
ColorPointer, TexCoordPointer, VertexPointer, EnableClientState, DisableClientState,
and ClientActiveTexture (section 2.8); Frustum, LoadIdentity,
LoadMatrix, LoadTransposeMatrix, MatrixMode, Mult-
Matrix, MultTransposeMatrix, Ortho, PopMatrix, PushMatrix, Rotate,
Scale, and Translate (section 2.12.2; Enable/Disable targets
RESCALE NORMAL and NORMALIZE (section 2.12.3); TexGen*
and Enable/Disable targets TEXTURE GEN * (section 2.12.4, Material* [...]

This was put in the "Deprecation Model" section, which means these functions are marked deprecated. If so, does that mean that, for example, the glLoadIdentity procedure is old, too and shouldn't be used? :o How do I replace it then?

Andreaz
30-01-2010, 10:44 AM
This was put in the "Deprecation Model" section, which means these functions are marked deprecated. If so, does that mean that, for example, the glLoadIdentity procedure is old, too and shouldn't be used? :o How do I replace it then?


Afaik the new way is to send the transformation matrices to the GLSL shaders and using the shaders to transform the geometry.

epiece
30-01-2010, 12:56 PM
Thanks guys specially to Brainer :) .. I will be stick with Delphi. I cant find dpk download for OpenGL.. I only Have that (un)DelphiX ... I have Delphi 6 compiler... That only I have... Where to get OpenGL for free? Not only the header but also the dpk. I Googled the web and didn't find dpk for OpenGL :no:.. Can you help me Guys?

Best regards..
Thanks ..

noeska
30-01-2010, 01:57 PM
There is no dpk, but you can download the unit i use from http://www.delphigl.com

epiece
31-01-2010, 12:48 AM
Thanks noeska... I thought there was a dpk like the DelphiX ... I will use that Header..

Thank you 8) :yes: Thank you :yes: Thank you :yes: Thank you :yes: Masters :)

Brainer
31-01-2010, 08:40 AM
Sorry for putting it here, but I got a problem with mouse looking in my app.

Here's the shader I use:


// Vertex Shader – file "minimal.vert"

#version 150

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

in vec3 in_Position;
in vec3 in_Color;
out vec3 ex_Color;

void main(void)
{
gl_Position = projectionMatrix * modelViewMatrix * vec4(in_Position, 1.0);
ex_Color = in_Color;
}


And here's the camera class:


//************************************************** ****************************
//
// BrainEngine
// Copyright © 2008 - 2010 Patryk Nusbaum.
// All rights reserved.
//
// Last modified: 30.01.2010
// Mail: patrick.nusbaum@gmail.com
// WWW: www.pateman.net76.net
//
// Based on code by Luuk van Venrooij.
//
// License
// -------------------
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Patryk Nusbaum nor the names of his contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//************************************************** ****************************
unit BrainCamera;

interface

uses
Windows, dglOpenGL, BrainMath;

type
{ .: TBrainCamera :. }
TBrainCamera = class(TObject)
private
{ Private declarations }
FDir: TAffineVector;
FFOV: Single;
FFar: Single;
FRot: TAffineVector;
FNear: Single;
FInvert: Boolean;
FScreenHeight: Integer;
FSmooth: Single;
FUp: TAffineVector;
FPos: TAffineVector;
FScreenWidth: Integer;
procedure SetScreenHeight(const Value: Integer);
procedure SetScreenWidth(const Value: Integer);
protected
{ Protected declarations }
ProjectionLocation, ModelViewLocation: Integer;
ProjectionMatrix, ModelViewMatrix: TMatrix;
ScreenCenterX, ScreenCenterY: Integer;
public
{ Public declarations }
constructor Create(const AScreenWidth, AScreenHeight: Integer;
const ProjMatUniform, ModelViewUniform: Integer);

procedure ApplyPerspective();
procedure ApplyTransform(); virtual;

procedure Move(const ASpeed: Single); virtual; abstract;
procedure Strafe(const ASpeed: Single); virtual; abstract;
procedure MouseLook(); virtual; abstract;

property ScreenWidth: Integer read FScreenWidth write SetScreenWidth;
property ScreenHeight: Integer read FScreenHeight write SetScreenHeight;

property Position: TAffineVector read FPos write FPos;
property Direction: TAffineVector read FDir write FDir;
property Rotation: TAffineVector read FRot write FRot;
property Up: TAffineVector read FUp write FUp;

property FieldOfView: Single read FFOV write FFOV;
property NearPlane: Single read FNear write FNear;
property FarPlane: Single read FFar write FFar;

property MouseSmooth: Single read FSmooth write FSmooth;
property InvertMouse: Boolean read FInvert write FInvert;
end;

{ .: TBrainFreeCamera :. }
TBrainFreeCamera = class sealed(TBrainCamera)
private
{ Private declarations }
FMaxAngle: Single;
FMinAngle: Single;
protected
{ Protected declarations }
function MakeRotationMatrix(const V: TAffineVector): TMatrix;
public
{ Public declarations }
constructor Create(const AScreenWidth, AScreenHeight: Integer;
const ProjMatUniform, ModelViewUniform: Integer);

procedure ApplyTransform(); override;

procedure Move(const ASpeed: Single); override;
procedure Strafe(const ASpeed: Single); override;
procedure MouseLook(); override;

property MaxAngle: Single read FMaxAngle write FMaxAngle;
property MinAngle: Single read FMinAngle write FMinAngle;
end;

implementation


{ TBrainCamera }

procedure TBrainCamera.ApplyPerspective;
begin
if (FScreenHeight <= 0) then
FScreenHeight := 1;
glViewport(0, 0, FScreenWidth, FScreenHeight);

ProjectionMatrix := CalcPerspectiveMatrix(FFOV, FScreenWidth / FScreenHeight,
FNear, FFar);
glUniformMatrix4fv(ProjectionLocation, 1, False, @ProjectionMatrix);
end;

procedure TBrainCamera.ApplyTransform;
begin
// --
end;

constructor TBrainCamera.Create(const AScreenWidth, AScreenHeight,
ProjMatUniform, ModelViewUniform: Integer);
begin
inherited Create();

if (AScreenWidth <= 0) then
FScreenWidth := 1
else
FScreenWidth := AScreenWidth;
if (AScreenHeight <= 0) then
FScreenHeight := 1
else
FScreenHeight := AScreenHeight;
ScreenCenterX := FScreenWidth div 2;
ScreenCenterY := FScreenHeight div 2;

ProjectionLocation := ProjMatUniform;
ModelViewLocation := ModelViewUniform;

ApplyTransform();

FPos := NullVector;
FUp := YVector;
FDir := MinusZVector;
FRot := NullVector;

FInvert := False;
FSmooth := 0.25;

FFOV := 40.0;
FNear := 0.1;
FFar := 1000.0;
end;

procedure TBrainCamera.SetScreenHeight(const Value: Integer);
begin
if (Value <= 0) then
FScreenHeight := 1
else
FScreenHeight := Value;

ScreenCenterY := FScreenHeight div 2;
end;

procedure TBrainCamera.SetScreenWidth(const Value: Integer);
begin
FScreenWidth := Value;

ScreenCenterX := FScreenWidth div 2;
end;

{ TBrainFreeCamera }

procedure TBrainFreeCamera.ApplyTransform;
begin
ModelViewMatrix := LookAt(FPos, AffineVectorMake(FPos.V[0] + FDir.V[0],
FPos.V[1] + FDir.V[1], FPos.V[2] + FDir.V[2]), FUp);
glUniformMatrix4fv(ModelViewLocation, 1, False, @ModelViewMatrix);
end;

constructor TBrainFreeCamera.Create(const AScreenWidth, AScreenHeight,
ProjMatUniform, ModelViewUniform: Integer);
begin
inherited Create(AScreenWidth, AScreenHeight, ProjMatUniform, ModelViewUniform);

FMaxAngle := 89.0;
FMinAngle := -89.0;
end;

function TBrainFreeCamera.MakeRotationMatrix(const V: TAffineVector): TMatrix;
var
M, mX, mY, mZ: TMatrix;
begin
mX := CreateRotationMatrixX(DegToRad(V.V[0]));
mY := CreateRotationMatrixY(DegToRad(V.V[1]));
mZ := CreateRotationMatrixZ(DegToRad(V.V[2]));
M := MatrixMultiply(mZ, mY);
Result := MatrixMultiply(mX, M);
end;

procedure TBrainFreeCamera.MouseLook;
var
Pos, Delta: TPoint;
M: TMatrix;
begin
GetCursorPos(Pos);
SetCursorPos(ScreenCenterX, ScreenCenterY);

Delta.X := ScreenCenterX - Pos.X;
Delta.Y := ScreenCenterY - Pos.Y;

FRot.V[1] := FRot.V[1] + Delta.X * FSmooth;

if FInvert then
FRot.V[0] := FRot.V[0] - Delta.Y * FSmooth
else
FRot.V[0] := FRot.V[0] + Delta.Y * FSmooth;

if (FRot.V[0] < FMinAngle) then
FRot.V[0] := FMinAngle;
if (FRot.V[0] > FMaxAngle) then
FRot.V[0] := FMaxAngle;

M := MakeRotationMatrix(FRot);
FDir := VectorTransform(MinusZVector, M);
end;

procedure TBrainFreeCamera.Move(const ASpeed: Single);
var
M: TMatrix;
begin
M := MakeRotationMatrix(FRot);
FDir := VectorTransform(MinusZVector, M);

FPos.V[0] := FPos.V[0] + (FDir.V[0] * -ASpeed);
FPos.V[1] := FPos.V[1] + (FDir.V[1] * -ASpeed);
FPos.V[2] := FPos.V[2] + (FDir.V[2] * -ASpeed);
end;

procedure TBrainFreeCamera.Strafe(const ASpeed: Single);
var
M: TMatrix;
begin
M := MakeRotationMatrix(FRot);
FDir := VectorTransform(MinusZVector, M);

FPos.V[0] := FPos.V[0] + (FDir.V[2] * -ASpeed);
FPos.V[2] := FPos.V[2] + (-FDir.V[0] * -ASpeed);
end;

end.


I don't know why, but the code produces weird pespective dissonance when I move my mouse:
http://i46.tinypic.com/2s7dyqg.png/
I have no idea where the problem is. Is the shader code wrong or am I doing something wrong with the matrix operations? Can you point me out my mistake?

Brainer
07-02-2010, 12:05 PM
Hello again.

I got a problem with my application. It uses OpenGL 3.0, but anything doesn't get rendered. I don't know what I am doing wrong, that's why I'm including full source code.
http://www.sendspace.com/file/rch2a4

Can someone tell me what's wrong there?

chronozphere
13-02-2010, 10:48 AM
Hey Noeska

I tried your GL3.0 examples but there seem to be some problems:

Most samples given an "I/O error 6" exception in the LoadTGA() routine at line:

BlockRead(lfile,buf,1);


The ProcessKeys method in example4 gives the impression that you can control the speed:

{------------------------------------------------------------------}
{ Processes all the keystrokes }
{------------------------------------------------------------------}
procedure ProcessKeys;
begin
if (keys[VK_UP]) then xspeed := xspeed - 0.002;
if (keys[VK_DOWN]) then xspeed := xspeed + 0.002;
if (keys[VK_RIGHT]) then yspeed := yspeed + 0.002;
if (keys[VK_LEFT]) then yspeed := yspeed - 0.002;
end;

However, it doesn't seem to work. :?

Can you take a look at this (especially the first one)?

Thanks

noeska
13-02-2010, 12:46 PM
Hmm i never got the io error myself. Can the .tga file be found?
Also if you know the filename/path used is correct can you give a linenumber also as the code you mentioned is used in several parts in the tga loader.
The tga loader is a bit of a quick hack.

The xspeed,yspeed is part of my basic template, but are not used in examples before example6. I better should have removed it completely. If you want to use them you need to add something like:

rotateRzRyRxMatrixf(model, 30.0*xspeed, 30.0*yspeed, 0.0); //cube can now be move by arrow keys ... to move the cube. An complete example of that is in example 6.

chronozphere
13-02-2010, 03:15 PM
Hmm i never got the io error myself. Can the .tga file be found?
Also if you know the filename/path used is correct can you give a linenumber also as the code you mentioned is used in several parts in the tga loader.
The tga loader is a bit of a quick hack.


Yeah.. The TGA can be found. :) The error happens on the following line:


// check, if we have a valid pointer
if (filename='') then
begin
result := false;
exit;
end;

// open filename in "read binary" mode
AssignFile(lfile, filename);
Reset( lfile,1 ); //Read bytes

// seek through the tga header, up to the type:
BlockRead(lfile,buf,1); << ERROR HERE
BlockRead(lfile,buf,1);


I don't know why i get this error, because I have little experience with files. I always use filestreams.

Dendemble
10-05-2010, 05:16 PM
Hello,

I also tried the GL3.0 samples, and I also got an error while reading the TGA files.
It's exactly the same error than the one reported by chronozphere.

Modifying the LoadTGA function this way seems to fix the error :


function loadTGA(const filename: string;var width: GLushort; var height: GLushort; var format: GLenum; var pixelData: GLbufferb): GLboolean;


(Ps : I Use Delphi2007)

noeska
10-05-2010, 05:27 PM
What did you change, i cannot see that in your post?

Dendemble
10-05-2010, 05:30 PM
I just change :

function loadTGA(const filename: pansichar;...

to

function loadTGA(const filename: string;...