2 registered members (Akow, tomaslolo),
1,536
guests, and 12
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: A wild engine appears!
[Re: the_clown]
#439194
03/28/14 12:01
03/28/14 12:01
|
Joined: Nov 2007
Posts: 2,568 Germany, BW, Stuttgart
MasterQ32
OP
Expert
|
OP
Expert
Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
|
Without searching for the bug because of a wrong thread context: 20 Minutes
Creating WebCore, WebSession, WebView, Default BitmapSurface that copies itself on update into a Texture2D, calling WebCore.Update from the update loop and drawing the Texture2D on the screen.
Javascript Integration is also pretty easy.
I can post an example project if you like...
|
|
|
Re: A wild engine appears!
[Re: MasterQ32]
#439233
03/29/14 12:32
03/29/14 12:32
|
Joined: Nov 2007
Posts: 2,568 Germany, BW, Stuttgart
MasterQ32
OP
Expert
|
OP
Expert
Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
|
So finally only one thing is still missing from the new system: The shader source code format I've thought about it, the user should be able to have a maximum of flexibility to write their shaders but i also want a unified shader interface. So i need some kind of markup language around the shader source files XML doesn't really work because the contained glsl code may contains < or > so no option JSON is another spread markup language. But its syntax isn't that easy to read. So my solution was Lua. The engine already has a lua scripting interface so easy integration for me. Also way more options for the user to create shaders. Here is a basic example for an object shader:
-- We compile with GLSL Version 3.3
shader.version = "330"
-- Add a global shader source file that is accessible from all shaders:
shader.add
{
type = "global",
source =
[[
uniform mat4 matWorld;
uniform mat4 matView;
uniform mat4 matProjection;
uniform sampler2D meshDiffuseTexture;
]]
}
-- Add a vertex shader. The input variables and layout is specified by the input entry
shader.add
{
type = "vertex",
input = "mesh",
source =
[[
out vec2 uv;
void main()
{
vec4 pos = vec4(vertexPosition, 1);
gl_Position = matProjection * matView * matWorld * pos;
uv = vertexUV;
}
]]
}
-- Add a fragment shader. Simple alpha-testing shader.
shader.add
{
type = "fragment",
source =
[[
layout(location = 0) out vec4 color;
in vec2 uv;
void main()
{
color = texture(meshDiffuseTexture, uv);
if(color.a < 0.5f) discard;
}
]]
}
Imho this solution is really acceptible because it is easy to read and provides flexibility. The coolest thing is that your shaders are not static code. You can easily create a shader based on the system specs or some dynamic settings based on os, graphics card, ... What do you think?
|
|
|
Re: A wild engine appears!
[Re: MasterQ32]
#439237
03/29/14 13:26
03/29/14 13:26
|
Joined: Nov 2008
Posts: 946
the_clown
User
|
User
Joined: Nov 2008
Posts: 946
|
|
|
|
Re: A wild engine appears!
[Re: the_clown]
#439246
03/29/14 18:57
03/29/14 18:57
|
Joined: Nov 2007
Posts: 2,568 Germany, BW, Stuttgart
MasterQ32
OP
Expert
|
OP
Expert
Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
|
Okay, i reworked the whole shader system. Was a bunch of work but it's great now. Much easier as to use as long as you don't write custom renderning. Then you have to write 3 lines instead of one The engine now has only one default shader that will expand with the rest of the engine. It will be compiled on demand with the correct subshaders so it works for forward rendering as well as deferred rendering. Here an example:
shader:add
{
type = "global",
source =
[[
// Transformation matrices
uniform mat4 matWorld;
uniform mat4 matView;
uniform mat4 matProjection;
// Mesh textures
uniform sampler2D meshDiffuseTexture;
uniform sampler2D meshSpecularTexture;
uniform sampler2D meshEmissiveTexture;
// Deferred renderer uniforms
uniform sampler2D renderDiffuseLightBuffer;
uniform sampler2D renderSpecularLightBuffer;
// Material Values
uniform vec4 mtlDiffuse;
uniform vec4 mtlSpecular;
uniform vec4 mtlEmissive;
uniform float mtlEmissiveScale;
]]
}
shader:add
{
type = "vertex",
input = "mesh",
source =
[[
out vec3 position;
out vec3 normal;
out vec3 tangent;
out vec3 bitangent;
out vec2 uv;
out vec4 screenSpaceUV;
void main()
{
vec4 pos = vec4(vertexPosition, 1);
gl_Position = matProjection * matView * matWorld * pos;
position = (matWorld * pos).xyz;
mat3 mv3x3 = mat3(matWorld);
normal = normalize(mv3x3 * vertexNormal);
tangent = normalize(mv3x3 * vertexTangent);
bitangent = normalize(mv3x3 * vertexBiTangent);
uv = vertexUV;
screenSpaceUV = gl_Position;
}
]]
}
shader:add
{
type = "fragment",
source =
[[
layout(location = 0) out vec4 color;
in vec2 uv;
void main()
{
color = texture(meshDiffuseTexture, uv);
if(color.a < 0.5f) discard;
}
]]
}
shader:add
{
type = "fragment",
class = "DeferredRenderer",
source =
[[
in vec2 uv;
in vec4 screenSpaceUV;
layout(location = 0) out vec4 color;
void main()
{
vec4 diffuseColor = texture(meshDiffuseTexture, uv);
vec3 specularColor = texture(meshSpecularTexture, uv).rgb;
vec3 emissiveColor = texture(meshEmissiveTexture, uv).rgb;
vec2 ss = 0.5f + 0.5f * screenSpaceUV.xy / screenSpaceUV.w;
color.rgb = mtlDiffuse.rgb * diffuseColor.rgb * textureLod(renderDiffuseLightBuffer, ss, 0.0f).rgb;
color.rgb += mtlSpecular.rgb * specularColor * textureLod(renderSpecularLightBuffer, ss, 0.0f).rgb;
color.rgb += emissiveColor * mtlEmissiveScale * mtlEmissive.rgb;
color.a = diffuseColor.a;
if(color.a < 0.5f) discard;
}
]]
}
As you can see, the shader defines two fragment shaders. One without a class. That's the default fragment shader that will be used. To bind a shader, we use the Shader.Select method:
// Select the default shader:
CompiledShader cs = shader.Select();
// Bind it!
cs.Bind();
To bind the shader with the class, we use:
// Select the shader with class modifier:
CompiledShader cs = shader.Select("DeferredRenderer");
// Bind it (again)
cs.Bind();
But that's not all! We can also override some subshaders if we want/need to.
// Create a custom fragment shader
var geometryPixelShader = new ShaderFragment(ShaderType.FragmentShader, geomPixSource);
// Select the shader with class and override the pixel shader.
CompiledShader cs = shader.Select("DeferredRenderer", geometryPixelShader);
// Should be known already
cs.Bind();
I'm using this functionality in the deferred renderer. Just provide any custom shader and my renderer can use it (if the output variables of the vertex/geometry/tesselation shader are right ) Oh, how do you load a shader? Several possibilities: Using the AssetManager, create it in the engine with Shader.Load or even built it with CompiledShader and ShaderFragment. I hope I could give some insight on how the new shader system works. Don't hesitate to ask me some questions! Regards Felix
|
|
|
Re: A wild engine appears!
[Re: MasterQ32]
#439250
03/29/14 20:25
03/29/14 20:25
|
Joined: Nov 2007
Posts: 2,568 Germany, BW, Stuttgart
MasterQ32
OP
Expert
|
OP
Expert
Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
|
@the_clown: Your Awesomium example is here!
using Awesomium.Core;
using OpenTK;
using OpenTK.Graphics.OpenGL4;
using OpenWorld.Engine;
using System;
namespace WebDemo
{
class Program : Game
{
static void Main(string[] args)
{
Program pgm = new Program();
pgm.Run();
}
protected override PresentationParameters GetPresentationParameters()
{
var def = base.GetPresentationParameters();
def.Title = "OpenWorld goes Web";
return def;
}
Texture2D webTexture;
WebSession session;
WebView view;
protected override void OnLoad()
{
base.OnLoad();
FrameBuffer.ClearColor = Color.White;
this.webTexture = new Texture2D(
this.Width,
this.Height,
PixelInternalFormat.Rgba,
PixelFormat.Rgba,
PixelType.UnsignedByte);
WebConfig config = new WebConfig()
{
};
WebCore.Initialize(config, true);
this.session = WebCore.CreateWebSession(new WebPreferences()
{
WebAudio = true,
WebGL = true,
AllowInsecureContent = true,
WebSecurity = false,
AppCache = false,
CanScriptsOpenWindows = false,
CanScriptsCloseWindows = false,
CanScriptsAccessClipboard = true,
Plugins = false,
});
this.view = WebCore.CreateWebView(this.webTexture.Width, this.webTexture.Height, this.session, WebViewType.Offscreen);
this.view.IsTransparent = true; // Website background is transparent
this.view.CreateSurface += (s, e) =>
{
// Create Awesomium default bitmap surface
var bmpSurface = new BitmapSurface(e.Width, e.Height);
bmpSurface.Updated += (s1, e1) =>
{
// If the surface changes, update the OpenGL texture
this.webTexture.Load(bmpSurface.Buffer, bmpSurface.Width, bmpSurface.Height);
};
e.Surface = bmpSurface;
};
// Set injection events
Input.Mouse.Move += Mouse_Move;
Input.Mouse.ButtonDown += Mouse_ButtonDown;
Input.Mouse.ButtonUp += Mouse_ButtonUp;
Input.Mouse.WheelChanged += Mouse_WheelChanged;
view.Source = new Uri("http://masterq32.de/");
}
void Mouse_ButtonDown(object sender, OpenTK.Input.MouseButtonEventArgs e)
{
switch (e.Button)
{
case OpenTK.Input.MouseButton.Left:
view.InjectMouseDown(MouseButton.Left);
break;
case OpenTK.Input.MouseButton.Middle:
view.InjectMouseDown(MouseButton.Middle);
break;
case OpenTK.Input.MouseButton.Right:
view.InjectMouseDown(MouseButton.Right);
break;
}
}
void Mouse_ButtonUp(object sender, OpenTK.Input.MouseButtonEventArgs e)
{
switch (e.Button)
{
case OpenTK.Input.MouseButton.Left:
view.InjectMouseUp(MouseButton.Left);
break;
case OpenTK.Input.MouseButton.Middle:
view.InjectMouseUp(MouseButton.Middle);
break;
case OpenTK.Input.MouseButton.Right:
view.InjectMouseUp(MouseButton.Right);
break;
}
}
void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs e)
{
if (Input.Keyboard[OpenTK.Input.Key.ShiftLeft])
view.InjectMouseWheel(0, 20 * e.Delta);
else
view.InjectMouseWheel(20 * e.Delta, 0);
}
void Mouse_Move(object sender, OpenTK.Input.MouseMoveEventArgs e)
{
view.InjectMouseMove(e.X, e.Y);
}
protected override void OnUpdate(GameTime time)
{
// WebCore.Update must be called in OpenGL-Thread
OpenGL.Invoke(WebCore.Update);
base.OnUpdate(time);
}
protected override void OnDrawPreState(GameTime time)
{
// Clears the screen
FrameBuffer.Clear();
}
protected override void OnDrawPostState(GameTime time)
{
// Draws the web interface over everything else
this.Utilities.Draw(new Box2(0, 0, this.Width, this.Height), this.webTexture);
}
}
}
|
|
|
|