/// <summary> /// Loads the model from file. /// </summary> /// <param name="filePath">The file path.</param> /// <returns></returns> public override Model LoadModel(string filePath) { Model result = null; ObjLoader loader = new ObjLoader(); MeshData modelData = loader.LoadFile(filePath); if (modelData != null) { result = new Model() { Data = loader.LoadFile(filePath) }; } return result; }
private void AddBuffer(Model model, OpenGLEventArgs args, int bufferNum) { OpenGL gl = args.OpenGL; gl.Enable(OpenGL.GL_DEPTH_TEST); gl.ShadeModel(OpenGL.GL_SMOOTH); gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_NICEST); vertices.Add(new float[model.Data.Vertices.Count() * 3]); colors.Add(new byte[model.Data.Vertices.Count() * 3]); indices.Add(new uint[model.Data.Tris.Count() * 3]); normals.Add(new float[model.Data.Tris.Count() * 9]); texCoords.Add(new float[model.Data.Tris.Count() * 6]); int i = 0; foreach (var vertice in model.Data.Vertices) { vertices.ElementAt(bufferNum)[i] = (float)vertice.X; vertices.ElementAt(bufferNum)[i + 1] = (float)vertice.Y; vertices.ElementAt(bufferNum)[i + 2] = (float)vertice.Z; if (bufferNum < 4) { colors.ElementAt(bufferNum)[i] = 255; colors.ElementAt(bufferNum)[i + 1] = 204; colors.ElementAt(bufferNum)[i + 2] = 51; } else { colors.ElementAt(bufferNum)[i] = 177; colors.ElementAt(bufferNum)[i + 1] = 177; colors.ElementAt(bufferNum)[i + 2] = 139; } i += 3; } i = 0; int j = 0; foreach (var tri in model.Data.Tris) { //normals normals.ElementAt(bufferNum)[i] = (float)model.Data.Normals.ElementAt(tri.P1.Normal).X; normals.ElementAt(bufferNum)[i + 1] = (float)model.Data.Normals.ElementAt(tri.P1.Normal).Y; normals.ElementAt(bufferNum)[i + 2] = (float)model.Data.Normals.ElementAt(tri.P1.Normal).Z; //textures texCoords.ElementAt(bufferNum)[j] = (float)model.Data.TexCoords.ElementAt(tri.P1.TexCoord).X; texCoords.ElementAt(bufferNum)[j + 1] = (float)model.Data.TexCoords.ElementAt(tri.P1.TexCoord).Y; i += 3; j += 2; //normals normals.ElementAt(bufferNum)[i] = (float)model.Data.Normals.ElementAt(tri.P2.Normal).X; normals.ElementAt(bufferNum)[i + 1] = (float)model.Data.Normals.ElementAt(tri.P2.Normal).Y; normals.ElementAt(bufferNum)[i + 2] = (float)model.Data.Normals.ElementAt(tri.P2.Normal).Z; //textures texCoords.ElementAt(bufferNum)[j] = (float)model.Data.TexCoords.ElementAt(tri.P2.TexCoord).X; texCoords.ElementAt(bufferNum)[j + 1] = (float)model.Data.TexCoords.ElementAt(tri.P2.TexCoord).Y; i += 3; j += 2; //normals normals.ElementAt(bufferNum)[i] = (float)model.Data.Normals.ElementAt(tri.P3.Normal).X; normals.ElementAt(bufferNum)[i + 1] = (float)model.Data.Normals.ElementAt(tri.P3.Normal).Y; normals.ElementAt(bufferNum)[i + 2] = (float)model.Data.Normals.ElementAt(tri.P3.Normal).Z; //textures texCoords.ElementAt(bufferNum)[j] = (float)model.Data.TexCoords.ElementAt(tri.P3.TexCoord).X; texCoords.ElementAt(bufferNum)[j + 1] = (float)model.Data.TexCoords.ElementAt(tri.P3.TexCoord).Y; i += 3; j += 2; } i = 0; foreach (var ind in model.Data.Tris) { indices.ElementAt(bufferNum)[i] = (uint)ind.P1.Vertex; indices.ElementAt(bufferNum)[i + 1] = (uint)ind.P2.Vertex; indices.ElementAt(bufferNum)[i + 2] = (uint)ind.P3.Vertex; i += 3; } gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, vertexBufferObjectIds[bufferNum]); unsafe { fixed (float* verts = vertices.ElementAt(bufferNum)) { var ptr = new IntPtr(verts); int size = vertices.ElementAt(bufferNum).Length * sizeof(float); IntPtr nullPointer = new IntPtr(); gl.BufferData(OpenGL.GL_ARRAY_BUFFER, size, nullPointer, OpenGL.GL_STREAM_DRAW); gl.BufferSubData(OpenGL.GL_ARRAY_BUFFER, 0, size, ptr); } } gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, colorBufferObjectIds[bufferNum]); unsafe { fixed (byte* color = colors.ElementAt(bufferNum)) { var ptr = new IntPtr(color); int size = colors.ElementAt(bufferNum).Length * sizeof(byte); IntPtr nullPointer = new IntPtr(); gl.BufferData(OpenGL.GL_ARRAY_BUFFER, size, nullPointer, OpenGL.GL_STREAM_DRAW); gl.BufferSubData(OpenGL.GL_ARRAY_BUFFER, 0, size, ptr); } } gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, normalBufferObjectIds[bufferNum]); unsafe { fixed (float* normal = normals.ElementAt(bufferNum)) { var ptr = new IntPtr(normal); int size = normals.ElementAt(bufferNum).Length * sizeof(float); IntPtr nullPointer = new IntPtr(); gl.BufferData(OpenGL.GL_ARRAY_BUFFER, size, nullPointer, OpenGL.GL_STATIC_DRAW); gl.BufferSubData(OpenGL.GL_ARRAY_BUFFER, 0, size, ptr); } } gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, texCoordsBufferObjectIds[bufferNum]); unsafe { fixed (float* texCoord = texCoords.ElementAt(bufferNum)) { var ptr = new IntPtr(texCoord); int size = texCoords.ElementAt(bufferNum).Length * sizeof(float); IntPtr nullPointer = new IntPtr(); gl.BufferData(OpenGL.GL_ARRAY_BUFFER, size, nullPointer, OpenGL.GL_STATIC_DRAW); gl.BufferSubData(OpenGL.GL_ARRAY_BUFFER, 0, size, ptr); } } }
/// <summary> /// Handles the OpenGLInitialized event of the OpenGLControl control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="args">The <see cref="SharpGL.SceneGraph.OpenGLEventArgs"/> instance containing the event data.</param> private void OpenGLControl_OpenGLInitialized(object sender, OpenGLEventArgs args) { ObjModelLoader modelLoader = new ObjModelLoader(); towerModel = modelLoader.LoadModel(@"..\..\Resources\Tower crane_tower.obj"); boomModel = modelLoader.LoadModel(@"..\..\Resources\Tower crane_boomWithCabin.obj"); hookModel = modelLoader.LoadModel(@"..\..\Resources\Tower crane_hook.obj"); platformModel = modelLoader.LoadModel(@"..\..\Resources\Tower crane_platform.obj"); groundModel = modelLoader.LoadModel(@"..\..\Resources\ground.obj"); skySphereModel = modelLoader.LoadModel(@"..\..\Resources\sphere.obj"); OpenGL gl = args.OpenGL; groundTexture.Create(gl, @"..\..\Resources\ground-texture04.jpg"); skyTexture.Create(gl, @"..\..\Resources\sky-tex3.jpg"); //Create the shadow map texture gl.GenTextures(1, shadowTex); gl.BindTexture(OpenGL.GL_TEXTURE_2D, shadowTex[0]); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER,OpenGL. GL_NEAREST); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_NEAREST); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP); gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_DEPTH_COMPONENT, 1366, 768, 0, OpenGL.GL_DEPTH_COMPONENT, OpenGL.GL_UNSIGNED_BYTE, null); //shadowTex = Shadow(args, (int)Application.Current.MainWindow.Height, (int)Application.Current.MainWindow.Width); //// Framebuffer Object (FBO) для рендера в него буфера глубины //uint[] depthFBO = new uint[1]; //// переменная для получения состояния FBO //uint fboStatus; //// создаем FBO для рендера глубины в текстуру //gl.GenFramebuffersEXT(1, depthFBO); //// делаем созданный FBO текущим //gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, depthFBO[0]); //// отключаем вывод цвета в текущий FBO //gl.DrawBuffer(OpenGL.GL_NONE); //gl.ReadBuffer(OpenGL.GL_NONE); //// указываем для текущего FBO текстуру, куда следует производить рендер глубины //gl.FramebufferTexture(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_DEPTH_ATTACHMENT_EXT, shadowTex[0], 0); //// проверим текущий FBO на корректность //if ((fboStatus = gl.CheckFramebufferStatusEXT(OpenGL.GL_FRAMEBUFFER_EXT)) != OpenGL.GL_FRAMEBUFFER_COMPLETE_EXT) //{ // return; //} //// возвращаем FBO по-умолчанию //gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, 0); //// установим активный FBO //gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, depthFBO[0]); //// размер вьюпорта должен совпадать с размером текстуры для хранения буфера глубины //gl.Viewport(0, 0, (int)Application.Current.MainWindow.Height, (int)Application.Current.MainWindow.Width); //// отключаем вывод цвета ////gl.ColorMask((byte)OpenGL.GL_FALSE, (byte)OpenGL.GL_FALSE, (byte)OpenGL.GL_FALSE, (byte)OpenGL.GL_FALSE); //// включаем вывод буфера глубины //gl.DepthMask((byte)OpenGL.GL_TRUE); //// очищаем буфер глубины перед его заполнением //gl.Clear(OpenGL.GL_DEPTH_BUFFER_BIT); //// отключаем отображение внешних граней объекта, оставляя внутренние //gl.CullFace(OpenGL.GL_FRONT); gl.Enable(OpenGL.GL_COLOR_MATERIAL); gl.Enable(OpenGL.GL_LIGHTING); gl.LightModel(OpenGL.GL_LIGHT_MODEL_TWO_SIDE, OpenGL.GL_TRUE); gl.Enable(OpenGL.GL_NORMALIZE); gl.Enable(OpenGL.GL_LIGHT1); gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_DIFFUSE, light1Diffuse); gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_POSITION, light1Position); gl.Enable(OpenGL.GL_TEXTURE_2D); gl.GenBuffers(modelsCount, vertexBufferObjectIds); gl.GenBuffers(modelsCount, normalBufferObjectIds); gl.GenBuffers(modelsCount, colorBufferObjectIds); gl.GenBuffers(modelsCount, texCoordsBufferObjectIds); AddBuffer(towerModel, args, 0); AddBuffer(boomModel, args, 1); AddBuffer(hookModel, args, 2); AddBuffer(platformModel, args, 3); AddBuffer(groundModel, args, 4); AddBuffer(skySphereModel, args, 5); }