From 1c96ae4fd77402a7a5834e6899e5653e50a580a1 Mon Sep 17 00:00:00 2001 From: hzzhouqq Date: Sat, 4 Nov 2023 19:01:07 +0800 Subject: [PATCH 1/2] miniGLRender first commit first commit --- src/miniGLRender/bufferObjects.cpp | 423 +++++++++++++++++++++++++++++ src/miniGLRender/bufferObjects.h | 108 ++++++++ src/miniGLRender/common.cpp | 3 + src/miniGLRender/common.h | 31 +++ src/miniGLRender/math_common.cpp | 12 + src/miniGLRender/math_common.h | 16 ++ src/miniGLRender/miniRenderApp.cpp | 161 +++++++++++ src/miniGLRender/tr_common.cpp | 2 + src/miniGLRender/tr_common.h | 22 ++ src/miniGLRender/vertexCache.cpp | 161 +++++++++++ src/miniGLRender/vertexCache.h | 161 +++++++++++ 11 files changed, 1100 insertions(+) create mode 100644 src/miniGLRender/bufferObjects.cpp create mode 100644 src/miniGLRender/bufferObjects.h create mode 100644 src/miniGLRender/common.cpp create mode 100644 src/miniGLRender/common.h create mode 100644 src/miniGLRender/math_common.cpp create mode 100644 src/miniGLRender/math_common.h create mode 100644 src/miniGLRender/miniRenderApp.cpp create mode 100644 src/miniGLRender/tr_common.cpp create mode 100644 src/miniGLRender/tr_common.h create mode 100644 src/miniGLRender/vertexCache.cpp create mode 100644 src/miniGLRender/vertexCache.h diff --git a/src/miniGLRender/bufferObjects.cpp b/src/miniGLRender/bufferObjects.cpp new file mode 100644 index 0000000..7a933cc --- /dev/null +++ b/src/miniGLRender/bufferObjects.cpp @@ -0,0 +1,423 @@ +#include "bufferObjects.h" +#include "vgl.h" + +//static const GLenum bufferUsage = GL_STATIC_DRAW_ARB; +static const GLenum bufferUsage = GL_DYNAMIC_DRAW; + +bool IsWriteCombined(void* base) +{ + MEMORY_BASIC_INFORMATION info; + SIZE_T size = VirtualQueryEx(GetCurrentProcess(), base, &info, sizeof(info)); + if (size == 0) { + DWORD error = GetLastError(); + error = error; + return false; + } + bool isWriteCombined = ((info.AllocationProtect & PAGE_WRITECOMBINE) != 0); + return isWriteCombined; +} + +// qqVertexBuffer +qqVertexBuffer::qqVertexBuffer() +{ + size = 0; + offsetInOtherBuffer = OWNS_BUFFER_FLAG; + apiObject = 0; + SetUnmapped(); +} + +qqVertexBuffer::~qqVertexBuffer() +{ + FreeBufferObject(); +} + +bool qqVertexBuffer::AllocBufferObject(const void* data, int allocSize) +{ + assert(apiObject == NULL); + assert_16_byte_aligned(data); + + if (allocSize <= 0) { + return false; + } + + size = allocSize; + + bool allocationFailed = false; + + int numBytes = GetAllocedSize(); + + + // clear out any previous error + glGetError(); + + GLuint bufferObject = 0xFFFF; + glGenBuffers(1, &bufferObject); + if (bufferObject == 0xFFFF) { + //idLib::FatalError("idVertexBuffer::AllocBufferObject: failed"); + return false; + } + glBindBuffer(GL_ARRAY_BUFFER, bufferObject); + + // these are rewritten every frame + glBufferData(GL_ARRAY_BUFFER, numBytes, NULL, bufferUsage); + apiObject = (bufferObject); + + GLenum err = glGetError(); + if (err == GL_OUT_OF_MEMORY) { + //idLib::Warning("idVertexBuffer::AllocBufferObject: allocation failed"); + allocationFailed = true; + } + + // copy the data + if (data != NULL) { + Update(data, allocSize); + } + + return !allocationFailed; +} + +void qqVertexBuffer::FreeBufferObject() +{ + if (IsMapped()) { + UnmapBuffer(); + } + + // if this is a sub-allocation inside a larger buffer, don't actually free anything. + if (OwnsBuffer() == false) { + ClearWithoutFreeing(); + return; + } + + if (apiObject == NULL) { + return; + } + + //if (r_showBuffers.GetBool()) { + // idLib::Printf("vertex buffer free %p, api %p (%i bytes)\n", this, GetAPIObject(), GetSize()); + //} + + GLuint bufferObject = (apiObject); + glDeleteBuffers(1, &bufferObject); + + ClearWithoutFreeing(); +} + +void qqVertexBuffer::Reference(const qqVertexBuffer& other) +{ + assert(IsMapped() == false); + //assert( other.IsMapped() == false ); // this happens when building idTriangles while at the same time setting up idDrawVerts + assert(other.GetAPIObject() != NULL); + assert(other.GetSize() > 0); + + FreeBufferObject(); + size = other.GetSize(); // this strips the MAPPED_FLAG + offsetInOtherBuffer = other.GetOffset(); // this strips the OWNS_BUFFER_FLAG + apiObject = other.apiObject; + assert(OwnsBuffer() == false); +} + +void qqVertexBuffer::Reference(const qqVertexBuffer& other, int refOffset, int refSize) +{ + assert(IsMapped() == false); + //assert( other.IsMapped() == false ); // this happens when building idTriangles while at the same time setting up idDrawVerts + assert(other.GetAPIObject() != NULL); + assert(refOffset >= 0); + assert(refSize >= 0); + assert(refOffset + refSize <= other.GetSize()); + + FreeBufferObject(); + size = refSize; + offsetInOtherBuffer = other.GetOffset() + refOffset; + apiObject = other.apiObject; + assert(OwnsBuffer() == false); +} + +void qqVertexBuffer::Update(const void* data, int updateSize) const +{ + assert(apiObject != NULL); + assert(IsMapped() == false); + assert_16_byte_aligned(data); + assert((GetOffset() & 15) == 0); + + if (updateSize > size) { + //idLib::FatalError("idVertexBuffer::Update: size overrun, %i > %i\n", updateSize, GetSize()); + return; + } + + int numBytes = (updateSize + 15) & ~15; + + GLuint bufferObject = apiObject; + + glBindBuffer(GL_ARRAY_BUFFER, bufferObject); + glBufferSubData(GL_ARRAY_BUFFER, GetOffset(), (GLsizeiptr)numBytes, data); + /* + void * buffer = MapBuffer( BM_WRITE ); + CopyBuffer( (byte *)buffer + GetOffset(), (byte *)data, numBytes ); + UnmapBuffer(); + */ +} + +void* qqVertexBuffer::MapBuffer(bufferMapType_t mapType) const +{ + assert(apiObject != NULL); + assert(IsMapped() == false); + + void* buffer = NULL; + + GLuint bufferObject = (apiObject); + + glBindBuffer(GL_ARRAY_BUFFER, bufferObject); + if (mapType == BM_READ) { + //buffer = qglMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB ); + buffer = glMapBufferRange(GL_ARRAY_BUFFER, 0, GetAllocedSize(), GL_MAP_READ_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + if (buffer != NULL) { + buffer = (byte*)buffer + GetOffset(); + } + } + else if (mapType == BM_WRITE) { + //buffer = qglMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB ); + buffer = glMapBufferRange(GL_ARRAY_BUFFER, 0, GetAllocedSize(), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + if (buffer != NULL) { + buffer = (byte*)buffer + GetOffset(); + } + assert(IsWriteCombined(buffer)); + } + else { + assert(false); + return nullptr; + } + + SetMapped(); + + if (buffer == NULL) { + //idLib::FatalError("idVertexBuffer::MapBuffer: failed"); + return nullptr; + } + return buffer; +} + +void qqVertexBuffer::UnmapBuffer() const +{ + assert(apiObject != NULL); + assert(IsMapped()); + + GLuint bufferObject = (apiObject); + glBindBuffer(GL_ARRAY_BUFFER, bufferObject); + if (!glUnmapBuffer(GL_ARRAY_BUFFER)) { + //idLib::Printf("idVertexBuffer::UnmapBuffer failed\n"); + } + + SetUnmapped(); +} + +void qqVertexBuffer::ClearWithoutFreeing() { + size = 0; + offsetInOtherBuffer = OWNS_BUFFER_FLAG; + apiObject = 0; +} + + +// qqIndexBuffer +qqIndexBuffer::qqIndexBuffer() +{ + size = 0; + offsetInOtherBuffer = OWNS_BUFFER_FLAG; + apiObject = NULL; + SetUnmapped(); +} + +qqIndexBuffer::~qqIndexBuffer() +{ + FreeBufferObject(); +} + +bool qqIndexBuffer::AllocBufferObject(const void* data, int allocSize) +{ + assert(apiObject == NULL); + assert_16_byte_aligned(data); + + if (allocSize <= 0) { + //idLib::Error("qqIndexBuffer::AllocBufferObject: allocSize = %i", allocSize); + return false; + } + + size = allocSize; + + bool allocationFailed = false; + + int numBytes = GetAllocedSize(); + + + // clear out any previous error + glGetError(); + + GLuint bufferObject = 0xFFFF; + glGenBuffers(1, &bufferObject); + if (bufferObject == 0xFFFF) { + GLenum error = glGetError(); + //idLib::FatalError("qqIndexBuffer::AllocBufferObject: failed - GL_Error %d", error); + return false; + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObject); + + // these are rewritten every frame + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numBytes, NULL, bufferUsage); + apiObject = (bufferObject); + + GLenum err = glGetError(); + if (err == GL_OUT_OF_MEMORY) + { + //idLib::Warning("qqIndexBuffer:AllocBufferObject: allocation failed"); + allocationFailed = true; + } + + //if (r_showBuffers.GetBool()) { + // idLib::Printf("index buffer alloc %p, api %p (%i bytes)\n", this, GetAPIObject(), GetSize()); + //} + + // copy the data + if (data != NULL) { + Update(data, allocSize); + } + + return !allocationFailed; +} + +void qqIndexBuffer::FreeBufferObject() +{ + if (IsMapped()) { + UnmapBuffer(); + } + + // if this is a sub-allocation inside a larger buffer, don't actually free anything. + if (OwnsBuffer() == false) { + ClearWithoutFreeing(); + return; + } + + if (apiObject == NULL) { + return; + } + + //if (r_showBuffers.GetBool()) { + // idLib::Printf("index buffer free %p, api %p (%i bytes)\n", this, GetAPIObject(), GetSize()); + //} + + GLuint bufferObject = (apiObject); + glDeleteBuffers(1, &bufferObject); + + ClearWithoutFreeing(); +} + +void qqIndexBuffer::Reference(const qqIndexBuffer& other) +{ + assert(IsMapped() == false); + //assert( other.IsMapped() == false ); // this happens when building idTriangles while at the same time setting up triIndex_t + assert(other.GetAPIObject() != NULL); + assert(other.GetSize() > 0); + + FreeBufferObject(); + size = other.GetSize(); // this strips the MAPPED_FLAG + offsetInOtherBuffer = other.GetOffset(); // this strips the OWNS_BUFFER_FLAG + apiObject = other.apiObject; + assert(OwnsBuffer() == false); +} + +void qqIndexBuffer::Reference(const qqIndexBuffer& other, int refOffset, int refSize) +{ + assert(IsMapped() == false); + //assert( other.IsMapped() == false ); // this happens when building idTriangles while at the same time setting up triIndex_t + assert(other.GetAPIObject() != NULL); + assert(refOffset >= 0); + assert(refSize >= 0); + assert(refOffset + refSize <= other.GetSize()); + + FreeBufferObject(); + size = refSize; + offsetInOtherBuffer = other.GetOffset() + refOffset; + apiObject = other.apiObject; + assert(OwnsBuffer() == false); +} + +void qqIndexBuffer::Update(const void* data, int updateSize) const +{ + + assert(apiObject != NULL); + assert(IsMapped() == false); + assert_16_byte_aligned(data); + assert((GetOffset() & 15) == 0); + + if (updateSize > size) { + //idLib::FatalError("qqIndexBuffer::Update: size overrun, %i > %i\n", updateSize, GetSize()); + return; + } + + int numBytes = (updateSize + 15) & ~15; + + GLuint bufferObject = (apiObject); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObject); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, GetOffset(), (GLsizeiptr)numBytes, data); + /* + void * buffer = MapBuffer( BM_WRITE ); + CopyBuffer( (byte *)buffer + GetOffset(), (byte *)data, numBytes ); + UnmapBuffer(); + */ +} + +void* qqIndexBuffer::MapBuffer(bufferMapType_t mapType) const +{ + + assert(apiObject != NULL); + assert(IsMapped() == false); + + void* buffer = NULL; + + GLuint bufferObject = (apiObject); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObject); + if (mapType == BM_READ) { + //buffer = qglMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB ); + buffer = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, GetAllocedSize(), GL_MAP_READ_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + if (buffer != NULL) { + buffer = (byte*)buffer + GetOffset(); + } + } + else if (mapType == BM_WRITE) { + //buffer = qglMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB ); + buffer = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, GetAllocedSize(), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + if (buffer != NULL) { + buffer = (byte*)buffer + GetOffset(); + } + assert(IsWriteCombined(buffer)); + } + else { + assert(false); + } + + SetMapped(); + + if (buffer == NULL) { + //idLib::FatalError("qqIndexBuffer::MapBuffer: failed"); + } + return buffer; +} + +void qqIndexBuffer::UnmapBuffer() const +{ + assert(apiObject != NULL); + assert(IsMapped()); + + GLuint bufferObject = (apiObject); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObject); + if (!glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)) { + //idLib::Printf("qqIndexBuffer::UnmapBuffer failed\n"); + } + + SetUnmapped(); +} + +void qqIndexBuffer::ClearWithoutFreeing() +{ + size = 0; + offsetInOtherBuffer = OWNS_BUFFER_FLAG; + apiObject = NULL; +} diff --git a/src/miniGLRender/bufferObjects.h b/src/miniGLRender/bufferObjects.h new file mode 100644 index 0000000..52d8c2d --- /dev/null +++ b/src/miniGLRender/bufferObjects.h @@ -0,0 +1,108 @@ +#ifndef __BUFFEROBJECT_H__ +#define __BUFFEROBJECT_H__ + +#include "tr_common.h" + + +enum bufferMapType_t +{ + BM_READ, // map for reading + BM_WRITE // map for writing +}; + +/* +================================================ +qqVertexBuffer +================================================ +*/ +class qqVertexBuffer +{ +public: + qqVertexBuffer(); + ~qqVertexBuffer(); + + // Allocate or free the buffer. + bool AllocBufferObject(const void* data, int allocSize); + void FreeBufferObject(); + + // Make this buffer a reference to another buffer. + void Reference(const qqVertexBuffer& other); + void Reference(const qqVertexBuffer& other, int refOffset, int refSize); + + // Copies data to the buffer. 'size' may be less than the originally allocated size. + void Update(const void* data, int updateSize) const; + + void* MapBuffer(bufferMapType_t mapType) const; + qqDrawVert* MapVertexBuffer(bufferMapType_t mapType) const { return static_cast(MapBuffer(mapType)); } + void UnmapBuffer() const; + bool IsMapped() const { return (size & MAPPED_FLAG) != 0; } + + int GetSize() const { return (size & ~MAPPED_FLAG); } + int GetAllocedSize() const { return ((size & ~MAPPED_FLAG) + 15) & ~15; } + unsigned int GetAPIObject() const { return apiObject; } + int GetOffset() const { return (offsetInOtherBuffer & ~OWNS_BUFFER_FLAG); } + +private: + int size; // size in bytes + int offsetInOtherBuffer; // offset in bytes + unsigned int apiObject; + + // sizeof() confuses typeinfo... + static const int MAPPED_FLAG = 1 << (4 /* sizeof( int ) */ * 8 - 1); + static const int OWNS_BUFFER_FLAG = 1 << (4 /* sizeof( int ) */ * 8 - 1); + +private: + void ClearWithoutFreeing(); + void SetMapped() const { const_cast(size) |= MAPPED_FLAG; } + void SetUnmapped() const { const_cast(size) &= ~MAPPED_FLAG; } + bool OwnsBuffer() const { return ((offsetInOtherBuffer & OWNS_BUFFER_FLAG) != 0); } + + DISALLOW_COPY_AND_ASSIGN(qqVertexBuffer); +}; + +class qqIndexBuffer +{ +public: + qqIndexBuffer(); + ~qqIndexBuffer(); + + // Allocate or free the buffer. + bool AllocBufferObject(const void* data, int allocSize); + void FreeBufferObject(); + + // Make this buffer a reference to another buffer. + void Reference(const qqIndexBuffer& other); + void Reference(const qqIndexBuffer& other, int refOffset, int refSize); + + // Copies data to the buffer. 'size' may be less than the originally allocated size. + void Update(const void* data, int updateSize) const; + + void* MapBuffer(bufferMapType_t mapType) const; + triIndex_t* MapIndexBuffer(bufferMapType_t mapType) const { return static_cast(MapBuffer(mapType)); } + void UnmapBuffer() const; + bool IsMapped() const { return (size & MAPPED_FLAG) != 0; } + + int GetSize() const { return (size & ~MAPPED_FLAG); } + int GetAllocedSize() const { return ((size & ~MAPPED_FLAG) + 15) & ~15; } + unsigned int GetAPIObject() const { return apiObject; } + int GetOffset() const { return (offsetInOtherBuffer & ~OWNS_BUFFER_FLAG); } + +private: + int size; // size in bytes + int offsetInOtherBuffer; // offset in bytes + unsigned int apiObject; + + // sizeof() confuses typeinfo... + static const int MAPPED_FLAG = 1 << (4 /* sizeof( int ) */ * 8 - 1); + static const int OWNS_BUFFER_FLAG = 1 << (4 /* sizeof( int ) */ * 8 - 1); + +private: + void ClearWithoutFreeing(); + void SetMapped() const { const_cast(size) |= MAPPED_FLAG; } + void SetUnmapped() const { const_cast(size) &= ~MAPPED_FLAG; } + bool OwnsBuffer() const { return ((offsetInOtherBuffer & OWNS_BUFFER_FLAG) != 0); } + + DISALLOW_COPY_AND_ASSIGN(qqIndexBuffer); +}; + +#endif diff --git a/src/miniGLRender/common.cpp b/src/miniGLRender/common.cpp new file mode 100644 index 0000000..cc17f0d --- /dev/null +++ b/src/miniGLRender/common.cpp @@ -0,0 +1,3 @@ +#include "common.h" + + diff --git a/src/miniGLRender/common.h b/src/miniGLRender/common.h new file mode 100644 index 0000000..b61898f --- /dev/null +++ b/src/miniGLRender/common.h @@ -0,0 +1,31 @@ +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include +#include + +// A macro to disallow the copy constructor and operator= functions +// NOTE: The macro contains "private:" so all members defined after it will be private until +// public: or protected: is specified. +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ +private: \ + TypeName(const TypeName&); \ + void operator=(const TypeName&); + +// assert +#define assert_2_byte_aligned( ptr ) assert( ( ((UINT_PTR)(ptr)) & 1 ) == 0 ) +#define assert_4_byte_aligned( ptr ) assert( ( ((UINT_PTR)(ptr)) & 3 ) == 0 ) +#define assert_8_byte_aligned( ptr ) assert( ( ((UINT_PTR)(ptr)) & 7 ) == 0 ) +#define assert_16_byte_aligned( ptr ) assert( ( ((UINT_PTR)(ptr)) & 15 ) == 0 ) +#define assert_32_byte_aligned( ptr ) assert( ( ((UINT_PTR)(ptr)) & 31 ) == 0 ) +#define assert_64_byte_aligned( ptr ) assert( ( ((UINT_PTR)(ptr)) & 63 ) == 0 ) +#define assert_128_byte_aligned( ptr ) assert( ( ((UINT_PTR)(ptr)) & 127 ) == 0 ) +#define assert_aligned_to_type_size( ptr ) assert( ( ((UINT_PTR)(ptr)) & ( sizeof( (ptr)[0] ) - 1 ) ) == 0 ) + + +typedef unsigned char byte; +// halfFloat_t +typedef unsigned short halfFloat_t; + + +#endif // __COMMON_H__ diff --git a/src/miniGLRender/math_common.cpp b/src/miniGLRender/math_common.cpp new file mode 100644 index 0000000..b4bcbd0 --- /dev/null +++ b/src/miniGLRender/math_common.cpp @@ -0,0 +1,12 @@ +#include "math_common.h" + +// qqVec3 +qqVec3::qqVec3() +{ + x = y = z = 0.0f; +} + +qqVec3::~qqVec3() +{ + +} diff --git a/src/miniGLRender/math_common.h b/src/miniGLRender/math_common.h new file mode 100644 index 0000000..71d0486 --- /dev/null +++ b/src/miniGLRender/math_common.h @@ -0,0 +1,16 @@ +#ifndef __MATH_COMMON_H__ +#define __MATH_COMMON_H__ + + +// qqVec3 +class qqVec3 +{ +public: + qqVec3(); + ~qqVec3(); + +public: + float x, y, z; +}; + +#endif // __MATH_COMMON_H__ diff --git a/src/miniGLRender/miniRenderApp.cpp b/src/miniGLRender/miniRenderApp.cpp new file mode 100644 index 0000000..f4a08ed --- /dev/null +++ b/src/miniGLRender/miniRenderApp.cpp @@ -0,0 +1,161 @@ + +#include "vapp.h" +#include "vutils.h" + +#include "vmath.h" + +#include "LoadShaders.h" + +#include + +using namespace vmath; + +BEGIN_APP_DECLARATION(DrawCommandExample) + // Override functions from base class + virtual void Initialize(const char * title); + virtual void Display(bool auto_redraw); + virtual void Finalize(void); + virtual void Resize(int width, int height); + + // Member variables + float aspect; + GLuint render_prog; + GLuint vao[1]; + GLuint vbo[1]; + GLuint ebo[1]; + + GLint render_model_matrix_loc; + GLint render_projection_matrix_loc; +END_APP_DECLARATION() + +DEFINE_APP(DrawCommandExample, "Drawing Commands Example") + +void DrawCommandExample::Initialize(const char * title) +{ + base::Initialize(title); + + ShaderInfo shader_info[] = + { + { GL_VERTEX_SHADER, "media/shaders/primitive_restart/primitive_restart.vs.glsl" }, + { GL_FRAGMENT_SHADER, "media/shaders/primitive_restart/primitive_restart.fs.glsl" }, + { GL_NONE, NULL } + }; + + render_prog = LoadShaders(shader_info); + + glUseProgram(render_prog); + + // "model_matrix" is actually an array of 4 matrices + render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix"); + render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix"); + + // A single triangle + static const GLfloat vertex_positions[] = + { + -1.0f, -1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f, + }; + + // Color for each vertex + static const GLfloat vertex_colors[] = + { + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 1.0f + }; + + // Indices for the triangle strips + static const GLushort vertex_indices[] = + { + 0, 1, 2 + }; + + // Set up the element array buffer + glGenBuffers(1, ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW); + + // Set up the vertex attributes + glGenVertexArrays(1, vao); + glBindVertexArray(vao[0]); + + glGenBuffers(1, vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors); + + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions)); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); +} + +void DrawCommandExample::Display(bool auto_redraw) +{ + float t = float(app_time() & 0x1FFF) / float(0x1FFF); + static float q = 0.0f; + static const vmath::vec3 X(1.0f, 0.0f, 0.0f); + static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); + static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); + static const vmath::vec4 black = vmath::vec4(0.0f, 0.0f, 0.0f, 0.0f); + + mat4 model_matrix; + + // Setup + glEnable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + glClearBufferfv(GL_COLOR, 0, black); + + // Activate simple shading program + glUseProgram(render_prog); + + // Set up the model and projection matrix + vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f)); + glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, projection_matrix); + + // Set up for a glDrawElements call + glBindVertexArray(vao[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); + + // Draw Arrays... + model_matrix = vmath::translate(-3.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawArrays(GL_TRIANGLES, 0, 3); + + // DrawElements + model_matrix = vmath::translate(-1.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL); + + // DrawElementsBaseVertex + model_matrix = vmath::translate(1.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1); + + // DrawArraysInstanced + model_matrix = vmath::translate(3.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); + + base::Display(); +} + +void DrawCommandExample::Finalize(void) +{ + glUseProgram(0); + glDeleteProgram(render_prog); + glDeleteVertexArrays(1, vao); + glDeleteBuffers(1, vbo); +} + +void DrawCommandExample::Resize(int width, int height) +{ + glViewport(0, 0 , width, height); + + aspect = float(height) / float(width); +} diff --git a/src/miniGLRender/tr_common.cpp b/src/miniGLRender/tr_common.cpp new file mode 100644 index 0000000..c18c85a --- /dev/null +++ b/src/miniGLRender/tr_common.cpp @@ -0,0 +1,2 @@ +#include "tr_common.h" + diff --git a/src/miniGLRender/tr_common.h b/src/miniGLRender/tr_common.h new file mode 100644 index 0000000..e82eddd --- /dev/null +++ b/src/miniGLRender/tr_common.h @@ -0,0 +1,22 @@ +#ifndef __TR_COMMON_H__ +#define __TR_COMMON_H__ + +#include "common.h" +#include "math_common.h" + +typedef unsigned short triIndex_t; + +// qqDrawVert +class qqDrawVert +{ +public: + qqVec3 xyz; + halfFloat_t st[2]; + unsigned char normal[4]; + unsigned char tangent[4]; + unsigned char color[4]; + unsigned char color2[4]; +}; + + +#endif // __TR_COMMON_H__ diff --git a/src/miniGLRender/vertexCache.cpp b/src/miniGLRender/vertexCache.cpp new file mode 100644 index 0000000..f4a08ed --- /dev/null +++ b/src/miniGLRender/vertexCache.cpp @@ -0,0 +1,161 @@ + +#include "vapp.h" +#include "vutils.h" + +#include "vmath.h" + +#include "LoadShaders.h" + +#include + +using namespace vmath; + +BEGIN_APP_DECLARATION(DrawCommandExample) + // Override functions from base class + virtual void Initialize(const char * title); + virtual void Display(bool auto_redraw); + virtual void Finalize(void); + virtual void Resize(int width, int height); + + // Member variables + float aspect; + GLuint render_prog; + GLuint vao[1]; + GLuint vbo[1]; + GLuint ebo[1]; + + GLint render_model_matrix_loc; + GLint render_projection_matrix_loc; +END_APP_DECLARATION() + +DEFINE_APP(DrawCommandExample, "Drawing Commands Example") + +void DrawCommandExample::Initialize(const char * title) +{ + base::Initialize(title); + + ShaderInfo shader_info[] = + { + { GL_VERTEX_SHADER, "media/shaders/primitive_restart/primitive_restart.vs.glsl" }, + { GL_FRAGMENT_SHADER, "media/shaders/primitive_restart/primitive_restart.fs.glsl" }, + { GL_NONE, NULL } + }; + + render_prog = LoadShaders(shader_info); + + glUseProgram(render_prog); + + // "model_matrix" is actually an array of 4 matrices + render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix"); + render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix"); + + // A single triangle + static const GLfloat vertex_positions[] = + { + -1.0f, -1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f, + }; + + // Color for each vertex + static const GLfloat vertex_colors[] = + { + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 1.0f + }; + + // Indices for the triangle strips + static const GLushort vertex_indices[] = + { + 0, 1, 2 + }; + + // Set up the element array buffer + glGenBuffers(1, ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW); + + // Set up the vertex attributes + glGenVertexArrays(1, vao); + glBindVertexArray(vao[0]); + + glGenBuffers(1, vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors); + + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions)); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); +} + +void DrawCommandExample::Display(bool auto_redraw) +{ + float t = float(app_time() & 0x1FFF) / float(0x1FFF); + static float q = 0.0f; + static const vmath::vec3 X(1.0f, 0.0f, 0.0f); + static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); + static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); + static const vmath::vec4 black = vmath::vec4(0.0f, 0.0f, 0.0f, 0.0f); + + mat4 model_matrix; + + // Setup + glEnable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + glClearBufferfv(GL_COLOR, 0, black); + + // Activate simple shading program + glUseProgram(render_prog); + + // Set up the model and projection matrix + vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f)); + glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, projection_matrix); + + // Set up for a glDrawElements call + glBindVertexArray(vao[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); + + // Draw Arrays... + model_matrix = vmath::translate(-3.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawArrays(GL_TRIANGLES, 0, 3); + + // DrawElements + model_matrix = vmath::translate(-1.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL); + + // DrawElementsBaseVertex + model_matrix = vmath::translate(1.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1); + + // DrawArraysInstanced + model_matrix = vmath::translate(3.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); + + base::Display(); +} + +void DrawCommandExample::Finalize(void) +{ + glUseProgram(0); + glDeleteProgram(render_prog); + glDeleteVertexArrays(1, vao); + glDeleteBuffers(1, vbo); +} + +void DrawCommandExample::Resize(int width, int height) +{ + glViewport(0, 0 , width, height); + + aspect = float(height) / float(width); +} diff --git a/src/miniGLRender/vertexCache.h b/src/miniGLRender/vertexCache.h new file mode 100644 index 0000000..f4a08ed --- /dev/null +++ b/src/miniGLRender/vertexCache.h @@ -0,0 +1,161 @@ + +#include "vapp.h" +#include "vutils.h" + +#include "vmath.h" + +#include "LoadShaders.h" + +#include + +using namespace vmath; + +BEGIN_APP_DECLARATION(DrawCommandExample) + // Override functions from base class + virtual void Initialize(const char * title); + virtual void Display(bool auto_redraw); + virtual void Finalize(void); + virtual void Resize(int width, int height); + + // Member variables + float aspect; + GLuint render_prog; + GLuint vao[1]; + GLuint vbo[1]; + GLuint ebo[1]; + + GLint render_model_matrix_loc; + GLint render_projection_matrix_loc; +END_APP_DECLARATION() + +DEFINE_APP(DrawCommandExample, "Drawing Commands Example") + +void DrawCommandExample::Initialize(const char * title) +{ + base::Initialize(title); + + ShaderInfo shader_info[] = + { + { GL_VERTEX_SHADER, "media/shaders/primitive_restart/primitive_restart.vs.glsl" }, + { GL_FRAGMENT_SHADER, "media/shaders/primitive_restart/primitive_restart.fs.glsl" }, + { GL_NONE, NULL } + }; + + render_prog = LoadShaders(shader_info); + + glUseProgram(render_prog); + + // "model_matrix" is actually an array of 4 matrices + render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix"); + render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix"); + + // A single triangle + static const GLfloat vertex_positions[] = + { + -1.0f, -1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f, + }; + + // Color for each vertex + static const GLfloat vertex_colors[] = + { + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 1.0f + }; + + // Indices for the triangle strips + static const GLushort vertex_indices[] = + { + 0, 1, 2 + }; + + // Set up the element array buffer + glGenBuffers(1, ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW); + + // Set up the vertex attributes + glGenVertexArrays(1, vao); + glBindVertexArray(vao[0]); + + glGenBuffers(1, vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors); + + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions)); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); +} + +void DrawCommandExample::Display(bool auto_redraw) +{ + float t = float(app_time() & 0x1FFF) / float(0x1FFF); + static float q = 0.0f; + static const vmath::vec3 X(1.0f, 0.0f, 0.0f); + static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); + static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); + static const vmath::vec4 black = vmath::vec4(0.0f, 0.0f, 0.0f, 0.0f); + + mat4 model_matrix; + + // Setup + glEnable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + glClearBufferfv(GL_COLOR, 0, black); + + // Activate simple shading program + glUseProgram(render_prog); + + // Set up the model and projection matrix + vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f)); + glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, projection_matrix); + + // Set up for a glDrawElements call + glBindVertexArray(vao[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); + + // Draw Arrays... + model_matrix = vmath::translate(-3.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawArrays(GL_TRIANGLES, 0, 3); + + // DrawElements + model_matrix = vmath::translate(-1.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL); + + // DrawElementsBaseVertex + model_matrix = vmath::translate(1.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1); + + // DrawArraysInstanced + model_matrix = vmath::translate(3.0f, 0.0f, -5.0f); + glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); + glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); + + base::Display(); +} + +void DrawCommandExample::Finalize(void) +{ + glUseProgram(0); + glDeleteProgram(render_prog); + glDeleteVertexArrays(1, vao); + glDeleteBuffers(1, vbo); +} + +void DrawCommandExample::Resize(int width, int height) +{ + glViewport(0, 0 , width, height); + + aspect = float(height) / float(width); +} From 33a1742d0f2ea1c0dcac4acf04813e9705e5c224 Mon Sep 17 00:00:00 2001 From: hzzhouqq Date: Sun, 5 Nov 2023 21:47:54 +0800 Subject: [PATCH 2/2] miniGLRender minor commit miniGLRender minor commit --- CMakeLists.txt | 30 +++ src/miniGLRender/bufferObjects.cpp | 2 +- src/miniGLRender/common.h | 17 +- src/miniGLRender/miniRenderApp.cpp | 164 ++-------------- src/miniGLRender/renderSystem.cpp | 2 + src/miniGLRender/renderSystem.h | 18 ++ src/miniGLRender/thread.cpp | 23 +++ src/miniGLRender/thread.h | 27 +++ src/miniGLRender/tr_common.cpp | 1 - src/miniGLRender/tr_common.h | 34 ++++ src/miniGLRender/vertexCache.cpp | 238 ++++++++-------------- src/miniGLRender/vertexCache.h | 305 ++++++++++++++--------------- 12 files changed, 396 insertions(+), 465 deletions(-) create mode 100644 src/miniGLRender/renderSystem.cpp create mode 100644 src/miniGLRender/renderSystem.h create mode 100644 src/miniGLRender/thread.cpp create mode 100644 src/miniGLRender/thread.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 05f3354..ea27892 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,10 @@ set(EXAMPLES 12-simplecompute ) +set(ADDITIONS + miniGLRender +) + find_package(OpenMP) if (OPENMP_FOUND) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") @@ -94,6 +98,32 @@ foreach(EXAMPLE ${EXAMPLES}) endif(MSVC) endforeach(EXAMPLE) +foreach(ADDITION ${ADDITIONS}) + add_executable(${ADDITION} WIN32 + src/${ADDITION}/miniRenderApp.cpp + src/${ADDITION}/tr_common.cpp + src/${ADDITION}/tr_common.h + src/${ADDITION}/common.cpp + src/${ADDITION}/common.h + src/${ADDITION}/math_common.cpp + src/${ADDITION}/math_common.h + src/${ADDITION}/thread.cpp + src/${ADDITION}/thread.h + src/${ADDITION}/renderSystem.cpp + src/${ADDITION}/renderSystem.h + src/${ADDITION}/bufferObjects.cpp + src/${ADDITION}/bufferObjects.h + src/${ADDITION}/vertexCache.cpp + src/${ADDITION}/vertexCache.h +) + + set_property(TARGET ${ADDITION} PROPERTY DEBUG_POSTFIX _d) + target_link_libraries(${ADDITION} ${COMMON_LIBS}) + if(MSVC) + configure_file(${PROJECT_SOURCE_DIR}/build/templates/vs2013.vcxproj.user.in ${CMAKE_CURRENT_BINARY_DIR}/${ADDITION}.vcxproj.user @ONLY) + endif(MSVC) +endforeach(ADDITION) + IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LINUX") ENDIF (${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff --git a/src/miniGLRender/bufferObjects.cpp b/src/miniGLRender/bufferObjects.cpp index 7a933cc..10947bf 100644 --- a/src/miniGLRender/bufferObjects.cpp +++ b/src/miniGLRender/bufferObjects.cpp @@ -1,5 +1,5 @@ #include "bufferObjects.h" -#include "vgl.h" + //static const GLenum bufferUsage = GL_STATIC_DRAW_ARB; static const GLenum bufferUsage = GL_DYNAMIC_DRAW; diff --git a/src/miniGLRender/common.h b/src/miniGLRender/common.h index b61898f..fdad426 100644 --- a/src/miniGLRender/common.h +++ b/src/miniGLRender/common.h @@ -23,7 +23,22 @@ private: \ #define assert_aligned_to_type_size( ptr ) assert( ( ((UINT_PTR)(ptr)) & ( sizeof( (ptr)[0] ) - 1 ) ) == 0 ) -typedef unsigned char byte; +typedef unsigned char byte; // 8 bits +typedef unsigned short word; // 16 bits +typedef unsigned int dword; // 32 bits +typedef unsigned int uint; +typedef unsigned long ulong; + +typedef signed char int8; +typedef unsigned char uint8; +typedef short int int16; +typedef unsigned short int uint16; +typedef int int32; +typedef unsigned int uint32; +typedef long long int64; +typedef unsigned long long uint64; + + // halfFloat_t typedef unsigned short halfFloat_t; diff --git a/src/miniGLRender/miniRenderApp.cpp b/src/miniGLRender/miniRenderApp.cpp index f4a08ed..a56e2bd 100644 --- a/src/miniGLRender/miniRenderApp.cpp +++ b/src/miniGLRender/miniRenderApp.cpp @@ -1,161 +1,23 @@ -#include "vapp.h" -#include "vutils.h" +#include +#include -#include "vmath.h" - -#include "LoadShaders.h" - -#include - -using namespace vmath; - -BEGIN_APP_DECLARATION(DrawCommandExample) - // Override functions from base class - virtual void Initialize(const char * title); - virtual void Display(bool auto_redraw); - virtual void Finalize(void); - virtual void Resize(int width, int height); - - // Member variables - float aspect; - GLuint render_prog; - GLuint vao[1]; - GLuint vbo[1]; - GLuint ebo[1]; - - GLint render_model_matrix_loc; - GLint render_projection_matrix_loc; -END_APP_DECLARATION() - -DEFINE_APP(DrawCommandExample, "Drawing Commands Example") - -void DrawCommandExample::Initialize(const char * title) -{ - base::Initialize(title); - - ShaderInfo shader_info[] = - { - { GL_VERTEX_SHADER, "media/shaders/primitive_restart/primitive_restart.vs.glsl" }, - { GL_FRAGMENT_SHADER, "media/shaders/primitive_restart/primitive_restart.fs.glsl" }, - { GL_NONE, NULL } - }; - - render_prog = LoadShaders(shader_info); - - glUseProgram(render_prog); - - // "model_matrix" is actually an array of 4 matrices - render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix"); - render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix"); - - // A single triangle - static const GLfloat vertex_positions[] = - { - -1.0f, -1.0f, 0.0f, 1.0f, - 1.0f, -1.0f, 0.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 1.0f, - }; - - // Color for each vertex - static const GLfloat vertex_colors[] = - { - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 0.0f, 1.0f, 1.0f, 1.0f - }; - - // Indices for the triangle strips - static const GLushort vertex_indices[] = - { - 0, 1, 2 - }; - - // Set up the element array buffer - glGenBuffers(1, ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW); - - // Set up the vertex attributes - glGenVertexArrays(1, vao); - glBindVertexArray(vao[0]); - - glGenBuffers(1, vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions); - glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors); - - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions)); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); -} - -void DrawCommandExample::Display(bool auto_redraw) +void test_gl() { - float t = float(app_time() & 0x1FFF) / float(0x1FFF); - static float q = 0.0f; - static const vmath::vec3 X(1.0f, 0.0f, 0.0f); - static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); - static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); - static const vmath::vec4 black = vmath::vec4(0.0f, 0.0f, 0.0f, 0.0f); - - mat4 model_matrix; - - // Setup - glEnable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - glClearBufferfv(GL_COLOR, 0, black); - - // Activate simple shading program - glUseProgram(render_prog); + gl3wInit(); - // Set up the model and projection matrix - vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f)); - glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, projection_matrix); + GLint i = 10; + i++; - // Set up for a glDrawElements call - glBindVertexArray(vao[0]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); - - // Draw Arrays... - model_matrix = vmath::translate(-3.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawArrays(GL_TRIANGLES, 0, 3); - - // DrawElements - model_matrix = vmath::translate(-1.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL); - - // DrawElementsBaseVertex - model_matrix = vmath::translate(1.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1); - - // DrawArraysInstanced - model_matrix = vmath::translate(3.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); - - base::Display(); + glCullFace(0); + glDrawArrays(GL_TRIANGLES, 0, 0); } -void DrawCommandExample::Finalize(void) +int WINAPI WinMain(HINSTANCE hInstance, // Instance + HINSTANCE hPrevInstance, // Previous Instance + LPSTR lpCmdLine, // Command Line Parameters + int nCmdShow) // Window Show State { - glUseProgram(0); - glDeleteProgram(render_prog); - glDeleteVertexArrays(1, vao); - glDeleteBuffers(1, vbo); + return 0; } -void DrawCommandExample::Resize(int width, int height) -{ - glViewport(0, 0 , width, height); - - aspect = float(height) / float(width); -} diff --git a/src/miniGLRender/renderSystem.cpp b/src/miniGLRender/renderSystem.cpp new file mode 100644 index 0000000..a6c9f78 --- /dev/null +++ b/src/miniGLRender/renderSystem.cpp @@ -0,0 +1,2 @@ +#include "renderSystem.h" + diff --git a/src/miniGLRender/renderSystem.h b/src/miniGLRender/renderSystem.h new file mode 100644 index 0000000..1598354 --- /dev/null +++ b/src/miniGLRender/renderSystem.h @@ -0,0 +1,18 @@ +#ifndef __RENDER_SYSTEM_H__ +#define __RENDER_SYSTEM_H__ + +#include "tr_common.h" + +// qqRenderSystem +class qqRenderSystem +{ +public: + + virtual ~qqRenderSystem() {} + virtual void Init() = 0; + virtual void Shutdown() = 0; + + virtual const emptyCommand_t* SwapCommandBuffers(uint64* frontEndMicroSec, uint64* backEndMicroSec, uint64* shadowMicroSec, uint64* gpuMicroSec) = 0; + +}; +#endif // __RENDER_SYSTEM_H__ diff --git a/src/miniGLRender/thread.cpp b/src/miniGLRender/thread.cpp new file mode 100644 index 0000000..bedd001 --- /dev/null +++ b/src/miniGLRender/thread.cpp @@ -0,0 +1,23 @@ +#include "thread.h" +#include + +//// qqSysInterlockedInteger +//interlockedInt_t qqSysInterlockedInteger::Sys_InterlockedIncrement(interlockedInt_t& value) +//{ +// return InterlockedIncrementAcquire(&value); +//} +// +//interlockedInt_t qqSysInterlockedInteger::Sys_InterlockedDecrement(interlockedInt_t& value) +//{ +// return InterlockedDecrementRelease(&value); +//} +// +//interlockedInt_t qqSysInterlockedInteger::Sys_InterlockedAdd(interlockedInt_t& value, interlockedInt_t i) +//{ +// return InterlockedExchangeAdd(&value, i) + i; +//} +// +//interlockedInt_t qqSysInterlockedInteger::Sys_InterlockedSub(interlockedInt_t& value, interlockedInt_t i) +//{ +// return InterlockedExchangeAdd(&value, -i) - i; +//} diff --git a/src/miniGLRender/thread.h b/src/miniGLRender/thread.h new file mode 100644 index 0000000..9e52871 --- /dev/null +++ b/src/miniGLRender/thread.h @@ -0,0 +1,27 @@ +#ifndef __THREAD_H__ +#define __THREAD_H__ + +typedef int interlockedInt_t; + +class qqSysInterlockedInteger +{ +public: + qqSysInterlockedInteger() : value(0) {} + + int Increment() { return Sys_InterlockedIncrement(value); } + int Decrement() { return Sys_InterlockedDecrement(value); } + int Add(int v) { return Sys_InterlockedAdd(value, (interlockedInt_t)v); } + int Sub(int v) { return Sys_InterlockedSub(value, (interlockedInt_t)v); } + int GetValue() const { return value; } + void SetValue(int v) { value = (interlockedInt_t)v; } + +private: + interlockedInt_t Sys_InterlockedIncrement(interlockedInt_t& value); + interlockedInt_t Sys_InterlockedDecrement(interlockedInt_t& value); + interlockedInt_t Sys_InterlockedAdd(interlockedInt_t& value, interlockedInt_t i); + interlockedInt_t Sys_InterlockedSub(interlockedInt_t& value, interlockedInt_t i); + + interlockedInt_t value; +}; + +#endif // __COMMON_H__ diff --git a/src/miniGLRender/tr_common.cpp b/src/miniGLRender/tr_common.cpp index c18c85a..cdba0ed 100644 --- a/src/miniGLRender/tr_common.cpp +++ b/src/miniGLRender/tr_common.cpp @@ -1,2 +1 @@ #include "tr_common.h" - diff --git a/src/miniGLRender/tr_common.h b/src/miniGLRender/tr_common.h index e82eddd..98ad955 100644 --- a/src/miniGLRender/tr_common.h +++ b/src/miniGLRender/tr_common.h @@ -4,8 +4,42 @@ #include "common.h" #include "math_common.h" +#include +#include +#include + typedef unsigned short triIndex_t; +// renderCommand_t +enum renderCommand_t +{ + RC_NOP, + RC_DRAW_VIEW_3D, // may be at a reduced resolution, will be upsampled before 2D GUIs + RC_DRAW_VIEW_GUI, // not resolution scaled + RC_SET_BUFFER, + RC_COPY_RENDER, + RC_POST_PROCESS, +}; + +struct emptyCommand_t { + renderCommand_t commandId; + renderCommand_t* next; +}; + + +struct setBufferCommand_t +{ + renderCommand_t commandId; + renderCommand_t* next; + GLenum buffer; +}; + +struct drawSurfsCommand_t { + renderCommand_t commandId; + renderCommand_t* next; + //viewDef_t* viewDef; +}; + // qqDrawVert class qqDrawVert { diff --git a/src/miniGLRender/vertexCache.cpp b/src/miniGLRender/vertexCache.cpp index f4a08ed..8fac3b2 100644 --- a/src/miniGLRender/vertexCache.cpp +++ b/src/miniGLRender/vertexCache.cpp @@ -1,161 +1,93 @@ - -#include "vapp.h" -#include "vutils.h" - -#include "vmath.h" - -#include "LoadShaders.h" - -#include - -using namespace vmath; - -BEGIN_APP_DECLARATION(DrawCommandExample) - // Override functions from base class - virtual void Initialize(const char * title); - virtual void Display(bool auto_redraw); - virtual void Finalize(void); - virtual void Resize(int width, int height); - - // Member variables - float aspect; - GLuint render_prog; - GLuint vao[1]; - GLuint vbo[1]; - GLuint ebo[1]; - - GLint render_model_matrix_loc; - GLint render_projection_matrix_loc; -END_APP_DECLARATION() - -DEFINE_APP(DrawCommandExample, "Drawing Commands Example") - -void DrawCommandExample::Initialize(const char * title) +#include "vertexCache.h" + +/* +============== +ClearGeoBufferSet +============== +*/ +static void ClearGeoBufferSet(geoBufferSet_t& gbs) { - base::Initialize(title); - - ShaderInfo shader_info[] = - { - { GL_VERTEX_SHADER, "media/shaders/primitive_restart/primitive_restart.vs.glsl" }, - { GL_FRAGMENT_SHADER, "media/shaders/primitive_restart/primitive_restart.fs.glsl" }, - { GL_NONE, NULL } - }; - - render_prog = LoadShaders(shader_info); - - glUseProgram(render_prog); - - // "model_matrix" is actually an array of 4 matrices - render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix"); - render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix"); - - // A single triangle - static const GLfloat vertex_positions[] = - { - -1.0f, -1.0f, 0.0f, 1.0f, - 1.0f, -1.0f, 0.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 1.0f, - }; - - // Color for each vertex - static const GLfloat vertex_colors[] = - { - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 0.0f, 1.0f, 1.0f, 1.0f - }; - - // Indices for the triangle strips - static const GLushort vertex_indices[] = - { - 0, 1, 2 - }; - - // Set up the element array buffer - glGenBuffers(1, ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW); - - // Set up the vertex attributes - glGenVertexArrays(1, vao); - glBindVertexArray(vao[0]); - - glGenBuffers(1, vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions); - glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors); - - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions)); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); + gbs.indexMemUsed.SetValue(0); + gbs.vertexMemUsed.SetValue(0); + gbs.jointMemUsed.SetValue(0); + gbs.allocations = 0; } -void DrawCommandExample::Display(bool auto_redraw) -{ - float t = float(app_time() & 0x1FFF) / float(0x1FFF); - static float q = 0.0f; - static const vmath::vec3 X(1.0f, 0.0f, 0.0f); - static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); - static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); - static const vmath::vec4 black = vmath::vec4(0.0f, 0.0f, 0.0f, 0.0f); - - mat4 model_matrix; - - // Setup - glEnable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - glClearBufferfv(GL_COLOR, 0, black); - - // Activate simple shading program - glUseProgram(render_prog); - - // Set up the model and projection matrix - vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f)); - glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, projection_matrix); - - // Set up for a glDrawElements call - glBindVertexArray(vao[0]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); - - // Draw Arrays... - model_matrix = vmath::translate(-3.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawArrays(GL_TRIANGLES, 0, 3); - - // DrawElements - model_matrix = vmath::translate(-1.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL); - - // DrawElementsBaseVertex - model_matrix = vmath::translate(1.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1); - - // DrawArraysInstanced - model_matrix = vmath::translate(3.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); - - base::Display(); +/* +============== +MapGeoBufferSet +============== +*/ +static void MapGeoBufferSet(geoBufferSet_t& gbs) { + if (gbs.mappedVertexBase == NULL) { + gbs.mappedVertexBase = (byte*)gbs.vertexBuffer.MapBuffer(BM_WRITE); + } + if (gbs.mappedIndexBase == NULL) { + gbs.mappedIndexBase = (byte*)gbs.indexBuffer.MapBuffer(BM_WRITE); + } + //if (gbs.mappedJointBase == NULL && gbs.jointBuffer.GetAllocedSize() != 0) { + // gbs.mappedJointBase = (byte*)gbs.jointBuffer.MapBuffer(BM_WRITE); + //} } -void DrawCommandExample::Finalize(void) -{ - glUseProgram(0); - glDeleteProgram(render_prog); - glDeleteVertexArrays(1, vao); - glDeleteBuffers(1, vbo); +/* +============== +UnmapGeoBufferSet +============== +*/ +static void UnmapGeoBufferSet(geoBufferSet_t& gbs) { + if (gbs.mappedVertexBase != NULL) { + gbs.vertexBuffer.UnmapBuffer(); + gbs.mappedVertexBase = NULL; + } + if (gbs.mappedIndexBase != NULL) { + gbs.indexBuffer.UnmapBuffer(); + gbs.mappedIndexBase = NULL; + } + //if (gbs.mappedJointBase != NULL) { + // gbs.jointBuffer.UnmapBuffer(); + // gbs.mappedJointBase = NULL; + //} } -void DrawCommandExample::Resize(int width, int height) -{ - glViewport(0, 0 , width, height); - - aspect = float(height) / float(width); +/* +============== +AllocGeoBufferSet +============== +*/ +static void AllocGeoBufferSet(geoBufferSet_t& gbs, const int vertexBytes, const int indexBytes, const int jointBytes) { + gbs.vertexBuffer.AllocBufferObject(NULL, vertexBytes); + gbs.indexBuffer.AllocBufferObject(NULL, indexBytes); + if (jointBytes != 0) { + // todo + //gbs.jointBuffer.AllocBufferObject(NULL, jointBytes / sizeof(idJointMat)); + } + ClearGeoBufferSet(gbs); } + +//// qqVertexCache +//void qqVertexCache::Init(bool restart) +//{ +// currentFrame = 0; +// listNum = 0; +// +// mostUsedVertex = 0; +// mostUsedIndex = 0; +// mostUsedJoint = 0; +// +// for (int i = 0; i < VERTCACHE_NUM_FRAMES; i++) { +// AllocGeoBufferSet(frameData[i], VERTCACHE_VERTEX_MEMORY_PER_FRAME, VERTCACHE_INDEX_MEMORY_PER_FRAME, VERTCACHE_JOINT_MEMORY_PER_FRAME); +// } +// AllocGeoBufferSet(staticData, STATIC_VERTEX_MEMORY, STATIC_INDEX_MEMORY, 0); +// +// MapGeoBufferSet(frameData[listNum]); +//} +// +//void qqVertexCache::Shutdown() +//{ +// for (int i = 0; i < VERTCACHE_NUM_FRAMES; i++) { +// frameData[i].vertexBuffer.FreeBufferObject(); +// frameData[i].indexBuffer.FreeBufferObject(); +// frameData[i].jointBuffer.FreeBufferObject(); +// } +//} diff --git a/src/miniGLRender/vertexCache.h b/src/miniGLRender/vertexCache.h index f4a08ed..c0b5bf2 100644 --- a/src/miniGLRender/vertexCache.h +++ b/src/miniGLRender/vertexCache.h @@ -1,161 +1,150 @@ - -#include "vapp.h" -#include "vutils.h" - -#include "vmath.h" - -#include "LoadShaders.h" - -#include - -using namespace vmath; - -BEGIN_APP_DECLARATION(DrawCommandExample) - // Override functions from base class - virtual void Initialize(const char * title); - virtual void Display(bool auto_redraw); - virtual void Finalize(void); - virtual void Resize(int width, int height); - - // Member variables - float aspect; - GLuint render_prog; - GLuint vao[1]; - GLuint vbo[1]; - GLuint ebo[1]; - - GLint render_model_matrix_loc; - GLint render_projection_matrix_loc; -END_APP_DECLARATION() - -DEFINE_APP(DrawCommandExample, "Drawing Commands Example") - -void DrawCommandExample::Initialize(const char * title) +#ifndef __VERTEXCACHE2_H__ +#define __VERTEXCACHE2_H__ + +#include "bufferObjects.h" +#include "thread.h" + +const int VERTCACHE_INDEX_MEMORY_PER_FRAME = 31 * 1024 * 1024; +const int VERTCACHE_VERTEX_MEMORY_PER_FRAME = 31 * 1024 * 1024; +const int VERTCACHE_JOINT_MEMORY_PER_FRAME = 256 * 1024; + +const int VERTCACHE_NUM_FRAMES = 2; + +// there are a lot more static indexes than vertexes, because interactions are just new +// index lists that reference existing vertexes +const int STATIC_INDEX_MEMORY = 31 * 1024 * 1024; +const int STATIC_VERTEX_MEMORY = 31 * 1024 * 1024; // make sure it fits in VERTCACHE_OFFSET_MASK! + +// vertCacheHandle_t packs size, offset, and frame number into 64 bits +typedef uint64 vertCacheHandle_t; +const int VERTCACHE_STATIC = 1; // in the static set, not the per-frame set +const int VERTCACHE_SIZE_SHIFT = 1; +const int VERTCACHE_SIZE_MASK = 0x7fffff; // 8 megs +const int VERTCACHE_OFFSET_SHIFT = 24; +const int VERTCACHE_OFFSET_MASK = 0x1ffffff; // 32 megs +const int VERTCACHE_FRAME_SHIFT = 49; +const int VERTCACHE_FRAME_MASK = 0x7fff; // 15 bits = 32k frames to wrap around + +const int VERTEX_CACHE_ALIGN = 32; +const int INDEX_CACHE_ALIGN = 16; +const int JOINT_CACHE_ALIGN = 16; + +enum cacheType_t { - base::Initialize(title); - - ShaderInfo shader_info[] = - { - { GL_VERTEX_SHADER, "media/shaders/primitive_restart/primitive_restart.vs.glsl" }, - { GL_FRAGMENT_SHADER, "media/shaders/primitive_restart/primitive_restart.fs.glsl" }, - { GL_NONE, NULL } - }; - - render_prog = LoadShaders(shader_info); - - glUseProgram(render_prog); - - // "model_matrix" is actually an array of 4 matrices - render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix"); - render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix"); - - // A single triangle - static const GLfloat vertex_positions[] = - { - -1.0f, -1.0f, 0.0f, 1.0f, - 1.0f, -1.0f, 0.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 1.0f, - }; - - // Color for each vertex - static const GLfloat vertex_colors[] = - { - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 0.0f, 1.0f, 1.0f, 1.0f - }; - - // Indices for the triangle strips - static const GLushort vertex_indices[] = - { - 0, 1, 2 - }; - - // Set up the element array buffer - glGenBuffers(1, ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW); - - // Set up the vertex attributes - glGenVertexArrays(1, vao); - glBindVertexArray(vao[0]); + CACHE_VERTEX, + CACHE_INDEX, + CACHE_JOINT +}; - glGenBuffers(1, vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions); - glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors); - - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions)); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); -} - -void DrawCommandExample::Display(bool auto_redraw) -{ - float t = float(app_time() & 0x1FFF) / float(0x1FFF); - static float q = 0.0f; - static const vmath::vec3 X(1.0f, 0.0f, 0.0f); - static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); - static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); - static const vmath::vec4 black = vmath::vec4(0.0f, 0.0f, 0.0f, 0.0f); - - mat4 model_matrix; - - // Setup - glEnable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - glClearBufferfv(GL_COLOR, 0, black); - - // Activate simple shading program - glUseProgram(render_prog); - - // Set up the model and projection matrix - vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f)); - glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, projection_matrix); - - // Set up for a glDrawElements call - glBindVertexArray(vao[0]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); - - // Draw Arrays... - model_matrix = vmath::translate(-3.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawArrays(GL_TRIANGLES, 0, 3); - - // DrawElements - model_matrix = vmath::translate(-1.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL); - - // DrawElementsBaseVertex - model_matrix = vmath::translate(1.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1); - - // DrawArraysInstanced - model_matrix = vmath::translate(3.0f, 0.0f, -5.0f); - glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, model_matrix); - glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); - - base::Display(); -} - -void DrawCommandExample::Finalize(void) -{ - glUseProgram(0); - glDeleteProgram(render_prog); - glDeleteVertexArrays(1, vao); - glDeleteBuffers(1, vbo); -} - -void DrawCommandExample::Resize(int width, int height) +struct geoBufferSet_t { - glViewport(0, 0 , width, height); - - aspect = float(height) / float(width); -} + qqIndexBuffer indexBuffer; + qqVertexBuffer vertexBuffer; + //qqJointBuffer jointBuffer; + + byte* mappedVertexBase; + byte* mappedIndexBase; + byte* mappedJointBase; + + qqSysInterlockedInteger indexMemUsed; + qqSysInterlockedInteger vertexMemUsed; + qqSysInterlockedInteger jointMemUsed; + int allocations; // number of index and vertex allocations combined +}; + +//// qqVertexCache +//class qqVertexCache +//{ +//public: +// void Init(bool restart = false); +// void Shutdown(); +// void PurgeAll(); +// +// // call on loading a new map +// void FreeStaticData(); +// +// // this data is only valid for one frame of rendering +// vertCacheHandle_t AllocVertex(const void* data, int bytes) { +// return ActuallyAlloc(frameData[listNum], data, bytes, CACHE_VERTEX); +// } +// vertCacheHandle_t AllocIndex(const void* data, int bytes) { +// return ActuallyAlloc(frameData[listNum], data, bytes, CACHE_INDEX); +// } +// vertCacheHandle_t AllocJoint(const void* data, int bytes) { +// return ActuallyAlloc(frameData[listNum], data, bytes, CACHE_JOINT); +// } +// +// // this data is valid until the next map load +// vertCacheHandle_t AllocStaticVertex(const void* data, int bytes) { +// if (staticData.vertexMemUsed.GetValue() + bytes > STATIC_VERTEX_MEMORY) { +// idLib::FatalError("AllocStaticVertex failed, increase STATIC_VERTEX_MEMORY"); +// } +// return ActuallyAlloc(staticData, data, bytes, CACHE_VERTEX); +// } +// vertCacheHandle_t AllocStaticIndex(const void* data, int bytes) { +// if (staticData.indexMemUsed.GetValue() + bytes > STATIC_INDEX_MEMORY) { +// idLib::FatalError("AllocStaticIndex failed, increase STATIC_INDEX_MEMORY"); +// } +// return ActuallyAlloc(staticData, data, bytes, CACHE_INDEX); +// } +// +// byte* MappedVertexBuffer(vertCacheHandle_t handle) { +// release_assert(!CacheIsStatic(handle)); +// const uint64 offset = (int)(handle >> VERTCACHE_OFFSET_SHIFT) & VERTCACHE_OFFSET_MASK; +// const uint64 frameNum = (int)(handle >> VERTCACHE_FRAME_SHIFT) & VERTCACHE_FRAME_MASK; +// release_assert(frameNum == (currentFrame & VERTCACHE_FRAME_MASK)); +// return frameData[listNum].mappedVertexBase + offset; +// } +// +// byte* MappedIndexBuffer(vertCacheHandle_t handle) { +// release_assert(!CacheIsStatic(handle)); +// const uint64 offset = (int)(handle >> VERTCACHE_OFFSET_SHIFT) & VERTCACHE_OFFSET_MASK; +// const uint64 frameNum = (int)(handle >> VERTCACHE_FRAME_SHIFT) & VERTCACHE_FRAME_MASK; +// release_assert(frameNum == (currentFrame & VERTCACHE_FRAME_MASK)); +// return frameData[listNum].mappedIndexBase + offset; +// } +// +// // Returns false if it's been purged +// // This can only be called by the front end, the back end should only be looking at +// // vertCacheHandle_t that are already validated. +// bool CacheIsCurrent(const vertCacheHandle_t handle) { +// const int isStatic = handle & VERTCACHE_STATIC; +// if (isStatic) { +// return true; +// } +// const uint64 frameNum = (int)(handle >> VERTCACHE_FRAME_SHIFT) & VERTCACHE_FRAME_MASK; +// if (frameNum != (currentFrame & VERTCACHE_FRAME_MASK)) { +// return false; +// } +// return true; +// } +// +// static bool CacheIsStatic(const vertCacheHandle_t handle) { +// return (handle & VERTCACHE_STATIC) != 0; +// } +// +// // vb/ib is a temporary reference -- don't store it +// bool GetVertexBuffer(vertCacheHandle_t handle, qqVertexBuffer* vb); +// bool GetIndexBuffer(vertCacheHandle_t handle, qqIndexBuffer* ib); +// //bool GetJointBuffer(vertCacheHandle_t handle, idJointBuffer* jb); +// +// void BeginBackEnd(); +// +//public: +// int currentFrame; // for determining the active buffers +// int listNum; // currentFrame % VERTCACHE_NUM_FRAMES +// int drawListNum; // (currentFrame-1) % VERTCACHE_NUM_FRAMES +// +// geoBufferSet_t staticData; +// geoBufferSet_t frameData[VERTCACHE_NUM_FRAMES]; +// +// // High water marks for the per-frame buffers +// int mostUsedVertex; +// int mostUsedIndex; +// int mostUsedJoint; +// +// // Try to make room for bytes +// vertCacheHandle_t ActuallyAlloc(geoBufferSet_t& vcs, const void* data, int bytes, cacheType_t type); +//}; + +#endif