mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-17 11:11:30 +12:00
Merge pull request #33 from Wunkolo/span-vertex
Use `std::span` to pass vertex data
This commit is contained in:
commit
dafa919e1b
6 changed files with 62 additions and 32 deletions
|
@ -1,6 +1,6 @@
|
||||||
BasedOnStyle: Google
|
BasedOnStyle: Google
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
ColumnLimit: 120
|
ColumnLimit: 150
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -2
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
NamespaceIndentation: All
|
NamespaceIndentation: All
|
||||||
|
|
|
@ -30,6 +30,19 @@
|
||||||
|
|
||||||
#include "gl3w.h"
|
#include "gl3w.h"
|
||||||
|
|
||||||
|
// Check if we have C++20. If yes, we can add C++20 std::span support
|
||||||
|
#ifdef _MSVC_LANG // MSVC does not properly define __cplusplus without a compiler flag...
|
||||||
|
#if _MSVC_LANG >= 202002L
|
||||||
|
#define OPENGL_HAVE_CPP20
|
||||||
|
#endif
|
||||||
|
#elif __cplusplus >= 202002L
|
||||||
|
#define OPENGL_HAVE_CPP20
|
||||||
|
#endif // MSVC_LANG
|
||||||
|
|
||||||
|
#ifdef OPENGL_HAVE_CPP20
|
||||||
|
#include <span>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Uncomment the following define if you want GL objects to automatically free themselves when their lifetime ends
|
// Uncomment the following define if you want GL objects to automatically free themselves when their lifetime ends
|
||||||
// #define OPENGL_DESTRUCTORS
|
// #define OPENGL_DESTRUCTORS
|
||||||
|
|
||||||
|
@ -389,17 +402,30 @@ namespace OpenGL {
|
||||||
void free() { glDeleteBuffers(1, &m_handle); }
|
void free() { glDeleteBuffers(1, &m_handle); }
|
||||||
|
|
||||||
// Reallocates the buffer on every call. Prefer the sub version if possible.
|
// Reallocates the buffer on every call. Prefer the sub version if possible.
|
||||||
template <typename VertType>
|
template <typename VertType>
|
||||||
void bufferVerts(VertType* vertices, int vertCount, GLenum usage = GL_DYNAMIC_DRAW) {
|
void bufferVerts(VertType* vertices, int vertCount, GLenum usage = GL_DYNAMIC_DRAW) {
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertType) * vertCount, vertices, usage);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(VertType) * vertCount, vertices, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only use if you used createFixedSize
|
// Only use if you used createFixedSize
|
||||||
template <typename VertType>
|
template <typename VertType>
|
||||||
void bufferVertsSub(VertType* vertices, int vertCount, GLintptr offset = 0) {
|
void bufferVertsSub(VertType* vertices, int vertCount, GLintptr offset = 0) {
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(VertType) * vertCount, vertices);
|
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(VertType) * vertCount, vertices);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
// If C++20 is available, add overloads that take std::span instead of raw pointers
|
||||||
|
#ifdef OPENGL_HAVE_CPP20
|
||||||
|
template <typename VertType>
|
||||||
|
void bufferVerts(std::span<const VertType> vertices, GLenum usage = GL_DYNAMIC_DRAW) {
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(VertType) * vertices.size(), vertices.data(), usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VertType>
|
||||||
|
void bufferVertsSub(std::span<const VertType> vertices, GLintptr offset = 0) {
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(VertType) * vertices.size(), vertices.data());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
enum DepthFunc {
|
enum DepthFunc {
|
||||||
Never = GL_NEVER, // Depth test never passes
|
Never = GL_NEVER, // Depth test never passes
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
#include "opengl.hpp"
|
#include "opengl.hpp"
|
||||||
|
@ -24,7 +26,7 @@ class Renderer {
|
||||||
OpenGL::VertexBuffer vbo;
|
OpenGL::VertexBuffer vbo;
|
||||||
GLint alphaControlLoc = -1;
|
GLint alphaControlLoc = -1;
|
||||||
GLint texUnitConfigLoc = -1;
|
GLint texUnitConfigLoc = -1;
|
||||||
|
|
||||||
// Depth configuration uniform locations
|
// Depth configuration uniform locations
|
||||||
GLint depthOffsetLoc = -1;
|
GLint depthOffsetLoc = -1;
|
||||||
GLint depthScaleLoc = -1;
|
GLint depthScaleLoc = -1;
|
||||||
|
@ -41,11 +43,11 @@ class Renderer {
|
||||||
SurfaceCache<ColourBuffer, 10> colourBufferCache;
|
SurfaceCache<ColourBuffer, 10> colourBufferCache;
|
||||||
SurfaceCache<Texture, 256> textureCache;
|
SurfaceCache<Texture, 256> textureCache;
|
||||||
|
|
||||||
OpenGL::uvec2 fbSize; // The size of the framebuffer (ie both the colour and depth buffer)'
|
OpenGL::uvec2 fbSize; // The size of the framebuffer (ie both the colour and depth buffer)'
|
||||||
|
|
||||||
|
u32 colourBufferLoc; // Location in 3DS VRAM for the colour buffer
|
||||||
|
ColourBuffer::Formats colourBufferFormat; // Format of the colours stored in the colour buffer
|
||||||
|
|
||||||
u32 colourBufferLoc; // Location in 3DS VRAM for the colour buffer
|
|
||||||
ColourBuffer::Formats colourBufferFormat; // Format of the colours stored in the colour buffer
|
|
||||||
|
|
||||||
// Same for the depth/stencil buffer
|
// Same for the depth/stencil buffer
|
||||||
u32 depthBufferLoc;
|
u32 depthBufferLoc;
|
||||||
DepthBuffer::Formats depthBufferFormat;
|
DepthBuffer::Formats depthBufferFormat;
|
||||||
|
@ -54,7 +56,7 @@ class Renderer {
|
||||||
OpenGL::VertexArray dummyVAO;
|
OpenGL::VertexArray dummyVAO;
|
||||||
OpenGL::VertexBuffer dummyVBO;
|
OpenGL::VertexBuffer dummyVBO;
|
||||||
|
|
||||||
static constexpr u32 regNum = 0x300; // Number of internal PICA registers
|
static constexpr u32 regNum = 0x300; // Number of internal PICA registers
|
||||||
const std::array<u32, regNum>& regs;
|
const std::array<u32, regNum>& regs;
|
||||||
|
|
||||||
OpenGL::Framebuffer getColourFBO();
|
OpenGL::Framebuffer getColourFBO();
|
||||||
|
@ -64,16 +66,16 @@ class Renderer {
|
||||||
void setupBlending();
|
void setupBlending();
|
||||||
void bindDepthBuffer();
|
void bindDepthBuffer();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs) : gpu(gpu), regs(internalRegs) {}
|
Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs) : gpu(gpu), regs(internalRegs) {}
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void display(); // Display the 3DS screen contents to the window
|
void display(); // Display the 3DS screen contents to the window
|
||||||
void initGraphicsContext(); // Initialize graphics context
|
void initGraphicsContext(); // Initialize graphics context
|
||||||
void getGraphicsContext(); // Set up graphics context for rendering
|
void getGraphicsContext(); // Set up graphics context for rendering
|
||||||
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control); // Clear a GPU buffer in VRAM
|
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control); // Clear a GPU buffer in VRAM
|
||||||
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags); // Perform display transfer
|
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags); // Perform display transfer
|
||||||
void drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 count); // Draw the given vertices
|
void drawVertices(OpenGL::Primitives primType, std::span<const Vertex> vertices); // Draw the given vertices
|
||||||
|
|
||||||
void setFBSize(u32 width, u32 height) {
|
void setFBSize(u32 width, u32 height) {
|
||||||
fbSize.x() = width;
|
fbSize.x() = width;
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#include "PICA/gpu.hpp"
|
#include "PICA/gpu.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
#include "PICA/float_types.hpp"
|
#include "PICA/float_types.hpp"
|
||||||
#include "PICA/regs.hpp"
|
#include "PICA/regs.hpp"
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
using namespace Floats;
|
using namespace Floats;
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ void GPU::drawArrays(bool indexed) {
|
||||||
drawArrays<false>();
|
drawArrays<false>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex* vertices = new Vertex[Renderer::vertexBufferSize];
|
static std::array<Vertex, Renderer::vertexBufferSize> vertices;
|
||||||
|
|
||||||
template <bool indexed>
|
template <bool indexed>
|
||||||
void GPU::drawArrays() {
|
void GPU::drawArrays() {
|
||||||
|
@ -205,7 +208,7 @@ void GPU::drawArrays() {
|
||||||
OpenGL::Triangle, OpenGL::TriangleStrip, OpenGL::TriangleFan, OpenGL::Triangle
|
OpenGL::Triangle, OpenGL::TriangleStrip, OpenGL::TriangleFan, OpenGL::Triangle
|
||||||
};
|
};
|
||||||
const auto shape = primTypes[primType];
|
const auto shape = primTypes[primType];
|
||||||
renderer.drawVertices(shape, vertices, vertexCount);
|
renderer.drawVertices(shape, std::span(vertices).first(vertexCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex GPU::getImmediateModeVertex() {
|
Vertex GPU::getImmediateModeVertex() {
|
||||||
|
|
|
@ -157,7 +157,7 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
// If we've reached 3 verts, issue a draw call
|
// If we've reached 3 verts, issue a draw call
|
||||||
// Handle rendering depending on the primitive type
|
// Handle rendering depending on the primitive type
|
||||||
if (immediateModeVertIndex == 3) {
|
if (immediateModeVertIndex == 3) {
|
||||||
renderer.drawVertices(OpenGL::Triangle, &immediateModeVertices[0], 3);
|
renderer.drawVertices(OpenGL::Triangle, immediateModeVertices);
|
||||||
|
|
||||||
switch (primType) {
|
switch (primType) {
|
||||||
// Triangle or geometry primitive. Draw a triangle and discard all vertices
|
// Triangle or geometry primitive. Draw a triangle and discard all vertices
|
||||||
|
|
|
@ -213,7 +213,6 @@ void Renderer::initGraphicsContext() {
|
||||||
|
|
||||||
void Renderer::getGraphicsContext() {
|
void Renderer::getGraphicsContext() {
|
||||||
OpenGL::disableScissor();
|
OpenGL::disableScissor();
|
||||||
OpenGL::setViewport(400, 240);
|
|
||||||
|
|
||||||
vbo.bind();
|
vbo.bind();
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
@ -265,7 +264,7 @@ void Renderer::setupBlending() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 count) {
|
void Renderer::drawVertices(OpenGL::Primitives primType, std::span<const Vertex> vertices) {
|
||||||
// Adjust alpha test if necessary
|
// Adjust alpha test if necessary
|
||||||
const u32 alphaControl = regs[PICAInternalRegs::AlphaTestConfig];
|
const u32 alphaControl = regs[PICAInternalRegs::AlphaTestConfig];
|
||||||
if (alphaControl != oldAlphaControl) {
|
if (alphaControl != oldAlphaControl) {
|
||||||
|
@ -352,8 +351,8 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vbo.bufferVertsSub(vertices, count);
|
vbo.bufferVertsSub(vertices);
|
||||||
OpenGL::draw(primType, count);
|
OpenGL::draw(primType, vertices.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u32 topScreenBuffer = 0x1f000000;
|
constexpr u32 topScreenBuffer = 0x1f000000;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue