public ParentMesh(Mesh _mesh, Texture _texture, Matrix4 _localTransform, Matrix4 _localScale, Matrix4 _localRotation, ParentMesh _parent = null, float hdr = 0, int _cubemap = 0, Texture _normalMap = null) { mesh = _mesh; texture = _texture; localTranslation = _localTransform; localScale = _localScale; localRotation = _localRotation; normalMap = _normalMap; parent = _parent; intensity = hdr; if (_cubemap != 0) { cubemap = new cubemap(_cubemap); } }
// render the mesh using the supplied shader and matrix public void Render(Shader shader, Matrix4 transform, Matrix4 camera, Matrix4 cameraPosition, float intensity, Texture texture, Texture normalMap, cubemap cubemap, List <Pointlight> pointlights, List <DirectionalLight> directionalLights, List <Spotlight> spotlights) { // on first run, prepare buffers Prepare(shader); // safety dance GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit); // enable normal map // enable shader GL.UseProgram(shader.programID); // pass transform to vertex shader int tr = GL.GetUniformLocation(shader.programID, "transform"); GL.UniformMatrix4(tr, false, ref transform); GL.UniformMatrix4(shader.uniform_mview, false, ref camera); GL.Uniform4(GL.GetUniformLocation(shader.programID, "viewPos"), cameraPosition.Row3); int isNormal = GL.GetUniformLocation(shader.programID, "isNormalMap"); if (normalMap != null) { GL.Uniform1(isNormal, 1); } else { GL.Uniform1(isNormal, 0); } int cubeMapType = GL.GetUniformLocation(shader.programID, "cubeMapType"); if (cubemap != null) { GL.Uniform1(cubeMapType, cubemap.type); } else { GL.Uniform1(cubeMapType, 0); } //Directional lights int depthmaps = 0; for (int i = 0; i < directionalLights.Count; ++i) { int direction = GL.GetUniformLocation(shader.programID, "directionalLights[" + i + "].direction"); int color = GL.GetUniformLocation(shader.programID, "directionalLights[" + i + "].color"); int strength = GL.GetUniformLocation(shader.programID, "directionalLights[" + i + "].strength"); int map = GL.GetUniformLocation(shader.programID, "directionalLights[" + i + "].shadowMap"); int mat = GL.GetUniformLocation(shader.programID, "directionalLights[" + i + "].lightSpace"); GL.Uniform3(direction, Vector3.Normalize(directionalLights[i].direction.Xyz)); GL.Uniform3(color, directionalLights[i].color); GL.Uniform1(strength, directionalLights[i].strength); GL.Uniform1(map, 3 + depthmaps); GL.ActiveTexture(TextureUnit.Texture3 + depthmaps); GL.BindTexture(TextureTarget.Texture2D, directionalLights[i].shadowMap.id); GL.UniformMatrix4(mat, false, ref directionalLights[i].shadowMap.camera); depthmaps++; } int location = GL.GetUniformLocation(shader.programID, "directionalLightCount"); GL.Uniform1(location, directionalLights.Count); int cubes = 0; //Pointlights for (int i = 0; i < pointlights.Count; ++i) { int position = GL.GetUniformLocation(shader.programID, "pointlights[" + i + "].position"); int color = GL.GetUniformLocation(shader.programID, "pointlights[" + i + "].color"); int strength = GL.GetUniformLocation(shader.programID, "pointlights[" + i + "].strength"); int map = GL.GetUniformLocation(shader.programID, "pointlights[" + i + "].shadowMap"); GL.Uniform3(position, pointlights[i].position.Xyz); GL.Uniform3(color, pointlights[i].color); GL.Uniform1(strength, pointlights[i].strength); GL.Uniform1(map, 3 + depthmaps); GL.ActiveTexture(TextureUnit.Texture3 + depthmaps); GL.BindTexture(TextureTarget.TextureCubeMap, pointlights[i].shadowMap.id); depthmaps++; cubes++; } location = GL.GetUniformLocation(shader.programID, "pointlightCount"); GL.Uniform1(location, pointlights.Count); for (int i = cubes; i < 20; ++i) { int map = GL.GetUniformLocation(shader.programID, "pointlights[" + i + "].shadowMap"); GL.Uniform1(map, 3 + depthmaps - 1); GL.BindTexture(TextureTarget.TextureCubeMap, pointlights[0].shadowMap.id); } //Spotlights for (int i = 0; i < spotlights.Count; ++i) { int direction = GL.GetUniformLocation(shader.programID, "spotlights[" + i + "].direction"); int position = GL.GetUniformLocation(shader.programID, "spotlights[" + i + "].position"); int color = GL.GetUniformLocation(shader.programID, "spotlights[" + i + "].color"); int strength = GL.GetUniformLocation(shader.programID, "spotlights[" + i + "].strength"); int angle = GL.GetUniformLocation(shader.programID, "spotlights[" + i + "].angle"); GL.Uniform3(position, spotlights[i].position.Xyz); GL.Uniform3(direction, Vector3.Normalize(spotlights[i].direction.Xyz)); GL.Uniform3(color, spotlights[i].color); GL.Uniform1(strength, spotlights[i].strength); GL.Uniform1(angle, spotlights[i].angle); depthmaps++; } location = GL.GetUniformLocation(shader.programID, "spotlightCount"); GL.Uniform1(location, spotlights.Count); if (normalMap != null) { int normalLoc = GL.GetUniformLocation(shader.programID, "normalMap"); GL.Uniform1(normalLoc, 1); GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, normalMap.id); } if (cubemap != null) { int cubeLoc = GL.GetUniformLocation(shader.programID, "cubeMap"); GL.Uniform1(cubeLoc, 2); GL.ActiveTexture(TextureUnit.Texture2); GL.BindTexture(TextureTarget.TextureCubeMap, cubemap.id); } // enable texture int texLoc = GL.GetUniformLocation(shader.programID, "pixels"); GL.Uniform1(texLoc, 0); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texture.id); GL.Uniform1(GL.GetUniformLocation(shader.programID, "intensity"), intensity); // enable position, normal and uv attributes GL.EnableVertexAttribArray(shader.attribute_vpos); GL.EnableVertexAttribArray(shader.attribute_vnrm); GL.EnableVertexAttribArray(shader.attribute_vuvs); GL.EnableVertexAttribArray(shader.attribute_vtan); GL.EnableVertexAttribArray(shader.attribute_vbit); // bind interleaved vertex data GL.EnableClientState(ArrayCap.VertexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); GL.InterleavedArrays(InterleavedArrayFormat.T2fN3fV3f, Marshal.SizeOf(typeof(ObjVertex)), IntPtr.Zero); // link vertex attributes to shader parameters GL.VertexAttribPointer(shader.attribute_vuvs, 2, VertexAttribPointerType.Float, false, 56, 0); GL.VertexAttribPointer(shader.attribute_vnrm, 3, VertexAttribPointerType.Float, true, 56, 2 * 4); GL.VertexAttribPointer(shader.attribute_vpos, 3, VertexAttribPointerType.Float, false, 56, 5 * 4); GL.VertexAttribPointer(shader.attribute_vtan, 3, VertexAttribPointerType.Float, false, 56, 8 * 4); GL.VertexAttribPointer(shader.attribute_vbit, 3, VertexAttribPointerType.Float, false, 56, 11 * 4); // bind triangle index data and render GL.BindBuffer(BufferTarget.ElementArrayBuffer, triangleBufferId); GL.DrawArrays(PrimitiveType.Triangles, 0, triangles.Length * 3); // bind quad index data and render if (quads.Length > 0) { GL.BindBuffer(BufferTarget.ElementArrayBuffer, quadBufferId); GL.DrawArrays(PrimitiveType.Quads, 0, quads.Length * 4); } // restore previous OpenGL state GL.UseProgram(0); GL.PopClientAttrib(); }