Implemented lighting. Yay! Unfortunately, faces that show up the wrong way around in BFC red/green mode also show up with inverted lighting here.

Thu, 09 Feb 2017 23:46:45 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 09 Feb 2017 23:46:45 +0200
changeset 1119
749fdf61b5cd
parent 1118
3eeb258f1fb9
child 1120
c3f07620494e

Implemented lighting. Yay! Unfortunately, faces that show up the wrong way around in BFC red/green mode also show up with inverted lighting here.

src/glCompiler.cpp file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
src/glShared.h file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.ui file | annotate | diff | comparison | revisions
src/toolsets/viewtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/viewtoolset.h file | annotate | diff | comparison | revisions
--- a/src/glCompiler.cpp	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/glCompiler.cpp	Thu Feb 09 23:46:45 2017 +0200
@@ -116,6 +116,7 @@
 	switch (complement)
 	{
 	case SurfacesVboComplement:
+	case NormalsVboComplement:
 		return {};
 
 	case BfcFrontColorsVboComplement:
@@ -344,6 +345,16 @@
 	default: return;
 	}
 
+	// Determine the normals for the polygon.
+	Vertex normals[4];
+	for (int i = 0; i < numverts; ++i)
+	{
+		const Vertex& v1 = poly.vertices[(i - 1 + numverts) % numverts];
+		const Vertex& v2 = poly.vertices[i];
+		const Vertex& v3 = poly.vertices[(i + 1) % numverts];
+		normals[i] = Vertex::crossProduct(v3 - v2, v1 - v2).normalized();
+	}
+
 	for (ComplementVboType complement : iterateEnum<ComplementVboType>())
 	{
 		const int vbonum = vboNumber (surface, complement);
@@ -359,6 +370,12 @@
 						<< -poly.vertices[vert].y()
 						<< -poly.vertices[vert].z();
 			}
+			else if (complement == NormalsVboComplement)
+			{
+				vbodata << normals[vert].x()
+				        << -normals[vert].y()
+				        << -normals[vert].z();
+			}
 			else
 			{
 				vbodata	<< ((GLfloat) color.red()) / 255.0f
--- a/src/glRenderer.cpp	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/glRenderer.cpp	Thu Feb 09 23:46:45 2017 +0200
@@ -62,6 +62,7 @@
 ConfigOption (bool DrawSurfaces = true)
 ConfigOption (bool DrawEdgeLines = true)
 ConfigOption (bool DrawConditionalLines = true)
+ConfigOption (bool Lighting = true)
 
 const QPen GLRenderer::thinBorderPen {QColor {0, 0, 0, 208}, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin};
 
@@ -236,11 +237,27 @@
 	setFocusPolicy (Qt::WheelFocus);
 	compiler()->initialize();
 	initializeAxes();
+	initializeLighting();
 	m_initialized = true;
 	// Now that GL is initialized, we can reset angles.
 	resetAllAngles();
 }
 
+void GLRenderer::initializeLighting()
+{
+	GLfloat materialShininess[] = {5.0};
+	GLfloat lightPosition[] = {1.0, 1.0, 1.0, 0.0};
+	GLfloat ambientLightingLevel[] = {0.8, 0.8, 0.8, 1.0};
+	glShadeModel(GL_SMOOTH);
+	glMaterialfv(GL_FRONT, GL_SHININESS, materialShininess);
+	glMaterialfv(GL_FRONT, GL_AMBIENT, ambientLightingLevel);
+	glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
+	glEnable(GL_LIGHTING);
+	glEnable(GL_LIGHT0);
+	glEnable(GL_COLOR_MATERIAL);
+	glEnable(GL_DEPTH_TEST);
+}
+
 // =============================================================================
 //
 void GLRenderer::initializeAxes()
@@ -356,6 +373,11 @@
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 	glEnable(GL_DEPTH_TEST);
 
+	if (m_config->lighting())
+		glEnable(GL_LIGHTING);
+	else
+		glDisable(GL_LIGHTING);
+
 	if (camera() != FreeCamera)
 	{
 		glMatrixMode (GL_PROJECTION);
@@ -389,6 +411,7 @@
 		glMultMatrixf(m_rotationMatrix.constData());
 	}
 
+	glEnableClientState (GL_NORMAL_ARRAY);
 	glEnableClientState (GL_VERTEX_ARRAY);
 	glEnableClientState (GL_COLOR_ARRAY);
 
@@ -445,6 +468,7 @@
 	glBindBuffer (GL_ARRAY_BUFFER, 0);
 	glDisableClientState (GL_VERTEX_ARRAY);
 	glDisableClientState (GL_COLOR_ARRAY);
+	glDisableClientState (GL_NORMAL_ARRAY);
 	CHECK_GL_ERROR();
 	glDisable (GL_CULL_FACE);
 	glMatrixMode (GL_MODELVIEW);
@@ -465,10 +489,13 @@
 
 	int surfaceVboNumber = m_compiler->vboNumber(surface, SurfacesVboComplement);
 	int colorVboNumber = m_compiler->vboNumber(surface, colors);
+	int normalVboNumber = m_compiler->vboNumber(surface, NormalsVboComplement);
 	m_compiler->prepareVBO(surfaceVboNumber, currentDocument());
 	m_compiler->prepareVBO(colorVboNumber, currentDocument());
+	m_compiler->prepareVBO(normalVboNumber, currentDocument());
 	GLuint surfaceVbo = m_compiler->vbo(surfaceVboNumber);
 	GLuint colorVbo = m_compiler->vbo(colorVboNumber);
+	GLuint normalVbo = m_compiler->vbo(normalVboNumber);
 	GLsizei count = m_compiler->vboSize(surfaceVboNumber) / 3;
 
 	if (count > 0)
@@ -479,6 +506,9 @@
 		glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
 		glColorPointer(4, GL_FLOAT, 0, nullptr);
 		CHECK_GL_ERROR();
+		glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
+		glNormalPointer(GL_FLOAT, 0, nullptr);
+		CHECK_GL_ERROR();
 		glDrawArrays(type, 0, count);
 		CHECK_GL_ERROR();
 	}
--- a/src/glRenderer.h	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/glRenderer.h	Thu Feb 09 23:46:45 2017 +0200
@@ -182,6 +182,7 @@
 	void zoomAllToFit();
 
 private slots:
-	void	slot_toolTipTimer();
-	void	initializeAxes();
+	void slot_toolTipTimer();
+	void initializeAxes();
+	void initializeLighting();
 };
--- a/src/glShared.h	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/glShared.h	Thu Feb 09 23:46:45 2017 +0200
@@ -54,9 +54,10 @@
 	BfcFrontColorsVboComplement,
 	BfcBackColorsVboComplement,
 	RandomColorsVboComplement,
+	NormalsVboComplement,
 };
 
-MAKE_ITERABLE_ENUM (ComplementVboType, SurfacesVboComplement, RandomColorsVboComplement)
+MAKE_ITERABLE_ENUM (ComplementVboType, SurfacesVboComplement, NormalsVboComplement)
 
 enum
 {
--- a/src/mainwindow.cpp	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/mainwindow.cpp	Thu Feb 09 23:46:45 2017 +0200
@@ -940,6 +940,7 @@
 	ui.actionDrawSurfaces->setChecked (m_config.drawSurfaces());
 	ui.actionDrawEdgeLines->setChecked (m_config.drawEdgeLines());
 	ui.actionDrawConditionalLines->setChecked (m_config.drawConditionalLines());
+	ui.actionLighting->setChecked(m_config.lighting());
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
--- a/src/mainwindow.ui	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/mainwindow.ui	Thu Feb 09 23:46:45 2017 +0200
@@ -492,6 +492,7 @@
    <addaction name="actionBfcView"/>
    <addaction name="actionRandomColors"/>
    <addaction name="actionDrawAngles"/>
+   <addaction name="actionLighting"/>
   </widget>
   <widget class="QToolBar" name="toolBarEditTools">
    <property name="windowTitle">
@@ -1706,6 +1707,14 @@
     <string>C</string>
    </property>
   </action>
+  <action name="actionLighting">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Lighting</string>
+   </property>
+  </action>
  </widget>
  <resources>
   <include location="../ldforge.qrc"/>
--- a/src/toolsets/viewtoolset.cpp	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/toolsets/viewtoolset.cpp	Thu Feb 09 23:46:45 2017 +0200
@@ -280,4 +280,10 @@
 {
 	m_config->toggleDrawConditionalLines();
 	m_window->updateActions();
-}
\ No newline at end of file
+}
+
+void ViewToolset::lighting()
+{
+	m_config->toggleLighting();
+	m_window->updateActions();
+}
--- a/src/toolsets/viewtoolset.h	Thu Feb 09 23:45:53 2017 +0200
+++ b/src/toolsets/viewtoolset.h	Thu Feb 09 23:46:45 2017 +0200
@@ -33,6 +33,7 @@
 	Q_INVOKABLE void drawEdgeLines();
 	Q_INVOKABLE void drawSurfaces();
 	Q_INVOKABLE void jumpTo();
+	Q_INVOKABLE void lighting();
 	Q_INVOKABLE void randomColors();
 	Q_INVOKABLE void resetView();
 	Q_INVOKABLE void screenshot();

mercurial