CAM: Fix new CAM simulator on macOS
This commit is contained in:
@@ -56,14 +56,11 @@ DlgCAMSimulator::DlgCAMSimulator(ViewCAMSimulator& view, QWidget* parent)
|
||||
|
||||
viewCAMSimulator = &view;
|
||||
|
||||
QSurfaceFormat format;
|
||||
format.setVersion(4, 1); // Request OpenGL 4.1 - for MacOS
|
||||
format.setProfile(QSurfaceFormat::CoreProfile); // Use the core profile = for MacOS
|
||||
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
|
||||
int samples = Gui::View3DInventorViewer::getNumSamples();
|
||||
if (samples > 1) {
|
||||
format.setSamples(samples);
|
||||
}
|
||||
format.setSwapInterval(2);
|
||||
format.setDepthBufferSize(24);
|
||||
format.setStencilBufferSize(8);
|
||||
setFormat(format);
|
||||
|
||||
@@ -35,24 +35,24 @@ using namespace MillSim;
|
||||
// clang-format off
|
||||
// NOLINTBEGIN(*-magic-numbers)
|
||||
static const std::vector<DefaultGuiItem> defaultGuiItems = {
|
||||
{.name=eGuiItemSlider, .vbo=0, .vao=0, .sx=28, .sy=-80, .actionKey=0, .hidden=false, .flags=0},
|
||||
{.name=eGuiItemThumb, .vbo=0, .vao=0, .sx=328, .sy=-94, .actionKey=1, .hidden=false, .flags=0},
|
||||
{.name=eGuiItemPause, .vbo=0, .vao=0, .sx=28, .sy=-50, .actionKey='P', .hidden=true, .flags=0},
|
||||
{.name=eGuiItemPlay, .vbo=0, .vao=0, .sx=28, .sy=-50, .actionKey='S', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemSingleStep, .vbo=0, .vao=0, .sx=68, .sy=-50, .actionKey='T', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemSlower, .vbo=0, .vao=0, .sx=113, .sy=-50, .actionKey=' ', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemFaster, .vbo=0, .vao=0, .sx=158, .sy=-50, .actionKey='F', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemX, .vbo=0, .vao=0, .sx=208, .sy=-45, .actionKey=0, .hidden=false, .flags=0},
|
||||
{.name=eGuiItem1, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=false, .flags=0},
|
||||
{.name=eGuiItem5, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItem10, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItem25, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItem50, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItemRotate, .vbo=0, .vao=0, .sx=-140, .sy=-50, .actionKey=' ', .hidden=false, .flags=GUIITEM_CHECKABLE},
|
||||
{.name=eGuiItemPath, .vbo=0, .vao=0, .sx=-100, .sy=-50, .actionKey='L', .hidden=false, .flags=GUIITEM_CHECKABLE},
|
||||
{.name=eGuiItemAmbientOclusion, .vbo=0, .vao=0, .sx=-60, .sy=-50, .actionKey='A', .hidden=false, .flags=GUIITEM_CHECKABLE},
|
||||
{.name=eGuiItemView, .vbo=0, .vao=0, .sx=-180, .sy=-50, .actionKey='V', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemHome, .vbo=0, .vao=0, .sx=-220, .sy=-50, .actionKey='H', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemSlider, .vbo=0, .sx=28, .sy=-80, .actionKey=0, .hidden=false, .flags=0},
|
||||
{.name=eGuiItemThumb, .vbo=0, .sx=328, .sy=-94, .actionKey=1, .hidden=false, .flags=0},
|
||||
{.name=eGuiItemPause, .vbo=0, .sx=28, .sy=-50, .actionKey='P', .hidden=true, .flags=0},
|
||||
{.name=eGuiItemPlay, .vbo=0, .sx=28, .sy=-50, .actionKey='S', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemSingleStep, .vbo=0, .sx=68, .sy=-50, .actionKey='T', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemSlower, .vbo=0, .sx=113, .sy=-50, .actionKey=' ', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemFaster, .vbo=0, .sx=158, .sy=-50, .actionKey='F', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemX, .vbo=0, .sx=208, .sy=-45, .actionKey=0, .hidden=false, .flags=0},
|
||||
{.name=eGuiItem1, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=false, .flags=0},
|
||||
{.name=eGuiItem5, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItem10, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItem25, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItem50, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0},
|
||||
{.name=eGuiItemRotate, .vbo=0, .sx=-140, .sy=-50, .actionKey=' ', .hidden=false, .flags=GUIITEM_CHECKABLE},
|
||||
{.name=eGuiItemPath, .vbo=0, .sx=-100, .sy=-50, .actionKey='L', .hidden=false, .flags=GUIITEM_CHECKABLE},
|
||||
{.name=eGuiItemAmbientOclusion, .vbo=0, .sx=-60, .sy=-50, .actionKey='A', .hidden=false, .flags=GUIITEM_CHECKABLE},
|
||||
{.name=eGuiItemView, .vbo=0, .sx=-180, .sy=-50, .actionKey='V', .hidden=false, .flags=0},
|
||||
{.name=eGuiItemHome, .vbo=0, .sx=-220, .sy=-50, .actionKey='H', .hidden=false, .flags=0},
|
||||
};
|
||||
// NOLINTEND(*-magic-numbers)
|
||||
// clang-format on
|
||||
@@ -143,17 +143,6 @@ bool GuiDisplay::GenerateGlItem(GuiItem* guiItem)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, guiItem->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex2D), verts, GL_STATIC_DRAW);
|
||||
|
||||
// glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, nullptr);
|
||||
// vertex array
|
||||
glGenVertexArrays(1, &(guiItem->vao));
|
||||
glBindVertexArray(guiItem->vao);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, x));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, tx));
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIbo);
|
||||
glBindVertexArray(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -197,22 +186,22 @@ bool GuiDisplay::HStretchGlItem(GuiItem* guiItem, float newWidth, float edgeWidt
|
||||
glBindBuffer(GL_ARRAY_BUFFER, guiItem->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(Vertex2D), verts, GL_STATIC_DRAW);
|
||||
|
||||
glGenVertexArrays(1, &(guiItem->vao));
|
||||
glBindVertexArray(guiItem->vao);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiDisplay::SetupVertexAttribs(GuiItem* guiItem)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, guiItem->vbo);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, x));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, tx));
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIbo);
|
||||
glBindVertexArray(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiDisplay::DestroyGlItem(GuiItem* guiItem)
|
||||
{
|
||||
GLDELETE_BUFFER((guiItem->vbo));
|
||||
GLDELETE_VERTEXARRAY((guiItem->vao));
|
||||
}
|
||||
|
||||
bool GuiDisplay::InitGui()
|
||||
@@ -271,6 +260,7 @@ void GuiDisplay::RenderItem(int itemId)
|
||||
if (item->hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
mat4x4 model;
|
||||
mat4x4_translate(model, (float)item->posx(), (float)item->posy(), 0);
|
||||
mShader.UpdateModelMat(model, {});
|
||||
@@ -290,7 +280,7 @@ void GuiDisplay::RenderItem(int itemId)
|
||||
mShader.UpdateObjColor(mStdColor);
|
||||
}
|
||||
|
||||
glBindVertexArray(item->vao);
|
||||
SetupVertexAttribs(item);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIbo);
|
||||
int nTriangles = (item->flags & GUIITEM_STRETCHED) == 0 ? 6 : 18;
|
||||
glDrawElements(GL_TRIANGLES, nTriangles, GL_UNSIGNED_SHORT, nullptr);
|
||||
@@ -466,6 +456,10 @@ int GuiDisplay::height() const
|
||||
|
||||
void GuiDisplay::Render(float progress)
|
||||
{
|
||||
if (!guiInitiated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPressedItem == nullptr || mPressedItem->name != eGuiItemThumb) {
|
||||
mItems[eGuiItemThumb].setPosx((int)(mThumbMaxMotion * progress) + mThumbStartX);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ enum eGuiItems
|
||||
struct DefaultGuiItem
|
||||
{
|
||||
eGuiItems name;
|
||||
unsigned int vbo, vao;
|
||||
unsigned int vbo = 0;
|
||||
int sx, sy; // screen location
|
||||
int actionKey; // action key when item pressed
|
||||
bool hidden {}; // is item hidden
|
||||
@@ -126,6 +126,7 @@ private:
|
||||
void UpdateProjection();
|
||||
bool GenerateGlItem(GuiItem* guiItem);
|
||||
bool HStretchGlItem(GuiItem* guiItem, float newWidth, float edgeWidth);
|
||||
void SetupVertexAttribs(GuiItem* guiItem);
|
||||
void DestroyGlItem(GuiItem* guiItem);
|
||||
void RenderItem(int itemId);
|
||||
void SetupTooltips();
|
||||
|
||||
@@ -8,27 +8,24 @@
|
||||
namespace MillSim
|
||||
{
|
||||
|
||||
|
||||
MillPathLine::MillPathLine()
|
||||
{
|
||||
mVao = mVbo = 0;
|
||||
}
|
||||
|
||||
void MillPathLine::GenerateModel()
|
||||
{
|
||||
mNumVerts = MillPathPointsBuffer.size();
|
||||
void* vbuffer = MillPathPointsBuffer.data();
|
||||
|
||||
// vertex array
|
||||
glGenVertexArrays(1, &mVao);
|
||||
glBindVertexArray(mVao);
|
||||
|
||||
// vertex buffer
|
||||
glGenBuffers(1, &mVbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, mNumVerts * sizeof(MillPathPosition), vbuffer, GL_STATIC_DRAW);
|
||||
|
||||
// vertex attribs
|
||||
// free
|
||||
MillPathPointsBuffer.clear();
|
||||
}
|
||||
|
||||
void MillPathLine::SetupVertexAttibs()
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
@@ -39,31 +36,26 @@ void MillPathLine::GenerateModel()
|
||||
(void*)offsetof(MillPathPosition, X)
|
||||
);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribIPointer(
|
||||
glVertexAttribPointer(
|
||||
1,
|
||||
1,
|
||||
GL_INT,
|
||||
GL_FALSE,
|
||||
sizeof(MillPathPosition),
|
||||
(void*)offsetof(MillPathPosition, SegmentId)
|
||||
);
|
||||
|
||||
// unbind and free
|
||||
glBindVertexArray(0);
|
||||
MillPathPointsBuffer.clear();
|
||||
}
|
||||
|
||||
void MillPathLine::Clear()
|
||||
{
|
||||
MillPathPointsBuffer.clear();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
GLDELETE_BUFFER(mVbo);
|
||||
GLDELETE_VERTEXARRAY(mVao);
|
||||
}
|
||||
|
||||
void MillPathLine::Render()
|
||||
{
|
||||
glBindVertexArray(mVao);
|
||||
SetupVertexAttibs();
|
||||
glDrawArrays(GL_LINE_STRIP, 0, mNumVerts);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace MillSim
|
||||
@@ -15,8 +16,8 @@ struct MillPathPosition
|
||||
class MillPathLine
|
||||
{
|
||||
public:
|
||||
MillPathLine();
|
||||
void GenerateModel();
|
||||
void SetupVertexAttibs();
|
||||
void Clear();
|
||||
void Render();
|
||||
|
||||
@@ -24,8 +25,7 @@ public:
|
||||
std::vector<MillPathPosition> MillPathPointsBuffer;
|
||||
|
||||
protected:
|
||||
unsigned int mVbo;
|
||||
unsigned int mVao;
|
||||
unsigned int mVbo = 0;
|
||||
int mNumVerts;
|
||||
};
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ void MillSimulation::Clear()
|
||||
mCurStep = 0;
|
||||
mPathStep = -1;
|
||||
mNTotalSteps = 0;
|
||||
|
||||
simulationInitiated = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +124,8 @@ void MillSimulation::InitSimulation(float quality)
|
||||
mNPathSteps = (int)MillPathSegments.size();
|
||||
millPathLine.GenerateModel();
|
||||
InitDisplay(quality);
|
||||
|
||||
simulationInitiated = true;
|
||||
}
|
||||
|
||||
EndMill* MillSimulation::GetTool(int toolId)
|
||||
@@ -370,6 +374,10 @@ void MillSimulation::RenderBaseShape()
|
||||
|
||||
void MillSimulation::Render()
|
||||
{
|
||||
if (!simulationInitiated) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set background
|
||||
glClearColor(bgndColor[0], bgndColor[1], bgndColor[2], 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
@@ -113,6 +113,8 @@ protected:
|
||||
void RemoveTool(int toolId);
|
||||
|
||||
protected:
|
||||
bool simulationInitiated = false;
|
||||
|
||||
std::vector<EndMill*> mToolTable;
|
||||
GCodeParser mCodeParser;
|
||||
GuiDisplay guiDisplay;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "DlgCAMSimulator.h"
|
||||
|
||||
#define gSimWindow CAMSimulator::DlgCAMSimulator::instance()
|
||||
#define glClearColor gSimWindow->glClearColor
|
||||
#define glBlendFunc gSimWindow->glBlendFunc
|
||||
@@ -36,6 +37,8 @@
|
||||
#define glBindVertexArray gSimWindow->glBindVertexArray
|
||||
#define glEnableVertexAttribArray gSimWindow->glEnableVertexAttribArray
|
||||
#define glVertexAttribPointer gSimWindow->glVertexAttribPointer
|
||||
#define glBindAttribLocation gSimWindow->glBindAttribLocation
|
||||
#define glGetAttribLocation gSimWindow->glGetAttribLocation
|
||||
#define glShaderSource gSimWindow->glShaderSource
|
||||
#define glCompileShader gSimWindow->glCompileShader
|
||||
#define glDeleteShader gSimWindow->glDeleteShader
|
||||
@@ -44,7 +47,7 @@
|
||||
#define glLinkProgram gSimWindow->glLinkProgram
|
||||
#define glGetProgramiv gSimWindow->glGetProgramiv
|
||||
#define glGetUniformLocation gSimWindow->glGetUniformLocation
|
||||
#define glGetError gSimWindow->glGetError
|
||||
#define glGetError(...) /* GL( */ gSimWindow->glGetError(__VA_ARGS__) /* ) */
|
||||
#define glEnable gSimWindow->glEnable
|
||||
#define glColorMask gSimWindow->glColorMask
|
||||
#define glCullFace gSimWindow->glCullFace
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "GlUtils.h"
|
||||
#include "Shader.h"
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <Base/Console.h>
|
||||
|
||||
namespace MillSim
|
||||
@@ -199,13 +200,51 @@ bool CheckCompileResult(int shaderId, const char* shaderName, bool isVertex)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void preprocessVertexShader(std::string& shader, std::map<int, std::string>& attributes)
|
||||
{
|
||||
// The new CAM simulator relies on "layout(location = x)" to specify vertex attributes. However,
|
||||
// on macOS we're limited to OpenGL 2.1 and GLSL 1.20 and layout specifiers are not supported.
|
||||
// We use a regex to search those specifiers and extract the information manually. This can then
|
||||
// be used with glBindAttribLocation to achieve the same result.
|
||||
|
||||
const std::regex attributeRegex {
|
||||
"layout\\s*\\(\\s*location\\s*=\\s*(\\d+)\\s*\\)\\s*attribute\\s+(\\w+)\\s+(\\w+);"
|
||||
};
|
||||
|
||||
for (int i = 0; i < (int)shader.size();) {
|
||||
std::smatch match;
|
||||
if (!std::regex_search(shader.cbegin() + i, shader.cend(), match, attributeRegex)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const int location = std::stoi(match[1]);
|
||||
const std::string type = match[2];
|
||||
const std::string name = match[3];
|
||||
|
||||
attributes[location] = name;
|
||||
|
||||
const std::string prefix {shader.cbegin(), match.prefix().second};
|
||||
const std::string suffix = match.suffix().str();
|
||||
|
||||
const std::string decl = "attribute " + type + " " + name + ";";
|
||||
|
||||
shader = prefix + decl + suffix;
|
||||
i += decl.length();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Shader::CompileShader(const char* name, const char* _vertShader, const char* _fragShader)
|
||||
{
|
||||
vertShader = _vertShader;
|
||||
fragShader = _fragShader;
|
||||
|
||||
std::map<int, std::string> attributes;
|
||||
preprocessVertexShader(vertShader, attributes);
|
||||
|
||||
const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLint res = 0;
|
||||
glShaderSource(vertex_shader, 1, &vertShader, NULL);
|
||||
const char* vertShaderData[] = {vertShader.c_str()};
|
||||
glShaderSource(vertex_shader, 1, vertShaderData, NULL);
|
||||
glCompileShader(vertex_shader);
|
||||
if (CheckCompileResult(vertex_shader, name, true)) {
|
||||
glDeleteShader(vertex_shader);
|
||||
@@ -213,7 +252,8 @@ unsigned int Shader::CompileShader(const char* name, const char* _vertShader, co
|
||||
}
|
||||
|
||||
const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment_shader, 1, &fragShader, NULL);
|
||||
const char* fragShaderData[] = {fragShader.c_str()};
|
||||
glShaderSource(fragment_shader, 1, fragShaderData, NULL);
|
||||
glCompileShader(fragment_shader);
|
||||
if (CheckCompileResult(fragment_shader, name, false)) {
|
||||
glDeleteShader(fragment_shader);
|
||||
@@ -224,6 +264,11 @@ unsigned int Shader::CompileShader(const char* name, const char* _vertShader, co
|
||||
shaderId = glCreateProgram();
|
||||
glAttachShader(shaderId, vertex_shader);
|
||||
glAttachShader(shaderId, fragment_shader);
|
||||
|
||||
for (auto [pos, name] : attributes) {
|
||||
glBindAttribLocation(shaderId, pos, name.c_str());
|
||||
}
|
||||
|
||||
glLinkProgram(shaderId);
|
||||
|
||||
glGetProgramiv(shaderId, GL_LINK_STATUS, &res);
|
||||
@@ -279,13 +324,13 @@ void Shader::Destroy()
|
||||
|
||||
|
||||
const char* VertShader3DNorm = R"(
|
||||
#version 330 core
|
||||
#version 120
|
||||
|
||||
layout(location = 0) in vec3 aPosition;
|
||||
layout(location = 1) in vec3 aNormal;
|
||||
layout(location = 0) attribute vec3 aPosition;
|
||||
layout(location = 1) attribute vec3 aNormal;
|
||||
|
||||
out vec3 Normal;
|
||||
out vec3 Position;
|
||||
varying vec3 Normal;
|
||||
varying vec3 Position;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
@@ -302,13 +347,13 @@ const char* VertShader3DNorm = R"(
|
||||
)";
|
||||
|
||||
const char* VertShader3DInvNorm = R"(
|
||||
#version 330 core
|
||||
#version 120
|
||||
|
||||
layout(location = 0) in vec3 aPosition;
|
||||
layout(location = 1) in vec3 aNormal;
|
||||
layout(location = 0) attribute vec3 aPosition;
|
||||
layout(location = 1) attribute vec3 aNormal;
|
||||
|
||||
out vec3 Normal;
|
||||
out vec3 Position;
|
||||
varying vec3 Normal;
|
||||
varying vec3 Position;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
@@ -325,12 +370,12 @@ const char* VertShader3DInvNorm = R"(
|
||||
|
||||
|
||||
const char* VertShader2DTex = R"(
|
||||
#version 330 core
|
||||
#version 120
|
||||
|
||||
layout(location = 0) in vec2 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
layout(location = 0) attribute vec2 aPosition;
|
||||
layout(location = 1) attribute vec2 aTexCoord;
|
||||
|
||||
out vec2 texCoord;
|
||||
varying vec2 texCoord;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 model;
|
||||
@@ -343,29 +388,26 @@ const char* VertShader2DTex = R"(
|
||||
)";
|
||||
|
||||
const char* FragShader2dTex = R"(
|
||||
#version 330
|
||||
#version 120
|
||||
|
||||
out vec4 FragColor;
|
||||
in vec2 texCoord;
|
||||
varying vec2 texCoord;
|
||||
|
||||
uniform vec3 objectColor;
|
||||
uniform sampler2D texSlot;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texColor = texture(texSlot, texCoord);
|
||||
FragColor = vec4(objectColor, 1.0) * texColor;
|
||||
vec4 texColor = texture2D(texSlot, texCoord);
|
||||
gl_FragColor = vec4(objectColor, 1.0) * texColor;
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
const char* FragShaderNorm = R"(
|
||||
#version 330
|
||||
#version 120
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 Normal;
|
||||
in vec3 Position;
|
||||
varying vec3 Normal;
|
||||
varying vec3 Position;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 lightColor;
|
||||
@@ -379,33 +421,29 @@ const char* FragShaderNorm = R"(
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * lightColor;
|
||||
vec3 result = (lightAmbient + diffuse) * objectColor;
|
||||
FragColor = vec4(result, 1.0);
|
||||
gl_FragColor = vec4(result, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
const char* FragShaderFlat = R"(
|
||||
#version 330
|
||||
#version 120
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 Normal;
|
||||
in vec3 Position;
|
||||
uniform vec3 objectColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(objectColor, 1.0);
|
||||
gl_FragColor = vec4(objectColor, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
const char* VertShader2DFbo = R"(
|
||||
#version 330 core
|
||||
#version 120
|
||||
|
||||
layout(location = 0) in vec2 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
layout(location = 0) attribute vec2 aPosition;
|
||||
layout(location = 1) attribute vec2 aTexCoord;
|
||||
|
||||
out vec2 texCoord;
|
||||
varying vec2 texCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
@@ -415,27 +453,27 @@ const char* VertShader2DFbo = R"(
|
||||
)";
|
||||
|
||||
const char* FragShader2dFbo = R"(
|
||||
#version 330
|
||||
#version 120
|
||||
|
||||
out vec4 FragColor;
|
||||
in vec2 texCoord;
|
||||
varying vec2 texCoord;
|
||||
|
||||
uniform sampler2D texSlot;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tc = texture(texSlot, texCoord);
|
||||
FragColor = tc;
|
||||
vec4 tc = texture2D(texSlot, texCoord);
|
||||
gl_FragColor = tc;
|
||||
}
|
||||
)";
|
||||
|
||||
const char* VertShaderGeom = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
#version 120
|
||||
|
||||
out vec3 Position;
|
||||
out vec3 Normal;
|
||||
layout(location = 0) attribute vec3 aPosition;
|
||||
layout(location = 1) attribute vec3 aNormal;
|
||||
|
||||
varying vec3 Position;
|
||||
varying vec3 Normal;
|
||||
|
||||
uniform bool invertedNormals;
|
||||
|
||||
@@ -445,10 +483,10 @@ const char* VertShaderGeom = R"(
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 viewPos = view * model * vec4(aPos, 1.0);
|
||||
vec4 viewPos = view * model * vec4(aPosition, 1.0);
|
||||
Position = viewPos.xyz;
|
||||
|
||||
mat3 normalMatrix = transpose(inverse(mat3(view * model)));
|
||||
mat3 normalMatrix = /* transpose(inverse( */ mat3(view * model) /* )) */;
|
||||
Normal = normalMatrix * (invertedNormals ? -aNormal : aNormal);
|
||||
|
||||
gl_Position = projection * viewPos;
|
||||
@@ -456,30 +494,26 @@ const char* VertShaderGeom = R"(
|
||||
)";
|
||||
|
||||
const char* FragShaderGeom = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) out vec4 ColorTex;
|
||||
layout (location = 1) out vec3 PositionTex;
|
||||
layout (location = 2) out vec3 NormalTex;
|
||||
#version 120
|
||||
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
varying vec3 Position;
|
||||
varying vec3 Normal;
|
||||
|
||||
uniform vec3 objectColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Store position, normal, and diffuse color in textures
|
||||
PositionTex = Position;
|
||||
NormalTex = normalize(Normal);
|
||||
ColorTex = vec4(objectColor, 1.0f);
|
||||
gl_FragData[0] = vec4(objectColor, 1.0f);
|
||||
gl_FragData[1] = vec4(Position, 0.0f);
|
||||
gl_FragData[2] = vec4(normalize(Normal), 0.0f);
|
||||
}
|
||||
)";
|
||||
|
||||
const char* FragShaderSSAO = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) out float AoData;
|
||||
#version 120
|
||||
|
||||
in vec2 texCoord;
|
||||
varying vec2 texCoord;
|
||||
|
||||
uniform sampler2D RandTex;
|
||||
uniform sampler2D PositionTex;
|
||||
@@ -497,8 +531,8 @@ const char* FragShaderSSAO = R"(
|
||||
{
|
||||
// Create the random tangent space matrix
|
||||
vec2 randScale = vec2( screenWidth / 4.0, screenHeight / 4.0 );
|
||||
vec3 randDir = normalize( texture(RandTex, texCoord.xy * randScale).xyz );
|
||||
vec3 n = normalize( texture(NormalTex, texCoord).xyz );
|
||||
vec3 randDir = normalize( texture2D(RandTex, texCoord.xy * randScale).xyz );
|
||||
vec3 n = normalize( texture2D(NormalTex, texCoord).xyz );
|
||||
vec3 biTang = cross( n, randDir );
|
||||
if( length(biTang) < 0.0001 ) // If n and randDir are parallel, n is in x-y plane
|
||||
biTang = cross( n, vec3(0,0,1));
|
||||
@@ -507,7 +541,7 @@ const char* FragShaderSSAO = R"(
|
||||
mat3 toCamSpace = mat3(tang, biTang, n);
|
||||
|
||||
float occlusionSum = 0.0;
|
||||
vec3 camPos = texture(PositionTex, texCoord).xyz;
|
||||
vec3 camPos = texture2D(PositionTex, texCoord).xyz;
|
||||
for( int i = 0; i < kernelSize; i++ ) {
|
||||
vec3 samplePos = camPos + Radius * (toCamSpace * SampleKernel[i]);
|
||||
|
||||
@@ -517,7 +551,7 @@ const char* FragShaderSSAO = R"(
|
||||
p.xyz = p.xyz * 0.5 + 0.5;
|
||||
|
||||
// Access camera space z-coordinate at that point
|
||||
float surfaceZ = texture(PositionTex, p.xy).z;
|
||||
float surfaceZ = texture2D(PositionTex, p.xy).z;
|
||||
float zDist = surfaceZ - camPos.z;
|
||||
|
||||
// Count points that ARE occluded
|
||||
@@ -525,39 +559,38 @@ const char* FragShaderSSAO = R"(
|
||||
}
|
||||
|
||||
float occ = occlusionSum / kernelSize;
|
||||
AoData = 1.0 - occ;
|
||||
gl_FragData[0] = vec4(1.0 - occ);
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
const char* FragShaderSSAOBlur = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) out float AoData;
|
||||
|
||||
in vec2 texCoord;
|
||||
#version 120
|
||||
|
||||
uniform sampler2D AoTex;
|
||||
|
||||
uniform float screenWidth;
|
||||
uniform float screenHeight;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 pix = ivec2( gl_FragCoord.xy );
|
||||
float sum = 0.0;
|
||||
for( int x = -1; x <= 2; ++x ) {
|
||||
for( int y = -1; y <= 2; y++ ) {
|
||||
sum += texelFetch( AoTex, pix + ivec2(x,y), 0).r;
|
||||
sum += texture2D( AoTex, (pix + ivec2(x,y)) / vec2(screenWidth, screenHeight), 0).r;
|
||||
}
|
||||
}
|
||||
|
||||
float ao = sum * (1.0 / 16.0);
|
||||
AoData = ao;
|
||||
gl_FragData[0] = vec4(ao);
|
||||
}
|
||||
)";
|
||||
|
||||
const char* FragShaderSSAOLighting = R"(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
#version 120
|
||||
|
||||
in vec2 texCoord;
|
||||
varying vec2 texCoord;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 lightColor;
|
||||
@@ -580,25 +613,26 @@ const char* FragShaderSSAOLighting = R"(
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 pos = texture( PositionTex, texCoord ).xyz;
|
||||
vec3 norm = texture( NormalTex, texCoord ).xyz;
|
||||
vec4 DiffColorA = texture(ColorTex, texCoord);
|
||||
vec3 pos = texture2D( PositionTex, texCoord ).xyz;
|
||||
vec3 norm = texture2D( NormalTex, texCoord ).xyz;
|
||||
vec4 DiffColorA = texture2D(ColorTex, texCoord);
|
||||
vec3 diffColor = DiffColorA.rgb;
|
||||
float aoVal = ssaoActive ? texture( AoTex, texCoord).r : 1.0;
|
||||
float aoVal = ssaoActive ? texture2D( AoTex, texCoord).r : 1.0;
|
||||
|
||||
vec3 col = ambAndDiffuse(pos, norm, diffColor, aoVal);
|
||||
col = pow(col, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4( col, DiffColorA.a );
|
||||
gl_FragColor = vec4( col, DiffColorA.a );
|
||||
}
|
||||
)";
|
||||
|
||||
const char* VertShader3DLine = R"(
|
||||
#version 330 core
|
||||
#version 120
|
||||
|
||||
layout(location = 0) in vec3 aPosition;
|
||||
layout(location = 1) in int aIndex;
|
||||
flat out int Index;
|
||||
layout(location = 0) attribute vec3 aPosition;
|
||||
layout(location = 1) attribute float aIndex;
|
||||
|
||||
varying float Index;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
@@ -611,19 +645,18 @@ const char* VertShader3DLine = R"(
|
||||
)";
|
||||
|
||||
const char* FragShader3DLine = R"(
|
||||
#version 330
|
||||
#version 120
|
||||
|
||||
out vec4 FragColor;
|
||||
varying float Index;
|
||||
|
||||
flat in int Index;
|
||||
uniform vec4 objectColorAlpha;
|
||||
uniform vec3 objectColor;
|
||||
uniform int curSegment;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (Index > curSegment) FragColor = objectColorAlpha;
|
||||
else FragColor = vec4(objectColor, objectColorAlpha.a);
|
||||
if (Index > curSegment) gl_FragColor = objectColorAlpha;
|
||||
else gl_FragColor = vec4(objectColor, objectColorAlpha.a);
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
return shaderId > 0;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
int mModelPos = -1;
|
||||
int mNormalRotPos = -1;
|
||||
@@ -88,8 +87,8 @@ protected:
|
||||
int mScreenWidthPos = -1;
|
||||
int mScreenHeightPos = -1;
|
||||
|
||||
const char* vertShader = nullptr;
|
||||
const char* fragShader = nullptr;
|
||||
std::string vertShader;
|
||||
std::string fragShader;
|
||||
};
|
||||
|
||||
extern Shader* CurrentShader;
|
||||
|
||||
@@ -91,11 +91,15 @@ void SimDisplay::CreateFboQuad()
|
||||
1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &mFboQuadVAO);
|
||||
glGenBuffers(1, &mFboQuadVBO);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mFboQuadVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices[0], GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
void SimDisplay::SetupVertexAttribs()
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mFboQuadVBO);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
@@ -149,7 +153,6 @@ void SimDisplay::CreateDisplayFbos()
|
||||
CreateGBufTex(GL_TEXTURE2, GL_RGB32F, GL_RGBA, GL_FLOAT, mFboNormTexture);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, mFboNormTexture, 0);
|
||||
|
||||
|
||||
unsigned int attachments[3] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
|
||||
glDrawBuffers(3, attachments);
|
||||
|
||||
@@ -277,7 +280,6 @@ void SimDisplay::CleanGL()
|
||||
CleanFbos();
|
||||
|
||||
// cleanup geometry
|
||||
GLDELETE_VERTEXARRAY(mFboQuadVAO);
|
||||
GLDELETE_BUFFER(mFboQuadVBO);
|
||||
|
||||
// cleanup shaders
|
||||
@@ -368,6 +370,10 @@ void SimDisplay::ScaleViewToStock(StockObject* obj)
|
||||
|
||||
void SimDisplay::RenderResult(bool recalculate, bool ssao)
|
||||
{
|
||||
if (!displayInitiated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSsaoValid && ssao) {
|
||||
RenderResultSSAO(recalculate);
|
||||
}
|
||||
@@ -388,7 +394,7 @@ void SimDisplay::RenderResultStandard()
|
||||
shaderSSAOLighting.UpdateNormalTexSlot(2);
|
||||
shaderSSAOLighting.UpdateSsaoActive(false);
|
||||
// shaderSimFbo.Activate();
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
SetupVertexAttribs();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -423,7 +429,7 @@ void SimDisplay::RenderResultSSAO(bool recalculate)
|
||||
glBindTexture(GL_TEXTURE_2D, mFboPosTexture);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboNormTexture);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
SetupVertexAttribs();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
@@ -434,7 +440,8 @@ void SimDisplay::RenderResultSSAO(bool recalculate)
|
||||
shaderSSAOBlur.UpdateSsaoTexSlot(0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoTexture);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
shaderSSAOBlur.UpdateScreenDimension(mWidth, mHeight);
|
||||
SetupVertexAttribs();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
@@ -456,7 +463,7 @@ void SimDisplay::RenderResultSSAO(bool recalculate)
|
||||
glBindTexture(GL_TEXTURE_2D, mFboSsaoBlurTexture);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBindVertexArray(mFboQuadVAO);
|
||||
SetupVertexAttribs();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ protected:
|
||||
void CreateDisplayFbos();
|
||||
void CreateSsaoFbos();
|
||||
void CreateFboQuad();
|
||||
void SetupVertexAttribs();
|
||||
void CreateGBufTex(GLenum texUnit, GLint intFormat, GLenum format, GLenum type, GLuint& texid);
|
||||
void UniformHemisphere(vec3& randVec);
|
||||
void UniformCircle(vec3& randVec);
|
||||
@@ -127,7 +128,7 @@ protected:
|
||||
unsigned int mFboPosTexture = 0;
|
||||
unsigned int mFboNormTexture = 0;
|
||||
unsigned int mRboDepthStencil = 0;
|
||||
unsigned int mFboQuadVAO = 0, mFboQuadVBO = 0;
|
||||
unsigned int mFboQuadVBO = 0;
|
||||
|
||||
// ssao frame buffers
|
||||
bool mSsaoValid = false;
|
||||
|
||||
@@ -333,9 +333,7 @@ void Shape::GenerateModel(const float* vbuffer, const GLushort* ibuffer, int num
|
||||
|
||||
// vertex buffer
|
||||
glGenBuffers(1, &vbo);
|
||||
GLClearError();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
GLLogError();
|
||||
glBufferData(GL_ARRAY_BUFFER, numVerts * sizeof(Vertex), vbuffer, GL_STATIC_DRAW);
|
||||
|
||||
// index buffer
|
||||
@@ -343,15 +341,17 @@ void Shape::GenerateModel(const float* vbuffer, const GLushort* ibuffer, int num
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(GLushort), ibuffer, GL_STATIC_DRAW);
|
||||
|
||||
// vertex array
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
numIndices = nIndices;
|
||||
}
|
||||
|
||||
void Shape::SetupVertexAttribs()
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, nx));
|
||||
|
||||
numIndices = nIndices;
|
||||
}
|
||||
|
||||
void Shape::SetModelData(const std::vector<Vertex>& vbuffer, const std::vector<GLushort>& ibuffer)
|
||||
@@ -361,7 +361,7 @@ void Shape::SetModelData(const std::vector<Vertex>& vbuffer, const std::vector<G
|
||||
|
||||
void Shape::Render()
|
||||
{
|
||||
glBindVertexArray(vao);
|
||||
SetupVertexAttribs();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
||||
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, nullptr);
|
||||
}
|
||||
@@ -374,10 +374,8 @@ void Shape::Render(const mat4x4& modelMat, const mat4x4& normallMat) // normals
|
||||
|
||||
void Shape::FreeResources()
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
GLDELETE_BUFFER(vbo);
|
||||
GLDELETE_BUFFER(ibo);
|
||||
GLDELETE_VERTEXARRAY(vao);
|
||||
}
|
||||
|
||||
Shape::~Shape()
|
||||
|
||||
@@ -75,7 +75,6 @@ public:
|
||||
~Shape();
|
||||
|
||||
public:
|
||||
uint vao = 0;
|
||||
uint vbo = 0;
|
||||
uint ibo = 0;
|
||||
int numIndices = 0;
|
||||
@@ -120,6 +119,7 @@ public:
|
||||
|
||||
protected:
|
||||
void GenerateModel(const float* vbuffer, const GLushort* ibuffer, int numVerts, int numIndices);
|
||||
void SetupVertexAttribs();
|
||||
void CalculateExtrudeBufferSizes(
|
||||
int nProfilePoints,
|
||||
bool capStart,
|
||||
|
||||
Reference in New Issue
Block a user