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> /// 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); // }} }