mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 22:41:46 +00:00
- fix vertex array object binding bug
- add shader program - fix that alpha color was stored in red channel in Color4 - fix buffer upload bug
This commit is contained in:
parent
fd37c455d2
commit
2eaf323ad0
15 changed files with 331 additions and 42 deletions
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Rendering
|
||||
{
|
||||
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Matrix
|
||||
{
|
||||
public float M11, M12, M13, M14;
|
||||
|
@ -189,7 +190,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
result.M11 = xScale;
|
||||
result.M22 = yScale;
|
||||
result.M33 = zfar / (znear - zfar);
|
||||
result.M43 = -znear * zfar / (znear - zfar);
|
||||
result.M43 = -2.0f * znear * zfar / (znear - zfar);
|
||||
result.M34 = 1.0f;
|
||||
return result;
|
||||
}
|
||||
|
@ -203,7 +204,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
result.M11 = xScale;
|
||||
result.M22 = yScale;
|
||||
result.M33 = zfar / (znear - zfar);
|
||||
result.M43 = znear * zfar / (znear - zfar);
|
||||
result.M43 = 2.0f * znear * zfar / (znear - zfar);
|
||||
result.M34 = -1.0f;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -125,19 +125,19 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// To ColorValue
|
||||
public Color4 ToColorValue()
|
||||
{
|
||||
return new Color4(a * BYTE_TO_FLOAT,
|
||||
r * BYTE_TO_FLOAT,
|
||||
return new Color4(r * BYTE_TO_FLOAT,
|
||||
g * BYTE_TO_FLOAT,
|
||||
b * BYTE_TO_FLOAT);
|
||||
b * BYTE_TO_FLOAT,
|
||||
a * BYTE_TO_FLOAT);
|
||||
}
|
||||
|
||||
// To ColorValue
|
||||
public Color4 ToColorValue(float withalpha)
|
||||
{
|
||||
return new Color4(withalpha,
|
||||
r * BYTE_TO_FLOAT,
|
||||
return new Color4(r * BYTE_TO_FLOAT,
|
||||
g * BYTE_TO_FLOAT,
|
||||
b * BYTE_TO_FLOAT);
|
||||
b * BYTE_TO_FLOAT,
|
||||
withalpha);
|
||||
}
|
||||
|
||||
// This returns a new PixelColor with adjusted alpha
|
||||
|
|
|
@ -72,11 +72,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
RenderDevice_SetAlphaBlendEnable(Handle, value);
|
||||
}
|
||||
|
||||
public void SetAlphaRef(int value)
|
||||
{
|
||||
RenderDevice_SetAlphaRef(Handle, value);
|
||||
}
|
||||
|
||||
public void SetAlphaTestEnable(bool value)
|
||||
{
|
||||
RenderDevice_SetAlphaTestEnable(Handle, value);
|
||||
|
@ -232,7 +227,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
// Setup renderstates
|
||||
SetAlphaBlendEnable(false);
|
||||
SetAlphaRef(0x0000007E);
|
||||
SetAlphaTestEnable(false);
|
||||
SetCullMode(Cull.None);
|
||||
SetDestinationBlend(Blend.InverseSourceAlpha);
|
||||
|
@ -276,9 +270,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetAlphaBlendEnable(IntPtr handle, bool value);
|
||||
|
||||
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetAlphaRef(IntPtr handle, int value);
|
||||
|
||||
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetAlphaTestEnable(IntPtr handle, bool value);
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RenderDevice.cpp" />
|
||||
<ClCompile Include="Shader.cpp" />
|
||||
<ClCompile Include="Texture.cpp" />
|
||||
<ClCompile Include="VertexBuffer.cpp" />
|
||||
<ClCompile Include="VertexDeclaration.cpp" />
|
||||
|
@ -218,6 +219,7 @@
|
|||
<ClInclude Include="OpenGLContext.h" />
|
||||
<ClInclude Include="Precomp.h" />
|
||||
<ClInclude Include="RenderDevice.h" />
|
||||
<ClInclude Include="Shader.h" />
|
||||
<ClInclude Include="Texture.h" />
|
||||
<ClInclude Include="VertexBuffer.h" />
|
||||
<ClInclude Include="VertexDeclaration.h" />
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
<Filter>gl_load</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OpenGLContext.cpp" />
|
||||
<ClCompile Include="Precomp.cpp" />
|
||||
<ClCompile Include="Shader.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="IndexBuffer.h" />
|
||||
|
@ -24,6 +26,8 @@
|
|||
<Filter>gl_load</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="OpenGLContext.h" />
|
||||
<ClInclude Include="Precomp.h" />
|
||||
<ClInclude Include="Shader.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="exports.def" />
|
||||
|
|
|
@ -13,7 +13,7 @@ IndexBuffer::~IndexBuffer()
|
|||
|
||||
void IndexBuffer::SetBufferData(const void* data, int64_t size)
|
||||
{
|
||||
if (size > 0 && size < (int64_t)mData.size())
|
||||
if (size > 0 && size <= (int64_t)mData.size())
|
||||
memcpy(mData.data(), data, size);
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,20 @@ void OpenGLContext::SwapBuffers()
|
|||
End();
|
||||
}
|
||||
|
||||
int OpenGLContext::GetWidth() const
|
||||
{
|
||||
RECT box = { 0 };
|
||||
GetClientRect(window, &box);
|
||||
return box.right;
|
||||
}
|
||||
|
||||
int OpenGLContext::GetHeight() const
|
||||
{
|
||||
RECT box = { 0 };
|
||||
GetClientRect(window, &box);
|
||||
return box.bottom;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OpenGLCreationHelper::OpenGLCreationHelper(HWND window) : window(window)
|
||||
|
|
|
@ -10,6 +10,9 @@ public:
|
|||
void End();
|
||||
void SwapBuffers();
|
||||
|
||||
int GetWidth() const;
|
||||
int GetHeight() const;
|
||||
|
||||
explicit operator bool() const { return context != 0; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include <Windows.h>
|
||||
#include "gl_load/gl_system.h"
|
||||
|
|
|
@ -5,8 +5,64 @@
|
|||
#include "IndexBuffer.h"
|
||||
#include "VertexDeclaration.h"
|
||||
#include "Texture.h"
|
||||
#include "Shader.h"
|
||||
#include <stdexcept>
|
||||
|
||||
const char* mainVertexShader = R"(
|
||||
#version 150
|
||||
|
||||
in vec4 AttrPosition;
|
||||
in vec4 AttrColor;
|
||||
in vec2 AttrUV;
|
||||
in vec3 AttrNormal;
|
||||
|
||||
out vec4 Color;
|
||||
out vec2 UV;
|
||||
out vec3 Normal;
|
||||
|
||||
uniform mat4 World;
|
||||
uniform mat4 View;
|
||||
uniform mat4 Projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
Color = AttrColor;
|
||||
UV = AttrUV;
|
||||
Normal = AttrNormal;
|
||||
gl_Position = Projection * View * World * AttrPosition;
|
||||
}
|
||||
)";
|
||||
|
||||
const char* mainFragmentShader = R"(
|
||||
#version 150
|
||||
|
||||
in vec4 Color;
|
||||
in vec2 UV;
|
||||
in vec3 Normal;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(UV, 1.0, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
RenderDevice::RenderDevice(HWND hwnd) : Context(hwnd)
|
||||
{
|
||||
if (Context)
|
||||
{
|
||||
Context.Begin();
|
||||
mShader = std::make_unique<Shader>();
|
||||
if (!mShader->Compile(mainVertexShader, mainFragmentShader))
|
||||
{
|
||||
throw std::runtime_error(mShader->GetErrors());
|
||||
}
|
||||
Context.End();
|
||||
}
|
||||
}
|
||||
|
||||
RenderDevice::~RenderDevice()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -24,34 +80,44 @@ void RenderDevice::SetIndexBuffer(IndexBuffer* buffer)
|
|||
|
||||
void RenderDevice::SetAlphaBlendEnable(bool value)
|
||||
{
|
||||
}
|
||||
|
||||
void RenderDevice::SetAlphaRef(int value)
|
||||
{
|
||||
mAlphaBlend = value;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetAlphaTestEnable(bool value)
|
||||
{
|
||||
mAlphaTest = value;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetCullMode(Cull mode)
|
||||
{
|
||||
mCullMode = mode;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetBlendOperation(BlendOperation op)
|
||||
{
|
||||
mBlendOperation = op;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetSourceBlend(Blend blend)
|
||||
{
|
||||
mSourceBlend = blend;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetDestinationBlend(Blend blend)
|
||||
{
|
||||
mDestinationBlend = blend;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetFillMode(FillMode mode)
|
||||
{
|
||||
mFillMode = mode;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetFogEnable(bool value)
|
||||
|
@ -80,10 +146,14 @@ void RenderDevice::SetTextureFactor(int factor)
|
|||
|
||||
void RenderDevice::SetZEnable(bool value)
|
||||
{
|
||||
mDepthTest = value;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetZWriteEnable(bool value)
|
||||
{
|
||||
mDepthWrite = value;
|
||||
mNeedApply = true;
|
||||
}
|
||||
|
||||
void RenderDevice::SetTransform(TransformState state, float* matrix)
|
||||
|
@ -128,12 +198,12 @@ void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
|
|||
{
|
||||
glClearColor(RPART(backcolor) / 255.0f, GPART(backcolor) / 255.0f, BPART(backcolor) / 255.0f, APART(backcolor) / 255.0f);
|
||||
glClearDepthf(1.0f);
|
||||
glClear(GL_COLOR | GL_DEPTH);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else if (clear)
|
||||
{
|
||||
glClearColor(RPART(backcolor) / 255.0f, GPART(backcolor) / 255.0f, BPART(backcolor) / 255.0f, APART(backcolor) / 255.0f);
|
||||
glClear(GL_COLOR);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
Context.End();
|
||||
}
|
||||
|
@ -155,16 +225,80 @@ void RenderDevice::CopyTexture(Texture* src, Texture* dst, CubeMapFace face)
|
|||
{
|
||||
}
|
||||
|
||||
void RenderDevice::CheckError()
|
||||
{
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
throw std::runtime_error("OpenGL error!");
|
||||
}
|
||||
|
||||
void RenderDevice::ApplyChanges()
|
||||
{
|
||||
ApplyShader();
|
||||
ApplyVertexBuffers();
|
||||
ApplyIndexBuffer();
|
||||
ApplyMatrices();
|
||||
ApplyTextures();
|
||||
ApplyRasterizerState();
|
||||
ApplyBlendState();
|
||||
ApplyDepthState();
|
||||
|
||||
CheckError();
|
||||
|
||||
mNeedApply = false;
|
||||
}
|
||||
|
||||
void RenderDevice::ApplyShader()
|
||||
{
|
||||
glUseProgram(mShader->GetProgram());
|
||||
}
|
||||
|
||||
void RenderDevice::ApplyRasterizerState()
|
||||
{
|
||||
if (mCullMode == Cull::None)
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
GLenum fillMode2GL[] = { GL_FILL, GL_LINE };
|
||||
glPolygonMode(GL_FRONT_AND_BACK, fillMode2GL[(int)mFillMode]);
|
||||
}
|
||||
|
||||
void RenderDevice::ApplyBlendState()
|
||||
{
|
||||
if (mAlphaBlend)
|
||||
{
|
||||
static const GLenum blendOp2GL[] = { GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT };
|
||||
static const GLenum blendFunc2GL[] = { GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE, GL_CONSTANT_COLOR };
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(blendOp2GL[(int)mBlendOperation]);
|
||||
glBlendFunc(blendFunc2GL[(int)mSourceBlend], blendFunc2GL[(int)mDestinationBlend]);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::ApplyDepthState()
|
||||
{
|
||||
if (mDepthTest)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(mDepthWrite ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::ApplyIndexBuffer()
|
||||
{
|
||||
if (mIndexBuffer)
|
||||
|
@ -180,11 +314,17 @@ void RenderDevice::ApplyIndexBuffer()
|
|||
void RenderDevice::ApplyVertexBuffers()
|
||||
{
|
||||
static const int typeSize[] = { 2, 3, 4 };
|
||||
static const int type[] = { GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE };
|
||||
static const int type[] = { GL_FLOAT, GL_FLOAT, GL_BGRA };
|
||||
static const int typeNormalized[] = { GL_FALSE, GL_FALSE, GL_TRUE };
|
||||
|
||||
if (mVertexDeclaration)
|
||||
{
|
||||
if (!mVAO)
|
||||
{
|
||||
glGenVertexArrays(1, &mVAO);
|
||||
glBindVertexArray(mVAO);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mVertexDeclaration->Elements.size(); i++)
|
||||
{
|
||||
const auto& element = mVertexDeclaration->Elements[i];
|
||||
|
@ -193,11 +333,12 @@ void RenderDevice::ApplyVertexBuffers()
|
|||
if (vertBinding.Buffer)
|
||||
{
|
||||
GLuint vertexbuffer = vertBinding.Buffer->GetBuffer();
|
||||
glEnableVertexAttribArray(location);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
||||
glEnableVertexAttribArray(location);
|
||||
glVertexAttribPointer(location, typeSize[(int)element.Type], type[(int)element.Type], typeNormalized[(int)element.Type], vertBinding.Stride, (const void*)(element.Offset + (ptrdiff_t)vertBinding.Offset));
|
||||
|
||||
mEnabledVertexAttributes[location] = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
@ -207,7 +348,7 @@ void RenderDevice::ApplyVertexBuffers()
|
|||
{
|
||||
if (mEnabledVertexAttributes[i] == 2)
|
||||
{
|
||||
mEnabledVertexAttributes[i]--;
|
||||
mEnabledVertexAttributes[i] = 1;
|
||||
}
|
||||
else if (mEnabledVertexAttributes[i] == 1)
|
||||
{
|
||||
|
@ -219,10 +360,10 @@ void RenderDevice::ApplyVertexBuffers()
|
|||
|
||||
void RenderDevice::ApplyMatrices()
|
||||
{
|
||||
for (size_t i = 0; i < NumTransforms; i++)
|
||||
for (size_t i = 0; i < (size_t)TransformState::NumTransforms; i++)
|
||||
{
|
||||
auto& binding = mTransforms[i];
|
||||
glUniformMatrix4fv((GLuint)i, 1, GL_FALSE, binding.Values);
|
||||
glUniformMatrix4fv(mShader->TransformLocations[i], 1, GL_FALSE, binding.Values);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,6 +385,7 @@ void RenderDevice::ApplyTextures()
|
|||
|
||||
void RenderDevice::ApplyRenderTarget(Texture* target, bool usedepthbuffer)
|
||||
{
|
||||
glViewport(0, 0, Context.GetWidth(), Context.GetHeight());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -282,11 +424,6 @@ void RenderDevice_SetAlphaBlendEnable(RenderDevice* device, bool value)
|
|||
device->SetAlphaBlendEnable(value);
|
||||
}
|
||||
|
||||
void RenderDevice_SetAlphaRef(RenderDevice* device, int value)
|
||||
{
|
||||
device->SetAlphaRef(value);
|
||||
}
|
||||
|
||||
void RenderDevice_SetAlphaTestEnable(RenderDevice* device, bool value)
|
||||
{
|
||||
device->SetAlphaTestEnable(value);
|
||||
|
|
|
@ -6,13 +6,14 @@ class VertexBuffer;
|
|||
class IndexBuffer;
|
||||
class VertexDeclaration;
|
||||
class Texture;
|
||||
class Shader;
|
||||
enum class CubeMapFace;
|
||||
|
||||
enum class Cull : int { None, Counterclockwise };
|
||||
enum class Blend : int { InverseSourceAlpha, SourceAlpha, One, BlendFactor };
|
||||
enum class BlendOperation : int { Add, ReverseSubtract };
|
||||
enum class FillMode : int { Solid, Wireframe };
|
||||
enum class TransformState : int { World, View, Projection };
|
||||
enum class TransformState : int { World, View, Projection, NumTransforms };
|
||||
enum class TextureAddress : int { Wrap, Clamp };
|
||||
enum class ShaderFlags : int { None, Debug };
|
||||
enum class PrimitiveType : int { LineList, TriangleList, TriangleStrip };
|
||||
|
@ -22,11 +23,11 @@ class RenderDevice
|
|||
{
|
||||
public:
|
||||
RenderDevice(HWND hwnd);
|
||||
~RenderDevice();
|
||||
|
||||
void SetVertexBuffer(int index, VertexBuffer* buffer, long offset, long stride);
|
||||
void SetIndexBuffer(IndexBuffer* buffer);
|
||||
void SetAlphaBlendEnable(bool value);
|
||||
void SetAlphaRef(int value);
|
||||
void SetAlphaTestEnable(bool value);
|
||||
void SetCullMode(Cull mode);
|
||||
void SetBlendOperation(BlendOperation op);
|
||||
|
@ -55,10 +56,16 @@ public:
|
|||
void ApplyChanges();
|
||||
void ApplyVertexBuffers();
|
||||
void ApplyIndexBuffer();
|
||||
void ApplyShader();
|
||||
void ApplyMatrices();
|
||||
void ApplyTextures();
|
||||
void ApplyRasterizerState();
|
||||
void ApplyBlendState();
|
||||
void ApplyDepthState();
|
||||
void ApplyRenderTarget(Texture* target, bool usedepthbuffer);
|
||||
|
||||
void CheckError();
|
||||
|
||||
OpenGLContext Context;
|
||||
|
||||
struct VertexBinding
|
||||
|
@ -87,12 +94,31 @@ public:
|
|||
TextureAddress AddressW = TextureAddress::Wrap;
|
||||
};
|
||||
|
||||
enum { NumTransforms = 3, NumSlots = 16 };
|
||||
Mat4f mTransforms[NumTransforms];
|
||||
enum { NumSlots = 16 };
|
||||
Mat4f mTransforms[(int)TransformState::NumTransforms];
|
||||
|
||||
VertexDeclaration *mVertexDeclaration = nullptr;
|
||||
GLuint mVAO = 0;
|
||||
int mEnabledVertexAttributes[NumSlots] = { 0 };
|
||||
VertexBinding mVertexBindings[NumSlots];
|
||||
|
||||
SamplerState mSamplerStates[NumSlots];
|
||||
|
||||
IndexBuffer* mIndexBuffer = nullptr;
|
||||
|
||||
std::unique_ptr<Shader> mShader;
|
||||
|
||||
Cull mCullMode = Cull::None;
|
||||
FillMode mFillMode = FillMode::Solid;
|
||||
bool mAlphaTest = false;
|
||||
|
||||
bool mAlphaBlend = false;
|
||||
BlendOperation mBlendOperation = BlendOperation::Add;
|
||||
Blend mSourceBlend = Blend::SourceAlpha;
|
||||
Blend mDestinationBlend = Blend::InverseSourceAlpha;
|
||||
|
||||
bool mDepthTest = false;
|
||||
bool mDepthWrite = false;
|
||||
|
||||
bool mNeedApply = true;
|
||||
};
|
||||
|
|
83
Source/Native/Shader.cpp
Normal file
83
Source/Native/Shader.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
|
||||
#include "Precomp.h"
|
||||
#include "Shader.h"
|
||||
#include "VertexDeclaration.h"
|
||||
#include "RenderDevice.h"
|
||||
#include <stdexcept>
|
||||
|
||||
Shader::Shader()
|
||||
{
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
// To do: move to delete list
|
||||
}
|
||||
|
||||
bool Shader::Compile(const std::string& vertexShader, const std::string& fragmentShader)
|
||||
{
|
||||
mVertexShader = CompileShader(vertexShader, GL_VERTEX_SHADER);
|
||||
if (!mVertexShader)
|
||||
return false;
|
||||
|
||||
mFragmentShader = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
|
||||
if (!mFragmentShader)
|
||||
return false;
|
||||
|
||||
mProgram = glCreateProgram();
|
||||
glAttachShader(mProgram, mVertexShader);
|
||||
glAttachShader(mProgram, mFragmentShader);
|
||||
glBindAttribLocation(mProgram, (GLuint)DeclarationUsage::Position, "AttrPosition");
|
||||
glBindAttribLocation(mProgram, (GLuint)DeclarationUsage::Color, "AttrColor");
|
||||
glBindAttribLocation(mProgram, (GLuint)DeclarationUsage::TextureCoordinate, "AttrUV");
|
||||
glBindAttribLocation(mProgram, (GLuint)DeclarationUsage::Normal, "AttrNormal");
|
||||
glLinkProgram(mProgram);
|
||||
|
||||
GLint status = 0;
|
||||
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
|
||||
if (status != GL_TRUE)
|
||||
{
|
||||
GLsizei length = 0;
|
||||
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &length);
|
||||
std::vector<GLchar> errors(length + (size_t)1);
|
||||
glGetProgramInfoLog(mProgram, (GLsizei)errors.size(), &length, errors.data());
|
||||
mErrors = { errors.begin(), errors.begin() + length };
|
||||
|
||||
glDeleteProgram(mProgram);
|
||||
glDeleteShader(mVertexShader);
|
||||
glDeleteShader(mFragmentShader);
|
||||
mProgram = 0;
|
||||
mVertexShader = 0;
|
||||
mFragmentShader = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
TransformLocations[(int)TransformState::World] = glGetUniformLocation(mProgram, "World");
|
||||
TransformLocations[(int)TransformState::View] = glGetUniformLocation(mProgram, "View");
|
||||
TransformLocations[(int)TransformState::Projection] = glGetUniformLocation(mProgram, "Projection");
|
||||
|
||||
return mProgram;
|
||||
}
|
||||
|
||||
GLuint Shader::CompileShader(const std::string& code, GLenum type)
|
||||
{
|
||||
GLuint shader = glCreateShader(type);
|
||||
const GLchar* sources[] = { (GLchar*)code.data() };
|
||||
const GLint lengths[] = { (GLint)code.size() };
|
||||
glShaderSource(shader, 1, sources, lengths);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint status = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (status != GL_TRUE)
|
||||
{
|
||||
GLsizei length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
|
||||
std::vector<GLchar> errors(length + (size_t)1);
|
||||
glGetShaderInfoLog(shader, (GLsizei)errors.size(), &length, errors.data());
|
||||
mErrors = { errors.begin(), errors.begin() + length };
|
||||
glDeleteShader(shader);
|
||||
return 0;
|
||||
}
|
||||
return shader;
|
||||
}
|
29
Source/Native/Shader.h
Normal file
29
Source/Native/Shader.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "RenderDevice.h"
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader();
|
||||
~Shader();
|
||||
|
||||
bool Compile(const std::string& vertexShader, const std::string& fragmentShader);
|
||||
const char* GetErrors() const { return mErrors.c_str(); }
|
||||
|
||||
GLuint GetProgram() const { return mProgram; }
|
||||
|
||||
GLuint TransformLocations[(int)TransformState::NumTransforms] = { 0 };
|
||||
|
||||
private:
|
||||
GLuint CompileShader(const std::string& code, GLenum type);
|
||||
|
||||
GLuint mProgram = 0;
|
||||
GLuint mVertexShader = 0;
|
||||
GLuint mFragmentShader = 0;
|
||||
std::string mErrors;
|
||||
|
||||
Shader(const Shader&) = delete;
|
||||
Shader& operator=(const Shader&) = delete;
|
||||
};
|
|
@ -13,13 +13,13 @@ VertexBuffer::~VertexBuffer()
|
|||
|
||||
void VertexBuffer::SetBufferData(const void* data, int64_t size)
|
||||
{
|
||||
if (size > 0 && size < (int64_t)mData.size())
|
||||
if (size > 0 && size <= (int64_t)mData.size())
|
||||
memcpy(mData.data(), data, size);
|
||||
}
|
||||
|
||||
void VertexBuffer::SetBufferSubdata(int64_t destOffset, const void* data, int64_t size)
|
||||
{
|
||||
if (destOffset >= 0 && size > 0 && size < (int64_t)mData.size() - destOffset)
|
||||
if (destOffset >= 0 && size > 0 && size <= (int64_t)mData.size() - destOffset)
|
||||
memcpy(mData.data() + destOffset, data, size);
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,6 @@ GLuint VertexBuffer::GetBuffer()
|
|||
glGenBuffers(1, &mBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, mData.size(), mData.data(), GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
return mBuffer;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ EXPORTS
|
|||
RenderDevice_SetVertexBuffer
|
||||
RenderDevice_SetIndexBuffer
|
||||
RenderDevice_SetAlphaBlendEnable
|
||||
RenderDevice_SetAlphaRef
|
||||
RenderDevice_SetAlphaTestEnable
|
||||
RenderDevice_SetCullMode
|
||||
RenderDevice_SetBlendOperation
|
||||
|
|
Loading…
Reference in a new issue