From b5b43bac50ad58949e70bcd1a34b1e6c4765fd51 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 10 Apr 2019 09:03:57 +0800 Subject: *misc --- .../asura-core/graphics/binding/_gpu_buffer.cpp | 120 +++++++++++++++++++++ .../modules/asura-core/graphics/binding/_image.cpp | 10 -- .../asura-core/graphics/binding/_shader.cpp | 100 ++++++++++++++--- source/modules/asura-core/graphics/gl.cpp | 20 +++- source/modules/asura-core/graphics/gl.h | 7 +- source/modules/asura-core/graphics/gpu_buffer.cpp | 76 +++++++++---- source/modules/asura-core/graphics/gpu_buffer.h | 39 +++++-- source/modules/asura-core/graphics/image.cpp | 66 +++++++----- source/modules/asura-core/graphics/image.h | 23 ++-- .../modules/asura-core/graphics/index_buffer.cpp | 0 source/modules/asura-core/graphics/index_buffer.h | 0 .../modules/asura-core/graphics/matrix_stack.cpp | 4 +- source/modules/asura-core/graphics/matrix_stack.h | 4 +- source/modules/asura-core/graphics/mesh2d.h | 1 + source/modules/asura-core/graphics/render_state.h | 1 - source/modules/asura-core/graphics/shader.cpp | 112 ++++++++++++++++--- source/modules/asura-core/graphics/shader.h | 60 +++++------ source/modules/asura-core/graphics/texture.h | 16 ++- .../modules/asura-core/graphics/vertex_buffer.cpp | 0 source/modules/asura-core/graphics/vertex_buffer.h | 29 +++++ source/modules/asura-core/mesh/am2_handler.cpp | 6 +- source/modules/asura-core/mesh/mesh2d_data.h | 2 + 22 files changed, 533 insertions(+), 163 deletions(-) create mode 100644 source/modules/asura-core/graphics/binding/_gpu_buffer.cpp create mode 100644 source/modules/asura-core/graphics/index_buffer.cpp create mode 100644 source/modules/asura-core/graphics/index_buffer.h create mode 100644 source/modules/asura-core/graphics/vertex_buffer.cpp create mode 100644 source/modules/asura-core/graphics/vertex_buffer.h (limited to 'source/modules') diff --git a/source/modules/asura-core/graphics/binding/_gpu_buffer.cpp b/source/modules/asura-core/graphics/binding/_gpu_buffer.cpp new file mode 100644 index 0000000..7a63c48 --- /dev/null +++ b/source/modules/asura-core/graphics/binding/_gpu_buffer.cpp @@ -0,0 +1,120 @@ +#include + +#include "../image.h" +#include "../gpu_buffer.h" + +using namespace std; +using namespace Luax; + +namespace AsuraEngine +{ + namespace Graphics + { + + LUAX_REGISTRY(GPUBuffer) + { + LUAX_REGISTER_METHODS(state, + { "New", _New }, + { "Fill", _Fill }, + { "GetSize", _GetSize }, + { "GetCount", _GetCount } + ); + } + + LUAX_POSTPROCESS(GPUBuffer) + { + LUAX_REGISTER_ENUM(state, "EBufferType", + { "VERTEX", BUFFER_TYPE_VERTEX }, + { "INDEX", BUFFER_TYPE_INDEX } + ); + LUAX_REGISTER_ENUM(state, "EBufferUsage", + { "STREAM", BUFFER_USAGE_STREAM }, + { "DYNAMIC", BUFFER_USAGE_DYNAMIC }, + { "STATIC", BUFFER_USAGE_STATIC } + ); + LUAX_REGISTER_ENUM(state, "EBufferDataType", + { "INT", BUFFER_DATA_TYPE_INT }, + { "FLOAT", BUFFER_DATA_TYPE_FLOAT }, + { "UNSIGNED_BYTE", BUFFER_DATA_TYPE_UNSIGNED_BYTE } + ); + + } + + // buffer = GPUBuffer.New(bufferType, bufferUsage, bufferDataType, size) + // buffer = GPUBuffer.New(image) + // buffer = GPUBuffer.New(mesh2d) + // buffer = GPUBuffer.New(canvas) + // buffer = GPUBuffer.New(shape) + LUAX_IMPL_METHOD(GPUBuffer, _New) + { + LUAX_STATE(L); + + return 0; + } + + // gpubuffer:Fill({data unit list}, offseti) + // data_unit_list :存放数据的table + // offseti : 开始覆盖的地方所在的索引(从0开始) + LUAX_IMPL_METHOD(GPUBuffer, _Fill) + { + LUAX_PREPARE(L, GPUBuffer); + + // 使用buffer对应的类型数据修改buffer,在第一次调用时会初始化size大小的buffer,然后填充。 + int offset = state.GetValue(3, 0); + int count = lua_objlen(L, 2); + int size = count * self->GetDataTypeSize(); + byte* data = (byte*)malloc(size); + int unit = self->GetDataTypeSize(); + int i = 1; + lua_rawgeti(L, 2, i); + while (!lua_isnil(L, -1)) + { + switch (self->mDataType) + { + case GL_INT: + { + int n = state.CheckValue(-1); + memcpy(data + (i - 1)*unit, &n, unit); + break; + } + case GL_FLOAT: + { + float n = state.CheckValue(-1); + memcpy(data + (i - 1)*unit, &n, unit); + break; + } + case GL_UNSIGNED_BYTE: + { + unsigned char n = state.CheckValue(-1); + memcpy(data + (i - 1)*unit, &n, unit); + break; + } + } + state.Pop(1); // value + lua_rawgeti(L, 2, ++i); + } + state.Pop(); // nil + + self->Fill(data, size, offset * unit); + + free(data); + return 0; + } + + // gpubuffer:GetSize() + LUAX_IMPL_METHOD(GPUBuffer, _GetSize) + { + LUAX_PREPARE(L, GPUBuffer); + state.Push(self->mSize); + return 0; + } + + LUAX_IMPL_METHOD(GPUBuffer, _GetCount) + { + LUAX_PREPARE(L, GPUBuffer); + state.Push(self->mSize / self->GetDataTypeSize()); + return 0; + } + + } +} diff --git a/source/modules/asura-core/graphics/binding/_image.cpp b/source/modules/asura-core/graphics/binding/_image.cpp index 76ac635..99373e3 100644 --- a/source/modules/asura-core/graphics/binding/_image.cpp +++ b/source/modules/asura-core/graphics/binding/_image.cpp @@ -13,7 +13,6 @@ namespace AsuraEngine LUAX_REGISTER_METHODS(state, { "New", _New }, - { "Update", _Update }, { "GetWidth", _GetWidth }, { "GetHeight", _GetHeight }, { "GetSize", _GetSize }, @@ -34,15 +33,6 @@ namespace AsuraEngine return 1; } - // successed = image:Update(imgData) - LUAX_IMPL_METHOD(Image, _Update) - { - LUAX_PREPARE(L, Image); - ImageData* imgData = state.CheckUserdata(2); - state.Push(self->Load(imgData)); - return 1; - } - // width = image:GetWidth() LUAX_IMPL_METHOD(Image, _GetWidth) { diff --git a/source/modules/asura-core/graphics/binding/_shader.cpp b/source/modules/asura-core/graphics/binding/_shader.cpp index af6e981..e0a6320 100644 --- a/source/modules/asura-core/graphics/binding/_shader.cpp +++ b/source/modules/asura-core/graphics/binding/_shader.cpp @@ -1,6 +1,7 @@ #include "../shader.h" using namespace std; +using namespace Luax; namespace AsuraEngine { @@ -11,9 +12,8 @@ namespace AsuraEngine { LUAX_REGISTER_METHODS(state, { "New", _New }, - { "Use", _Use }, - { "Unuse", _Unuse }, { "Load", _Load }, + { "Update", _Update }, { "HasUniform", _HasUniform }, { "GetUniformLocation", _GetUniformLocation }, { "SetBuiltInUniforms", _SetBuiltInUniforms }, @@ -22,7 +22,16 @@ namespace AsuraEngine { "SetUniformVector2", _SetUniformVector2 }, { "SetUniformVector3", _SetUniformVector3 }, { "SetUniformVector4", _SetUniformVector4 }, - { "SetUniformColor", _SetUniformColor } + { "SetUniformColor", _SetUniformColor }, + { "SetAttribPosition", _SetAttribPosition }, + { "SetAttribTangent", _SetAttribTangent }, + { "SetAttribNormal", _SetAttribNormal }, + { "SetAttribColor", _SetAttribColor }, + { "SetAttribTexcoord0", _SetAttribTexcoord0 }, + { "SetAttribTexcoord1", _SetAttribTexcoord1 }, + { "SetAttribTexcoord2", _SetAttribTexcoord2 }, + { "SetAttribTexcoord3", _SetAttribTexcoord3 }, + { "SetBuiltInUniforms", _SetBuiltInUniforms } ); } @@ -39,24 +48,16 @@ namespace AsuraEngine return 0; } - // shader:Use() - LUAX_IMPL_METHOD(Shader, _Use) + // shader:Load() + LUAX_IMPL_METHOD(Shader, _Load) { LUAX_PREPARE(L, Shader); - return 0; - - } - // shader:Unuse() - LUAX_IMPL_METHOD(Shader, _Unuse) - { - LUAX_PREPARE(L, Shader); return 0; - } - // shader:Load() - LUAX_IMPL_METHOD(Shader, _Load) + // shader:Update() + LUAX_IMPL_METHOD(Shader, _Update) { LUAX_PREPARE(L, Shader); @@ -99,6 +100,7 @@ namespace AsuraEngine LUAX_IMPL_METHOD(Shader, _SetUniformTexture) { LUAX_PREPARE(L, Shader); + return 0; } @@ -106,6 +108,7 @@ namespace AsuraEngine LUAX_IMPL_METHOD(Shader, _SetUniformVector2) { LUAX_PREPARE(L, Shader); + return 0; } @@ -113,6 +116,7 @@ namespace AsuraEngine LUAX_IMPL_METHOD(Shader, _SetUniformVector3) { LUAX_PREPARE(L, Shader); + return 0; } @@ -120,6 +124,7 @@ namespace AsuraEngine LUAX_IMPL_METHOD(Shader, _SetUniformVector4) { LUAX_PREPARE(L, Shader); + return 0; } @@ -127,6 +132,71 @@ namespace AsuraEngine LUAX_IMPL_METHOD(Shader, _SetUniformColor) { LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribPosition() + LUAX_IMPL_METHOD(Shader, _SetAttribPosition) + { + LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribTangent() + LUAX_IMPL_METHOD(Shader, _SetAttribTangent) + { + LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribNormal() + LUAX_IMPL_METHOD(Shader, _SetAttribNormal) + { + LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribColor() + LUAX_IMPL_METHOD(Shader, _SetAttribColor) + { + LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribTexcoord0() + LUAX_IMPL_METHOD(Shader, _SetAttribTexcoord0) + { + LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribTexcoord1() + LUAX_IMPL_METHOD(Shader, _SetAttribTexcoord1) + { + LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribTexcoord2() + LUAX_IMPL_METHOD(Shader, _SetAttribTexcoord2) + { + LUAX_PREPARE(L, Shader); + + return 0; + } + + // shader:SetAttribTexcoord3() + LUAX_IMPL_METHOD(Shader, _SetAttribTexcoord3) + { + LUAX_PREPARE(L, Shader); + return 0; } diff --git a/source/modules/asura-core/graphics/gl.cpp b/source/modules/asura-core/graphics/gl.cpp index 537d40d..e51e8f0 100644 --- a/source/modules/asura-core/graphics/gl.cpp +++ b/source/modules/asura-core/graphics/gl.cpp @@ -82,7 +82,6 @@ namespace AsuraEngine void OpenGL::UseShader(Shader* shader) { glUseProgram(shader->GetGLProgram()); - int err = gl.HasError(); state.shader = shader; shader->OnUse(); } @@ -93,6 +92,17 @@ namespace AsuraEngine state.shader = nullptr; } + Shader* OpenGL::GetShader() + { + return state.shader; + } + + void OpenGL::DrawArrays(GLenum mode, GLint first, GLsizei count) + { + glDrawArrays(mode, first, count); + ++state.drawcall; + } + //------------------------------------------------------------------------------// void OpenGL::SetMatrixMode(MatrixMode mode) @@ -120,9 +130,9 @@ namespace AsuraEngine state.matrix[state.matrixMode].LoadIdentity(); } - void OpenGL::Rotate(float angle, float x, float y, float z) + void OpenGL::Rotate(float angle) { - state.matrix[state.matrixMode].Rotate(angle, x, y, z); + state.matrix[state.matrixMode].Rotate(angle); } void OpenGL::Translate(float x, float y) @@ -130,9 +140,9 @@ namespace AsuraEngine state.matrix[state.matrixMode].Translate(x, y); } - void OpenGL::Scale(float x, float y, float z) + void OpenGL::Scale(float x, float y) { - state.matrix[state.matrixMode].Scale(x, y, z); + state.matrix[state.matrixMode].Scale(x, y); } void OpenGL::Ortho(float l, float r, float b, float t, float n, float f) diff --git a/source/modules/asura-core/graphics/gl.h b/source/modules/asura-core/graphics/gl.h index 82b9821..f28b983 100644 --- a/source/modules/asura-core/graphics/gl.h +++ b/source/modules/asura-core/graphics/gl.h @@ -61,8 +61,12 @@ namespace AsuraEngine void UseShader(Shader* shader); void UnuseShader(); + Shader* GetShader(); - void Draw(); + /// + /// 用来方便统计drawcall + /// + void DrawArrays(GLenum mode, GLint first, GLsizei count); /// /// Matrix stack相关操作 @@ -100,6 +104,7 @@ namespace AsuraEngine AEMath::Recti viewport; ///< 当前的视区,在切换HDC或者本窗口大小改变或者部分刷新时变动 MatrixStack matrix[3]; ///< model, view, projection矩阵 MatrixMode matrixMode; ///< 当前操作的矩阵 + uint drawcall; ///< 统计drawcall } state; private: diff --git a/source/modules/asura-core/graphics/gpu_buffer.cpp b/source/modules/asura-core/graphics/gpu_buffer.cpp index 6e6aead..aecfa51 100644 --- a/source/modules/asura-core/graphics/gpu_buffer.cpp +++ b/source/modules/asura-core/graphics/gpu_buffer.cpp @@ -5,45 +5,64 @@ namespace AsuraEngine namespace Graphics { - GPUBuffer::GPUBuffer(BufferType type, BufferUsage usage, size_t size) + GPUBuffer::GPUBuffer(BufferType type, BufferUsage usage, BufferDataType dataType, size_t size) : mTarget(GL_ZERO) , mBuffer(GL_ZERO) , mSize(0) #if ASURA_DEBUG , mData(nullptr) #endif + { + mTarget = ConvertBufferType(type); + mUsage = ConvertBufferUsage(usage); + mDataType = ConvertBufferDataType(dataType); + mSize = size; + } + + GPUBuffer::~GPUBuffer() + { +#if ASURA_DEBUG + if (mData) + free(mData); +#endif + glDeleteBuffers(1, &mBuffer); + } + + GLenum GPUBuffer::ConvertBufferType(BufferType type) { switch (type) { case BUFFER_TYPE_VERTEX: - mTarget = GL_ARRAY_BUFFER; - break; + return GL_ARRAY_BUFFER; case BUFFER_TYPE_INDEX: - mTarget = GL_ELEMENT_ARRAY_BUFFER; - break; + return GL_ELEMENT_ARRAY_BUFFER; } + } + + GLenum GPUBuffer::ConvertBufferUsage(BufferUsage usage) + { switch (usage) { case BUFFER_USAGE_STREAM: - mUsage = GL_STREAM_DRAW; - break; + return GL_STREAM_DRAW; case BUFFER_USAGE_DYNAMIC: - mUsage = GL_DYNAMIC_DRAW; - break; + return GL_DYNAMIC_DRAW; case BUFFER_USAGE_STATIC: - mUsage = GL_STATIC_DRAW; - break; + return GL_STATIC_DRAW; } - mSize = size; } - GPUBuffer::~GPUBuffer() + GLenum GPUBuffer::ConvertBufferDataType(BufferDataType type) { -#if ASURA_DEBUG - if (mData) - free(mData); -#endif - glDeleteBuffers(1, &mBuffer); + switch (type) + { + case BUFFER_DATA_TYPE_INT: + return GL_INT; + case BUFFER_DATA_TYPE_FLOAT: + return GL_FLOAT; + case BUFFER_DATA_TYPE_UNSIGNED_BYTE: + return GL_UNSIGNED_BYTE; + } } bool GPUBuffer::Fill(const void * data, size_t size, uint offset) @@ -58,7 +77,7 @@ namespace AsuraEngine if (mBuffer == 0) throw Exception("OpenGL glGenBuffers failed."); glBindBuffer(mTarget, mBuffer); - glBufferData(mTarget, mSize, NULL, mUsage); // 初始化大小为size的缓冲 + glBufferData(mTarget, mSize, NULL, mUsage); // 初始化大小为size的缓冲,并根据usage存放到对应显存区块 if (gl.HasError()) { glBindBuffer(mTarget, 0); @@ -100,5 +119,24 @@ namespace AsuraEngine return mSize; } + GLenum GPUBuffer::GetDataType() + { + return mDataType; + } + + size_t GPUBuffer::GetDataTypeSize() + { + //https://blog.csdn.net/nklinux/article/details/16919017 + switch (mDataType) + { + case GL_UNSIGNED_BYTE: + return sizeof(GLbyte); + case GL_FLOAT : + return sizeof(GLfloat); + case GL_INT: + return sizeof(GLint); + } + } + } } \ No newline at end of file diff --git a/source/modules/asura-core/graphics/gpu_buffer.h b/source/modules/asura-core/graphics/gpu_buffer.h index c79ed4b..f2e83fc 100644 --- a/source/modules/asura-core/graphics/gpu_buffer.h +++ b/source/modules/asura-core/graphics/gpu_buffer.h @@ -14,7 +14,7 @@ namespace AsuraEngine enum BufferType { - BUFFER_TYPE_VERTEX, ///< 顶点缓冲 + BUFFER_TYPE_VERTEX, ///< 顶点缓冲,保存position\tangent\normal\color\texcoord(n) BUFFER_TYPE_INDEX, ///< 索引缓冲 }; @@ -25,16 +25,22 @@ namespace AsuraEngine BUFFER_USAGE_STATIC, ///< 经常修改和使用 }; + enum BufferDataType + { + BUFFER_DATA_TYPE_INT, + BUFFER_DATA_TYPE_FLOAT, + BUFFER_DATA_TYPE_UNSIGNED_BYTE, + }; + /// - /// GPU缓冲,分顶点缓冲和索引缓冲两种,避免每次都从内存向显存上传数据。 + /// GPU缓冲,分顶点缓冲vbo和索引缓冲ebo两种,避免每次都从内存向显存上传数据。 /// - class GPUBuffer - : AEScripting::Portable + ASURA_ABSTRACT class GPUBuffer : public AEScripting::Object { public: - GPUBuffer(BufferType type, BufferUsage usage, size_t size); - ~GPUBuffer(); + GPUBuffer(BufferType type, BufferUsage usage, BufferDataType datatype, size_t size); + virtual ~GPUBuffer(); /// /// 初始化\更新缓存,如果没有gpu buffer资源,认为是初始化,否则认为是更新。 @@ -49,24 +55,39 @@ namespace AsuraEngine uint GetBufferSize(); + GLenum GetDataType(); + private: //----------------------------------------------------------------------------// - LUAX_DECL_FACTORY(GPUBuffer); + LUAX_DECL_ABSTRACT_FACTORY(GPUBuffer); LUAX_DECL_ENUM(BufferType, 1); LUAX_DECL_ENUM(BufferUsage, 1); + LUAX_DECL_ENUM(BufferDataType, 2); - LUAX_DECL_METHOD(_New); LUAX_DECL_METHOD(_Fill); LUAX_DECL_METHOD(_GetSize); + LUAX_DECL_METHOD(_GetCount); //----------------------------------------------------------------------------// + GLenum ConvertBufferType(BufferType type); + GLenum ConvertBufferUsage(BufferUsage type); + GLenum ConvertBufferDataType(BufferDataType type); + size_t GetDataTypeSize(); + GLenum mTarget; GLuint mBuffer; - GLuint mUsage; + /// + /// opengl的显存缓冲并没有对数据类型的要求,只在glVertexAttribPointer时会指定,并在 + /// drawcall 时根据给定的数据起始地址和类型从buffer中取各类顶点数据,所以不同的数据类型 + /// 可以保存在一个buffer中。但是为了保持接口的简洁,这里在初始化buffer时指明保存的数据 + /// 类型,并在整个周期内保持数据类型的一致,所以不同的数据类型分属不同的buffer。 + /// + GLenum mDataType; + GLuint mUsage; uint mSize; #if ASURA_DEBUG diff --git a/source/modules/asura-core/graphics/image.cpp b/source/modules/asura-core/graphics/image.cpp index cb5b573..9244e73 100644 --- a/source/modules/asura-core/graphics/image.cpp +++ b/source/modules/asura-core/graphics/image.cpp @@ -2,6 +2,7 @@ #include "../core_config.h" +#include "shader.h" #include "image.h" #include "gl.h" @@ -13,16 +14,13 @@ namespace AsuraEngine { Image::Image() - : mVBO(nullptr) - , mWidth(0) + : mWidth(0) , mHeight(0) { } Image::~Image() { - if (mVBO) - delete mVBO; } bool Image::Load(ImageData* imgData) @@ -52,23 +50,6 @@ namespace AsuraEngine , imgData->pixels ); - // 初始化buffer - if (!mVBO) - mVBO = new GPUBuffer(BUFFER_TYPE_VERTEX, BUFFER_USAGE_STATIC, 16*sizeof(float)); // position和uv - - if (mWidth != imgData->width || mHeight != imgData->height) - { - float w = imgData->width, - h = imgData->height; - float buffer[] = { - 0, 0, 0, 0, - 0, h, 0, 1, - w, h, 1, 1, - w, 0, 1, 0 - }; - mVBO->Fill(buffer, sizeof(buffer)); - } - mWidth = imgData->width; mHeight = imgData->height; imgData->Unlock(); @@ -118,21 +99,48 @@ namespace AsuraEngine { return mHeight; } - - void Image::UpdateBuffer() + /* + void Image::Render() { - if (!mVBO) + Shader* shader = gl.GetShader(); + if (!shader) return; - float w = mWidth, - h = mHeight; - float buffer[] = { + uint32& w = mWidth, &h = mHeight; + int vertices[] = { 0, 0, 0, 0, 0, h, 0, 1, + w, 0, 1, 0, w, h, 1, 1, - w, 0, 1, 0 }; - mVBO->Fill(buffer, sizeof(buffer)); + // 设置断点坐标和UV + shader->SetAttribPosition(2, GL_INT, GL_FALSE, 4 * sizeof(int), vertices); + shader->SetAttribTexcoord0(2, GL_INT, GL_FALSE, 4 * sizeof(int), &vertices[2]); + gl.DrawArrays(GL_TRIANGLE_STRIP, 0, 4); } + void Image::Render(AEMath::Recti& quad) + { + // + Shader* shader = gl.GetShader(); + if (!shader) + return; + int &w = quad.w, &h = quad.h; + // UV + float l = quad.x / mWidth, + r = (quad.x + quad.w) / mWidth, + t = quad.y / mHeight, + b = (quad.y + quad.h) / mHeight; + float vertices[] = { + 0, 0, l, t, + 0, h, l, b, + w, 0, r, t, + w, h, r, b, + }; + // 设置断点坐标和UV + shader->SetAttribPosition(2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), vertices); + shader->SetAttribTexcoord0(2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), &vertices[2]); + gl.DrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + */ } } \ No newline at end of file diff --git a/source/modules/asura-core/graphics/image.h b/source/modules/asura-core/graphics/image.h index abb8a1a..a1fba9a 100644 --- a/source/modules/asura-core/graphics/image.h +++ b/source/modules/asura-core/graphics/image.h @@ -10,11 +10,11 @@ #include "../image/image_data.h" -#include "texture.h" #include "color.h" #include "color32.h" #include "render_state.h" #include "gpu_buffer.h" +#include "texture.h" namespace AsuraEngine { @@ -24,7 +24,9 @@ namespace AsuraEngine /// /// Image是图片从内存中载入后,读取进游戏后保存的结果。一个Image在内存、显存中只会保存一 /// 份,不会产生副本。需要特征化的区别image,如锚点位置,缩放和旋转角度,使用sprite。 - /// 是一个只读类。主要是考虑到editor和engine使用不同的封装。 + /// 是一个只读类。主要是考虑到editor和engine使用不同的封装。Image只提供渲染时需要的 + /// sampler2D,顶点数据严格来说和Image无关,不应该由Image类提供。在Framework中,真正的 + /// 渲染实体是sprite,sprite提供了顶点数据和仿射变换参数。 /// class Image ASURA_FINAL : public AEScripting::Portable @@ -44,11 +46,11 @@ namespace AsuraEngine uint GetWidth(); uint GetHeight(); -/* - void Render(const RenderTarget* rt, const RenderState& state) {}; - void Render(const RenderTarget* rt, const AEMath::Rectf& quad, const RenderState& state) {}; -*/ - void UpdateBuffer(); + + /// + /// 创建一个gpu buffer,填充顶点的position数据和UV数据. + /// + GPUBuffer* GenGPUBuffer(); private: @@ -57,7 +59,7 @@ namespace AsuraEngine LUAX_DECL_FACTORY(Image, Texture); LUAX_DECL_METHOD(_New); - LUAX_DECL_METHOD(_Update); + LUAX_DECL_METHOD(_Load); LUAX_DECL_METHOD(_GetWidth); LUAX_DECL_METHOD(_GetHeight); LUAX_DECL_METHOD(_GetSize); @@ -68,11 +70,6 @@ namespace AsuraEngine uint32 mWidth, mHeight; - /// - /// 缓冲,保存了position和UV数据 - /// - GPUBuffer* mVBO; - }; } diff --git a/source/modules/asura-core/graphics/index_buffer.cpp b/source/modules/asura-core/graphics/index_buffer.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/graphics/index_buffer.h b/source/modules/asura-core/graphics/index_buffer.h new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/graphics/matrix_stack.cpp b/source/modules/asura-core/graphics/matrix_stack.cpp index 920dded..d48a1e0 100644 --- a/source/modules/asura-core/graphics/matrix_stack.cpp +++ b/source/modules/asura-core/graphics/matrix_stack.cpp @@ -58,7 +58,7 @@ namespace AsuraEngine mStack[this->top].Ortho(left, right, bottom, top, near, far); } - void MatrixStack::Rotate(float angle, float x, float y, float z) + void MatrixStack::Rotate(float angle) { mStack[top].Rotate(angle); } @@ -68,7 +68,7 @@ namespace AsuraEngine mStack[top].Translate(x, y); } - void MatrixStack::Scale(float x, float y, float z) + void MatrixStack::Scale(float x, float y) { mStack[top].Scale(x, y); } diff --git a/source/modules/asura-core/graphics/matrix_stack.h b/source/modules/asura-core/graphics/matrix_stack.h index c8ab3d6..1a318fa 100644 --- a/source/modules/asura-core/graphics/matrix_stack.h +++ b/source/modules/asura-core/graphics/matrix_stack.h @@ -43,9 +43,9 @@ namespace AsuraEngine /// /// 仿射变换 /// - void Rotate(float angle, float x, float y, float z); + void Rotate(float angle); void Translate(float x, float y); - void Scale(float x, float y, float z); + void Scale(float x, float y); /// /// 投影变换 diff --git a/source/modules/asura-core/graphics/mesh2d.h b/source/modules/asura-core/graphics/mesh2d.h index 87f0d4b..420986e 100644 --- a/source/modules/asura-core/graphics/mesh2d.h +++ b/source/modules/asura-core/graphics/mesh2d.h @@ -16,6 +16,7 @@ namespace AsuraEngine /// /// 2D mesh,用于做一些顶点动画。 + /// https://en.wikipedia.org/wiki/Polygon_mesh /// class Mesh2D ASURA_FINAL : public Scripting::Portable diff --git a/source/modules/asura-core/graphics/render_state.h b/source/modules/asura-core/graphics/render_state.h index 4c3491c..b5814d3 100644 --- a/source/modules/asura-core/graphics/render_state.h +++ b/source/modules/asura-core/graphics/render_state.h @@ -29,7 +29,6 @@ namespace AsuraEngine /// /// 位置、缩放、中心位置和旋转 /// - Math::Transform transform; /// diff --git a/source/modules/asura-core/graphics/shader.cpp b/source/modules/asura-core/graphics/shader.cpp index 0d92c60..cf3d4b2 100644 --- a/source/modules/asura-core/graphics/shader.cpp +++ b/source/modules/asura-core/graphics/shader.cpp @@ -13,7 +13,7 @@ namespace AsuraEngine /// /// texture unit编号 /// - static int _texture_unit = 0; + static int _texture_unit; const char* Shader::SemanticsName[] = { // uniforms @@ -107,19 +107,8 @@ namespace AsuraEngine throw Exception("Link shader program failed:\n%s", warnning.c_str()); } - // 获得mvp的location - mMVP[MATRIX_MODE_MODEL] = glGetUniformLocation(mProgram, SemanticsName[SEMANTICS_UNIFORM_MODEL_MATRIX]); - mMVP[MATRIX_MODE_VIEW] = glGetUniformLocation(mProgram, SemanticsName[SEMANTICS_UNIFORM_VIEW_MATRIX]); - mMVP[MATRIX_MODE_PROJECTION] = glGetUniformLocation(mProgram, SemanticsName[SEMANTICS_UNIFORM_PROJECTION_MATRIX]); - - mPosition = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_POSITION]); - mTangent = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TANGENT]); - mNormal = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_NORMAL]); - mTexcoord0 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD0]); - mTexcoord1 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD1]); - mTexcoord2 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD2]); - mTexcoord3 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD3]); - mColor = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_COLOR]); + // 重新link后更新语义的locations + UpdateSemanticsLocations(); return true; } @@ -127,12 +116,20 @@ namespace AsuraEngine void Shader::OnUse() { _texture_unit = 0; - SetBuiltInUniforms(); + // Disable所有内置顶点属性,在set时开启 + glDisableVertexAttribArray(mPosition); + glDisableVertexAttribArray(mTangent); + glDisableVertexAttribArray(mNormal); + glDisableVertexAttribArray(mColor); + glDisableVertexAttribArray(mTexcoord0); + glDisableVertexAttribArray(mTexcoord1); + glDisableVertexAttribArray(mTexcoord2); + glDisableVertexAttribArray(mTexcoord3); } void Shader::OnUnuse() { - _texture_unit = 0; + _texture_unit; } /* int Shader::GetAttributeLocation(const std::string& name) @@ -223,7 +220,7 @@ namespace AsuraEngine uint Shader::GetGLTextureUnitCount() { - GLint maxTextureUnits = 0; + GLint maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); return (uint)maxTextureUnits; } @@ -268,5 +265,86 @@ namespace AsuraEngine return warnings; } + void Shader::UpdateSemanticsLocations() + { + // 获得mvp的location + mMVP[MATRIX_MODE_MODEL] = glGetUniformLocation(mProgram, SemanticsName[SEMANTICS_UNIFORM_MODEL_MATRIX]); + mMVP[MATRIX_MODE_VIEW] = glGetUniformLocation(mProgram, SemanticsName[SEMANTICS_UNIFORM_VIEW_MATRIX]); + mMVP[MATRIX_MODE_PROJECTION] = glGetUniformLocation(mProgram, SemanticsName[SEMANTICS_UNIFORM_PROJECTION_MATRIX]); + + mPosition = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_POSITION]); + mTangent = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TANGENT]); + mNormal = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_NORMAL]); + mTexcoord0 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD0]); + mTexcoord1 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD1]); + mTexcoord2 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD2]); + mTexcoord3 = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_TEXCOORD3]); + mColor = glGetAttribLocation(mProgram, SemanticsName[SEMANTICS_ATTRIBUTE_COLOR]); + } + + void Shader::SetAttribPosition(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mPosition, size, vbo->GetDataType(), normalized, stride, (GLvoid*)offset); + vbo->UnBind(); + glEnableVertexAttribArray(mPosition); + } + + void Shader::SetAttribTangent(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mTangent, size, vbo->GetDataType(), normalized, stride, (GLvoid*)offset); + vbo->UnBind(); + glEnableVertexAttribArray(mTangent); + } + + void Shader::SetAttribNormal(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mNormal, size, vbo->GetDataType(), normalized, stride, (GLvoid*)offset); + vbo->UnBind(); + glEnableVertexAttribArray(mNormal); + } + + void Shader::SetAttribColor(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mColor, size, vbo->GetDataType(), normalized, stride, (GLvoid*)offset); + vbo->UnBind(); + glEnableVertexAttribArray(mColor); + } + + void Shader::SetAttribTexcoord0(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mTexcoord0, size, vbo->GetDataType(), normalized, stride, (GLvoid*)offset); + vbo->UnBind(); + glEnableVertexAttribArray(mTexcoord0); + } + + void Shader::SetAttribTexcoord1(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mTexcoord1, size, vbo->GetDataType(), normalized, stride, (GLvoid*) offset); + vbo->UnBind(); + glEnableVertexAttribArray(mTexcoord1); + } + + void Shader::SetAttribTexcoord2(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mTexcoord2, size, vbo->GetDataType(), normalized, stride, (GLvoid*)offset); + vbo->UnBind(); + glEnableVertexAttribArray(mTexcoord2); + } + + void Shader::SetAttribTexcoord3(int size, GPUBuffer* vbo, GLsizei offset, GLsizei stride , bool normalized) + { + vbo->Bind(); + glVertexAttribPointer(mTexcoord3, size, vbo->GetDataType(), normalized, stride, (GLvoid*)offset); + vbo->UnBind(); + glEnableVertexAttribArray(mTexcoord3); + } + } } \ No newline at end of file diff --git a/source/modules/asura-core/graphics/shader.h b/source/modules/asura-core/graphics/shader.h index 25b36dc..a725ccf 100644 --- a/source/modules/asura-core/graphics/shader.h +++ b/source/modules/asura-core/graphics/shader.h @@ -45,23 +45,18 @@ namespace AsuraEngine void OnUnuse(); /// - /// 设置顶点属性,Asura只支持2维顶点数据 + /// 设置顶点属性,这些值在framework的renderer里面被设置,而不是Image、Mesh2D这些“数据源“ + /// 如果normalized为true,输入的数据会在给定buffer的类型下归一化,如255的颜色归一化到 + /// 0~1。 /// - //int GetAttributeLocation(const std::string& name); - //void SetAttribute(int loc, void* data, uint offset = 0, uint stride = 0); - //void SetAttribute(int loc, GPUBuffer* vbo, uint offset = 0, uint stride = 0); - - /// - /// 绘制前设置顶点属性 - /// - void SetAttribPosition(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - void SetAttribTangent(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - void SetAttribNormal(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - void SetAttribTexcoord0(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - void SetAttribTexcoord1(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - void SetAttribTexcoord2(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - void SetAttribTexcoord3(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - void SetAttribColor(int size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); + void SetAttribPosition(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); + void SetAttribTangent(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); + void SetAttribNormal(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); + void SetAttribColor(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); + void SetAttribTexcoord0(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); + void SetAttribTexcoord1(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); + void SetAttribTexcoord2(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); + void SetAttribTexcoord3(int size, GPUBuffer* vbo, GLsizei offset = 0, GLsizei stride = 0, bool normalized = false); /// /// 设置uniform变量 @@ -98,31 +93,40 @@ namespace AsuraEngine LUAX_DECL_FACTORY(Shader); LUAX_DECL_METHOD(_New); - LUAX_DECL_METHOD(_Use); - LUAX_DECL_METHOD(_Unuse); LUAX_DECL_METHOD(_Load); LUAX_DECL_METHOD(_Update); LUAX_DECL_METHOD(_HasUniform); LUAX_DECL_METHOD(_GetUniformLocation); - LUAX_DECL_METHOD(_SetBuiltInUniforms); LUAX_DECL_METHOD(_SetUniformFloat); LUAX_DECL_METHOD(_SetUniformTexture); LUAX_DECL_METHOD(_SetUniformVector2); LUAX_DECL_METHOD(_SetUniformVector3); LUAX_DECL_METHOD(_SetUniformVector4); LUAX_DECL_METHOD(_SetUniformColor); + // 设置vertex attributes + LUAX_DECL_METHOD(_SetAttribPosition); + LUAX_DECL_METHOD(_SetAttribTangent); + LUAX_DECL_METHOD(_SetAttribNormal); + LUAX_DECL_METHOD(_SetAttribColor); + LUAX_DECL_METHOD(_SetAttribTexcoord0); + LUAX_DECL_METHOD(_SetAttribTexcoord1); + LUAX_DECL_METHOD(_SetAttribTexcoord2); + LUAX_DECL_METHOD(_SetAttribTexcoord3); + // 设置内置uniform变量 + LUAX_DECL_METHOD(_SetBuiltInUniforms); //----------------------------------------------------------------------------// std::string GetProgramWarnings(); std::string GetShaderWarnings(GLuint shader); + void UpdateSemanticsLocations(); /// - /// AsuraShader的语义,包含顶点属性和uniform变量。在framework中会对shader做封装。 + /// AsuraShader的语义,包含顶点属性和uniform变量。在framework中会对shader做再次封装。 /// 所谓的语义,指shader自定义的变量,和外部程序交互时,需要提供这些变量值,满足基本 /// 的绘制需要。这里用来索引语义名。 /// - enum ASLSemantics + enum Semantics { // MVP矩阵 SEMANTICS_UNIFORM_MODEL_MATRIX = 0, @@ -154,24 +158,12 @@ namespace AsuraEngine GLuint mVertShader; GLuint mFragShader; - /// - /// Model\View\Projection matrix uniform变量的location。Asura要求shader必须有以下 - /// 语义: - /// 1: asura_model_matrix 模型矩阵 - /// 2: asura_view_matrix 观察者矩阵 - /// 3: asura_projection_matrix 投影(正交)矩阵 - /// 会在framework里设置更多的内置语义,公共部分的语义是游戏和编辑器共有的。 - /// + // 内置语义 GLint mMVP[3]; - - /// - /// 顶点属性的location - /// GLint mPosition; GLint mTangent; GLint mNormal; GLint mColor; - // 支持四套UV GLint mTexcoord0; GLint mTexcoord1; GLint mTexcoord2; diff --git a/source/modules/asura-core/graphics/texture.h b/source/modules/asura-core/graphics/texture.h index 333a8c6..36a773d 100644 --- a/source/modules/asura-core/graphics/texture.h +++ b/source/modules/asura-core/graphics/texture.h @@ -78,16 +78,26 @@ namespace AsuraEngine /// 如果设置U或V方向filter为 /// bool IsGenMipmap(); - +/* /// /// 渲染整个texture到rt上,原点在左上角,向右,向下延伸 /// - //virtual void Render(const RenderTarget* rt, const RenderState& state) = 0; + virtual void Render(const RenderTarget* rt, const RenderState& state) = 0; /// /// 渲染texture的一部分到rt上,原点在左上角,向右,向下延伸。 /// - //virtual void Render(const RenderTarget* rt, const AEMath::Rectf& quad, const RenderState& state) = 0; + virtual void Render(const RenderTarget* rt, const AEMath::Rectf& quad, const RenderState& state) = 0; +*/ + /// + /// 渲染整个image。 + /// + //virtual void Render() = 0; + + /// + /// 渲染部分image。 + /// + //virtual void Render(AEMath::Recti& quad) = 0; protected: diff --git a/source/modules/asura-core/graphics/vertex_buffer.cpp b/source/modules/asura-core/graphics/vertex_buffer.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/graphics/vertex_buffer.h b/source/modules/asura-core/graphics/vertex_buffer.h new file mode 100644 index 0000000..b8245e5 --- /dev/null +++ b/source/modules/asura-core/graphics/vertex_buffer.h @@ -0,0 +1,29 @@ +#ifndef __ASURA_VERTEX_BUFFER_H__ +#define __ASURA_VERTEX_BUFFER_H__ + +#include + +#include "gpu_buffer.h" + +namespace AsuraEngine +{ + namespace Graphics + { + + class VertexBuffer : AEScripting::Portable + { + public: + + VertexBuffer(BufferUsage usage, BufferDataType datatype, size_t size); + ~VertexBuffer(); + + private: + + LUAX_DECL_FACTORY(VertexBuffer, GPUBuffer); + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-core/mesh/am2_handler.cpp b/source/modules/asura-core/mesh/am2_handler.cpp index fce7817..31bd51b 100644 --- a/source/modules/asura-core/mesh/am2_handler.cpp +++ b/source/modules/asura-core/mesh/am2_handler.cpp @@ -21,13 +21,13 @@ f surface 举例: ASURAMESH2D -p0 +p 0 v 0, 0 t -0.2, 0.45 n -0.3, 0.6 -p1 - +p 1 +f 0, 1, 2 */ diff --git a/source/modules/asura-core/mesh/mesh2d_data.h b/source/modules/asura-core/mesh/mesh2d_data.h index ad4b6c8..409451d 100644 --- a/source/modules/asura-core/mesh/mesh2d_data.h +++ b/source/modules/asura-core/mesh/mesh2d_data.h @@ -40,6 +40,8 @@ namespace AsuraEngine private: + LUAX_DECL_FACTORY(Mesh2DData); + /// /// mesh的所有顶点。 /// -- cgit v1.1-26-g67d0