DxDrawMaterialPrimitive3D: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
(Created page with "__NOTOC__ {{Client function}} This function draws a 3D primitive shape with material applied to it in the 3D world - rendered for one frame. This should be used in conjuncti...")
 
(Remove obsolete Requirements section)
 
(12 intermediate revisions by 7 users not shown)
Line 5: Line 5:
Power of two: 2px, 4px, 8px, 16px, 32px, 64px, 128px, 256px, 512px, 1024px...
Power of two: 2px, 4px, 8px, 16px, 32px, 64px, 128px, 256px, 512px, 1024px...


{{Legacy|legacy/dxDrawMaterialPrimitive3D}}
{{Updated feature/item|1.5.9|1.5.9|22465|
==Syntax==  
==Syntax==  
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
bool dxDrawMaterialPrimitive3D ( primitiveType pType, mixed material, bool postGUI, table vertice1 [, table vertice2, ...] )
bool dxDrawMaterialPrimitive3D ( primitiveType pType, mixed material, string stage, table vertex1 [, table vertex2, ...] )
</syntaxhighlight>
</syntaxhighlight>


Line 13: Line 16:
* '''pType:''' Type of primitive to be drawn.
* '''pType:''' Type of primitive to be drawn.
* '''image:''' Either a [[material]] element or a [[filepath]] of the image which is going to be drawn. (.dds images are also supported). Image files should ideally have dimensions that are a power of two, to prevent possible blurring. Use a texture created with [[dxCreateTexture]] to '''speed up drawing'''.
* '''image:''' Either a [[material]] element or a [[filepath]] of the image which is going to be drawn. (.dds images are also supported). Image files should ideally have dimensions that are a power of two, to prevent possible blurring. Use a texture created with [[dxCreateTexture]] to '''speed up drawing'''.
* '''postGUI:''' A bool representing whether the line should be drawn on top of or behind any ingame GUI (rendered by CEGUI).
* '''stage:''' A string representing a stage at which the actual drawcall should happen:
* '''vertices:''' Tables representing each primitive vertice, required amount of them is determined by primitive type.
** prefx - Primitives are rendered before the color correction. This stage makes primitives look natural to SA but colors could be distorted.
** postfx - Primitives are rendered after the color correction. This stage conveys a color from the function to a screen without distortions.
** postgui - Primitives are rendered after GUI. The primitives should be drawn on top of or behind any ingame GUI (rendered by CEGUI).
* '''vertices:''' Tables representing each primitive vertex, required amount of them is determined by primitive type.


==Allowed types==
==Allowed types==
[[Image:MTAsa_primitives.png|thumb|240px|Available primitive types.]]
[[Image:MTAsa_primitives.png|thumb|240px|Available primitive types.]]
More info on primitives may be found on [https://msdn.microsoft.com/en-us/library/windows/desktop/bb147291(v=vs.85).aspx this MSDN site]  
More info on primitives may be found on [https://msdn.microsoft.com/en-us/library/windows/desktop/bb147291.aspx this MSDN site]  
* '''pointlist:''' Renders the vertices as a collection of isolated points.
* '''pointlist:''' Renders the vertices as a collection of isolated points.
* '''linelist:''' Renders the vertices as a list of isolated straight line segments.
* '''linelist:''' Renders the vertices as a list of isolated straight line segments.
Line 27: Line 33:


==Vertices format==
==Vertices format==
* '''posX:''' An float representing the X position of the vertice in the GTA world.
* '''posX:''' An float representing the X position of the vertex in the GTA world.
* '''posY:''' An float representing the Y position of the vertice in the GTA world.
* '''posY:''' An float representing the Y position of the vertex in the GTA world.
* '''posZ:''' An float representing the Z position of the vertice in the GTA world.
* '''posZ:''' An float representing the Z position of the vertex in the GTA world.
* '''color (optional):''' An integer of the hex color, produced using [[tocolor]] or 0xAARRGGBB (AA = alpha, RR = red, GG = green, BB = blue). If it's not specified, white color is used.
* '''color (optional):''' An integer of the hex color, produced using [[tocolor]] or 0xAARRGGBB. If it's not specified, white color is used.
* '''u:''' An float representing  the relative X coordinate of the top left corner of the material which should be drawn from image
* '''u:''' An float representing  the relative X coordinate of the top left corner of the material which should be drawn from image
* '''v:''' An float representing  the relative Y coordinate of the top left corner of the material which should be drawn from image
* '''v:''' An float representing  the relative Y coordinate of the top left corner of the material which should be drawn from image
Line 36: Line 42:
===Returns===
===Returns===
Returns a ''true'' if the operation was successful, ''false'' otherwise.
Returns a ''true'' if the operation was successful, ''false'' otherwise.
}}
==Remarks==
When a 3D draw call is issued by any such material MTA function then the principle to [https://github.com/multitheftauto/mtasa-blue/blob/16769b8d1c94e2b9fe6323dcba46d1305f87a190/Client/core/Graphics/CMaterialPrimitive3DBatcher.cpp#L42 push it directly to the 3D adapter] does apply. To achieve this there is '''no software-side 3D clipping mathematics''' being performed. This way the vertex data is always being pushed to the vertex shader, leaving the entire freedom to the developer on how to interpret this vertex data in the shader. For example, even though this function does imply an use in 3D world space, the vertex coordinates could be translated directly into Direct3D 9 screen space instead, effectively discarding any multiplication with the camera projection matrix. The mathematical model for translation into valid Direct3D 9 screen-space coordinates is described [https://docs.microsoft.com/en-us/windows/win32/direct3d9/viewports-and-clipping here]. Let's assume that you are drawing the rectangle on a classic sheet of paper with a mathematical 2D X,Y coordinate system.
[[File:D3d9_screen_space_transformation.png|frameless|center|Direct3D 9 screen-space transformation]]
To transform the coordinates you first have to flip the Y coordinate using negation and then apply the Direct3D 9 screen-space rasterization cross-hair by using the screen dimensions (sw, sh). Since linear shapes are being preserved across linear translations, you can simplify each vertex-based figure into it's set of vertices for the purpose shown above. By using this function in such a way it can perform all the operations in the same quality such as the simpler [[dxDrawMaterialPrimitive]] function.


==Example==
==Example==
{{Example}}
This example draws the picture with the file name 'test.png' on the ground of Grove Street and adds a /flip command to flip it. The 'test.png' file needs to be included in the [[meta.xml]] in order for this example to work.
<syntaxhighlight lang="lua">
local picture = "test.png"
local worldRenderPositions = { -- create a table with all the world positions
   
    { 2483, -1663, 12.4, 0, 0 }, -- top left
    { 2493, -1663, 12.4, 1, 0 }, -- top right
    { 2483, -1673, 12.4, 0, 1 }, -- bottom left
    { 2493, -1673, 12.4, 1, 1 }, -- bottom right
   
    }
   
function renderPicture()
    dxDrawMaterialPrimitive3D( "trianglestrip", picture, false, unpack(worldRenderPositions) ) -- use unpack() to separate the points
end
addEventHandler( "onClientRender", root, renderPicture )
 
function flipPicture()
    for index, point in ipairs(worldRenderPositions) do
        if point[4] == 1 then
            point[4] = 0
        else
            point[4] = 1
        end
        if point[5] == 1 then
            point[5] = 0
        else
            point[5] = 1
        end
    end
end
addCommandHandler( "flip", flipPicture )
</syntaxhighlight>
 
This function can be used to draw billboards in the game world. You have to [https://forum.mtasa.com/topic/133065-naruto-jutsus-help-me/?do=findComment&comment=1003073 understand the mathematical models about the human vision] to calculate the proper vertices.


==See Also==
==See Also==
{{Drawing_functions}}
{{Drawing_functions}}
[[hu:dxDrawMaterialPrimitive3D]]

Latest revision as of 17:21, 7 November 2024

This function draws a 3D primitive shape with material applied to it in the 3D world - rendered for one frame. This should be used in conjunction with onClientRender in order to display continuously. If image file is used, it should ideally have dimensions that are a power of two, to prevent possible blurring. Power of two: 2px, 4px, 8px, 16px, 32px, 64px, 128px, 256px, 512px, 1024px...


Dialog-info.png This page describes the current implementation. For older versions check legacy version



Syntax

bool dxDrawMaterialPrimitive3D ( primitiveType pType, mixed material, string stage, table vertex1 [, table vertex2, ...] )

Required Arguments

  • pType: Type of primitive to be drawn.
  • image: Either a material element or a filepath of the image which is going to be drawn. (.dds images are also supported). Image files should ideally have dimensions that are a power of two, to prevent possible blurring. Use a texture created with dxCreateTexture to speed up drawing.
  • stage: A string representing a stage at which the actual drawcall should happen:
    • prefx - Primitives are rendered before the color correction. This stage makes primitives look natural to SA but colors could be distorted.
    • postfx - Primitives are rendered after the color correction. This stage conveys a color from the function to a screen without distortions.
    • postgui - Primitives are rendered after GUI. The primitives should be drawn on top of or behind any ingame GUI (rendered by CEGUI).
  • vertices: Tables representing each primitive vertex, required amount of them is determined by primitive type.

Allowed types

Available primitive types.

More info on primitives may be found on this MSDN site

  • pointlist: Renders the vertices as a collection of isolated points.
  • linelist: Renders the vertices as a list of isolated straight line segments.
  • linestrip: Renders the vertices as a single polyline.
  • trianglelist: Renders the specified vertices as a sequence of isolated triangles. Each group of three vertices defines a separate triangle.
  • trianglestrip: Renders the vertices as a triangle strip.
  • trianglefan: Renders the vertices as a triangle fan.

Vertices format

  • posX: An float representing the X position of the vertex in the GTA world.
  • posY: An float representing the Y position of the vertex in the GTA world.
  • posZ: An float representing the Z position of the vertex in the GTA world.
  • color (optional): An integer of the hex color, produced using tocolor or 0xAARRGGBB. If it's not specified, white color is used.
  • u: An float representing the relative X coordinate of the top left corner of the material which should be drawn from image
  • v: An float representing the relative Y coordinate of the top left corner of the material which should be drawn from image

Returns

Returns a true if the operation was successful, false otherwise.

Remarks

When a 3D draw call is issued by any such material MTA function then the principle to push it directly to the 3D adapter does apply. To achieve this there is no software-side 3D clipping mathematics being performed. This way the vertex data is always being pushed to the vertex shader, leaving the entire freedom to the developer on how to interpret this vertex data in the shader. For example, even though this function does imply an use in 3D world space, the vertex coordinates could be translated directly into Direct3D 9 screen space instead, effectively discarding any multiplication with the camera projection matrix. The mathematical model for translation into valid Direct3D 9 screen-space coordinates is described here. Let's assume that you are drawing the rectangle on a classic sheet of paper with a mathematical 2D X,Y coordinate system.

Direct3D 9 screen-space transformation

To transform the coordinates you first have to flip the Y coordinate using negation and then apply the Direct3D 9 screen-space rasterization cross-hair by using the screen dimensions (sw, sh). Since linear shapes are being preserved across linear translations, you can simplify each vertex-based figure into it's set of vertices for the purpose shown above. By using this function in such a way it can perform all the operations in the same quality such as the simpler dxDrawMaterialPrimitive function.

Example

This example draws the picture with the file name 'test.png' on the ground of Grove Street and adds a /flip command to flip it. The 'test.png' file needs to be included in the meta.xml in order for this example to work.

local picture = "test.png"
local worldRenderPositions = { -- create a table with all the world positions
    
    { 2483, -1663, 12.4, 0, 0 }, -- top left
    { 2493, -1663, 12.4, 1, 0 }, -- top right
    { 2483, -1673, 12.4, 0, 1 }, -- bottom left
    { 2493, -1673, 12.4, 1, 1 }, -- bottom right
    
    }
    
function renderPicture()
    dxDrawMaterialPrimitive3D( "trianglestrip", picture, false, unpack(worldRenderPositions) ) -- use unpack() to separate the points
end
addEventHandler( "onClientRender", root, renderPicture )

function flipPicture()
    for index, point in ipairs(worldRenderPositions) do
        if point[4] == 1 then
            point[4] = 0
        else
            point[4] = 1
        end
        if point[5] == 1 then
            point[5] = 0
        else
            point[5] = 1
        end
    end
end
addCommandHandler( "flip", flipPicture )

This function can be used to draw billboards in the game world. You have to understand the mathematical models about the human vision to calculate the proper vertices.

See Also