Skip to content

Commit

Permalink
Use buffers for RenderMesh and axes
Browse files Browse the repository at this point in the history
  • Loading branch information
vanjac committed Aug 21, 2023
1 parent 9bef739 commit fd44749
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 27 deletions.
10 changes: 8 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,16 +269,22 @@ void MainWindow::updateStatus() {

void MainWindow::refreshAll() {
g_renderMeshDirty = true;
mainViewport.invalidateRenderMesh();
mainViewport.refresh();
for (auto viewport : extraViewports)
for (auto viewport : extraViewports) {
viewport->invalidateRenderMesh();
viewport->refresh();
}
}

void MainWindow::refreshAllImmediate() {
g_renderMeshDirty = true;
mainViewport.invalidateRenderMesh();
mainViewport.refreshImmediate();
for (auto viewport : extraViewports)
for (auto viewport : extraViewports) {
viewport->invalidateRenderMesh();
viewport->refreshImmediate();
}
}

void MainWindow::flashSel() {
Expand Down
1 change: 1 addition & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class MainWindow : public chroma::WindowImpl {
void pushUndo();
void pushUndo(EditorState newState);
void updateStatus();
void invalidateRenderMesh();
void refreshAll();
void refreshAllImmediate();
void flashSel();
Expand Down
124 changes: 99 additions & 25 deletions src/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ static EditorState join(EditorState state) {
return state;
}

void ViewportWindow::invalidateRenderMesh() {
renderMeshDirtyLocal = true;
}

void ViewportWindow::refresh() {
InvalidateRect(wnd, NULL, false);
}
Expand Down Expand Up @@ -546,6 +550,21 @@ static ShaderProgram programFromShaders(GLuint vert, GLuint frag) {
return prog;
}

static void initSizedBuffer(SizedBuffer *buf, GLenum target, size_t initialSize, GLenum usage) {
buf->size = initialSize;
glBufferData(target, initialSize, NULL, usage);
}

static void writeSizedBuffer(SizedBuffer *buf, GLenum target, size_t dataSize, void *data,
GLenum usage) {
if (dataSize > buf->size) {
while (dataSize > buf->size)
buf->size *= 2;
glBufferData(target, buf->size, NULL, usage);
}
glBufferSubData(target, 0, dataSize, data);
}

BOOL ViewportWindow::onCreate(HWND, LPCREATESTRUCT) {
HDC dc = GetDC(wnd);
int pixelFormat = ChoosePixelFormat(dc, &g_formatDesc);
Expand Down Expand Up @@ -583,6 +602,36 @@ BOOL ViewportWindow::onCreate(HWND, LPCREATESTRUCT) {

glEnableVertexAttribArray(ATTR_VERTEX);

// static buffers
glGenBuffers(1, &axisPoints);
glGenBuffers(1, &axisIndices);
glBindBuffer(GL_ARRAY_BUFFER, axisPoints);
const glm::vec3 axisPointsData[] = {{0, 0, 0}, {8, 0, 0}, {0, 8, 0}, {0, 0, 8}};
glBufferData(GL_ARRAY_BUFFER, sizeof(axisPointsData), axisPointsData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, axisIndices);
const GLubyte axisIndicesData[] = {0, 1, 0, 2, 0, 3};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(axisIndicesData), axisIndicesData, GL_STATIC_DRAW);

// dynamic buffers
glGenBuffers(1, &verticesBuffer.id);
glGenBuffers(1, &normalsBuffer.id);
glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer.id);
initSizedBuffer(&verticesBuffer, GL_ARRAY_BUFFER, 16 * sizeof(glm::vec3), GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, normalsBuffer.id);
initSizedBuffer(&normalsBuffer, GL_ARRAY_BUFFER, 16 * sizeof(glm::vec3), GL_DYNAMIC_DRAW);

GLuint buffers[ELEM_COUNT];
glGenBuffers(ELEM_COUNT, buffers);
for (GLuint i = 0; i < ELEM_COUNT; i++) {
indexBuffers[i].id = buffers[i];
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[i]);
initSizedBuffer(&indexBuffers[i], GL_ELEMENT_ARRAY_BUFFER, 32 * sizeof(GLushort),
GL_DYNAMIC_DRAW);
}

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

GLuint vertUnlit = shaderFromResource(GL_VERTEX_SHADER, IDR_VERT_UNLIT);
GLuint vertFace = shaderFromResource(GL_VERTEX_SHADER, IDR_VERT_FACE);
GLuint fragSolid = shaderFromResource(GL_FRAGMENT_SHADER, IDR_FRAG_SOLID);
Expand Down Expand Up @@ -839,10 +888,6 @@ static void setColorHex(uint32_t color) {
((color >> 24) & 0xFF) / 255.0f);
}

static void drawElementVector(GLenum mode, const std::vector<GLushort> &v) {
glDrawElements(mode, (GLsizei)v.size(), GL_UNSIGNED_SHORT, v.data());
}

void ViewportWindow::onPaint(HWND) {
PAINTSTRUCT ps;
BeginPaint(wnd, &ps);
Expand Down Expand Up @@ -871,20 +916,23 @@ void ViewportWindow::onPaint(HWND) {
glUseProgram(programs[PROG_UNLIT].id);

// axes
const glm::vec3 axisPoints[] = {{0, 0, 0}, {8, 0, 0}, {0, 8, 0}, {0, 0, 8}};
const GLubyte xAxisI[] = {0, 1}, yAxisI[] = {0, 2}, zAxisI[] = {0, 3};
glVertexAttribPointer(ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, axisPoints);
glBindBuffer(GL_ARRAY_BUFFER, axisPoints);
glVertexAttribPointer(ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glLineWidth(WIDTH_AXIS);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, axisIndices);
setColorHex(COLOR_X_AXIS);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, xAxisI);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, (void *)0);
setColorHex(COLOR_Y_AXIS);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, yAxisI);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, (void *)2);
setColorHex(COLOR_Z_AXIS);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, zAxisI);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, (void *)4);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

if (g_renderMeshDirty) {
generateRenderMesh(&g_renderMesh, g_state);
g_renderMeshDirty = false;
generateRenderMesh(&g_renderMesh, g_state);
}
drawMesh(g_renderMesh);

Expand Down Expand Up @@ -914,6 +962,7 @@ void ViewportWindow::onPaint(HWND) {
gridPoints[j++] = p.org - uVec * (float)GRID_SIZE + vVec * (float)i;
gridPoints[j++] = p.org + uVec * (float)GRID_SIZE + vVec * (float)i;
}
// TODO: use buffer
glVertexAttribPointer(ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, gridPoints);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
Expand All @@ -931,64 +980,89 @@ void ViewportWindow::onPaint(HWND) {
}

void ViewportWindow::drawMesh(const RenderMesh &mesh) {
glVertexAttribPointer(ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, mesh.vertices.data());
glVertexAttribPointer(ATTR_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, mesh.normals.data());
if (renderMeshDirtyLocal) {
renderMeshDirtyLocal = false;
glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer.id);
writeSizedBuffer(&verticesBuffer, GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(glm::vec3),
(void *)mesh.vertices.data(), GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, normalsBuffer.id);
writeSizedBuffer(&normalsBuffer, GL_ARRAY_BUFFER, mesh.normals.size() * sizeof(glm::vec3),
(void *)mesh.normals.data(), GL_DYNAMIC_DRAW);
for (GLuint i = 0; i < ELEM_COUNT; i++) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffers[i].id);
writeSizedBuffer(&indexBuffers[i], GL_ELEMENT_ARRAY_BUFFER,
mesh.indices[i].size() * sizeof(GLushort), (void *)mesh.indices[i].data(),
GL_DYNAMIC_DRAW);
}
}

glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer.id);
glVertexAttribPointer(ATTR_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, normalsBuffer.id);
glVertexAttribPointer(ATTR_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

if (view.showElem & PICK_EDGE) {
glLineWidth(WIDTH_EDGE_SEL);
setColorHex(g_flashSel ? COLOR_EDGE_FLASH : COLOR_EDGE_SEL);
drawElementVector(GL_LINES, mesh.indices[ELEM_SEL_EDGE]);
drawMeshElements(mesh, ELEM_SEL_EDGE, GL_LINES);

glLineWidth(WIDTH_EDGE_HOVER);
setColorHex(COLOR_EDGE_HOVER);
drawElementVector(GL_LINES, mesh.indices[ELEM_HOV_EDGE]);
drawMeshElements(mesh, ELEM_HOV_EDGE, GL_LINES);
}

if (view.showElem & PICK_VERT) {
glPointSize(SIZE_VERT);
setColorHex(COLOR_VERT);
drawElementVector(GL_POINTS, mesh.indices[ELEM_REG_VERT]);
drawMeshElements(mesh, ELEM_REG_VERT, GL_POINTS);

setColorHex(g_flashSel ? COLOR_VERT_FLASH : COLOR_VERT_SEL);
drawElementVector(GL_POINTS, mesh.indices[ELEM_SEL_VERT]);
drawMeshElements(mesh, ELEM_SEL_VERT, GL_POINTS);

setColorHex(COLOR_DRAW_POINT);
drawElementVector(GL_POINTS, mesh.indices[ELEM_DRAW_POINT]);
drawMeshElements(mesh, ELEM_DRAW_POINT, GL_POINTS);

glPointSize(SIZE_VERT_HOVER);
setColorHex(COLOR_VERT_HOVER);
drawElementVector(GL_POINTS, mesh.indices[ELEM_HOV_VERT]);
drawMeshElements(mesh, ELEM_HOV_VERT, GL_POINTS);

glLineWidth(WIDTH_DRAW);
setColorHex(COLOR_DRAW_LINE);
drawElementVector(GL_LINE_STRIP, mesh.indices[ELEM_DRAW_LINE]);
drawMeshElements(mesh, ELEM_DRAW_LINE, GL_LINE_STRIP);
}

if (view.showElem & PICK_EDGE) {
glLineWidth(WIDTH_EDGE);
setColorHex(COLOR_EDGE);
drawElementVector(GL_LINES, mesh.indices[ELEM_REG_EDGE]);
drawMeshElements(mesh, ELEM_REG_EDGE, GL_LINES);
}

if (view.showElem & PICK_FACE) {
glEnableVertexAttribArray(ATTR_NORMAL);

setColorHex(g_flashSel ? COLOR_FACE_FLASH : COLOR_FACE_SEL);
drawElementVector(GL_TRIANGLES, mesh.indices[ELEM_SEL_FACE]);
drawMeshElements(mesh, ELEM_SEL_FACE, GL_TRIANGLES);
setColorHex(COLOR_FACE_HOVER);
drawElementVector(GL_TRIANGLES, mesh.indices[ELEM_HOV_FACE]);
drawMeshElements(mesh, ELEM_HOV_FACE, GL_TRIANGLES);
setColorHex(COLOR_FACE_ERROR);
drawElementVector(GL_TRIANGLES, mesh.indices[ELEM_ERR_FACE]);
drawMeshElements(mesh, ELEM_ERR_FACE, GL_TRIANGLES);

if (view.mode != VIEW_ORTHO)
glUseProgram(programs[PROG_FACE].id);
setColorHex(COLOR_FACE);
drawElementVector(GL_TRIANGLES, mesh.indices[ELEM_REG_FACE]);
drawMeshElements(mesh, ELEM_REG_FACE, GL_TRIANGLES);
if (view.mode != VIEW_ORTHO)
glUseProgram(programs[PROG_UNLIT].id);

glDisableVertexAttribArray(ATTR_NORMAL);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void ViewportWindow::drawMeshElements(const RenderMesh &mesh, RenderElement elem, GLenum mode) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffers[elem].id);
glDrawElements(mode, (GLsizei)mesh.indices[elem].size(), GL_UNSIGNED_SHORT, 0);
}

LRESULT ViewportWindow::handleMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
Expand Down
11 changes: 11 additions & 0 deletions src/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum MouseMode {
};

// OpenGL
using buffer_t = unsigned int;
enum ProgramIndex {
PROG_UNLIT, PROG_FACE,
PROG_COUNT
Expand All @@ -31,6 +32,10 @@ struct ShaderProgram {
unsigned int id;
int uniforms[UNIF_COUNT];
};
struct SizedBuffer {
buffer_t id;
size_t size;
};

const TCHAR VIEWPORT_CLASS[] = _T("WingEd Viewport");
class ViewportWindow : public chroma::WindowImpl {
Expand All @@ -41,6 +46,7 @@ class ViewportWindow : public chroma::WindowImpl {
MouseMode mouseMode = MOUSE_NONE;
glm::vec3 moved;

void invalidateRenderMesh();
void refresh();
void refreshImmediate();
glm::vec3 forwardAxis();
Expand All @@ -55,7 +61,11 @@ class ViewportWindow : public chroma::WindowImpl {
glm::vec3 startPlanePos;
float snapAccum;

bool renderMeshDirtyLocal = true;
ShaderProgram programs[PROG_COUNT];
buffer_t axisPoints, axisIndices;
SizedBuffer verticesBuffer, normalsBuffer;
SizedBuffer indexBuffers[ELEM_COUNT];

void lockMouse(POINT clientPos, MouseMode mode);
void setViewMode(ViewMode mode);
Expand All @@ -64,6 +74,7 @@ class ViewportWindow : public chroma::WindowImpl {
void startToolAdjust(POINT pos);
void toolAdjust(POINT pos, SIZE delta, UINT keyFlags);
void drawMesh(const RenderMesh &mesh);
void drawMeshElements(const RenderMesh &mesh, RenderElement elem, unsigned int mode);

BOOL onCreate(HWND, LPCREATESTRUCT);
void onDestroy(HWND);
Expand Down

0 comments on commit fd44749

Please sign in to comment.