aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2017-12-26 17:29:28 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-18 15:21:48 +0100
commitffe9dac56488ebfc9f5c37c4e400f4f5469a8a46 (patch)
tree5958b66f16d217e31215d2f6ec56bb341ec06a76 /src
parentb5f06b6c4cd07f3073897af32626b9b21a4d2ef8 (diff)
Add device memory, device frame. Rendering works
Diffstat (limited to 'src')
-rw-r--r--src/RenderBackend/OpenGL/CompiledShader.cpp7
-rw-r--r--src/RenderBackend/OpenGL/DeviceFrame.cpp36
-rw-r--r--src/RenderBackend/OpenGL/DeviceMemory.cpp51
-rw-r--r--src/RenderBackend/OpenGL/PixelShader.cpp2
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp17
-rw-r--r--src/RenderBackend/OpenGL/ShaderVec.cpp31
-rw-r--r--src/RenderBackend/OpenGL/VertexShader.cpp16
-rw-r--r--src/main.cpp29
8 files changed, 160 insertions, 29 deletions
diff --git a/src/RenderBackend/OpenGL/CompiledShader.cpp b/src/RenderBackend/OpenGL/CompiledShader.cpp
index 6707b7a..f4a1fec 100644
--- a/src/RenderBackend/OpenGL/CompiledShader.cpp
+++ b/src/RenderBackend/OpenGL/CompiledShader.cpp
@@ -1,6 +1,8 @@
#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+using namespace std;
+
namespace amalgine
{
CompiledVertexShader::CompiledVertexShader(u32 _shaderId) :
@@ -19,8 +21,9 @@ namespace amalgine
return shaderId;
}
- CompiledPixelShader::CompiledPixelShader(u32 _shaderId) :
- shaderId(_shaderId)
+ CompiledPixelShader::CompiledPixelShader(u32 _shaderId, unordered_map<string, i32> &&_pixelAttributes) :
+ shaderId(_shaderId),
+ pixelAttributes(_pixelAttributes)
{
}
diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp
new file mode 100644
index 0000000..9d60597
--- /dev/null
+++ b/src/RenderBackend/OpenGL/DeviceFrame.cpp
@@ -0,0 +1,36 @@
+#include "../../../include/RenderBackend/OpenGL/DeviceFrame.hpp"
+#include "../../../include/RenderBackend/OpenGL/DeviceMemory.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+
+namespace amalgine
+{
+ DeviceFrame::DeviceFrame()
+ {
+ glGenVertexArrays(1, &vertexArrayObjectId);
+ }
+
+ DeviceFrame::~DeviceFrame()
+ {
+ for(DeviceMemory *deviceMemory : buffers)
+ {
+ delete deviceMemory;
+ }
+ glDeleteVertexArrays(1, &vertexArrayObjectId);
+ }
+
+ DeviceMemory* DeviceFrame::alloc()
+ {
+ glBindVertexArray(vertexArrayObjectId);
+ DeviceMemory *deviceMemory = new DeviceMemory();
+ buffers.push_back(deviceMemory);
+ return deviceMemory;
+ }
+
+ void DeviceFrame::draw()
+ {
+ for(DeviceMemory *deviceMemory : buffers)
+ {
+ deviceMemory->draw();
+ }
+ }
+}
diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp
index 9e33ac9..faf2943 100644
--- a/src/RenderBackend/OpenGL/DeviceMemory.cpp
+++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp
@@ -3,7 +3,33 @@
namespace amalgine
{
- DeviceMemory::DeviceMemory()
+ u32 getOpenglStorageType(DeviceMemory::StorageType storageType)
+ {
+ switch(storageType)
+ {
+ case DeviceMemory::StorageType::STATIC: return GL_STATIC_DRAW;
+ case DeviceMemory::StorageType::DYNAMIC: return GL_DYNAMIC_DRAW;
+ case DeviceMemory::StorageType::STREAM: return GL_STREAM_DRAW;
+ }
+ }
+
+ u32 getOpenglPrimitiveType(DeviceMemory::PrimitiveType primitiveType)
+ {
+ switch(primitiveType)
+ {
+ case DeviceMemory::PrimitiveType::TRIANGLE: return GL_TRIANGLES;
+ }
+ }
+
+ u32 getPrimitiveTypePointsPerVertices(DeviceMemory::PrimitiveType primitiveType)
+ {
+ switch(primitiveType)
+ {
+ case DeviceMemory::PrimitiveType::TRIANGLE: return 3;
+ }
+ }
+
+ DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0)
{
glGenBuffers(1, &vertexBufferObjectId);
}
@@ -13,24 +39,29 @@ namespace amalgine
glDeleteBuffers(1, &vertexBufferObjectId);
}
- void DeviceMemory::copyAsStatic(const DataView<f32> &data)
+ void DeviceMemory::operator delete(void *data)
{
- copy(data, GL_STATIC_DRAW);
+ free(data);
}
- void DeviceMemory::copyAsDynamic(const DataView<f32> &data)
+ void DeviceMemory::use() const
{
- copy(data, GL_DYNAMIC_DRAW);
+ // TODO: Bind vao here?
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
}
- void DeviceMemory::copyAsStream(const DataView<f32> &data)
+ void DeviceMemory::copy(const DataView<f32> &data, StorageType storageType, PrimitiveType primitiveType)
{
- copy(data, GL_STREAM_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
+ glBufferData(GL_ARRAY_BUFFER, data.getByteSize(), data.data, getOpenglStorageType(storageType));
+ this->primitiveType = getOpenglPrimitiveType(primitiveType);
+ numVertices = getPrimitiveTypePointsPerVertices(primitiveType);
}
- void DeviceMemory::copy(const DataView<f32> &data, i32 storageType)
+ void DeviceMemory::draw()
{
- glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
- glBufferData(GL_ARRAY_BUFFER, data.getByteSize(), data.data, storageType);
+ if(primitiveType == 0)
+ throw DeviceMemoryEmpty("Unable to draw buffer as no data has been copied to device memory");
+ glDrawArrays(primitiveType, 0, 3);
}
}
diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp
index 2af68e5..8aa4d9a 100644
--- a/src/RenderBackend/OpenGL/PixelShader.cpp
+++ b/src/RenderBackend/OpenGL/PixelShader.cpp
@@ -131,7 +131,7 @@ namespace amalgine
{
if(!compileLog.empty())
printf("Pixel shader compile log:\n%s", compileLog.c_str());
- return Result<CompiledPixelShader*>::Ok(new CompiledPixelShader(fragmentShaderId));
+ return Result<CompiledPixelShader*>::Ok(new CompiledPixelShader(fragmentShaderId, move(pixelAttributes)));
}
else
return Result<CompiledPixelShader*>::Err(compileLog);
diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp
index f76903e..40f5b6c 100644
--- a/src/RenderBackend/OpenGL/ShaderProgram.cpp
+++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp
@@ -36,17 +36,30 @@ namespace amalgine
// TODO: Before adding shader to program, check if it has already been added
- bool ShaderProgram::addVertexShader(CompiledVertexShader *vertexShader)
+ bool ShaderProgram::setVertexShader(CompiledVertexShader *vertexShader)
{
+ if(!vertexShader) return false;
+
// TODO: Do not allow adding shader if the program has already been built
glAttachShader(shaderProgramId, vertexShader->getShaderId());
return true;
}
- bool ShaderProgram::addPixelShader(CompiledPixelShader *pixelShader)
+ bool ShaderProgram::setPixelShader(CompiledPixelShader *pixelShader)
{
+ if(!pixelShader) return false;
+
// TODO: Do not allow adding shader if the program has already been built
glAttachShader(shaderProgramId, pixelShader->getShaderId());
+
+ const auto &pixelAttributes = pixelShader->getPixelAttributes();
+ for(const auto &pixelAttribute : pixelAttributes)
+ {
+ const string &attributeName = pixelAttribute.first;
+ i32 attributeLocation = pixelAttribute.second;
+ glBindFragDataLocation(shaderProgramId, attributeLocation, attributeName.c_str());
+ }
+
return true;
}
diff --git a/src/RenderBackend/OpenGL/ShaderVec.cpp b/src/RenderBackend/OpenGL/ShaderVec.cpp
index 6411650..3bbe0be 100644
--- a/src/RenderBackend/OpenGL/ShaderVec.cpp
+++ b/src/RenderBackend/OpenGL/ShaderVec.cpp
@@ -2,16 +2,47 @@
#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp"
#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp"
#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+#include <cstring>
+#include <cassert>
using namespace std;
namespace amalgine
{
+ AttributeType getAttributeTypeByName(const char *attributeName)
+ {
+ if(strncmp(attributeName, "vec2", 4) == 0)
+ {
+ return AttributeType::VEC2;
+ }
+
+ return AttributeType::NONE;
+ }
+
const string& ShaderInputVec2::getName() const
{
return vertexShader->getInputAttributeName(attributeIndex);
}
+ void ShaderInputVec2::setData(const DeviceMemory &data)
+ {
+ data.use();
+ AttributeType attributeType = vertexShader->getInputAttributeType(attributeIndex);
+ switch(attributeType)
+ {
+ case AttributeType::VEC2:
+ {
+ glVertexAttribPointer(attributeIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ break;
+ }
+ default:
+ assert(false);
+ break;
+ }
+ glEnableVertexAttribArray(attributeIndex);
+ }
+
const string& ShaderOutputVec4::getName() const
{
return pixelShader->getOutputAttributeName(attributeIndex);
diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp
index 1505ff4..ac9a159 100644
--- a/src/RenderBackend/OpenGL/VertexShader.cpp
+++ b/src/RenderBackend/OpenGL/VertexShader.cpp
@@ -1,5 +1,4 @@
#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
@@ -37,10 +36,16 @@ namespace amalgine
writeHeader("#version 330 core\n\n");
}
- const string& VertexShader::getInputAttributeName(i32 attributeIndex)
+ const string& VertexShader::getInputAttributeName(i32 attributeIndex) const
{
assert(attributeIndex < vertexAttributeNames.size());
- return vertexAttributeNames[attributeIndex];
+ return vertexAttributeNames[attributeIndex].name;
+ }
+
+ AttributeType VertexShader::getInputAttributeType(i32 attributeIndex) const
+ {
+ assert(attributeIndex < vertexAttributeNames.size());
+ return getAttributeTypeByName(vertexAttributeNames[attributeIndex].typeName);
}
ShaderInputVec2 VertexShader::defineInputVec2(const std::string &name)
@@ -75,7 +80,10 @@ namespace amalgine
i32 attributeIndex = locationCounter;
vertexAttributes[variableName] = locationCounter;
- vertexAttributeNames.push_back(variableName);
+ ShaderAttribute shaderAttribute;
+ shaderAttribute.name = variableName;
+ shaderAttribute.typeName = typeName;
+ vertexAttributeNames.push_back(shaderAttribute);
writeHeader("layout(location = ");
writeHeader(to_string(locationCounter));
diff --git a/src/main.cpp b/src/main.cpp
index b1a0d62..0e72df0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,11 +1,16 @@
#include <cstdio>
-#include <GL/glew.h>
-#include <GLFW/glfw3.h>
-#include <glm/glm.hpp>
+#include "../include/RenderBackend/OpenGL/opengl.hpp"
#include "../include/RenderBackend/OpenGL/VertexShader.hpp"
#include "../include/RenderBackend/OpenGL/PixelShader.hpp"
#include "../include/RenderBackend/OpenGL/ShaderProgram.hpp"
#include "../include/RenderBackend/OpenGL/DeviceMemory.hpp"
+#include "../include/RenderBackend/OpenGL/DeviceFrame.hpp"
+
+// TODO: Disallow shader variables that begin with "gl_" as reserved variables
+// start with that. What about hlsl?
+
+// TODO: Creating buffers etc should be somehow created/drawn using the window object, since they are associated with the window
+// opengl context
using namespace amalgine;
using namespace std;
@@ -14,7 +19,7 @@ void initGlfw();
void initGlew();
GLFWwindow *createWindow();
-CompiledVertexShader* createVertexShader();
+CompiledVertexShader* createVertexShader(const DeviceMemory &inputData);
CompiledPixelShader* createPixelShader();
int main()
@@ -22,22 +27,24 @@ int main()
initGlfw();
GLFWwindow *window = createWindow();
+ DeviceFrame frame;
+
f32 verticesRaw[] =
{
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
+ DeviceMemory *triangle = frame.alloc();
DataView<f32> vertices(verticesRaw, 6);
- DeviceMemory triangle;
- triangle.copyAsStatic(vertices);
+ triangle->copy(vertices, DeviceMemory::StorageType::STATIC);
- CompiledVertexShader *vertexShader = createVertexShader();
+ CompiledVertexShader *vertexShader = createVertexShader(*triangle);
CompiledPixelShader *pixelShader = createPixelShader();
ShaderProgram shaderProgram;
- shaderProgram.addVertexShader(vertexShader);
- shaderProgram.addPixelShader(pixelShader);
+ shaderProgram.setVertexShader(vertexShader);
+ shaderProgram.setPixelShader(pixelShader);
Result<bool> shaderBuildResult = shaderProgram.build();
if(!shaderBuildResult)
{
@@ -52,6 +59,7 @@ int main()
glfwSetWindowShouldClose(window, GL_TRUE);
shaderProgram.use();
+ frame.draw();
glfwSwapBuffers(window);
}
@@ -102,10 +110,11 @@ GLFWwindow* createWindow()
return window;
}
-CompiledVertexShader* createVertexShader()
+CompiledVertexShader* createVertexShader(const DeviceMemory &inputData)
{
VertexShader vertexShader;
ShaderInputVec2 inputPosition = vertexShader.defineInputVec2("position");
+ inputPosition.setData(inputData);
vertexShader.defineMain([&inputPosition]()
{