- Implemented RenderTarget in OpenGL

- Implemented dynamic shader attributes mapping in the vertex buffer in OpenGL
This commit is contained in:
SND\AstrorEnales_cp 2011-12-08 19:48:15 +00:00
parent 1d61c78f88
commit 8239306d2e
12 changed files with 462 additions and 231 deletions

View File

@ -5,8 +5,8 @@ using System.IO;
using ANX.Framework.Graphics;
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.RenderSystem;
using OpenTK;
using NLog;
using OpenTK;
#region License

View File

@ -63,6 +63,16 @@ namespace ANX.Framework.Windows.GL3
/// </summary>
public class EffectGL3 : INativeEffect
{
#region ShaderAttribute (Helper struct)
public struct ShaderAttribute
{
public string Name;
public uint Location;
public int Size;
public ActiveAttribType Type;
}
#endregion
#region Constants
private const string FragmentSeparator = "##!fragment!##";
#endregion
@ -74,6 +84,12 @@ namespace ANX.Framework.Windows.GL3
internal int programHandle;
private Effect managedEffect;
internal Dictionary<string, ShaderAttribute> ActiveAttributes
{
get;
private set;
}
#endregion
#region Public
@ -193,6 +209,8 @@ namespace ANX.Framework.Windows.GL3
throw new InvalidDataException("Failed to link the shader program " +
"because of: " + programError);
}
GetAttributes();
}
#endregion
@ -308,6 +326,31 @@ namespace ANX.Framework.Windows.GL3
}
#endregion
#region GetAttributes
private void GetAttributes()
{
ActiveAttributes = new Dictionary<string, ShaderAttribute>();
int attributeCount;
GL.GetProgram(programHandle, ProgramParameter.ActiveAttributes,
out attributeCount);
for (int index = 0; index < attributeCount; index++)
{
int attributeSize;
ActiveAttribType attributeType;
string name = GL.GetActiveAttrib(programHandle, index,
out attributeSize, out attributeType);
uint attributeIndex = (uint)GL.GetAttribLocation(programHandle, name);
ActiveAttributes.Add(name, new ShaderAttribute
{
Name = name,
Location = attributeIndex,
Size = attributeSize,
Type = attributeType,
});
}
}
#endregion
#region Apply (TODO)
public void Apply(GraphicsDevice graphicsDevice)
{

View File

@ -1,10 +1,11 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using ANX.Framework.Graphics;
using ANX.Framework.NonXNA;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform;
using System.Runtime.InteropServices;
#region License
@ -136,6 +137,8 @@ namespace ANX.Framework.Windows.GL3
internal static VertexBufferGL3[] boundVertexBuffers =
new VertexBufferGL3[0];
private static RenderTarget2DGL3[] boundRenderTargets =
new RenderTarget2DGL3[0];
internal static IndexBufferGL3 boundIndexBuffer;
internal static EffectGL3 activeEffect;
#endregion
@ -457,8 +460,7 @@ namespace ANX.Framework.Windows.GL3
GL.BindBuffer(BufferTarget.ArrayBuffer,
boundVertexBuffers[index].BufferHandle);
ErrorHelper.Check("BindBuffer");
boundVertexBuffers[index].MapVertexDeclaration(
activeEffect.programHandle);
boundVertexBuffers[index].MapVertexDeclaration(activeEffect);
}
}
#endregion
@ -476,40 +478,79 @@ namespace ANX.Framework.Windows.GL3
}
#endregion
private void ResizeRenderWindow(PresentationParameters presentationParameters)
#region ResizeRenderWindow
private void ResizeRenderWindow(
PresentationParameters presentationParameters)
{
if (OpenTK.Configuration.RunningOnWindows)
{
RECT windowRect;
RECT clientRect;
if (GetWindowRect(presentationParameters.DeviceWindowHandle, out windowRect) &&
GetClientRect(presentationParameters.DeviceWindowHandle, out clientRect))
if (GetWindowRect(presentationParameters.DeviceWindowHandle,
out windowRect) &&
GetClientRect(presentationParameters.DeviceWindowHandle,
out clientRect))
{
int width = presentationParameters.BackBufferWidth + ((windowRect.Right - windowRect.Left) - clientRect.Right);
int height = presentationParameters.BackBufferHeight + ((windowRect.Bottom - windowRect.Top) - clientRect.Bottom);
int width = presentationParameters.BackBufferWidth +
((windowRect.Right - windowRect.Left) - clientRect.Right);
int height = presentationParameters.BackBufferHeight +
((windowRect.Bottom - windowRect.Top) - clientRect.Bottom);
SetWindowPos(presentationParameters.DeviceWindowHandle, IntPtr.Zero, windowRect.Left, windowRect.Top, width, height, 0);
SetWindowPos(presentationParameters.DeviceWindowHandle, IntPtr.Zero,
windowRect.Left, windowRect.Top, width, height, 0);
}
}
}
#endregion
#region GetStaticFieldValue
static object GetStaticFieldValue(Type type, string fieldName)
{
return type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
}
#endregion
#region SetStaticFieldValue
static void SetStaticFieldValue(Type type, string fieldName, object value)
{
type.GetField(fieldName,
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, value);
}
#endregion
#region SetRenderTargets
public void SetRenderTargets(params RenderTargetBinding[] renderTargets)
{
throw new NotImplementedException();
if (renderTargets == null)
{
if (boundRenderTargets.Length > 0)
{
for (int index = 0; index < boundRenderTargets.Length; index++)
{
boundRenderTargets[index].Unbind();
}
boundRenderTargets = new RenderTarget2DGL3[0];
}
}
else
{
boundRenderTargets = new RenderTarget2DGL3[renderTargets.Length];
for (int index = 0; index < renderTargets.Length; index++)
{
RenderTarget2D renderTarget =
renderTargets[index].RenderTarget as RenderTarget2D;
RenderTarget2DGL3 nativeRenderTarget =
renderTarget.NativeRenderTarget as RenderTarget2DGL3;
boundRenderTargets[index] = nativeRenderTarget;
nativeRenderTarget.Bind();
}
}
}
#endregion
#region GetBackBufferData (TODO)
public void GetBackBufferData<T>(Rectangle? rect, T[] data,
int startIndex, int elementCount) where T : struct
{
@ -521,22 +562,35 @@ namespace ANX.Framework.Windows.GL3
throw new NotImplementedException();
}
public void GetBackBufferData<T>(T[] data, int startIndex, int elementCount) where T : struct
public void GetBackBufferData<T>(T[] data, int startIndex,
int elementCount) where T : struct
{
throw new NotImplementedException();
}
#endregion
#region ResizeBuffers (TODO)
public void ResizeBuffers(PresentationParameters presentationParameters)
{
ResizeRenderWindow(presentationParameters);
throw new NotImplementedException();
}
#endregion
#region Dispose
public void Dispose()
{
//TODO: implement
}
boundVertexBuffers = null;
boundIndexBuffer = null;
activeEffect = null;
boundRenderTargets = null;
nativeContext.Dispose();
nativeContext = null;
nativeWindowInfo.Dispose();
nativeWindowInfo = null;
}
#endregion
}
}

View File

@ -32,7 +32,7 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.5.8.0")]
[assembly: AssemblyFileVersion("0.5.8.0")]
[assembly: AssemblyVersion("0.5.9.0")]
[assembly: AssemblyFileVersion("0.5.9.0")]
[assembly: InternalsVisibleTo("ANX.Framework.ContentPipeline")]

View File

@ -1,15 +1,142 @@
using System;
using ANX.Framework.NonXNA.RenderSystem;
using ANX.Framework.Graphics;
using ANX.Framework.NonXNA.RenderSystem;
using OpenTK.Graphics.OpenGL;
namespace ANX.Framework.Windows.GL3
{
public class RenderTarget2DGL3 : INativeRenderTarget2D
public class RenderTarget2DGL3 : Texture2DGL3, INativeRenderTarget2D
{
#region Private
private int framebufferHandle;
private int renderbufferHandle;
private bool generateMipmaps;
#endregion
// TODO: usage, preferredMultiSampleCount
#region Constructor
public RenderTarget2DGL3(int width, int height, bool mipMap,
SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat,
int preferredMultiSampleCount, RenderTargetUsage usage)
{
generateMipmaps = mipMap;
PixelInternalFormat nativeFormat =
DatatypesMapping.SurfaceToPixelInternalFormat(preferredFormat);
#region Image creation
NativeHandle = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMagFilter, (int)All.Linear);
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureWrapT, (int)All.ClampToEdge);
if (generateMipmaps)
{
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.GenerateMipmap, 1);
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMinFilter, (int)All.LinearMipmapLinear);
}
else
{
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMinFilter, (int)All.Linear);
}
GL.TexImage2D(TextureTarget.Texture2D, 0, nativeFormat,
width, height, 0, (PixelFormat)nativeFormat, PixelType.UnsignedByte,
IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D, 0);
#endregion
// create a renderbuffer object to store depth info
GL.GenRenderbuffers(1, out renderbufferHandle);
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderbufferHandle);
GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer,
DepthFormatConversion(preferredDepthFormat), width, height);
GL.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, 0);
// create a framebuffer object
GL.GenFramebuffers(1, out framebufferHandle);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebufferHandle);
// attach the texture to FBO color attachment point
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer,
FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D,
NativeHandle, 0);
// attach the renderbuffer to depth attachment point
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer,
FramebufferAttachment.DepthAttachment,
RenderbufferTarget.Renderbuffer, renderbufferHandle);
// check FBO status
FramebufferErrorCode status = GL.CheckFramebufferStatus(
FramebufferTarget.Framebuffer);
if (status != FramebufferErrorCode.FramebufferComplete)
{
throw new InvalidOperationException(
"Failed to create the render target! Error=" + status);
}
// switch back to window-system-provided framebuffer
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}
#endregion
#region DepthFormatConversion
private RenderbufferStorage DepthFormatConversion(DepthFormat depthFormat)
{
switch(depthFormat)
{
default:
case DepthFormat.None:
// TODO
return RenderbufferStorage.DepthComponent16;
//return (RenderbufferStorage)All.DepthComponent;
case DepthFormat.Depth16:
return RenderbufferStorage.DepthComponent16;
case DepthFormat.Depth24:
return RenderbufferStorage.DepthComponent24;
case DepthFormat.Depth24Stencil8:
return RenderbufferStorage.DepthComponent32;
}
}
#endregion
#region Bind
public void Bind()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebufferHandle);
}
#endregion
#region Unbind
public void Unbind()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
if (generateMipmaps)
{
GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, 0);
}
}
#endregion
#region Dispose
public override void Dispose()
{
base.Dispose();
GL.DeleteFramebuffers(1, ref framebufferHandle);
GL.DeleteRenderbuffers(1, ref renderbufferHandle);
}
#endregion
}
}

View File

@ -54,7 +54,7 @@ namespace ANX.Framework.Windows.GL3
#region SpriteBatchShader
internal static byte[] SpriteBatchByteCode = new byte[]
{
160,
186,
003, 117, 110, 105, 102, 111, 114, 109, 032, 109, 097, 116, 052, 032, 077, 097, 116, 114, 105, 120,
084, 114, 097, 110, 115, 102, 111, 114, 109, 059, 010, 097, 116, 116, 114, 105, 098, 117, 116, 101,
032, 118, 101, 099, 052, 032, 112, 111, 115, 059, 010, 097, 116, 116, 114, 105, 098, 117, 116, 101,
@ -67,19 +67,20 @@ namespace ANX.Framework.Windows.GL3
114, 105, 120, 084, 114, 097, 110, 115, 102, 111, 114, 109, 042, 112, 111, 115, 059, 010, 100, 105,
102, 102, 117, 115, 101, 084, 101, 120, 067, 111, 111, 114, 100, 061, 116, 101, 120, 059, 010, 100,
105, 102, 102, 117, 115, 101, 067, 111, 108, 111, 114, 061, 099, 111, 108, 059, 125, 010, 035, 035,
033, 102, 114, 097, 103, 109, 101, 110, 116, 033, 035, 035, 010, 117, 110, 105, 102, 111, 114, 109,
032, 115, 097, 109, 112, 108, 101, 114, 050, 068, 032, 084, 101, 120, 116, 117, 114, 101, 059, 010,
118, 097, 114, 121, 105, 110, 103, 032, 118, 101, 099, 052, 032, 100, 105, 102, 102, 117, 115, 101,
067, 111, 108, 111, 114, 059, 010, 118, 097, 114, 121, 105, 110, 103, 032, 118, 101, 099, 050, 032,
100, 105, 102, 102, 117, 115, 101, 084, 101, 120, 067, 111, 111, 114, 100, 059, 010, 118, 111, 105,
100, 032, 109, 097, 105, 110, 040, 118, 111, 105, 100, 041, 123, 010, 103, 108, 095, 070, 114, 097,
103, 067, 111, 108, 111, 114, 061, 116, 101, 120, 116, 117, 114, 101, 050, 068, 040, 084, 101, 120,
116, 117, 114, 101, 044, 100, 105, 102, 102, 117, 115, 101, 084, 101, 120, 067, 111, 111, 114, 100,
041, 042, 100, 105, 102, 102, 117, 115, 101, 067, 111, 108, 111, 114, 059, 125, 010, 095, 046, 094,
078, 240, 054, 006, 106, 005, 190, 104, 250, 201, 129, 166, 050, 199, 249, 189, 159, 008, 207, 084,
062, 171, 010, 076, 101, 119, 047, 079, 245, 134, 024, 149, 110, 166, 213, 153, 023, 179, 120, 191,
146, 106, 047, 180, 084, 037, 088, 036, 132, 126, 030, 027, 054, 044, 236, 120, 086, 102, 211, 178,
125
033, 102, 114, 097, 103, 109, 101, 110, 116, 033, 035, 035, 010, 112, 114, 101, 099, 105, 115, 115,
105, 111, 110, 032, 109, 101, 100, 105, 117, 109, 112, 032, 102, 108, 111, 097, 116, 059, 010, 117,
110, 105, 102, 111, 114, 109, 032, 115, 097, 109, 112, 108, 101, 114, 050, 068, 032, 084, 101, 120,
116, 117, 114, 101, 059, 010, 118, 097, 114, 121, 105, 110, 103, 032, 118, 101, 099, 052, 032, 100,
105, 102, 102, 117, 115, 101, 067, 111, 108, 111, 114, 059, 010, 118, 097, 114, 121, 105, 110, 103,
032, 118, 101, 099, 050, 032, 100, 105, 102, 102, 117, 115, 101, 084, 101, 120, 067, 111, 111, 114,
100, 059, 010, 118, 111, 105, 100, 032, 109, 097, 105, 110, 040, 118, 111, 105, 100, 041, 123, 010,
103, 108, 095, 070, 114, 097, 103, 067, 111, 108, 111, 114, 061, 116, 101, 120, 116, 117, 114, 101,
050, 068, 040, 084, 101, 120, 116, 117, 114, 101, 044, 100, 105, 102, 102, 117, 115, 101, 084, 101,
120, 067, 111, 111, 114, 100, 041, 042, 100, 105, 102, 102, 117, 115, 101, 067, 111, 108, 111, 114,
059, 125, 010, 204, 002, 066, 009, 044, 094, 101, 149, 163, 197, 203, 229, 083, 172, 100, 007, 002,
181, 147, 172, 186, 193, 103, 068, 009, 005, 065, 152, 020, 077, 034, 207, 124, 030, 210, 046, 182,
155, 204, 156, 086, 170, 100, 065, 083, 209, 239, 206, 226, 075, 115, 157, 118, 160, 025, 101, 098,
159, 062, 171, 094, 128, 095, 188
};
#endregion //SpriteBatchShader

View File

@ -89,14 +89,18 @@ namespace ANX.Framework.Windows.GL3
/// <summary>
/// The OpenGL texture handle.
/// </summary>
internal int NativeHandle
protected internal int NativeHandle
{
get;
private set;
protected set;
}
#endregion
#region Constructor
internal Texture2DGL3()
{
}
/// <summary>
/// Create a new native OpenGL texture.
/// </summary>
@ -165,6 +169,11 @@ namespace ANX.Framework.Windows.GL3
"Loading mipmaps is not correctly implemented yet!");
}
GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
#if DEBUG
ErrorHelper.Check("BindTexture");
#endif
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
// TODO: get size of first mipmap!
@ -235,7 +244,7 @@ namespace ANX.Framework.Windows.GL3
/// <summary>
/// Dispose the native OpenGL texture handle.
/// </summary>
public void Dispose()
public virtual void Dispose()
{
GL.DeleteTexture(NativeHandle);
#if DEBUG

View File

@ -178,67 +178,54 @@ namespace ANX.Framework.Windows.GL3
#endregion
#region MapVertexDeclaration
internal void MapVertexDeclaration(int programHandle)
internal void MapVertexDeclaration(EffectGL3 effect)
{
int attributes;
GL.GetProgram(programHandle, ProgramParameter.ActiveAttributes,
out attributes);
VertexElement[] elements = vertexDeclaration.GetVertexElements();
if (elements.Length != attributes)
if (elements.Length != effect.ActiveAttributes.Count)
{
throw new InvalidOperationException("Mapping the VertexDeclaration " +
"onto the glsl attributes failed because we have " +
attributes + " Shader Attributes and " + elements.Length +
" elements in the vertex declaration which doesn't fit!");
effect.ActiveAttributes.Count + " Shader Attributes and " +
elements.Length + " elements in the vertex declaration which " +
"doesn't fit!");
}
foreach (VertexElement element in elements)
foreach (string key in effect.ActiveAttributes.Keys)
{
// TODO: element.UsageIndex?
EffectGL3.ShaderAttribute attribute = effect.ActiveAttributes[key];
GL.EnableVertexAttribArray(attribute.Location);
VertexElement element = elements[(int)attribute.Location];
switch (element.VertexElementUsage)
{
case VertexElementUsage.Binormal:
case VertexElementUsage.Normal:
case VertexElementUsage.Tangent:
case VertexElementUsage.BlendIndices:
case VertexElementUsage.BlendWeight:
case VertexElementUsage.Position:
int loc = GL.GetAttribLocation(programHandle, "pos");
ErrorHelper.Check("GetAttribLocation pos");
GL.EnableVertexAttribArray(loc);
ErrorHelper.Check("EnableVertexAttribArray pos");
GL.VertexAttribPointer(loc, 3, VertexAttribPointerType.Float,
false, vertexDeclaration.VertexStride, element.Offset);
ErrorHelper.Check("VertexAttribPointer pos");
GL.VertexAttribPointer((int)attribute.Location, 3,
VertexAttribPointerType.Float, false,
vertexDeclaration.VertexStride, element.Offset);
break;
case VertexElementUsage.Color:
int col = GL.GetAttribLocation(programHandle, "col");
ErrorHelper.Check("GetAttribLocation col");
GL.EnableVertexAttribArray(col);
ErrorHelper.Check("EnableVertexAttribArray col");
GL.VertexAttribPointer(col, 4, VertexAttribPointerType.UnsignedByte,
GL.VertexAttribPointer((int)attribute.Location, 4,
VertexAttribPointerType.UnsignedByte,
true, vertexDeclaration.VertexStride, element.Offset);
ErrorHelper.Check("VertexAttribPointer col");
break;
case VertexElementUsage.TextureCoordinate:
int tex = GL.GetAttribLocation(programHandle, "tex");
ErrorHelper.Check("GetAttribLocation tex");
GL.EnableVertexAttribArray(tex);
ErrorHelper.Check("EnableVertexAttribArray tex");
GL.VertexAttribPointer(tex, 2, VertexAttribPointerType.Float,
false, vertexDeclaration.VertexStride, element.Offset);
ErrorHelper.Check("VertexAttribPointer tex");
GL.VertexAttribPointer((int)attribute.Location, 2,
VertexAttribPointerType.Float, false,
vertexDeclaration.VertexStride, element.Offset);
break;
// TODO
case VertexElementUsage.Binormal:
case VertexElementUsage.BlendIndices:
case VertexElementUsage.BlendWeight:
case VertexElementUsage.Depth:
case VertexElementUsage.Fog:
case VertexElementUsage.Normal:
case VertexElementUsage.PointSize:
case VertexElementUsage.Sample:
case VertexElementUsage.Tangent:
case VertexElementUsage.TessellateFactor:
throw new NotImplementedException();
}

View File

@ -1,4 +1,5 @@
using System;
using ANX.Framework.NonXNA;
namespace RenderTarget
{
@ -10,6 +11,7 @@ namespace RenderTarget
/// </summary>
static void Main(string[] args)
{
//AddInSystemFactory.Instance.PreferredRenderSystem = "OpenGL3";
using (Game1 game = new Game1())
{
game.Run();

View File

@ -91,6 +91,10 @@
<Project>{5BE49183-2F6F-4527-AC90-D816911FCF90}</Project>
<Name>ANX.Framework.Windows.DX10</Name>
</ProjectReference>
<ProjectReference Include="..\..\RenderSystems\ANX.Framework.Windows.GL3\ANX.Framework.Windows.GL3.csproj">
<Project>{EB8258E0-6741-4DB9-B756-1EBDF67B1ED6}</Project>
<Name>ANX.Framework.Windows.GL3</Name>
</ProjectReference>
<ProjectReference Include="..\..\SoundSystems\ANX.SoundSystem.Windows.XAudio\ANX.SoundSystem.Windows.XAudio.csproj">
<Project>{6A582788-C4D2-410C-96CD-177F75712D65}</Project>
<Name>ANX.SoundSystem.Windows.XAudio</Name>

View File

@ -1,4 +1,5 @@
using System;
using ANX.Framework.NonXNA;
namespace WindowsGame1
{
@ -10,6 +11,7 @@ namespace WindowsGame1
/// </summary>
static void Main(string[] args)
{
//AddInSystemFactory.Instance.PreferredRenderSystem = "OpenGL3";
using (Game1 game = new Game1())
{
game.Run();

View File

@ -53,7 +53,7 @@ attribute vec2 tex;
varying vec4 diffuseColor;
varying vec2 diffuseTexCoord;
void main(void)
void main( )
{
gl_Position = MatrixTransform * pos;
diffuseTexCoord = tex;
@ -66,11 +66,13 @@ void main(void)
// Fragment Shader
//
precission mediump float;
uniform sampler2D Texture;
varying vec4 diffuseColor;
varying vec2 diffuseTexCoord;
void main(void)
void main( )
{
gl_FragColor = texture2D(Texture, diffuseTexCoord) * diffuseColor;
}