/// <summary> /// Rendering code itself (separated for clarity). /// </summary> void RenderScene() { // Scene rendering. if (scene != null && (scene.Lines > 0 || scene.Triangles > 0) && // scene is nonempty => render it useVBO) { GL.LineWidth(scene.LineWidth); // [txt] [colors] [normals] vertices GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); IntPtr p = IntPtr.Zero; if (useShaders) { SetVertexPointer(false); SetVertexAttrib(true); // Using GLSL shaders. GL.UseProgram(activeProgram.Id); // Uniforms. Matrix4 modelView = cam.ModelView; Matrix4 projection = cam.Projection; Vector3 eye = cam.Eye; GL.UniformMatrix4(activeProgram.GetUniform("matrixModelView"), false, ref modelView); GL.UniformMatrix4(activeProgram.GetUniform("matrixProjection"), false, ref projection); GL.Uniform3(activeProgram.GetUniform("globalAmbient"), ref globalAmbient); GL.Uniform3(activeProgram.GetUniform("lightColor"), ref whiteLight); GL.Uniform3(activeProgram.GetUniform("lightPosition"), ref lightPosition); GL.Uniform3(activeProgram.GetUniform("eyePosition"), ref eye); GL.Uniform3(activeProgram.GetUniform("Ka"), ref matAmbient); GL.Uniform3(activeProgram.GetUniform("Kd"), ref matDiffuse); GL.Uniform3(activeProgram.GetUniform("Ks"), ref matSpecular); GL.Uniform1(activeProgram.GetUniform("shininess"), matShininess); // Color handling. bool useGlobalColor = checkGlobalColor.Checked; if (!scene.HasColors()) { useGlobalColor = true; } GL.Uniform1(activeProgram.GetUniform("globalColor"), useGlobalColor ? 1 : 0); // Shading. bool shadingPhong = checkPhong.Checked; bool shadingGouraud = checkSmooth.Checked; if (!shadingGouraud) { shadingPhong = false; } GL.Uniform1(activeProgram.GetUniform("shadingPhong"), shadingPhong ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("shadingGouraud"), shadingGouraud ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("useAmbient"), checkAmbient.Checked ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("useDiffuse"), checkDiffuse.Checked ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("useSpecular"), checkSpecular.Checked ? 1 : 0); GlInfo.LogError("set-uniforms"); // Texture handling. bool useTexture = checkTexture.Checked; if (!scene.HasTxtCoords() || texName == 0) { useTexture = false; } GL.Uniform1(activeProgram.GetUniform("useTexture"), useTexture ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("texSurface"), 0); if (useTexture) { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texName); } GlInfo.LogError("set-texture"); if (activeProgram.HasAttribute("texCoords")) { GL.VertexAttribPointer(activeProgram.GetAttribute("texCoords"), 2, VertexAttribPointerType.Float, false, stride, p); } if (scene.HasTxtCoords()) { p += Vector2.SizeInBytes; } if (activeProgram.HasAttribute("color")) { GL.VertexAttribPointer(activeProgram.GetAttribute("color"), 3, VertexAttribPointerType.Float, false, stride, p); } if (scene.HasColors()) { p += Vector3.SizeInBytes; } if (activeProgram.HasAttribute("normal")) { GL.VertexAttribPointer(activeProgram.GetAttribute("normal"), 3, VertexAttribPointerType.Float, false, stride, p); } if (scene.HasNormals()) { p += Vector3.SizeInBytes; } GL.VertexAttribPointer(activeProgram.GetAttribute("position"), 3, VertexAttribPointerType.Float, false, stride, p); GlInfo.LogError("set-attrib-pointers"); // Index buffer. GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); // Engage! if (scene.Triangles > 0) { GL.DrawElements(PrimitiveType.Triangles, scene.Triangles * 3, DrawElementsType.UnsignedInt, IntPtr.Zero); } else { GL.DrawElements(PrimitiveType.Lines, scene.Lines * 2, DrawElementsType.UnsignedInt, IntPtr.Zero); } GlInfo.LogError("draw-elements-shader"); // Cleanup. GL.UseProgram(0); if (useTexture) { GL.BindTexture(TextureTarget.Texture2D, 0); } } else { SetVertexAttrib(false); SetVertexPointer(true); // Texture handling. bool useTexture = checkTexture.Checked; if (!scene.HasTxtCoords() || texName == 0) { useTexture = false; } if (useTexture) { GL.Enable(EnableCap.Texture2D); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texName); GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Replace); } // Using FFP. if (scene.HasTxtCoords()) { GL.TexCoordPointer(2, TexCoordPointerType.Float, stride, p); p += Vector2.SizeInBytes; } if (scene.HasColors()) { GL.ColorPointer(3, ColorPointerType.Float, stride, p); p += Vector3.SizeInBytes; } if (scene.HasNormals()) { GL.NormalPointer(NormalPointerType.Float, stride, p); p += Vector3.SizeInBytes; } GL.VertexPointer(3, VertexPointerType.Float, stride, p); // Index buffer. GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); // Engage! if (scene.Triangles > 0) { GL.DrawElements(PrimitiveType.Triangles, scene.Triangles * 3, DrawElementsType.UnsignedInt, IntPtr.Zero); } else { GL.DrawElements(PrimitiveType.Lines, scene.Lines * 2, DrawElementsType.UnsignedInt, IntPtr.Zero); } GlInfo.LogError("draw-elements-ffp"); if (useTexture) { GL.BindTexture(TextureTarget.Texture2D, 0); GL.Disable(EnableCap.Texture2D); } } triangleCounter += scene.Triangles + scene.Lines; } else // color cube { SetVertexPointer(false); SetVertexAttrib(false); GL.Begin(PrimitiveType.Quads); GL.Color3(0.0f, 1.0f, 0.0f); // Set The Color To Green GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Top) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top) GL.Vertex3(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top) GL.Vertex3(1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top) GL.Color3(1.0f, 0.5f, 0.0f); // Set The Color To Orange GL.Vertex3(1.0f, -1.0f, 1.0f); // Top Right Of The Quad (Bottom) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Top Left Of The Quad (Bottom) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Bottom) GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Bottom) GL.Color3(1.0f, 0.0f, 0.0f); // Set The Color To Red GL.Vertex3(1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front) GL.Vertex3(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Quad (Front) GL.Vertex3(1.0f, -1.0f, 1.0f); // Bottom Right Of The Quad (Front) GL.Color3(1.0f, 1.0f, 0.0f); // Set The Color To Yellow GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Back) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Back) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Back) GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Back) GL.Color3(0.0f, 0.0f, 1.0f); // Set The Color To Blue GL.Vertex3(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Left) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Left) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Quad (Left) GL.Color3(1.0f, 0.0f, 1.0f); // Set The Color To Violet GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Right) GL.Vertex3(1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right) GL.Vertex3(1.0f, -1.0f, 1.0f); // Bottom Left Of The Quad (Right) GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Right) GL.End(); triangleCounter += 12; } // Support: axes. if (checkAxes.Checked) { float origWidth = GL.GetFloat(GetPName.LineWidth); float origPoint = GL.GetFloat(GetPName.PointSize); // Axes. GL.LineWidth(2.0f); GL.Begin(PrimitiveType.Lines); GL.Color3(1.0f, 0.1f, 0.1f); GL.Vertex3(center); GL.Vertex3(center + new Vector3(0.5f, 0.0f, 0.0f) * diameter); GL.Color3(0.0f, 1.0f, 0.0f); GL.Vertex3(center); GL.Vertex3(center + new Vector3(0.0f, 0.5f, 0.0f) * diameter); GL.Color3(0.2f, 0.2f, 1.0f); GL.Vertex3(center); GL.Vertex3(center + new Vector3(0.0f, 0.0f, 0.5f) * diameter); GL.End(); // Support: pointing. if (pointOrigin != null) { GL.Begin(PrimitiveType.Lines); GL.Color3(1.0f, 1.0f, 0.0f); GL.Vertex3(pointOrigin.Value); GL.Vertex3(pointTarget); GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex3(pointOrigin.Value); GL.Vertex3(eye); GL.End(); GL.PointSize(4.0f); GL.Begin(PrimitiveType.Points); GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex3(pointOrigin.Value); GL.Color3(0.0f, 1.0f, 0.2f); GL.Vertex3(pointTarget); GL.Color3(1.0f, 1.0f, 1.0f); if (spot != null) { GL.Vertex3(spot.Value); } GL.Vertex3(eye); GL.End(); } // Support: frustum. if (frustumFrame.Count >= 8) { GL.LineWidth(2.0f); GL.Begin(PrimitiveType.Lines); GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex3(frustumFrame[0]); GL.Vertex3(frustumFrame[1]); GL.Vertex3(frustumFrame[1]); GL.Vertex3(frustumFrame[3]); GL.Vertex3(frustumFrame[3]); GL.Vertex3(frustumFrame[2]); GL.Vertex3(frustumFrame[2]); GL.Vertex3(frustumFrame[0]); GL.Color3(1.0f, 1.0f, 1.0f); GL.Vertex3(frustumFrame[0]); GL.Vertex3(frustumFrame[4]); GL.Vertex3(frustumFrame[1]); GL.Vertex3(frustumFrame[5]); GL.Vertex3(frustumFrame[2]); GL.Vertex3(frustumFrame[6]); GL.Vertex3(frustumFrame[3]); GL.Vertex3(frustumFrame[7]); GL.Color3(0.0f, 1.0f, 0.0f); GL.Vertex3(frustumFrame[4]); GL.Vertex3(frustumFrame[5]); GL.Vertex3(frustumFrame[5]); GL.Vertex3(frustumFrame[7]); GL.Vertex3(frustumFrame[7]); GL.Vertex3(frustumFrame[6]); GL.Vertex3(frustumFrame[6]); GL.Vertex3(frustumFrame[4]); GL.End(); } GL.LineWidth(origWidth); GL.PointSize(origPoint); } }
//==================================================================== // Rendering - graph //==================================================================== /// <summary> /// Rendering code itself (separated for clarity). /// </summary> /// <param name="cam">Camera parameters.</param> /// <param name="style">Current rendering style.</param> /// <param name="primitiveCounter">Number of GL primitives rendered.</param> public void RenderScene( IDynamicCamera cam, RenderingStyle style, ref long primitiveCounter) { // Scene rendering. if (Form1.form.drawGraph && VBOlen[0] > 0L && activeProgram != null) // buffers are nonempty & shaders are ready => render { // Vertex buffer: [texture] [color] [normal] coordinate GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); // GLSL shaders. activeProgram.EnableVertexAttribArrays(); GL.UseProgram(activeProgram.Id); // Uniforms. Matrix4 modelView = cam.ModelView; Matrix4 projection = cam.Projection; Vector3 eye = cam.Eye; GL.UniformMatrix4(activeProgram.GetUniform("matrixModelView"), false, ref modelView); GL.UniformMatrix4(activeProgram.GetUniform("matrixProjection"), false, ref projection); GL.Uniform3(activeProgram.GetUniform("globalAmbient"), ref style.globalAmbient); GL.Uniform3(activeProgram.GetUniform("lightColor"), ref style.whiteLight); GL.Uniform3(activeProgram.GetUniform("lightPosition"), ref style.lightPosition); GL.Uniform3(activeProgram.GetUniform("eyePosition"), ref eye); GL.Uniform3(activeProgram.GetUniform("Ka"), ref style.matAmbient); GL.Uniform3(activeProgram.GetUniform("Kd"), ref style.matDiffuse); GL.Uniform3(activeProgram.GetUniform("Ks"), ref style.matSpecular); GL.Uniform1(activeProgram.GetUniform("shininess"), style.matShininess); // Color handling. bool useGlobalColor = style.useGlobalColor; if (!haveColors) // use global color if vertices haven't got color! { useGlobalColor = true; } GL.Uniform1(activeProgram.GetUniform("globalColor"), useGlobalColor ? 1 : 0); // Shading, color interpolation. // shadingGouraud <=> lighting is computed in VS // shadingPhong <=> lighting is computed in FS (normal interpolation) // shadingSmooth <=> colors are interpolated in FS (color interpolation) bool shadingGouraud = style.lighting && !style.phong; bool shadingPhong = style.lighting && style.phong; bool shadingSmooth = style.smooth; GL.Uniform1(activeProgram.GetUniform("shadingGouraud"), shadingGouraud ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("shadingPhong"), shadingPhong ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("shadingSmooth"), shadingSmooth ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("useAmbient"), style.useAmbient ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("useDiffuse"), style.useDiffuse ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("useSpecular"), style.useSpecular ? 1 : 0); GlInfo.LogError("set-uniforms"); // Color texture in slot #0. bool okTexture = style.texture && haveTexture; GL.Uniform1(activeProgram.GetUniform("useTexture"), okTexture ? 1 : 0); GL.Uniform1(activeProgram.GetUniform("texSurface"), 0); if (okTexture) { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texName); } GlInfo.LogError("set-texture"); // Vertex attributes. IntPtr p = IntPtr.Zero; if (activeProgram.HasAttribute("texCoords")) { GL.VertexAttribPointer(activeProgram.GetAttribute("texCoords"), 2, VertexAttribPointerType.Float, false, stride, p); } if (haveTexture) { p += Vector2.SizeInBytes; } if (activeProgram.HasAttribute("color")) { GL.VertexAttribPointer(activeProgram.GetAttribute("color"), 3, VertexAttribPointerType.Float, false, stride, p); } if (haveColors) { p += Vector3.SizeInBytes; } if (activeProgram.HasAttribute("normal")) { GL.VertexAttribPointer(activeProgram.GetAttribute("normal"), 3, VertexAttribPointerType.Float, false, stride, p); } if (haveNormals) { p += Vector3.SizeInBytes; } GL.VertexAttribPointer(activeProgram.GetAttribute("position"), 3, VertexAttribPointerType.Float, false, stride, p); GlInfo.LogError("set-attrib-pointers"); // Index buffer. GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); // Draw! // !!!{{ CHANGE THIS PART if you want to add axes, legend, etc... // Triangle part of the scene. // Draw total 'vertices' vertices from the beginning of the index-buffer, // that gives us 'vertices/3' triangles. GL.DrawElements(PrimitiveType.Triangles, vertices, DrawElementsType.UnsignedInt, IntPtr.Zero); GlInfo.LogError("draw-elements-shader"); // How to draw lines (e.g. coordinate axes): //GL.DrawElements(PrimitiveType.Lines, lineVertices, DrawElementsType.UnsignedInt, lineOffset); // lineVertices ... number of vertex indices for lines (e.g. 'lineVertices/2' lines) // lineOffset ... start offset in the index-buffer primitiveCounter += vertices / 3; // !!!}} // Cleanup. GL.UseProgram(0); if (okTexture) { GL.BindTexture(TextureTarget.Texture2D, 0); } } else { // Color cube in very old OpenGL style! GL.Begin(PrimitiveType.Quads); GL.Color3(0.0f, 1.0f, 0.0f); // Set The Color To Green GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Top) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top) GL.Vertex3(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top) GL.Vertex3(1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top) GL.Color3(1.0f, 0.5f, 0.0f); // Set The Color To Orange GL.Vertex3(1.0f, -1.0f, 1.0f); // Top Right Of The Quad (Bottom) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Top Left Of The Quad (Bottom) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Bottom) GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Bottom) GL.Color3(1.0f, 0.0f, 0.0f); // Set The Color To Red GL.Vertex3(1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front) GL.Vertex3(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Quad (Front) GL.Vertex3(1.0f, -1.0f, 1.0f); // Bottom Right Of The Quad (Front) GL.Color3(1.0f, 1.0f, 0.0f); // Set The Color To Yellow GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Back) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Back) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Back) GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Back) GL.Color3(0.0f, 0.0f, 1.0f); // Set The Color To Blue GL.Vertex3(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left) GL.Vertex3(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Left) GL.Vertex3(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Quad (Left) GL.Vertex3(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Quad (Left) GL.Color3(1.0f, 0.0f, 1.0f); // Set The Color To Violet GL.Vertex3(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Right) GL.Vertex3(1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right) GL.Vertex3(1.0f, -1.0f, 1.0f); // Bottom Left Of The Quad (Right) GL.Vertex3(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Right) GL.End(); primitiveCounter += 12; } }