1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
{
Copyright 2017-2017 Michalis Kamburelis.
This file is part of "Castle Game Engine".
"Castle Game Engine" is free software; see the file COPYING.txt,
included in this distribution, for details about the copyright.
"Castle Game Engine" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
}
{ Define and display a 3D object with custom shaders in Object Pascal code.
In CGE, you can build and edit X3D scene graph using Object Pascal,
see https://castle-engine.sourceforge.io/manual_scene.php#section_building_and_editing .
See also other X3D-build code, e.g. build_3d_object_by_code.lpr, build_3d_tunnel.lpr ,
ExportToX3D in ../terrain/terrain.lpr (uses shaders too)...
}
uses SysUtils,
CastleLog, CastleRendererBaseTypes, CastleVectors, X3DNodes, CastleWindow,
CastleSceneCore, CastleScene, CastleUtils;
function BuildX3D: TX3DRootNode;
var
Box: TBoxNode;
BoxShape: TShapeNode;
Appearance: TAppearanceNode;
ComposedShader: TComposedShaderNode;
VertexShader, FragmentShader: TShaderPartNode;
begin
{ create Box and BoxShape in one go }
Box := TBoxNode.CreateWithShape(BoxShape);
Box.Size := Vector3(1, 2, 3);
{ Note: if you're looking instead at a way to enhance the default shaders
(not replace them), use the Effect and EffectPart
nodes instead of ComposedShader and ShaderPart.
See https://castle-engine.sourceforge.io/compositing_shaders.php . }
VertexShader := TShaderPartNode.Create;
VertexShader.ShaderType := stVertex;
VertexShader.Contents :=
'uniform mat4 castle_ModelViewMatrix;' + NL +
'uniform mat4 castle_ProjectionMatrix;' + NL +
'attribute vec4 castle_Vertex;' + NL +
'void main(void)' + NL +
'{' + NL +
' gl_Position = castle_ProjectionMatrix * (castle_ModelViewMatrix * castle_Vertex);' + NL +
'}';
FragmentShader := TShaderPartNode.Create;
FragmentShader.ShaderType := stFragment;
FragmentShader.Contents :=
'void main(void)' + NL +
'{' + NL +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);' + NL +
'}';
ComposedShader := TComposedShaderNode.Create;
ComposedShader.SetParts([VertexShader, FragmentShader]);
Appearance := TAppearanceNode.Create;
Appearance.SetShaders([ComposedShader]);
// Appearance.Material is only used when OpenGL does not support shaders,
// or if the shader failed to compile.
// Appearance.Material := TMaterialNode.Create;
BoxShape.Appearance := Appearance;
Result := TX3DRootNode.Create;
Result.AddChildren(BoxShape);
end;
var
Window: TCastleWindow;
Scene: TCastleScene;
begin
{ the log will contain e.g. information if the GLSL failed to compile }
InitializeLog;
Scene := TCastleScene.Create(Application);
Scene.Load(BuildX3D, true);
Scene.Spatial := [ssRendering, ssDynamicCollisions];
Scene.ProcessEvents := true;
Window := TCastleWindow.Create(Application);
Window.SceneManager.Items.Add(Scene);
Window.SceneManager.MainScene := Scene;
Window.Open;
Application.Run;
end.
|