CAM: Fix new CAM simulator on macOS

This commit is contained in:
jffmichi
2026-03-02 11:32:02 -06:00
committed by Chris Hennes
parent be1ec84709
commit fe25d8d0f7
14 changed files with 212 additions and 177 deletions
@@ -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);
+31 -37
View File
@@ -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);
}
+2 -1
View File
@@ -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
+122 -89
View File
@@ -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);
}
)";
+2 -3
View File
@@ -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;
+15 -8
View File
@@ -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);
}
+2 -1
View File
@@ -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;
+8 -10
View File
@@ -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()
+1 -1
View File
@@ -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,