-
Notifications
You must be signed in to change notification settings - Fork 9
HipRenderer
-
HipRenderer was built based on OpenGL 3, as it was the first one to be implemented. That said, most of the nomenclatures are based on known OpenGL jargon.
-
Specific Direct3D object wrappers were created later, so, on the OpenGL side it is a do nothing implementation. As a rule of thumb, the abstraction must always cover/prioritize the most specific case.
-
Metal was implemented quite later, and after thoughtful sessions implementing it, it was decided that from that point onwards the renderer API would be more resembling to how Metal works, i.e: Less resource binding and more parameter sending based API.
-
Not currently thread safe, the class could even be a struct since its purely static.
- HipBlendEquation
- HipBlendFunction
- HipRendererMode (Could later be changed to Primitives)
- HipRendererType
Can be switched by changing the renderer.conf screen.renderer property:
- GL3
- D3D11
- METAL
When the application does not own the Window, that is, built with the version(dll), it should be started with HipRenderer.initExternal(HipRendererType)
Hipreme Engine | OpenGL | Direct3D | Metal |
---|---|---|---|
HipFrameBuffer | glFramebuffer/glRenderbuffer | ID3DRenderTargetView/ID3DShaderResourceView | None |
IHipVertexArrayImpl | glVertexArray | ID3D11InputLayout | MTLVertexDescriptor |
IHipVertexBufferImpl | glGenBuffer + GL_ARRAY_BUFFER | ID3D11Buffer + D3D11_BIND_VERTEX_BUFFER | MTLBuffer |
IHipIndexBufferImpl | glGenBuffers + GL_ELEMENT_ARRAY_BUFFER | ID3D11Buffer + D3D11_BIND_INDEX_BUFFER | MTLBuffer |
ShaderVariablesLayout | glGenBuffers + GL_UNIFORM_BUFFER | ID3D11Buffer + D3D11_BIND_CONSTANT_BUFFER | MTLBuffer |
- For the OpenGL versions that doesn't support GL_UNIFORM_BUFFER, it uses glUniform* calls.
Hipreme Engine | OpenGL | Direct3D | Metal |
---|---|---|---|
POINT | GL_POINTS | D3D11_PRIMITIVE_TOPOLOGY_POINTLIST | MTLPrimitiveType.Point |
LINE | GL_LINES | D3D11_PRIMITIVE_TOPOLOGY_LINELIST | MTLPrimitiveType.Line |
LINE_STRIP | GL_LINE_STRIP | D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP | MTLPrimitiveType.LineStrip |
TRIANGLES | GL_TRIANGLES | D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST | MTLPrimitiveType.Triangle |
TRIANGLE_STRIP | GL_TRIANGLE_STRIP | D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP | MTLPrimitiveType.TriangleStrip |
Hipreme Engine | OpenGL | Direct3D | Metal | Additional info |
---|---|---|---|---|
CLAMP_TO_EDGE | GL_CLAMP_TO_EDGE | D3D11_TEXTURE_ADDRESS_CLAMP | MTLSamplerAddressMode.ClampToEdge | None |
REPEAT | GL_REPEAT | D3D11_TEXTURE_ADDRESS_WRAP | MTLSamplerAddressMode.Repeat | None |
MIRRORED_REPEAT | GL_MIRRORED_REPEAT | D3D11_TEXTURE_ADDRESS_MIRROR | MTLSamplerAddressMode.MirrorRepeat | None |
MIRRORED_CLAMP_TO_EDGE | GL_MIRROR_CLAMP_TO_EDGE | D3D11_TEXTURE_ADDRESS_MIRROR_ONCE | MTLSamplerAddressMode.ClampToEdge | Unsupported on GLES |
CLAMP_TO_BORDER | GL_CLAMP_TO_BORDER | D3D11_TEXTURE_ADDRESS_BORDER | MTLSamplerAddressMode.ClampToBorderColor | Unsupported on GLES |
- Function to create a FragmentShader
- Function to create a VertexShader
- Function to create a ShaderProgram
- A function to send the variable to the shader. The Uniform/Constant buffer
- They have specific implementations for GeometryBatch, SpriteBatch and BitmapText, listed on
HipShaderPresets
For actually using a shader, you must first add a ShaderVariablesLayout
, for it being able to connect Shader variables with the D code sent variable.
An example can be found on HipSpriteBatch
.
//"Cbuf1" means that if there is a struct/cbuffer, it'll be accessed from that name
@HipShaderVertexUniform("Cbuf1")
struct HipSpriteVertexUniform
{
Matrix4 uModel = Matrix4.identity;
Matrix4 uView = Matrix4.identity;
Matrix4 uProj = Matrix4.identity;
}
@HipShaderFragmentUniform("Cbuf")
struct HipSpriteFragmentUniform
{
float[4] uBatchColor = [1,1,1,1];
@(ShaderHint.Blackbox | ShaderHint.MaxTextures)
IHipTexture[] uTex;
}
Shader shader = HipRenderer.newShader(q{vertexShaderSource}, q{fragmentShaderSource});
///Create a variable layout for the vertex shader
shader.addVarLayout(ShaderVariablesLayout.from!HipSpriteVertexUniform);
//Now it is possible to set those values
//Setting variable layout for the fragment shader:
shader.addVarLayout(ShaderVariablesLayout.from!HipSpriteFragmentUniform);
//Pretty much the same thing, only ShaderTypes has changed.
//Now, there comes an important part if you wish to make it work in both OpenGL and Direct3D with the same commands
//You can define a default Cbuf to know which variables you're setting. If this struct is not found, the command is simply ignored, so, you can make it work for both OpenGL without uniform buffers and Direct3D which requires cbuffers
shader.useLayout.Cbuf; //Cbuf is now the default variable setting target.
shader.uBatchColor = cast(float[4])[0.5, 0.5, 0.5];
//Bind the shader
shader.bind();
//Update the shader variables
shader.sendVars();
- Using a HipVertexArrayObject:
@HipShaderInputLayout struct HipSpriteVertex
{
Vector3 vPosition = Vector3.zero;
HipColorf vColor = HipColorf(0,0,0,0);
Vector2 vTexST = Vector2.zero;
float vTexID = 0;
}
HipVertexArrayObject obj = HipVertexArrayObject.getVAO!HipSpriteVertex;
//Now, for locking this format, call sendAttributes passing a Shader as an argument:
obj.bind();
obj.sendAttributes(shader);
//Create the data input
vao.createIndexBuffer(6, HipBufferUsage.STATIC);
vao.createVertexBuffer(4, HipBufferUsage.DYNAMIC);
//Now you can call both setVertices/updateVertices, setIndices/updateIndices for setting your data
index_t[] indices = [0, 1, 2, 2, 1, 0];
vao.setIndices(indices.length, indices.ptr);
float[] vertices = [
// X, Y, S, T
0, 0, 0, 0,
0, 1, 0, 1,
1, 1, 1, 1,
1, 0, 1, 0
];
vao.setVertices(vertices.length, vertices.ptr);
- Using a Mesh
A mesh is basically a shader + vao wrapper, which can make things easier in the long run, it is the expected way on how you're going to use:
mesh = new Mesh(HipVertexArrayObject.getVAO!HipSpriteVertex(), spriteBatchShader);
mesh.vao.bind();
mesh.createVertexBuffer(4, HipBufferUsage.DYNAMIC);
mesh.createIndexBuffer(6, HipBufferUsage.STATIC);
mesh.sendAttributes();
//setIndices and setVertices almost the same
HipRenderer.begin();
if(mesh)
{
mesh.draw(indices.length);
}
else
{
shader.bind();
vao.bind();
HipRenderer.drawIndexed(indices.length, HipRendererMode.TRIANGLES);
}
HipRenderer.end();