Jump to content
  • Advertisement

Search the Community

Showing results for tags 'OpenGL'.

The search index is currently processing. Current results may not be complete.


More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Categories

  • Audio
    • Music and Sound FX
  • Business
    • Business and Law
    • Career Development
    • Production and Management
  • Game Design
    • Game Design and Theory
    • Writing for Games
    • UX for Games
  • Industry
    • Interviews
    • Event Coverage
  • Programming
    • Artificial Intelligence
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Engines and Middleware
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
  • Archive

Categories

  • Audio
  • Visual Arts
  • Programming
  • Writing

Categories

  • Game Dev Loadout
  • Game Dev Unchained

Categories

  • Game Developers Conference
    • GDC 2017
    • GDC 2018
  • Power-Up Digital Games Conference
    • PDGC I: Words of Wisdom
    • PDGC II: The Devs Strike Back
    • PDGC III: Syntax Error

Forums

  • Audio
    • Music and Sound FX
  • Business
    • Games Career Development
    • Production and Management
    • Games Business and Law
  • Game Design
    • Game Design and Theory
    • Writing for Games
  • Programming
    • Artificial Intelligence
    • Engines and Middleware
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
    • 2D and 3D Art
    • Art Critique and Feedback
  • Community
    • GameDev Challenges
    • GDNet+ Member Forum
    • GDNet Lounge
    • GDNet Comments, Suggestions, and Ideas
    • Coding Horrors
    • Your Announcements
    • Hobby Project Classifieds
    • Indie Showcase
    • Article Writing
  • Affiliates
    • NeHe Productions
    • AngelCode
  • Topical
    • Virtual and Augmented Reality
    • News
  • Workshops
    • C# Workshop
    • CPP Workshop
    • Freehand Drawing Workshop
    • Hands-On Interactive Game Development
    • SICP Workshop
    • XNA 4.0 Workshop
  • Archive
    • Topical
    • Affiliates
    • Contests
    • Technical
  • GameDev Challenges's Topics
  • For Beginners's Forum
  • Unreal Engine Users's Unreal Engine Group Forum
  • Unity Developers's Forum
  • Unity Developers's Asset Share

Calendars

  • Community Calendar
  • Games Industry Events
  • Game Jams
  • GameDev Challenges's Schedule

Blogs

There are no results to display.

There are no results to display.

Product Groups

  • Advertisements
  • GameDev Gear

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


About Me


Website


Role


Twitter


Github


Twitch


Steam

Found 13 results

  1. phil67rpg

    OpenGL tic tac toe

    well I am working on a simpler game called tic tac toe, my question is how do I get the mouse click to draw an X on the board. when I click the mouse nothing happens. #include <freeglut.h> #include <iostream> using namespace std; void drawBoard() { glPushMatrix(); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_LINE_STRIP); glVertex3f(-18.75f, 6.25f, 0.0f); glVertex3f(18.75f, 6.25f, 0.0f); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(-18.75f, -6.25f, 0.0f); glVertex3f(18.75f, -6.25f, 0.0f); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(-6.25f, 18.75f, 0.0f); glVertex3f(-6.25f, -18.75f, 0.0f); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(6.25f, 18.75f, 0.0f); glVertex3f(6.25f, -18.75f, 0.0f); glEnd(); glPopMatrix(); } void drawText() { glColor3f(0.0f, 1.0f, 1.0f); glRasterPos2f(10.0f, 10.0f); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'X'); } void renderScene() { glClear(GL_COLOR_BUFFER_BIT); drawBoard(); glutSwapBuffers(); } void ChangeSize(GLsizei w, GLsizei h) { GLfloat aspectRatio; if (h == 0) h = 1; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); aspectRatio = (GLfloat)w / (GLfloat)h; if (w <= h) glOrtho(-100.0, 100.0, -100.0 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0); else glOrtho(-100.0*aspectRatio, 100.0*aspectRatio, -100.0, 100.0, 1.0, -1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void mouseClicks(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { drawText(); } } int main(int argc, char**argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowPosition(600, 400); glutInitWindowSize(800, 600); glutCreateWindow("Tic Tac Toe"); glutDisplayFunc(renderScene); glutReshapeFunc(ChangeSize); glutMouseFunc(mouseClicks); glutMainLoop(); }
  2. Hi, I'd like to get & set the OpenGL View Port Matrix but it doesn't work I'm using the "GL_VIEWPORT" parameter any ideas?
  3. Is there a way to set up the projection matrix (in OpenGL) so that the vanishing point is not at the center of the screen? Let me explain what I mean in more detail. Imagine that I am rendering a 3D scene with a standard perspective projection matrix to a 1000x1000 window. There is no camera matrix, so planes of constant z are parallel to the screen, and objects move toward the center of the window as their z coordinate approaches infinity. Now, I want to only render the bottom half of this window. Planes of constant z are still parallel to the screen, but now objects move to a point at the top of the window as their z approaches infinity.
  4. I implemented rotation model for earth. It orbits around me instead it rotates on its center. Some tutorial explains ordering for model is: rotation * translation. I am figuring out but can't find solution yet. It did not work with code because it orbits around me (surface always face me around) instead of rotating its center. prm.dmProj = glm::perspective(cam->getFOV(), double(gl.getWidth()) / double(gl.getHeight()), DIST_NEAR, DIST_FAR); prm.dmView = glm::transpose(glm::toMat4(prm.crot)); // prm.obj.orot = glm::toMat4(body.getRotation(prm.now)); prm.obj.orot = glm::rotate(mat4d_t(1.0), glm::radians(90.0), vec3d_t(0.0, 1.0, 0.0)); prm.dmWorld = prm.dmView * glm::translate(glm::transpose(prm.obj.orot), prm.obj.cpos); prm.mvp = mat4f_t(prm.dmProj * prm.dmWorld); I tried to split dmWorld into dmView and dmModel but it still results the same but earth looks smaller. prm.dmProj = glm::perspective(cam->getFOV(), double(gl.getWidth()) / double(gl.getHeight()), DIST_NEAR, DIST_FAR); prm.dmView = glm::transpose(glm::toMat4(prm.crot)); // prm.obj.orot = glm::toMat4(body.getRotation(prm.now)); prm.obj.orot = glm::rotate(mat4d_t(1.0), glm::radians(90.0), vec3d_t(0.0, 1.0, 0.0)); prm.dmModel = glm::translate(glm::transpose(prm.obj.orot), prm.obj.cpos); prm.mvp = mat4f_t(prm.dmProj * prm.dmView * prm.dmModel); When I tried to rotate full 360 degrees (on Y axis) several times for flat spinning test but... Everything gradually became flat line when rotates away from earth. More spinning = more distorted like flat line effect. After more several times, it became completely horizontal flat line. I tried to rotate on its X axis and it became vertical flat line against earth on right side. I tried barrel roll several times and everything became vertical flat circle (line) on my side of me. Does anyone know any similar problem? // Free travel mode // Update current position and orientation (local reference frame) // Applying angular velocity to rotation quaternion in local space. // // dq/dt = q * w * t/2 // w = (0, x, y, z) // lqrot += lqrot * wv * (dt / 2.0f); lpos -= lqrot * tv * dt; That is my controls from keyboard for angular and travel velocity where prm.crot = lqrot and prm.cpos = lpos, wv = angular velocity and tv = travel velocity (6 DoF controls)
  5. phil67rpg

    move ship

    I got my ship to rotate about arbitrary axis. my next step is to get it to move up and down depending on which way it is facing. I got it to move up and down but not in the way it is facing after it is rotated. void drawShip() { glPushMatrix(); glColor3f(1.0f, 0.0f, 0.0f); glLoadIdentity(); glTranslatef(50.0f, 0.0f+thrust, 0.0f); glRotatef(shipAngle, 0.0f, 0.0f, 1.0f); glBegin(GL_LINE_LOOP); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-5.0f, -5.0f, 0.0f); glVertex3f(0.0f, 10.0f, 0.0f); glVertex3f(5.0f, -5.0f, 0.0f); glEnd(); glPopMatrix(); }
  6. I will rewrite examples from this book WebGL Programming Guide to OpenGL 3.1. I will commit here on GitHub. I will translate examples on C#/OpenTK and TypeScript. I hope it will be useful for someone. I work for you. Please, support me: https://www.paypal.me/8observer8 Original Examples on JSFiddle Playground I moved all JavaScript examples from the book on JSFiddle: TypeScript Example on Plunker Playground I will add TypeScript Playground example in this list: How to Build TypeScript Example locally I will inform you when I add new example in C# and TypeScript.
  7. In next time I will show how to draw graphs of functions using modern OpenGL 3.1 with text. Sin_WinFormsOpenGL11CSharp.zip
  8. What if you need to draw text with simple graphics? For example, you have a task in your college to draw plots with some text using C++. You can still use deprecated/legacy OpenGL 1.1 and FreeGLUT. This example shows how to draw a text using FreeGLUT and deprecated/legacy OpenGL 1.5. And this example shows how to set up FreeGLUT in Visual Studio 2015. Text_FreeGlutOpenGL15Cpp.zip - Just download and run this solution in your version of Visual Studio. But do not forget to set "Platform Toolset" to "Your Version Of VS" in the project settings. See screenshot: If you want to set up FreeGLUT from scratch then download the "Libs" folders and set settings by yourself: Libs: Libs_FreeGlutOpenGL15.zip Settings: main.cpp
  9. VS2015: Sin_FreeGlutOpenGL11Cpp.zip (Everything has been set up already. Just download, select your version of VS in "General/Platform Toolset" in the project settings and run) Release: Sin_x86_EXE.zip Tools: Visual Studio 2015 "Win32 Console Application" FreeGLUT deprecated/legacy OpenGL 1.1 (docs: https://docs.microsoft.com/en-us/windows/desktop/opengl/opengl) Settings main.cpp
  10. This example just create a window and clear a canvas with color. Tools: VS2015, GLFW, OpenGL, C++. All libraries are included in the project. You can just download and run it. But you need to set your Visual Studio version in the project settings, Platform Toolset, see the screenshot below: Visual Studio Project: EmptyWindow_GlfwOpenGL31Cpp.zip main.cpp DRAKON-flowchart Sandbox If you do not know what is DRAKON-flowchart, you can watch this short video that I found in Youtube:
  11. In this Blog Entry I will translate examples from the tutorial Math for Game Developers from C++ to C# and TypeScript. I will add unit tests to the examples. I use: NUnit and NSubstitute for C# Jasmine for TypeScript C# and TypeScript are very similar. TS has: properties and generics. TS has keywords like C#: interface, abstract (for classes and methods). Author of C# and TS is Anders Hejlsberg 001. Character Movement (Points and Vectors) TypeScript TypeScript Demo: Click to run the example in Sandbox TypeScript Source Code: 001_PointsAndVectors C# C# Source Code: 001_PointsAndVectors
  12. Zemlaynin

    DevBlog #34

    Hello dears! It's been more than a month since the last diary. Frankly, it was a hard month for me in terms of development. Most of the time was devoted to the construction of the structure of society, the interaction of the population, the transition from one stratum to another. It took a lot of time to build economic ties. At one point, I decided to throw some scheme of our project, which allowed a little systematize all my thoughts and see the degree of implementation of certain tasks. Who is interested to assess the scale, you can see the resulting scheme: https://mm.tt/1209438933?t=mBE5c38pFT In between work on the gameplay part of the thing with the mountains, and returned them again to the ice caps: Alexey made new optimized palm trees-270-350 triangles on one subtile Great result with such a landfill! I also managed to experiment with the user interface and made this sketch: And more or less brought him to mind: I prefer this interface concept. Before the interface was very heavy and it looked as if looking into the tube. But now clearly lacks any curls Then I experimented with transparent objects, we had an idea to implement such fields initially: But, in the end, we decided to focus on such an option: In a long box I had the task of building walls around our settlements. Alexey made models, already as half a year ago, but his hands did not reach them. I had to dust them off.: The problem was not trivial, it was necessary to carry out a lot of calculations to determine the need for a wall with an entrance, here is an example of such a case: And here is masterpiece deciduous trees on 800 triangles on subtil: Then I broke everything.: There came a ten-day period of optimization and rethinking of everything that was done on the render. And all this is due to the fact that I came up with one idea, how else to optimize our render. Unfortunately, I was not able to implement all my ideas, so to speak, theoretical calculations went against the practical results. But the result was still impressive. The first thing I want to mention — we now have 16 subtiles on the tile, and was 9. Before mesh subflow was 3x3, 4x4 now. 484 tops against 1089 now. The number of vertices per tile has increased 2.25 times, and the performance has remained at the same level and the map generation is now faster, as the most time-consuming process of normals calculation is now faster. This happened due to the fact that I removed from the calculations all the numbers with a period after the decimal point, such as 1\3 and 2\3. Now all calculations on both CPU side so GPU are faster. This is especially noticeable on large and huge worlds: The increase in the number of vertices and subflow allowed to implement more realistic mountains: Now our render takes out 32 million polygons!!! True to my GTX660 IS only 10FPS Alteration of the whole world on the structure of 4x4 sub-tails resulted in alteration of generation of mountains, hills, rivers, scaling of all models. Which together took those 10 days. - Also, the following points have been implemented about which I would like to briefly tell: - Normalmaps for the whole of terrane. - An error with the calculation of normalmap. - Corrected an interface error on the containers voznikayuschaya when the MouseEntered MouseExited events. - Go to / from full screen mode by pressing F11. A lot of time I took one bug: 5 hours I killed on his the search Thank you for your attention!
  13. This article uses material originally posted on Diligent Graphics web site. Introduction Graphics APIs have come a long way from small set of basic commands allowing limited control of configurable stages of early 3D accelerators to very low-level programming interfaces exposing almost every aspect of the underlying graphics hardware. Next-generation APIs, Direct3D12 by Microsoft and Vulkan by Khronos are relatively new and have only started getting widespread adoption and support from hardware vendors, while Direct3D11 and OpenGL are still considered industry standard. New APIs can provide substantial performance and functional improvements, but may not be supported by older hardware. An application targeting wide range of platforms needs to support Direct3D11 and OpenGL. New APIs will not give any advantage when used with old paradigms. It is totally possible to add Direct3D12 support to an existing renderer by implementing Direct3D11 interface through Direct3D12, but this will give zero benefits. Instead, new approaches and rendering architectures that leverage flexibility provided by the next-generation APIs are expected to be developed. There are at least four APIs (Direct3D11, Direct3D12, OpenGL/GLES, Vulkan, plus Apple's Metal for iOS and osX platforms) that a cross-platform 3D application may need to support. Writing separate code paths for all APIs is clearly not an option for any real-world application and the need for a cross-platform graphics abstraction layer is evident. The following is the list of requirements that I believe such layer needs to satisfy: Lightweight abstractions: the API should be as close to the underlying native APIs as possible to allow an application leverage all available low-level functionality. In many cases this requirement is difficult to achieve because specific features exposed by different APIs may vary considerably. Low performance overhead: the abstraction layer needs to be efficient from performance point of view. If it introduces considerable amount of overhead, there is no point in using it. Convenience: the API needs to be convenient to use. It needs to assist developers in achieving their goals not limiting their control of the graphics hardware. Multithreading: ability to efficiently parallelize work is in the core of Direct3D12 and Vulkan and one of the main selling points of the new APIs. Support for multithreading in a cross-platform layer is a must. Extensibility: no matter how well the API is designed, it still introduces some level of abstraction. In some cases the most efficient way to implement certain functionality is to directly use native API. The abstraction layer needs to provide seamless interoperability with the underlying native APIs to provide a way for the app to add features that may be missing. Diligent Engine is designed to solve these problems. Its main goal is to take advantages of the next-generation APIs such as Direct3D12 and Vulkan, but at the same time provide support for older platforms via Direct3D11, OpenGL and OpenGLES. Diligent Engine exposes common C++ front-end for all supported platforms and provides interoperability with underlying native APIs. It also supports integration with Unity and is designed to be used as graphics subsystem in a standalone game engine, Unity native plugin or any other 3D application. Full source code is available for download at GitHub and is free to use. Overview Diligent Engine API takes some features from Direct3D11 and Direct3D12 as well as introduces new concepts to hide certain platform-specific details and make the system easy to use. It contains the following main components: Render device (IRenderDevice interface) is responsible for creating all other objects (textures, buffers, shaders, pipeline states, etc.). Device context (IDeviceContext interface) is the main interface for recording rendering commands. Similar to Direct3D11, there are immediate context and deferred contexts (which in Direct3D11 implementation map directly to the corresponding context types). Immediate context combines command queue and command list recording functionality. It records commands and submits the command list for execution when it contains sufficient number of commands. Deferred contexts are designed to only record command lists that can be submitted for execution through the immediate context. An alternative way to design the API would be to expose command queue and command lists directly. This approach however does not map well to Direct3D11 and OpenGL. Besides, some functionality (such as dynamic descriptor allocation) can be much more efficiently implemented when it is known that a command list is recorded by a certain deferred context from some thread. The approach taken in the engine does not limit scalability as the application is expected to create one deferred context per thread, and internally every deferred context records a command list in lock-free fashion. At the same time this approach maps well to older APIs. In current implementation, only one immediate context that uses default graphics command queue is created. To support multiple GPUs or multiple command queue types (compute, copy, etc.), it is natural to have one immediate contexts per queue. Cross-context synchronization utilities will be necessary. Swap Chain (ISwapChain interface). Swap chain interface represents a chain of back buffers and is responsible for showing the final rendered image on the screen. Render device, device contexts and swap chain are created during the engine initialization. Resources (ITexture and IBuffer interfaces). There are two types of resources - textures and buffers. There are many different texture types (2D textures, 3D textures, texture array, cubmepas, etc.) that can all be represented by ITexture interface. Resources Views (ITextureView and IBufferView interfaces). While textures and buffers are mere data containers, texture views and buffer views describe how the data should be interpreted. For instance, a 2D texture can be used as a render target for rendering commands or as a shader resource. Pipeline State (IPipelineState interface). GPU pipeline contains many configurable stages (depth-stencil, rasterizer and blend states, different shader stage, etc.). Direct3D11 uses coarse-grain objects to set all stage parameters at once (for instance, a rasterizer object encompasses all rasterizer attributes), while OpenGL contains myriad functions to fine-grain control every individual attribute of every stage. Both methods do not map very well to modern graphics hardware that combines all states into one monolithic state under the hood. Direct3D12 directly exposes pipeline state object in the API, and Diligent Engine uses the same approach. Shader Resource Binding (IShaderResourceBinding interface). Shaders are programs that run on the GPU. Shaders may access various resources (textures and buffers), and setting correspondence between shader variables and actual resources is called resource binding. Resource binding implementation varies considerably between different API. Diligent Engine introduces a new object called shader resource binding that encompasses all resources needed by all shaders in a certain pipeline state. API Basics Creating Resources Device resources are created by the render device. The two main resource types are buffers, which represent linear memory, and textures, which use memory layouts optimized for fast filtering. Graphics APIs usually have a native object that represents linear buffer. Diligent Engine uses IBuffer interface as an abstraction for a native buffer. To create a buffer, one needs to populate BufferDesc structure and call IRenderDevice::CreateBuffer() method as in the following example: BufferDesc BuffDesc; BufferDesc.Name = "Uniform buffer"; BuffDesc.BindFlags = BIND_UNIFORM_BUFFER; BuffDesc.Usage = USAGE_DYNAMIC; BuffDesc.uiSizeInBytes = sizeof(ShaderConstants); BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE; m_pDevice->CreateBuffer( BuffDesc, BufferData(), &m_pConstantBuffer ); While there is usually just one buffer object, different APIs use very different approaches to represent textures. For instance, in Direct3D11, there are ID3D11Texture1D, ID3D11Texture2D, and ID3D11Texture3D objects. In OpenGL, there is individual object for every texture dimension (1D, 2D, 3D, Cube), which may be a texture array, which may also be multisampled (i.e. GL_TEXTURE_2D_MULTISAMPLE_ARRAY). As a result there are nine different GL texture types that Diligent Engine may create under the hood. In Direct3D12, there is only one resource interface. Diligent Engine hides all these details in ITexture interface. There is only one IRenderDevice::CreateTexture() method that is capable of creating all texture types. Dimension, format, array size and all other parameters are specified by the members of the TextureDesc structure: TextureDesc TexDesc; TexDesc.Name = "My texture 2D"; TexDesc.Type = TEXTURE_TYPE_2D; TexDesc.Width = 1024; TexDesc.Height = 1024; TexDesc.Format = TEX_FORMAT_RGBA8_UNORM; TexDesc.Usage = USAGE_DEFAULT; TexDesc.BindFlags = BIND_SHADER_RESOURCE | BIND_RENDER_TARGET | BIND_UNORDERED_ACCESS; TexDesc.Name = "Sample 2D Texture"; m_pRenderDevice->CreateTexture( TexDesc, TextureData(), &m_pTestTex ); If native API supports multithreaded resource creation, textures and buffers can be created by multiple threads simultaneously. Interoperability with native API provides access to the native buffer/texture objects and also allows creating Diligent Engine objects from native handles. It allows applications seamlessly integrate native API-specific code with Diligent Engine. Next-generation APIs allow fine level-control over how resources are allocated. Diligent Engine does not currently expose this functionality, but it can be added by implementing IResourceAllocator interface that encapsulates specifics of resource allocation and providing this interface to CreateBuffer() or CreateTexture() methods. If null is provided, default allocator should be used. Initializing the Pipeline State As it was mentioned earlier, Diligent Engine follows next-gen APIs to configure the graphics/compute pipeline. One big Pipelines State Object (PSO) encompasses all required states (all shader stages, input layout description, depth stencil, rasterizer and blend state descriptions etc.). This approach maps directly to Direct3D12/Vulkan, but is also beneficial for older APIs as it eliminates pipeline misconfiguration errors. With many individual calls tweaking various GPU pipeline settings it is very easy to forget to set one of the states or assume the stage is already properly configured when in fact it is not. Using pipeline state object helps avoid these problems as all stages are configured at once. Creating Shaders While in earlier APIs shaders were bound separately, in the next-generation APIs as well as in Diligent Engine shaders are part of the pipeline state object. The biggest challenge when authoring shaders is that Direct3D and OpenGL/Vulkan use different shader languages (while Apple uses yet another language in their Metal API). Maintaining two versions of every shader is not an option for real applications and Diligent Engine implements shader source code converter that allows shaders authored in HLSL to be translated to GLSL. To create a shader, one needs to populate ShaderCreationAttribs structure. SourceLanguage member of this structure tells the system which language the shader is authored in: SHADER_SOURCE_LANGUAGE_DEFAULT - The shader source language matches the underlying graphics API: HLSL for Direct3D11/Direct3D12 mode, and GLSL for OpenGL and OpenGLES modes. SHADER_SOURCE_LANGUAGE_HLSL - The shader source is in HLSL. For OpenGL and OpenGLES modes, the source code will be converted to GLSL. SHADER_SOURCE_LANGUAGE_GLSL - The shader source is in GLSL. There is currently no GLSL to HLSL converter, so this value should only be used for OpenGL and OpenGLES modes. There are two ways to provide the shader source code. The first way is to use Source member. The second way is to provide a file path in FilePath member. Since the engine is entirely decoupled from the platform and the host file system is platform-dependent, the structure exposes pShaderSourceStreamFactory member that is intended to provide the engine access to the file system. If FilePath is provided, shader source factory must also be provided. If the shader source contains any #include directives, the source stream factory will also be used to load these files. The engine provides default implementation for every supported platform that should be sufficient in most cases. Custom implementation can be provided when needed. When sampling a texture in a shader, the texture sampler was traditionally specified as separate object that was bound to the pipeline at run time or set as part of the texture object itself. However, in most cases it is known beforehand what kind of sampler will be used in the shader. Next-generation APIs expose new type of sampler called static sampler that can be initialized directly in the pipeline state. Diligent Engine exposes this functionality: when creating a shader, textures can be assigned static samplers. If static sampler is assigned, it will always be used instead of the one initialized in the texture shader resource view. To initialize static samplers, prepare an array of StaticSamplerDesc structures and initialize StaticSamplers and NumStaticSamplers members. Static samplers are more efficient and it is highly recommended to use them whenever possible. On older APIs, static samplers are emulated via generic sampler objects. The following is an example of shader initialization: ShaderCreationAttribs Attrs; Attrs.Desc.Name = "MyPixelShader"; Attrs.FilePath = "MyShaderFile.fx"; Attrs.SearchDirectories = "shaders;shaders\\inc;"; Attrs.EntryPoint = "MyPixelShader"; Attrs.Desc.ShaderType = SHADER_TYPE_PIXEL; Attrs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; BasicShaderSourceStreamFactory BasicSSSFactory(Attrs.SearchDirectories); Attrs.pShaderSourceStreamFactory = &BasicSSSFactory; ShaderVariableDesc ShaderVars[] = { {"g_StaticTexture", SHADER_VARIABLE_TYPE_STATIC}, {"g_MutableTexture", SHADER_VARIABLE_TYPE_MUTABLE}, {"g_DynamicTexture", SHADER_VARIABLE_TYPE_DYNAMIC} }; Attrs.Desc.VariableDesc = ShaderVars; Attrs.Desc.NumVariables = _countof(ShaderVars); Attrs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC; StaticSamplerDesc StaticSampler; StaticSampler.Desc.MinFilter = FILTER_TYPE_LINEAR; StaticSampler.Desc.MagFilter = FILTER_TYPE_LINEAR; StaticSampler.Desc.MipFilter = FILTER_TYPE_LINEAR; StaticSampler.TextureName = "g_MutableTexture"; Attrs.Desc.NumStaticSamplers = 1; Attrs.Desc.StaticSamplers = &StaticSampler; ShaderMacroHelper Macros; Macros.AddShaderMacro("USE_SHADOWS", 1); Macros.AddShaderMacro("NUM_SHADOW_SAMPLES", 4); Macros.Finalize(); Attrs.Macros = Macros; RefCntAutoPtr<IShader> pShader; m_pDevice->CreateShader( Attrs, &pShader ); Creating the Pipeline State Object After all required shaders are created, the rest of the fields of the PipelineStateDesc structure provide depth-stencil, rasterizer, and blend state descriptions, the number and format of render targets, input layout format, etc. For instance, rasterizer state can be described as follows: PipelineStateDesc PSODesc; RasterizerStateDesc &RasterizerDesc = PSODesc.GraphicsPipeline.RasterizerDesc; RasterizerDesc.FillMode = FILL_MODE_SOLID; RasterizerDesc.CullMode = CULL_MODE_NONE; RasterizerDesc.FrontCounterClockwise = True; RasterizerDesc.ScissorEnable = True; RasterizerDesc.AntialiasedLineEnable = False; Depth-stencil and blend states are defined in a similar fashion. Another important thing that pipeline state object encompasses is the input layout description that defines how inputs to the vertex shader, which is the very first shader stage, should be read from the memory. Input layout may define several vertex streams that contain values of different formats and sizes: // Define input layout InputLayoutDesc &Layout = PSODesc.GraphicsPipeline.InputLayout; LayoutElement TextLayoutElems[] = { LayoutElement( 0, 0, 3, VT_FLOAT32, False ), LayoutElement( 1, 0, 4, VT_UINT8, True ), LayoutElement( 2, 0, 2, VT_FLOAT32, False ), }; Layout.LayoutElements = TextLayoutElems; Layout.NumElements = _countof( TextLayoutElems ); Finally, pipeline state defines primitive topology type. When all required members are initialized, a pipeline state object can be created by IRenderDevice::CreatePipelineState() method: // Define shader and primitive topology PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; PSODesc.GraphicsPipeline.pVS = pVertexShader; PSODesc.GraphicsPipeline.pPS = pPixelShader; PSODesc.Name = "My pipeline state"; m_pDev->CreatePipelineState(PSODesc, &m_pPSO); When PSO object is bound to the pipeline, the engine invokes all API-specific commands to set all states specified by the object. In case of Direct3D12 this maps directly to setting the D3D12 PSO object. In case of Direct3D11, this involves setting individual state objects (such as rasterizer and blend states), shaders, input layout etc. In case of OpenGL, this requires a number of fine-grain state tweaking calls. Diligent Engine keeps track of currently bound states and only calls functions to update these states that have actually changed. Binding Shader Resources Direct3D11 and OpenGL utilize fine-grain resource binding models, where an application binds individual buffers and textures to certain shader or program resource binding slots. Direct3D12 uses a very different approach, where resource descriptors are grouped into tables, and an application can bind all resources in the table at once by setting the table in the command list. Resource binding model in Diligent Engine is designed to leverage this new method. It introduces a new object called shader resource binding that encapsulates all resource bindings required for all shaders in a certain pipeline state. It also introduces the classification of shader variables based on the frequency of expected change that helps the engine group them into tables under the hood: Static variables (SHADER_VARIABLE_TYPE_STATIC) are variables that are expected to be set only once. They may not be changed once a resource is bound to the variable. Such variables are intended to hold global constants such as camera attributes or global light attributes constant buffers. Mutable variables (SHADER_VARIABLE_TYPE_MUTABLE) define resources that are expected to change on a per-material frequency. Examples may include diffuse textures, normal maps etc. Dynamic variables (SHADER_VARIABLE_TYPE_DYNAMIC) are expected to change frequently and randomly. Shader variable type must be specified during shader creation by populating an array of ShaderVariableDesc structures and initializing ShaderCreationAttribs::Desc::VariableDesc and ShaderCreationAttribs::Desc::NumVariables members (see example of shader creation above). Static variables cannot be changed once a resource is bound to the variable. They are bound directly to the shader object. For instance, a shadow map texture is not expected to change after it is created, so it can be bound directly to the shader: PixelShader->GetShaderVariable( "g_tex2DShadowMap" )->Set( pShadowMapSRV ); Mutable and dynamic variables are bound via a new Shader Resource Binding object (SRB) that is created by the pipeline state (IPipelineState::CreateShaderResourceBinding()): m_pPSO->CreateShaderResourceBinding(&m_pSRB); Note that an SRB is only compatible with the pipeline state it was created from. SRB object inherits all static bindings from shaders in the pipeline, but is not allowed to change them. Mutable resources can only be set once for every instance of a shader resource binding. Such resources are intended to define spe