/// <summary> /// Generate the texture. /// </summary> public void GenerateTexture() { GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); texName = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, texName); Vector3[] data = new Vector3[TEX_SIZE * TEX_SIZE]; for (int y = 0; y < TEX_SIZE; y++) { for (int x = 0; x < TEX_SIZE; x++) { int i = y * TEX_SIZE + x; bool odd = ((x / TEX_CHECKER_SIZE + y / TEX_CHECKER_SIZE) & 1) > 0; data[i] = odd ? colBlack : colWhite; // add some fancy shading on the edges: if ((x % TEX_CHECKER_SIZE) == 0 || (y % TEX_CHECKER_SIZE) == 0) { data[i] += colShade; } if (((x + 1) % TEX_CHECKER_SIZE) == 0 || ((y + 1) % TEX_CHECKER_SIZE) == 0) { data[i] -= colShade; } } } GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, TEX_SIZE, TEX_SIZE, 0, PixelFormat.Rgb, PixelType.Float, data); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMagFilter.Linear); GlInfo.LogError("create-texture"); }
/// <summary> /// Resize the texture object. /// </summary> void ResizeTexture(int width, int height) { // check the texture name: if (texName == 0) { texName = GL.GenTexture(); texWidth = 0; } if (texWidth == width && texHeight == height) { return; } texWidth = width; texHeight = height; GL.BindTexture(TextureTarget.Texture2D, texName); GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); GL.PixelStore(PixelStoreParameter.PackAlignment, 1); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, texWidth, texHeight, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)0); Debug.Assert(GL.GetError() == ErrorCode.NoError, "glTexImage2D"); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMagFilter.Nearest); GlInfo.LogError("resize-texture"); PrepareClBuffers(); }
/// <summary> /// Generate static procedural texture. /// </summary> /// <returns>Texture handle or 0 if no texture will be used.</returns> int GenerateTexture() { // !!! TODO: change this part if you want, return 0 if texture is not used. // Generated (procedural) texture. const int TEX_SIZE = 128; const int TEX_CHECKER_SIZE = 8; Vector3 colWhite = new Vector3(0.85f, 0.75f, 0.30f); Vector3 colBlack = new Vector3(0.15f, 0.15f, 0.60f); Vector3 colShade = new Vector3(0.15f, 0.15f, 0.15f); GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); int texName = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, texName); Vector3[] data = new Vector3[TEX_SIZE * TEX_SIZE]; for (int y = 0; y < TEX_SIZE; y++) { for (int x = 0; x < TEX_SIZE; x++) { int i = y * TEX_SIZE + x; bool odd = ((x / TEX_CHECKER_SIZE + y / TEX_CHECKER_SIZE) & 1) > 0; data[i] = odd ? colBlack : colWhite; // Add some fancy shading on the edges. if ((x % TEX_CHECKER_SIZE) == 0 || (y % TEX_CHECKER_SIZE) == 0) { data[i] += colShade; } if (((x + 1) % TEX_CHECKER_SIZE) == 0 || ((y + 1) % TEX_CHECKER_SIZE) == 0) { data[i] -= colShade; } // Add top-half texture markers. if (y < TEX_SIZE / 2) { if (x % TEX_CHECKER_SIZE == TEX_CHECKER_SIZE / 2 && y % TEX_CHECKER_SIZE == TEX_CHECKER_SIZE / 2) { data[i] -= colShade; } } } } GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, TEX_SIZE, TEX_SIZE, 0, PixelFormat.Rgb, PixelType.Float, data); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMagFilter.Linear); GlInfo.LogError("create-texture"); return(texName); }
void RenderInit(OpenglState OGL) { // Scene rendering from VBOs. OGL.SetVertexAttrib(true); // Using GLSL shaders. GL.UseProgram(OGL.activeProgram.Id); // Uniforms. // Camera, projection, .. Matrix4 modelView = OGL.GetModelView(); Matrix4 modelViewInv = OGL.GetModelViewInv(); Matrix4 projection = OGL.GetProjection(); Vector3 eye = OGL.GetEyePosition(); // Give matrices to shaders. GL.UniformMatrix4(OGL.activeProgram.GetUniform("matrixModelView"), false, ref modelView); GL.UniformMatrix4(OGL.activeProgram.GetUniform("matrixProjection"), false, ref projection); // Lighting constants. GL.Uniform3(OGL.activeProgram.GetUniform("globalAmbient"), ref OGL.globalAmbient); GL.Uniform3(OGL.activeProgram.GetUniform("lightColor"), ref OGL.whiteLight); GL.Uniform3(OGL.activeProgram.GetUniform("lightPosition"), ref OGL.lightPosition); GL.Uniform3(OGL.activeProgram.GetUniform("eyePosition"), ref eye); GL.Uniform3(OGL.activeProgram.GetUniform("Ka"), ref OGL.matAmbient); GL.Uniform3(OGL.activeProgram.GetUniform("Kd"), ref OGL.matDiffuse); GL.Uniform3(OGL.activeProgram.GetUniform("Ks"), ref OGL.matSpecular); GL.Uniform1(OGL.activeProgram.GetUniform("shininess"), OGL.matShininess); // Global color handling. bool useColors = !OGL.useGlobalColor; GL.Uniform1(OGL.activeProgram.GetUniform("globalColor"), useColors ? 0 : 1); // Use varying normals? bool useNormals = OGL.useNormals; GL.Uniform1(OGL.activeProgram.GetUniform("useNormal"), useNormals ? 1 : 0); GlInfo.LogError("set-uniforms"); // Texture handling. bool useTexture = OGL.useTexture; GL.Uniform1(OGL.activeProgram.GetUniform("useTexture"), useTexture ? 1 : 0); GL.Uniform1(OGL.activeProgram.GetUniform("texSurface"), 0); if (useTexture) { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, OGL.texName); } GlInfo.LogError("set-texture"); // [txt] [colors] [normals] vertices GL.BindBuffer(BufferTarget.ArrayBuffer, OGL.VBOid[0]); GL.BindBuffer(BufferTarget.ElementArrayBuffer, OGL.VBOid[1]); }
/// <summary> /// Prepare VBO content and upload it to the GPU. /// </summary> void PrepareDataBuffers() { if (useVBO && scene != null && (scene.Triangles > 0 || scene.Lines > 0)) { // Vertex array: color [normal] coord. GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); int vertexBufferSize = scene.VertexBufferSize(true, true, true, true); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)vertexBufferSize, IntPtr.Zero, BufferUsageHint.StaticDraw); IntPtr videoMemoryPtr = GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.WriteOnly); unsafe { stride = scene.FillVertexBuffer((float *)videoMemoryPtr.ToPointer(), true, true, true, true); } GL.UnmapBuffer(BufferTarget.ArrayBuffer); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GlInfo.LogError("fill vertex-buffer"); // Index buffer. GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); int indices = scene.Triangles * 3 + scene.Lines * 2; GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices * sizeof(uint)), IntPtr.Zero, BufferUsageHint.StaticDraw); videoMemoryPtr = GL.MapBuffer(BufferTarget.ElementArrayBuffer, BufferAccess.WriteOnly); unsafe { scene.FillIndexBuffer((uint *)videoMemoryPtr.ToPointer()); } GL.UnmapBuffer(BufferTarget.ElementArrayBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GlInfo.LogError("fill index-buffer"); } else { if (useVBO) { GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)0, IntPtr.Zero, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } } }
public void InitOpenGL(GLControl glc) { // log OpenGL info just for curiosity: GlInfo.LogGLProperties(); // general OpenGL: glc.VSync = true; GL.ClearColor(Color.FromArgb(14, 20, 40)); // darker "navy blue" GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.VertexProgramPointSize); GL.ShadeModel(ShadingModel.Flat); // VBO init: VBOid = new uint[2]; // one big buffer for vertex data, another buffer for tri/line indices GL.GenBuffers(2, VBOid); GlInfo.LogError("VBO init"); VBOlen = new long[2]; }
private void RenderFinish(OpenglState OGL, int vertexCount, int stride) { GL.UnmapBuffer(BufferTarget.ArrayBuffer); // Index buffer. GL.BindBuffer(BufferTarget.ElementArrayBuffer, OGL.VBOid[1]); // Set attribute pointers. IntPtr p = IntPtr.Zero; if (OGL.activeProgram.HasAttribute("texCoords")) { GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("texCoords"), 2, VertexAttribPointerType.Float, false, stride, p); } p += Vector2.SizeInBytes; if (OGL.activeProgram.HasAttribute("color")) { GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("color"), 3, VertexAttribPointerType.Float, false, stride, p); } p += Vector3.SizeInBytes; if (OGL.activeProgram.HasAttribute("normal")) { GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("normal"), 3, VertexAttribPointerType.Float, false, stride, p); } p += Vector3.SizeInBytes; GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("position"), 3, VertexAttribPointerType.Float, false, stride, p); GlInfo.LogError("triangles-set-attrib-pointers"); // The drawing command itself. GL.DrawElements(PrimitiveType.Triangles, vertexCount, DrawElementsType.UnsignedInt, IntPtr.Zero); GlInfo.LogError("triangles-draw-elements"); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.UseProgram(0); OGL.SetVertexAttrib(false); }
/// <summary> /// OpenGL init code. /// </summary> void InitOpenGL() { // Log OpenGL info just for curiosity. GlInfo.LogGLProperties(); // General OpenGL. glControl1.VSync = true; GL.ClearColor(Color.FromArgb(14, 20, 40)); // darker "navy blue" GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.VertexProgramPointSize); GL.ShadeModel(ShadingModel.Flat); // VBO init: VBOid = new uint[2]; // one big buffer for vertex data, another buffer for tri/line indices GL.GenBuffers(2, VBOid); GlInfo.LogError("VBO init"); VBOlen = new int[2]; // zeroes.. // Texture. GenerateTexture(); }
//==================================================================== // Rendering - OpenGL //==================================================================== /// <summary> /// OpenGL init code (cold init). /// </summary> public void InitOpenGL(GLControl glc) { // Log OpenGL info just for curiosity. GlInfo.LogGLProperties(); // General OpenGL. glc.VSync = true; GL.ClearColor(Color.FromArgb(14, 20, 40)); // darker "navy blue" GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.VertexProgramPointSize); GL.ShadeModel(ShadingModel.Flat); // VBO init. VBOid = new uint[2]; // one big buffer for vertex data, another buffer for tri/line indices GL.GenBuffers(2, VBOid); if (GlInfo.LogError("VBO init")) { Application.Exit(); } VBOlen = new long[2]; // current buffer lenghts in bytes // Shaders. InitShaderRepository(); if (!SetupShaders()) { Util.Log("Shader setup failed, giving up..."); Application.Exit(); } // Only shader VertexAttribPointers() or the very old glVertex() stuff. GL.DisableClientState(ArrayCap.VertexArray); GL.DisableClientState(ArrayCap.TextureCoordArray); GL.DisableClientState(ArrayCap.NormalArray); GL.DisableClientState(ArrayCap.ColorArray); // Texture. texName = GenerateTexture(); }
/// <summary> /// OpenGL init code. /// </summary> public void InitOpenGL() { // log OpenGL info just for curiosity: GlInfo.LogGLProperties(); // general OpenGL: glC.VSync = true; GL.ClearColor(Color.FromArgb(30, 40, 90)); GL.Enable(EnableCap.DepthTest); GL.ShadeModel(ShadingModel.Flat); // VBO init: VBOid = new uint[2]; // one big buffer for vertex data, another buffer for tri/line indices GL.GenBuffers(2, VBOid); GlInfo.LogError("VBO init"); // shaders: canShaders = SetupShaders(); // texture: GenerateTexture(); }
/// <summary> /// Initialize VBO buffers. /// Determine maximum buffer sizes and allocate VBO objects. /// Vertex buffer: /// <list type=">"> /// <item>cube - triangles</item> /// </list> /// Index buffer: /// <list type=">"> /// <item>cube - triangles</item> /// </list> /// </summary> unsafe void InitDataBuffers() { puz.Dirty = false; // Init data buffers for current simulation state. // triangles: determine maximum stride, maximum vertices and indices float *ptr = null; uint * iptr = null; uint origin = 0; int stride = 0; // Vertex-buffer size. int maxVB; maxVB = Align(puz.cube.TriangleVertices(ref ptr, ref origin, out stride, true, true, true, true)); // maxVB contains maximal vertex-buffer size for all batches // Index-buffer size. int maxIB; maxIB = Align(puz.cube.TriangleIndices(ref iptr, 0)); // maxIB contains maximal index-buffer size for all batches VBOlen[0] = maxVB; VBOlen[1] = maxIB; // Vertex buffer in VBO[ 0 ]. GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)VBOlen[0], IntPtr.Zero, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GlInfo.LogError("allocate vertex-buffer"); // Index buffer in VBO[ 1 ]. GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)VBOlen[1], IntPtr.Zero, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GlInfo.LogError("allocate index-buffer"); }
/// <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; } }
/// <summary> /// Renders the simulated data from the special object. /// </summary> /// <param name="OGL">Current OpenGL state object.</param> /// <param name="data">Data to render.</param> /// <returns>Number of actually drawn primitives.</returns> public long Render(OpenglState OGL, MarblesRenderData data) { // {{ TODO: modify the rendering code! // Scene rendering from VBOs. OGL.SetVertexAttrib(true); // Using GLSL shaders. GL.UseProgram(OGL.activeProgram.Id); // Uniforms. // Camera, projection, .. Matrix4 modelView = OGL.GetModelView(); Matrix4 modelViewInv = OGL.GetModelViewInv(); Matrix4 projection = OGL.GetProjection(); Vector3 eye = OGL.GetEyePosition(); // Give matrices to shaders. GL.UniformMatrix4(OGL.activeProgram.GetUniform("matrixModelView"), false, ref modelView); GL.UniformMatrix4(OGL.activeProgram.GetUniform("matrixProjection"), false, ref projection); // Lighting constants. GL.Uniform3(OGL.activeProgram.GetUniform("globalAmbient"), ref OGL.globalAmbient); GL.Uniform3(OGL.activeProgram.GetUniform("lightColor"), ref OGL.whiteLight); GL.Uniform3(OGL.activeProgram.GetUniform("lightPosition"), ref OGL.lightPosition); GL.Uniform3(OGL.activeProgram.GetUniform("eyePosition"), ref eye); GL.Uniform3(OGL.activeProgram.GetUniform("Ka"), ref OGL.matAmbient); GL.Uniform3(OGL.activeProgram.GetUniform("Kd"), ref OGL.matDiffuse); GL.Uniform3(OGL.activeProgram.GetUniform("Ks"), ref OGL.matSpecular); GL.Uniform1(OGL.activeProgram.GetUniform("shininess"), OGL.matShininess); // Global color handling. bool useColors = !OGL.useGlobalColor; GL.Uniform1(OGL.activeProgram.GetUniform("globalColor"), useColors ? 0 : 1); // Use varying normals? bool useNormals = OGL.useNormals; GL.Uniform1(OGL.activeProgram.GetUniform("useNormal"), useNormals ? 1 : 0); GlInfo.LogError("set-uniforms"); // Texture handling. bool useTexture = OGL.useTexture; GL.Uniform1(OGL.activeProgram.GetUniform("useTexture"), useTexture ? 1 : 0); GL.Uniform1(OGL.activeProgram.GetUniform("texSurface"), 0); if (useTexture) { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, OGL.texName); } GlInfo.LogError("set-texture"); // [txt] [colors] [normals] vertices GL.BindBuffer(BufferTarget.ArrayBuffer, OGL.VBOid[0]); GL.BindBuffer(BufferTarget.ElementArrayBuffer, OGL.VBOid[1]); int marbles = data.radii.Count; int stride = sizeof(float) * 11; // float[2] txt, float[3] color, float[3] normal, float[3] position int triangles = marbles; IntPtr videoMemoryPtr; if (marbles != lastMarbles) { // Relocate the buffers. // Vertex array: [ txt color coord ] GL.BindBuffer(BufferTarget.ArrayBuffer, OGL.VBOid[0]); int vertexBufferSize = (marbles * 3) * stride; // TODO: marble should be drawn as a SPHERE, not a triangle.. GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)vertexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); // Fill index array. GL.BindBuffer(BufferTarget.ElementArrayBuffer, OGL.VBOid[1]); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)((triangles * 3) * sizeof(uint)), IntPtr.Zero, BufferUsageHint.StaticDraw); videoMemoryPtr = GL.MapBuffer(BufferTarget.ElementArrayBuffer, BufferAccess.WriteOnly); unsafe { uint *ptr = (uint *)videoMemoryPtr.ToPointer(); for (uint i = 0; i < triangles * 3; i++) { *ptr++ = i; } } GL.UnmapBuffer(BufferTarget.ElementArrayBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); lastMarbles = marbles; } // Refill vertex buffer. GL.BindBuffer(BufferTarget.ArrayBuffer, OGL.VBOid[0]); videoMemoryPtr = GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.WriteOnly); unsafe { float *ptr = (float *)videoMemoryPtr.ToPointer(); for (int i = 0; i < marbles; i++) { float rad = data.radii[i]; float r = data.colors[i].R / 255.0f; float g = data.colors[i].G / 255.0f; float b = data.colors[i].B / 255.0f; // txt[2], color[3], normal[3], position[3] *ptr++ = 0.3f; *ptr++ = 0.3f; *ptr++ = r; *ptr++ = g; *ptr++ = b; *ptr++ = 0.0f; *ptr++ = 0.0f; *ptr++ = 1.0f; *ptr++ = data.centers[i].X; *ptr++ = data.centers[i].Y; *ptr++ = data.centers[i].Z; // txt[2], color[3], normal[3], position[3] *ptr++ = 0.7f; *ptr++ = 0.3f; *ptr++ = r; *ptr++ = g; *ptr++ = b; *ptr++ = 0.0f; *ptr++ = 0.0f; *ptr++ = 1.0f; *ptr++ = data.centers[i].X + rad; *ptr++ = data.centers[i].Y; *ptr++ = data.centers[i].Z; // txt[2], color[3], normal[3], position[3] *ptr++ = 0.3f; *ptr++ = 0.7f; *ptr++ = r; *ptr++ = g; *ptr++ = b; *ptr++ = 0.0f; *ptr++ = 0.0f; *ptr++ = 1.0f; *ptr++ = data.centers[i].X; *ptr++ = data.centers[i].Y + rad; *ptr++ = data.centers[i].Z; } } GL.UnmapBuffer(BufferTarget.ArrayBuffer); // Index buffer. GL.BindBuffer(BufferTarget.ElementArrayBuffer, OGL.VBOid[1]); // Set attribute pointers. IntPtr p = IntPtr.Zero; if (OGL.activeProgram.HasAttribute("texCoords")) { GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("texCoords"), 2, VertexAttribPointerType.Float, false, stride, p); } p += Vector2.SizeInBytes; if (OGL.activeProgram.HasAttribute("color")) { GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("color"), 3, VertexAttribPointerType.Float, false, stride, p); } p += Vector3.SizeInBytes; if (OGL.activeProgram.HasAttribute("normal")) { GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("normal"), 3, VertexAttribPointerType.Float, false, stride, p); } p += Vector3.SizeInBytes; GL.VertexAttribPointer(OGL.activeProgram.GetAttribute("position"), 3, VertexAttribPointerType.Float, false, stride, p); GlInfo.LogError("triangles-set-attrib-pointers"); // The drawing command itself. GL.DrawElements(PrimitiveType.Triangles, triangles * 3, DrawElementsType.UnsignedInt, IntPtr.Zero); GlInfo.LogError("triangles-draw-elements"); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.UseProgram(0); OGL.SetVertexAttrib(false); return(triangles); // }} }
/// <summary> /// Rendering code itself (separated for clarity). /// </summary> void RenderScene() { if (puz != null) { if (VBOlen[0] == 0 || VBOlen[1] == 0 || puz.Dirty) { InitDataBuffers(); } if (VBOlen[0] > 0 || VBOlen[1] > 0) { // Texture handling. bool useTexture = checkTexture.Checked; if (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); } // Scene rendering from VBOs: EnableArrays(useTexture); // [txt] [colors] [normals] [ptsize] vertices GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid[0]); GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); int stride; // stride for vertex arrays int indices; // number of indices for index arrays //------------------------- // Draw all triangles. IntPtr vertexPtr = GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.WriteOnly); IntPtr indexPtr = GL.MapBuffer(BufferTarget.ElementArrayBuffer, BufferAccess.WriteOnly); unsafe { float *ptr = (float *)vertexPtr.ToPointer(); uint * iptr = (uint *)indexPtr.ToPointer(); indices = puz.FillTriangleData(ref ptr, ref iptr, out stride, useTexture, !useTexture, false, false); } GL.UnmapBuffer(BufferTarget.ArrayBuffer); GL.UnmapBuffer(BufferTarget.ElementArrayBuffer); IntPtr p = IntPtr.Zero; // Using FFP. if (useTexture) { GL.TexCoordPointer(2, TexCoordPointerType.Float, stride, p); p += Vector2.SizeInBytes; } if (!useTexture) { GL.ColorPointer(3, ColorPointerType.Float, stride, p); p += Vector3.SizeInBytes; } GL.VertexPointer(3, VertexPointerType.Float, stride, p); // Index buffer. GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOid[1]); // Engage! GL.DrawElements(PrimitiveType.Triangles, indices, DrawElementsType.UnsignedInt, IntPtr.Zero); GlInfo.LogError("draw-elements-ffp"); if (useTexture) { GL.BindTexture(TextureTarget.Texture2D, 0); GL.Disable(EnableCap.Texture2D); } GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); DisableArrays(); } } else { DisableArrays(); // Default: draw trivial cube using immediate mode. 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; } // Support: axes if (checkDebug.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.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); if (spot != null) { GL.Color3(1.0f, 1.0f, 1.0f); GL.Vertex3(spot.Value); } 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); } }