svn merge -r40051:40075 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
531
doc/python_api/rst/gpu.rst
Normal file
531
doc/python_api/rst/gpu.rst
Normal file
@@ -0,0 +1,531 @@
|
|||||||
|
|
||||||
|
GPU functions (gpu)
|
||||||
|
===================
|
||||||
|
|
||||||
|
*****
|
||||||
|
Intro
|
||||||
|
*****
|
||||||
|
|
||||||
|
Module to provide functions concerning the GPU implementation in Blender, in particular
|
||||||
|
the GLSL shaders that blender generates automatically to render materials in the 3D view
|
||||||
|
and in the game engine.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
The API provided by this module should be consider unstable. The data exposed by the API
|
||||||
|
are are closely related to Blender's internal GLSL code and may change if the GLSL code
|
||||||
|
is modified (e.g. new uniform type).
|
||||||
|
|
||||||
|
.. module:: gpu
|
||||||
|
|
||||||
|
*********
|
||||||
|
Constants
|
||||||
|
*********
|
||||||
|
|
||||||
|
--------------
|
||||||
|
GLSL data type
|
||||||
|
--------------
|
||||||
|
|
||||||
|
.. _data-type:
|
||||||
|
|
||||||
|
Type of GLSL data.
|
||||||
|
For shader uniforms, the data type determines which glUniform function
|
||||||
|
variant to use to send the uniform value to the GPU.
|
||||||
|
For vertex attributes, the data type determines which glVertexAttrib function
|
||||||
|
variant to use to send the vertex attribute to the GPU.
|
||||||
|
|
||||||
|
See export_shader_
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_1I
|
||||||
|
|
||||||
|
one integer
|
||||||
|
|
||||||
|
:value: 1
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_1F
|
||||||
|
|
||||||
|
one float
|
||||||
|
|
||||||
|
:value: 2
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_2F
|
||||||
|
|
||||||
|
two floats
|
||||||
|
|
||||||
|
:value: 3
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_3F
|
||||||
|
|
||||||
|
three floats
|
||||||
|
|
||||||
|
:value: 4
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_4F
|
||||||
|
|
||||||
|
four floats
|
||||||
|
|
||||||
|
:value: 5
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_9F
|
||||||
|
|
||||||
|
matrix 3x3 in column-major order
|
||||||
|
|
||||||
|
:value: 6
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_16F
|
||||||
|
|
||||||
|
matrix 4x4 in column-major order
|
||||||
|
|
||||||
|
:value: 7
|
||||||
|
|
||||||
|
.. data:: GPU_DATA_4UB
|
||||||
|
|
||||||
|
four unsigned byte
|
||||||
|
|
||||||
|
:value: 8
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
GLSL uniform type
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
.. _uniform-type:
|
||||||
|
|
||||||
|
Constants that specify the type of uniform used in a GLSL shader.
|
||||||
|
The uniform type determines the data type, origin and method
|
||||||
|
of calculation used by Blender to compute the uniform value.
|
||||||
|
|
||||||
|
The calculation of some of the uniforms is based on matrices available in the scene:
|
||||||
|
|
||||||
|
.. _mat4_cam_to_world:
|
||||||
|
.. _mat4_world_to_cam:
|
||||||
|
|
||||||
|
*mat4_cam_to_world*
|
||||||
|
Model matrix of the camera. OpenGL 4x4 matrix that converts
|
||||||
|
camera local coordinates to world coordinates. In blender this is obtained from the
|
||||||
|
'matrix_world' attribute of the camera object.
|
||||||
|
|
||||||
|
Some uniform will need the *mat4_world_to_cam*
|
||||||
|
matrix computed as the inverse of this matrix.
|
||||||
|
|
||||||
|
.. _mat4_object_to_world:
|
||||||
|
.. _mat4_world_to_object:
|
||||||
|
|
||||||
|
*mat4_object_to_world*
|
||||||
|
Model matrix of the object that is being rendered. OpenGL 4x4 matric that converts
|
||||||
|
object local coordinates to world coordinates. In blender this is obtained from the
|
||||||
|
'matrix_world' attribute of the object.
|
||||||
|
|
||||||
|
Some uniform will need the *mat4_world_to_object* matrix, computed as the inverse of this matrix.
|
||||||
|
|
||||||
|
.. _mat4_lamp_to_world:
|
||||||
|
.. _mat4_world_to_lamp:
|
||||||
|
|
||||||
|
*mat4_lamp_to_world*
|
||||||
|
Model matrix of the lamp lighting the object. OpenGL 4x4 matrix that converts lamp
|
||||||
|
local coordinates to world coordinates. In blender this is obtained from the
|
||||||
|
'matrix_world' attribute of the lamp object.
|
||||||
|
|
||||||
|
Some uniform will need the *mat4_world_to_lamp* matrix
|
||||||
|
computed as the inverse of this matrix.
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_OBJECT_VIEWMAT
|
||||||
|
|
||||||
|
The uniform is a 4x4 GL matrix that converts world coordinates to
|
||||||
|
camera coordinates (see mat4_world_to_cam_). Can be set once per frame.
|
||||||
|
There is at most one uniform of that type per shader.
|
||||||
|
|
||||||
|
:value: 1
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_OBJECT_MAT
|
||||||
|
|
||||||
|
The uniform is a 4x4 GL matrix that converts object coordinates
|
||||||
|
to world coordinates (see mat4_object_to_world_). Must be set before drawing the object.
|
||||||
|
There is at most one uniform of that type per shader.
|
||||||
|
|
||||||
|
:value: 2
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_OBJECT_VIEWIMAT
|
||||||
|
|
||||||
|
The uniform is a 4x4 GL matrix that converts coordinates
|
||||||
|
in camera space to world coordinates (see mat4_cam_to_world_).
|
||||||
|
Can be set once per frame.
|
||||||
|
There is at most one uniform of that type per shader.
|
||||||
|
|
||||||
|
:value: 3
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_OBJECT_IMAT
|
||||||
|
|
||||||
|
The uniform is a 4x4 GL matrix that converts world coodinates
|
||||||
|
to object coordinates (see mat4_world_to_object_).
|
||||||
|
Must be set before drawing the object.
|
||||||
|
There is at most one uniform of that type per shader.
|
||||||
|
|
||||||
|
:value: 4
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_OBJECT_COLOR
|
||||||
|
|
||||||
|
The uniform is a vector of 4 float representing a RGB color + alpha defined at object level.
|
||||||
|
Each values between 0.0 and 1.0. In blender it corresponds to the 'color' attribute of the object.
|
||||||
|
Must be set before drawing the object.
|
||||||
|
There is at most one uniform of that type per shader.
|
||||||
|
|
||||||
|
:value: 5
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_LAMP_DYNVEC
|
||||||
|
|
||||||
|
The uniform is a vector of 3 float representing the direction of light in camera space.
|
||||||
|
In Blender, this is computed by
|
||||||
|
|
||||||
|
mat4_world_to_cam_ * (-vec3_lamp_Z_axis)
|
||||||
|
|
||||||
|
as the lamp Z axis points to the opposite direction of light.
|
||||||
|
The norm of the vector should be unity. Can be set once per frame.
|
||||||
|
There is one uniform of that type per lamp lighting the material.
|
||||||
|
|
||||||
|
:value: 6
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_LAMP_DYNCO
|
||||||
|
|
||||||
|
The uniform is a vector of 3 float representing the position of the light in camera space.
|
||||||
|
Computed as
|
||||||
|
|
||||||
|
mat4_world_to_cam_ * vec3_lamp_pos
|
||||||
|
|
||||||
|
Can be set once per frame.
|
||||||
|
There is one uniform of that type per lamp lighting the material.
|
||||||
|
|
||||||
|
:value: 7
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_LAMP_DYNIMAT
|
||||||
|
|
||||||
|
The uniform is a 4x4 GL matrix that converts vector in camera space to lamp space.
|
||||||
|
Computed as
|
||||||
|
|
||||||
|
mat4_world_to_lamp_ * mat4_cam_to_world_
|
||||||
|
|
||||||
|
Can be set once per frame.
|
||||||
|
There is one uniform of that type per lamp lighting the material.
|
||||||
|
|
||||||
|
:value: 8
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_LAMP_DYNPERSMAT
|
||||||
|
|
||||||
|
The uniform is a 4x4 GL matrix that converts a vector in camera space to shadow buffer depth space.
|
||||||
|
Computed as
|
||||||
|
|
||||||
|
mat4_perspective_to_depth_ * mat4_lamp_to_perspective_ * mat4_world_to_lamp_ * mat4_cam_to_world_.
|
||||||
|
|
||||||
|
.. _mat4_perspective_to_depth:
|
||||||
|
|
||||||
|
*mat4_perspective_to_depth* is a fixed matrix defined as follow::
|
||||||
|
|
||||||
|
0.5 0.0 0.0 0.5
|
||||||
|
0.0 0.5 0.0 0.5
|
||||||
|
0.0 0.0 0.5 0.5
|
||||||
|
0.0 0.0 0.0 1.0
|
||||||
|
|
||||||
|
This uniform can be set once per frame. There is one uniform of that type per lamp casting shadow in the scene.
|
||||||
|
|
||||||
|
:value: 9
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_LAMP_DYNENERGY
|
||||||
|
|
||||||
|
The uniform is a single float representing the lamp energy. In blender it corresponds
|
||||||
|
to the 'energy' attribute of the lamp data block.
|
||||||
|
There is one uniform of that type per lamp lighting the material.
|
||||||
|
|
||||||
|
:value: 10
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_LAMP_DYNCOL
|
||||||
|
|
||||||
|
The uniform is a vector of 3 float representing the lamp color.
|
||||||
|
Color elements are between 0.0 and 1.0. In blender it corresponds
|
||||||
|
to the 'color' attribute of the lamp data block.
|
||||||
|
There is one uniform of that type per lamp lighting the material.
|
||||||
|
|
||||||
|
:value: 11
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_SAMPLER_2DBUFFER
|
||||||
|
|
||||||
|
The uniform is an integer representing an internal texture used for certain effect
|
||||||
|
(color band, etc).
|
||||||
|
|
||||||
|
:value: 12
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_SAMPLER_2DIMAGE
|
||||||
|
|
||||||
|
The uniform is an integer representing a texture loaded from an image file.
|
||||||
|
|
||||||
|
:value: 13
|
||||||
|
|
||||||
|
.. data:: GPU_DYNAMIC_SAMPLER_2DSHADOW
|
||||||
|
|
||||||
|
The uniform is an integer representing a shadow buffer corresponding to a lamp
|
||||||
|
casting shadow.
|
||||||
|
|
||||||
|
:value: 14
|
||||||
|
|
||||||
|
-------------------
|
||||||
|
GLSL attribute type
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
.. _attribute-type:
|
||||||
|
|
||||||
|
Type of the vertex attribute used in the GLSL shader. Determines the mesh custom data
|
||||||
|
layer that contains the vertex attribute.
|
||||||
|
|
||||||
|
.. data:: CD_MTFACE
|
||||||
|
|
||||||
|
Vertex attribute is a UV layer. Data type is vector of 2 float.
|
||||||
|
|
||||||
|
There can be more than one attribute of that type, they are differenciated by name.
|
||||||
|
In blender, you can retrieve the attribute data with:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
mesh.uv_textures[attribute['name']]
|
||||||
|
|
||||||
|
:value: 5
|
||||||
|
|
||||||
|
.. data:: CD_MCOL
|
||||||
|
|
||||||
|
Vertex attribute is color layer. Data type is vector 4 unsigned byte (RGBA).
|
||||||
|
|
||||||
|
There can be more than one attribute of that type, they are differenciated by name.
|
||||||
|
In blender you can retrieve the attribute data with:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
mesh.vertex_colors[attribute['name']]
|
||||||
|
|
||||||
|
:value: 6
|
||||||
|
|
||||||
|
.. data:: CD_ORCO
|
||||||
|
|
||||||
|
Vertex attribute is original coordinates. Data type is vector 3 float.
|
||||||
|
|
||||||
|
There can be only 1 attribute of that type per shader.
|
||||||
|
In blender you can retrieve the attribute data with:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
mesh.vertices
|
||||||
|
|
||||||
|
:value: 14
|
||||||
|
|
||||||
|
.. data:: CD_TANGENT
|
||||||
|
|
||||||
|
Vertex attribute is the tangent vector. Data type is vector 4 float.
|
||||||
|
|
||||||
|
There can be only 1 attribute of that type per shader.
|
||||||
|
There is currently no way to retrieve this attribute data via the RNA API but a standalone
|
||||||
|
C function to compute the tangent layer from the other layers can be obtained from
|
||||||
|
blender.org.
|
||||||
|
|
||||||
|
:value: 18
|
||||||
|
|
||||||
|
*********
|
||||||
|
Functions
|
||||||
|
*********
|
||||||
|
|
||||||
|
.. _export_shader:
|
||||||
|
|
||||||
|
.. function:: export_shader(scene,material)
|
||||||
|
|
||||||
|
Extracts the GLSL shader producing the visual effect of material in scene for the purpose of
|
||||||
|
reusing the shader in an external engine. This function is meant to be used in material exporter
|
||||||
|
so that the GLSL shader can be exported entirely. The return value is a dictionary containing the
|
||||||
|
shader source code and all associated data.
|
||||||
|
|
||||||
|
:arg scene: the scene in which the material in rendered.
|
||||||
|
:type scene: :class:`bpy.types.Scene`
|
||||||
|
:arg material: the material that you want to export the GLSL shader
|
||||||
|
:type material: :class:`bpy.types.Material`
|
||||||
|
:return: the shader source code and all associated data in a dictionary
|
||||||
|
:rtype: dictionary
|
||||||
|
|
||||||
|
The dictionary contains the following elements:
|
||||||
|
|
||||||
|
* ['fragment'] : string
|
||||||
|
fragment shader source code.
|
||||||
|
|
||||||
|
* ['vertex'] : string
|
||||||
|
vertex shader source code.
|
||||||
|
|
||||||
|
* ['uniforms'] : sequence
|
||||||
|
list of uniforms used in fragment shader, can be empty list. Each element of the
|
||||||
|
sequence is a dictionary with the following elements:
|
||||||
|
|
||||||
|
* ['varname'] : string
|
||||||
|
name of the uniform in the fragment shader. Always of the form 'unf<number>'.
|
||||||
|
|
||||||
|
* ['datatype'] : integer
|
||||||
|
data type of the uniform variable. Can be one of the following:
|
||||||
|
|
||||||
|
* :data:`gpu.GPU_DATA_1I` : use glUniform1i
|
||||||
|
* :data:`gpu.GPU_DATA_1F` : use glUniform1fv
|
||||||
|
* :data:`gpu.GPU_DATA_2F` : use glUniform2fv
|
||||||
|
* :data:`gpu.GPU_DATA_3F` : use glUniform3fv
|
||||||
|
* :data:`gpu.GPU_DATA_4F` : use glUniform4fv
|
||||||
|
* :data:`gpu.GPU_DATA_9F` : use glUniformMatrix3fv
|
||||||
|
* :data:`gpu.GPU_DATA_16F` : use glUniformMatrix4fv
|
||||||
|
|
||||||
|
* ['type'] : integer
|
||||||
|
type of uniform, determines the origin and method of calculation. See uniform-type_.
|
||||||
|
Depending on the type, more elements will be be present.
|
||||||
|
|
||||||
|
* ['lamp'] : :class:`bpy.types.Object`
|
||||||
|
Reference to the lamp object from which the uniforms value are extracted. Set for the following uniforms types:
|
||||||
|
|
||||||
|
.. hlist::
|
||||||
|
:columns: 3
|
||||||
|
|
||||||
|
* :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC`
|
||||||
|
* :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO`
|
||||||
|
* :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT`
|
||||||
|
* :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT`
|
||||||
|
* :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY`
|
||||||
|
* :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL`
|
||||||
|
* :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW`
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* The uniforms :data:`gpu.GPU_DYNAMIC_LAMP_DYNVEC`, :data:`gpu.GPU_DYNAMIC_LAMP_DYNCO`, :data:`gpu.GPU_DYNAMIC_LAMP_DYNIMAT` and :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT`
|
||||||
|
refer to the lamp object position and orientation, both of can be derived from the object world matrix:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
obmat = uniform['lamp'].matrix_world
|
||||||
|
|
||||||
|
where obmat is the mat4_lamp_to_world_ matrix of the lamp as a 2 dimensional array,
|
||||||
|
the lamp world location location is in obmat[3].
|
||||||
|
|
||||||
|
* The uniform types :data:`gpu.GPU_DYNAMIC_LAMP_DYNENERGY` and :data:`gpu.GPU_DYNAMIC_LAMP_DYNCOL` refer to the lamp data bloc that you get from:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
la = uniform['lamp'].data
|
||||||
|
|
||||||
|
from which you get la.energy and la.color
|
||||||
|
|
||||||
|
* Lamp duplication is not supported: if you have duplicated lamps in your scene
|
||||||
|
(i.e. lamp that are instantiated by dupligroup, etc), this element will only
|
||||||
|
give you a reference to the orignal lamp and you will not know which instance
|
||||||
|
of the lamp it is refering too. You can still handle that case in the exporter
|
||||||
|
by distributing the uniforms amongst the duplicated lamps.
|
||||||
|
|
||||||
|
* ['image'] : :class:`bpy.types.Image`
|
||||||
|
Reference to the image databloc. Set for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE`. You can get the image data from:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# full path to image file
|
||||||
|
uniform['image'].filepath
|
||||||
|
# image size as a 2-dimensional array of int
|
||||||
|
uniform['image'].size
|
||||||
|
|
||||||
|
* ['texnumber'] : integer
|
||||||
|
Channel number to which the texture is bound when drawing the object.
|
||||||
|
Set for uniform types :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`, :data:`gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE` and :data:`gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW`.
|
||||||
|
|
||||||
|
This is provided for information only: when reusing the shader outside blencer,
|
||||||
|
you are free to assign the textures to the channel of your choice and to pass
|
||||||
|
that number channel to the GPU in the uniform.
|
||||||
|
|
||||||
|
* ['texpixels'] : byte array
|
||||||
|
texture data for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`. Although
|
||||||
|
the corresponding uniform is a 2D sampler, the texture is always a 1D texture
|
||||||
|
of n x 1 pixel. The texture size n is provided in ['texsize'] element.
|
||||||
|
These texture are only used for computer generated texture (colorband, etc).
|
||||||
|
The texture data is provided so that you can make a real image out of it in the
|
||||||
|
exporter.
|
||||||
|
|
||||||
|
* ['texsize'] : integer
|
||||||
|
horizontal size of texture for uniform type :data:`gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER`.
|
||||||
|
The texture data is in ['texpixels'].
|
||||||
|
|
||||||
|
* ['attributes'] : sequence
|
||||||
|
list of attributes used in vertex shader, can be empty. Blender doesn't use
|
||||||
|
standard attributes except for vertex position and normal. All other vertex
|
||||||
|
attributes must be passed using the generic glVertexAttrib functions.
|
||||||
|
The attribute data can be found in the derived mesh custom data using RNA.
|
||||||
|
Each element of the sequence is a dictionary containing the following elements:
|
||||||
|
|
||||||
|
* ['varname'] : string
|
||||||
|
name of the uniform in the vertex shader. Always of the form 'att<number>'.
|
||||||
|
|
||||||
|
* ['datatype'] : integer
|
||||||
|
data type of vertex attribute, can be one of the following:
|
||||||
|
|
||||||
|
* :data:`gpu.GPU_DATA_2F` : use glVertexAttrib2fv
|
||||||
|
* :data:`gpu.GPU_DATA_3F` : use glVertexAttrib3fv
|
||||||
|
* :data:`gpu.GPU_DATA_4F` : use glVertexAttrib4fv
|
||||||
|
* :data:`gpu.GPU_DATA_4UB` : use glVertexAttrib4ubv
|
||||||
|
|
||||||
|
* ['number'] : integer
|
||||||
|
generic attribute number. This is provided for information only. Blender
|
||||||
|
doesn't use glBindAttribLocation to place generic attributes at specific location,
|
||||||
|
it lets the shader compiler place the attributes automatically and query the
|
||||||
|
placement with glGetAttribLocation. The result of this placement is returned in
|
||||||
|
this element.
|
||||||
|
|
||||||
|
When using this shader in a render engine, you should either use
|
||||||
|
glBindAttribLocation to force the attribute at this location or use
|
||||||
|
glGetAttribLocation to get the placement chosen by the compiler of your GPU.
|
||||||
|
|
||||||
|
* ['type'] : integer
|
||||||
|
type of the mesh custom data from which the vertex attribute is loaded.
|
||||||
|
See attribute-type_.
|
||||||
|
|
||||||
|
* ['name'] : string or integer
|
||||||
|
custom data layer name, used for attribute type :data:`gpu.CD_MTFACE` and :data:`gpu.CD_MCOL`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import gpu
|
||||||
|
# get GLSL shader of material Mat.001 in scene Scene.001
|
||||||
|
scene = bpy.data.scenes['Scene.001']
|
||||||
|
material = bpy.data.materials['Mat.001']
|
||||||
|
shader = gpu.export_shader(scene,material)
|
||||||
|
# scan the uniform list and find the images used in the shader
|
||||||
|
for uniform in shader['uniforms']:
|
||||||
|
if uniform['type'] == gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE:
|
||||||
|
print("uniform {0} is using image {1}".format(uniform['varname'], uniform['image'].filepath))
|
||||||
|
# scan the attribute list and find the UV layer used in the shader
|
||||||
|
for attribute in shader['attributes']:
|
||||||
|
if attribute['type'] == gpu.CD_MTFACE:
|
||||||
|
print("attribute {0} is using UV layer {1}".format(attribute['varname'], attribute['name']))
|
||||||
|
|
||||||
|
*****
|
||||||
|
Notes
|
||||||
|
*****
|
||||||
|
|
||||||
|
.. _mat4_lamp_to_perspective:
|
||||||
|
|
||||||
|
1. Calculation of the *mat4_lamp_to_perspective* matrix for a spot lamp.
|
||||||
|
|
||||||
|
The following pseudo code shows how the *mat4_lamp_to_perspective* matrix is computed
|
||||||
|
in blender for uniforms of :data:`gpu.GPU_DYNAMIC_LAMP_DYNPERSMAT` type::
|
||||||
|
|
||||||
|
#Get the lamp datablock with:
|
||||||
|
lamp=bpy.data.objects[uniform['lamp']].data
|
||||||
|
|
||||||
|
#Compute the projection matrix:
|
||||||
|
# You will need these lamp attributes:
|
||||||
|
# lamp.clipsta : near clip plane in world unit
|
||||||
|
# lamp.clipend : far clip plane in world unit
|
||||||
|
# lamp.spotsize : angle in degree of the spot light
|
||||||
|
|
||||||
|
#The size of the projection plane is computed with the usual formula:
|
||||||
|
wsize = lamp.clista * tan(lamp.spotsize/2)
|
||||||
|
|
||||||
|
#And the projection matrix:
|
||||||
|
mat4_lamp_to_perspective = glFrustum(-wsize,wsize,-wsize,wsize,lamp.clista,lamp.clipend)
|
||||||
|
|
||||||
|
2. Creation of the shadow map for a spot lamp.
|
||||||
|
|
||||||
|
The shadow map is the depth buffer of a render performed by placing the camera at the
|
||||||
|
spot light position. The size of the shadow map is given by the attribute lamp.bufsize :
|
||||||
|
shadow map size in pixel, same size in both dimensions.
|
||||||
@@ -768,9 +768,9 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel):
|
|||||||
col = row.column()
|
col = row.column()
|
||||||
|
|
||||||
if brush.use_texture_overlay:
|
if brush.use_texture_overlay:
|
||||||
col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_OFF')
|
col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||||
else:
|
else:
|
||||||
col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_ON')
|
col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||||
|
|
||||||
col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
|
col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,13 @@ extern "C" {
|
|||||||
#define MALWAYS_INLINE MINLINE
|
#define MALWAYS_INLINE MINLINE
|
||||||
#else
|
#else
|
||||||
#define MINLINE static inline
|
#define MINLINE static inline
|
||||||
|
#if (defined(__APPLE__) && defined(__ppc__))
|
||||||
|
/* static inline __attribute__ here breaks osx ppc gcc42 build */
|
||||||
|
#define MALWAYS_INLINE static __attribute__((always_inline))
|
||||||
|
#else
|
||||||
#define MALWAYS_INLINE static inline __attribute__((always_inline))
|
#define MALWAYS_INLINE static inline __attribute__((always_inline))
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define MINLINE
|
#define MINLINE
|
||||||
#define MALWAYS_INLINE
|
#define MALWAYS_INLINE
|
||||||
|
|||||||
@@ -86,12 +86,25 @@ typedef struct uiWidgetTrias {
|
|||||||
|
|
||||||
} uiWidgetTrias;
|
} uiWidgetTrias;
|
||||||
|
|
||||||
|
/* max as used by round_box__edges */
|
||||||
|
#define WIDGET_CURVE_RESOLU 9
|
||||||
|
#define WIDGET_SIZE_MAX (WIDGET_CURVE_RESOLU*4)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
WIDGET_TOP_LEFT= 1,
|
||||||
|
WIDGET_TOP_RIGHT= 2,
|
||||||
|
WIDGET_BOTTOM_RIGHT= 4,
|
||||||
|
WIDGET_BOTTOM_LEFT= 8,
|
||||||
|
/* just for convenience */
|
||||||
|
WIDGET_ALL_CORNERS= (WIDGET_TOP_LEFT | WIDGET_TOP_RIGHT | WIDGET_BOTTOM_RIGHT | WIDGET_BOTTOM_LEFT)
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct uiWidgetBase {
|
typedef struct uiWidgetBase {
|
||||||
|
|
||||||
int totvert, halfwayvert;
|
int totvert, halfwayvert;
|
||||||
float outer_v[64][2];
|
float outer_v[WIDGET_SIZE_MAX][2];
|
||||||
float inner_v[64][2];
|
float inner_v[WIDGET_SIZE_MAX][2];
|
||||||
float inner_uv[64][2];
|
float inner_uv[WIDGET_SIZE_MAX][2];
|
||||||
|
|
||||||
short inner, outline, emboss; /* set on/off */
|
short inner, outline, emboss; /* set on/off */
|
||||||
short shadedir;
|
short shadedir;
|
||||||
@@ -123,7 +136,7 @@ typedef struct uiWidgetType {
|
|||||||
|
|
||||||
/* *********************** draw data ************************** */
|
/* *********************** draw data ************************** */
|
||||||
|
|
||||||
static float cornervec[9][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169},
|
static float cornervec[WIDGET_CURVE_RESOLU][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169},
|
||||||
{0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0}};
|
{0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0}};
|
||||||
|
|
||||||
static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820},
|
static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820},
|
||||||
@@ -175,6 +188,7 @@ GLubyte checker_stipple_sml[32*32/8] =
|
|||||||
|
|
||||||
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3)
|
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3)
|
||||||
{
|
{
|
||||||
|
float tri_arr[3][2]= {{x1, y1}, {x2, y2}, {x3, y3}};
|
||||||
float color[4];
|
float color[4];
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
@@ -183,19 +197,17 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y
|
|||||||
color[3] *= 0.125f;
|
color[3] *= 0.125f;
|
||||||
glColor4fv(color);
|
glColor4fv(color);
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, tri_arr);
|
||||||
|
|
||||||
/* for each AA step */
|
/* for each AA step */
|
||||||
for(j=0; j<8; j++) {
|
for(j=0; j<8; j++) {
|
||||||
glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f);
|
glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
glBegin(GL_POLYGON);
|
|
||||||
glVertex2f(x1, y1);
|
|
||||||
glVertex2f(x2, y2);
|
|
||||||
glVertex2f(x3, y3);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f);
|
glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -216,7 +228,7 @@ static void widget_init(uiWidgetBase *wtb)
|
|||||||
/* return tot */
|
/* return tot */
|
||||||
static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step)
|
static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step)
|
||||||
{
|
{
|
||||||
float vec[9][2];
|
float vec[WIDGET_CURVE_RESOLU][2];
|
||||||
float minx, miny, maxx, maxy;
|
float minx, miny, maxx, maxy;
|
||||||
int a, tot= 0;
|
int a, tot= 0;
|
||||||
|
|
||||||
@@ -231,59 +243,59 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
|
|||||||
maxy= rect->ymax+step;
|
maxy= rect->ymax+step;
|
||||||
|
|
||||||
/* mult */
|
/* mult */
|
||||||
for(a=0; a<9; a++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++) {
|
||||||
vec[a][0]= rad*cornervec[a][0];
|
vec[a][0]= rad*cornervec[a][0];
|
||||||
vec[a][1]= rad*cornervec[a][1];
|
vec[a][1]= rad*cornervec[a][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start with left-top, anti clockwise */
|
/* start with left-top, anti clockwise */
|
||||||
if(roundboxalign & 1) {
|
if(roundboxalign & WIDGET_TOP_LEFT) {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= minx+rad-vec[a][0];
|
vert[tot][0]= minx+rad-vec[a][0];
|
||||||
vert[tot][1]= maxy-vec[a][1];
|
vert[tot][1]= maxy-vec[a][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= minx;
|
vert[tot][0]= minx;
|
||||||
vert[tot][1]= maxy;
|
vert[tot][1]= maxy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(roundboxalign & 8) {
|
if(roundboxalign & WIDGET_BOTTOM_LEFT) {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= minx+vec[a][1];
|
vert[tot][0]= minx+vec[a][1];
|
||||||
vert[tot][1]= miny+rad-vec[a][0];
|
vert[tot][1]= miny+rad-vec[a][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= minx;
|
vert[tot][0]= minx;
|
||||||
vert[tot][1]= miny;
|
vert[tot][1]= miny;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(roundboxalign & 4) {
|
if(roundboxalign & WIDGET_BOTTOM_RIGHT) {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= maxx-rad+vec[a][0];
|
vert[tot][0]= maxx-rad+vec[a][0];
|
||||||
vert[tot][1]= miny+vec[a][1];
|
vert[tot][1]= miny+vec[a][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= maxx;
|
vert[tot][0]= maxx;
|
||||||
vert[tot][1]= miny;
|
vert[tot][1]= miny;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(roundboxalign & 2) {
|
if(roundboxalign & WIDGET_TOP_RIGHT) {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= maxx-vec[a][1];
|
vert[tot][0]= maxx-vec[a][1];
|
||||||
vert[tot][1]= maxy-rad+vec[a][0];
|
vert[tot][1]= maxy-rad+vec[a][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
vert[tot][0]= maxx;
|
vert[tot][0]= maxx;
|
||||||
vert[tot][1]= maxy;
|
vert[tot][1]= maxy;
|
||||||
}
|
}
|
||||||
@@ -294,7 +306,7 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
|
|||||||
/* this call has 1 extra arg to allow mask outline */
|
/* this call has 1 extra arg to allow mask outline */
|
||||||
static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi)
|
static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi)
|
||||||
{
|
{
|
||||||
float vec[9][2], veci[9][2];
|
float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2];
|
||||||
float minx= rect->xmin, miny= rect->ymin, maxx= rect->xmax, maxy= rect->ymax;
|
float minx= rect->xmin, miny= rect->ymin, maxx= rect->xmax, maxy= rect->ymax;
|
||||||
float minxi= minx + 1.0f; /* boundbox inner */
|
float minxi= minx + 1.0f; /* boundbox inner */
|
||||||
float maxxi= maxx - 1.0f;
|
float maxxi= maxx - 1.0f;
|
||||||
@@ -303,8 +315,10 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
|
|||||||
float facxi= (maxxi!=minxi) ? 1.0f/(maxxi-minxi) : 0.0f; /* for uv, can divide by zero */
|
float facxi= (maxxi!=minxi) ? 1.0f/(maxxi-minxi) : 0.0f; /* for uv, can divide by zero */
|
||||||
float facyi= (maxyi!=minyi) ? 1.0f/(maxyi-minyi) : 0.0f;
|
float facyi= (maxyi!=minyi) ? 1.0f/(maxyi-minyi) : 0.0f;
|
||||||
int a, tot= 0, minsize;
|
int a, tot= 0, minsize;
|
||||||
const int hnum= ((roundboxalign & (1|2))==(1|2) || (roundboxalign & (4|8))==(4|8)) ? 1 : 2;
|
const int hnum= ((roundboxalign & (WIDGET_TOP_LEFT|WIDGET_TOP_RIGHT))==(WIDGET_TOP_LEFT|WIDGET_TOP_RIGHT) ||
|
||||||
const int vnum= ((roundboxalign & (1|8))==(1|8) || (roundboxalign & (2|4))==(2|4)) ? 1 : 2;
|
(roundboxalign & (WIDGET_BOTTOM_RIGHT|WIDGET_BOTTOM_LEFT))==(WIDGET_BOTTOM_RIGHT|WIDGET_BOTTOM_LEFT)) ? 1 : 2;
|
||||||
|
const int vnum= ((roundboxalign & (WIDGET_TOP_LEFT|WIDGET_BOTTOM_LEFT))==(WIDGET_TOP_LEFT|WIDGET_BOTTOM_LEFT) ||
|
||||||
|
(roundboxalign & (WIDGET_TOP_RIGHT|WIDGET_BOTTOM_RIGHT))==(WIDGET_TOP_RIGHT|WIDGET_BOTTOM_RIGHT)) ? 1 : 2;
|
||||||
|
|
||||||
minsize= MIN2((rect->xmax-rect->xmin)*hnum, (rect->ymax-rect->ymin)*vnum);
|
minsize= MIN2((rect->xmax-rect->xmin)*hnum, (rect->ymax-rect->ymin)*vnum);
|
||||||
|
|
||||||
@@ -315,7 +329,7 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
|
|||||||
radi= 0.5f*minsize - 1.0f;
|
radi= 0.5f*minsize - 1.0f;
|
||||||
|
|
||||||
/* mult */
|
/* mult */
|
||||||
for(a=0; a<9; a++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++) {
|
||||||
veci[a][0]= radi*cornervec[a][0];
|
veci[a][0]= radi*cornervec[a][0];
|
||||||
veci[a][1]= radi*cornervec[a][1];
|
veci[a][1]= radi*cornervec[a][1];
|
||||||
vec[a][0]= rad*cornervec[a][0];
|
vec[a][0]= rad*cornervec[a][0];
|
||||||
@@ -323,9 +337,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* corner left-bottom */
|
/* corner left-bottom */
|
||||||
if(roundboxalign & 8) {
|
if(roundboxalign & WIDGET_BOTTOM_LEFT) {
|
||||||
|
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
wt->inner_v[tot][0]= minxi+veci[a][1];
|
wt->inner_v[tot][0]= minxi+veci[a][1];
|
||||||
wt->inner_v[tot][1]= minyi+radi-veci[a][0];
|
wt->inner_v[tot][1]= minyi+radi-veci[a][0];
|
||||||
|
|
||||||
@@ -350,9 +364,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* corner right-bottom */
|
/* corner right-bottom */
|
||||||
if(roundboxalign & 4) {
|
if(roundboxalign & WIDGET_BOTTOM_RIGHT) {
|
||||||
|
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
wt->inner_v[tot][0]= maxxi-radi+veci[a][0];
|
wt->inner_v[tot][0]= maxxi-radi+veci[a][0];
|
||||||
wt->inner_v[tot][1]= minyi+veci[a][1];
|
wt->inner_v[tot][1]= minyi+veci[a][1];
|
||||||
|
|
||||||
@@ -379,9 +393,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
|
|||||||
wt->halfwayvert= tot;
|
wt->halfwayvert= tot;
|
||||||
|
|
||||||
/* corner right-top */
|
/* corner right-top */
|
||||||
if(roundboxalign & 2) {
|
if(roundboxalign & WIDGET_TOP_RIGHT) {
|
||||||
|
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
wt->inner_v[tot][0]= maxxi-veci[a][1];
|
wt->inner_v[tot][0]= maxxi-veci[a][1];
|
||||||
wt->inner_v[tot][1]= maxyi-radi+veci[a][0];
|
wt->inner_v[tot][1]= maxyi-radi+veci[a][0];
|
||||||
|
|
||||||
@@ -406,9 +420,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* corner left-top */
|
/* corner left-top */
|
||||||
if(roundboxalign & 1) {
|
if(roundboxalign & WIDGET_TOP_LEFT) {
|
||||||
|
|
||||||
for(a=0; a<9; a++, tot++) {
|
for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
|
||||||
wt->inner_v[tot][0]= minxi+radi-veci[a][0];
|
wt->inner_v[tot][0]= minxi+radi-veci[a][0];
|
||||||
wt->inner_v[tot][1]= maxyi-veci[a][1];
|
wt->inner_v[tot][1]= maxyi-veci[a][1];
|
||||||
|
|
||||||
@@ -434,6 +448,8 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
|
|||||||
tot++;
|
tot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLI_assert(tot <= WIDGET_SIZE_MAX);
|
||||||
|
|
||||||
wt->totvert= tot;
|
wt->totvert= tot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,16 +532,13 @@ static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize
|
|||||||
|
|
||||||
static void widget_trias_draw(uiWidgetTrias *tria)
|
static void widget_trias_draw(uiWidgetTrias *tria)
|
||||||
{
|
{
|
||||||
int a;
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_INDEX_ARRAY);
|
||||||
glBegin(GL_TRIANGLES);
|
glIndexPointer(GL_INT, 0, tria->index);
|
||||||
for(a=0; a<tria->tot; a++) {
|
glVertexPointer(2, GL_FLOAT, 0, tria->vec);
|
||||||
glVertex2fv(tria->vec[ tria->index[a][0] ]);
|
glDrawArrays(GL_TRIANGLES, 0, tria->tot*3);
|
||||||
glVertex2fv(tria->vec[ tria->index[a][1] ]);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glVertex2fv(tria->vec[ tria->index[a][2] ]);
|
glDisableClientState(GL_INDEX_ARRAY);
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
|
static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
|
||||||
@@ -601,19 +614,48 @@ static void round_box_shade_col4(const char col1[4], const char col2[4], const f
|
|||||||
glColor4ubv(col);
|
glColor4ubv(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void widgetbase_outline(uiWidgetBase *wtb)
|
static void round_box_shade_col4_r(unsigned char col_r[4], const char col1[4], const char col2[4], const float fac)
|
||||||
|
{
|
||||||
|
const int faci= FTOCHAR(fac);
|
||||||
|
const int facm= 255-faci;
|
||||||
|
|
||||||
|
col_r[0]= (faci*col1[0] + facm*col2[0])>>8;
|
||||||
|
col_r[1]= (faci*col1[1] + facm*col2[1])>>8;
|
||||||
|
col_r[2]= (faci*col1[2] + facm*col2[2])>>8;
|
||||||
|
col_r[3]= (faci*col1[3] + facm*col2[3])>>8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void widget_verts_to_quad_strip(uiWidgetBase *wtb, const int totvert, float quad_strip[WIDGET_SIZE_MAX*2+2][2])
|
||||||
{
|
{
|
||||||
int a;
|
int a;
|
||||||
|
for(a=0; a<totvert; a++) {
|
||||||
/* outline */
|
copy_v2_v2(quad_strip[a*2], wtb->outer_v[a]);
|
||||||
glBegin(GL_QUAD_STRIP);
|
copy_v2_v2(quad_strip[a*2+1], wtb->inner_v[a]);
|
||||||
for(a=0; a<wtb->totvert; a++) {
|
|
||||||
glVertex2fv(wtb->outer_v[a]);
|
|
||||||
glVertex2fv(wtb->inner_v[a]);
|
|
||||||
}
|
}
|
||||||
glVertex2fv(wtb->outer_v[0]);
|
copy_v2_v2(quad_strip[a*2], wtb->outer_v[0]);
|
||||||
glVertex2fv(wtb->inner_v[0]);
|
copy_v2_v2(quad_strip[a*2+1], wtb->inner_v[0]);
|
||||||
glEnd();
|
}
|
||||||
|
|
||||||
|
static void widget_verts_to_quad_strip_open(uiWidgetBase *wtb, const int totvert, float quad_strip[WIDGET_SIZE_MAX*2][2])
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
for(a=0; a<totvert; a++) {
|
||||||
|
quad_strip[a*2][0]= wtb->outer_v[a][0];
|
||||||
|
quad_strip[a*2][1]= wtb->outer_v[a][1];
|
||||||
|
quad_strip[a*2+1][0]= wtb->outer_v[a][0];
|
||||||
|
quad_strip[a*2+1][1]= wtb->outer_v[a][1] - 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void widgetbase_outline(uiWidgetBase *wtb)
|
||||||
|
{
|
||||||
|
float quad_strip[WIDGET_SIZE_MAX*2+2][2]; /* + 2 because the last pair is wrapped */
|
||||||
|
widget_verts_to_quad_strip(wtb, wtb->totvert, quad_strip);
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, quad_strip);
|
||||||
|
glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert*2 + 2);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
|
static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
|
||||||
@@ -626,100 +668,124 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
|
|||||||
if(wtb->inner) {
|
if(wtb->inner) {
|
||||||
if(wcol->shaded==0) {
|
if(wcol->shaded==0) {
|
||||||
if (wcol->alpha_check) {
|
if (wcol->alpha_check) {
|
||||||
|
float inner_v_half[WIDGET_SIZE_MAX][2];
|
||||||
float x_mid= 0.0f; /* used for dumb clamping of values */
|
float x_mid= 0.0f; /* used for dumb clamping of values */
|
||||||
|
|
||||||
/* dark checkers */
|
/* dark checkers */
|
||||||
glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255);
|
glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255);
|
||||||
glBegin(GL_POLYGON);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
for(a=0; a<wtb->totvert; a++) {
|
glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
|
||||||
glVertex2fv(wtb->inner_v[a]);
|
glDrawArrays(GL_POLYGON, 0, wtb->totvert);
|
||||||
}
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnd();
|
|
||||||
|
|
||||||
/* light checkers */
|
/* light checkers */
|
||||||
glEnable(GL_POLYGON_STIPPLE);
|
glEnable(GL_POLYGON_STIPPLE);
|
||||||
glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255);
|
glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255);
|
||||||
glPolygonStipple(checker_stipple_sml);
|
glPolygonStipple(checker_stipple_sml);
|
||||||
glBegin(GL_POLYGON);
|
|
||||||
for(a=0; a<wtb->totvert; a++) {
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glVertex2fv(wtb->inner_v[a]);
|
glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
|
||||||
}
|
glDrawArrays(GL_POLYGON, 0, wtb->totvert);
|
||||||
glEnd();
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
glDisable(GL_POLYGON_STIPPLE);
|
glDisable(GL_POLYGON_STIPPLE);
|
||||||
|
|
||||||
/* alpha fill */
|
/* alpha fill */
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
glColor4ubv((unsigned char*)wcol->inner);
|
glColor4ubv((unsigned char*)wcol->inner);
|
||||||
glBegin(GL_POLYGON);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
for(a=0; a<wtb->totvert; a++) {
|
for(a=0; a<wtb->totvert; a++) {
|
||||||
glVertex2fv(wtb->inner_v[a]);
|
|
||||||
x_mid += wtb->inner_v[a][0];
|
x_mid += wtb->inner_v[a][0];
|
||||||
}
|
}
|
||||||
x_mid /= wtb->totvert;
|
x_mid /= wtb->totvert;
|
||||||
glEnd();
|
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
|
||||||
|
glDrawArrays(GL_POLYGON, 0, wtb->totvert);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
/* 1/2 solid color */
|
/* 1/2 solid color */
|
||||||
glColor4ub(wcol->inner[0], wcol->inner[1], wcol->inner[2], 255);
|
glColor4ub(wcol->inner[0], wcol->inner[1], wcol->inner[2], 255);
|
||||||
glBegin(GL_POLYGON);
|
|
||||||
for(a=0; a<wtb->totvert; a++)
|
for(a=0; a<wtb->totvert; a++) {
|
||||||
glVertex2f(MIN2(wtb->inner_v[a][0], x_mid), wtb->inner_v[a][1]);
|
inner_v_half[a][0]= MIN2(wtb->inner_v[a][0], x_mid);
|
||||||
glEnd();
|
inner_v_half[a][1]= wtb->inner_v[a][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, inner_v_half);
|
||||||
|
glDrawArrays(GL_POLYGON, 0, wtb->totvert);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* simple fill */
|
/* simple fill */
|
||||||
glColor4ubv((unsigned char*)wcol->inner);
|
glColor4ubv((unsigned char*)wcol->inner);
|
||||||
glBegin(GL_POLYGON);
|
|
||||||
for(a=0; a<wtb->totvert; a++)
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glVertex2fv(wtb->inner_v[a]);
|
glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
|
||||||
glEnd();
|
glDrawArrays(GL_POLYGON, 0, wtb->totvert);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char col1[4], col2[4];
|
char col1[4], col2[4];
|
||||||
|
unsigned char col_array[WIDGET_SIZE_MAX * 4];
|
||||||
|
unsigned char *col_pt= col_array;
|
||||||
|
|
||||||
shadecolors4(col1, col2, wcol->inner, wcol->shadetop, wcol->shadedown);
|
shadecolors4(col1, col2, wcol->inner, wcol->shadetop, wcol->shadedown);
|
||||||
|
|
||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
glBegin(GL_POLYGON);
|
for(a=0; a<wtb->totvert; a++, col_pt += 4) {
|
||||||
for(a=0; a<wtb->totvert; a++) {
|
round_box_shade_col4_r(col_pt, col1, col2, wtb->inner_uv[a][wtb->shadedir]);
|
||||||
round_box_shade_col4(col1, col2, wtb->inner_uv[a][wtb->shadedir]);
|
|
||||||
glVertex2fv(wtb->inner_v[a]);
|
|
||||||
}
|
}
|
||||||
glEnd();
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v);
|
||||||
|
glColorPointer(4, GL_UNSIGNED_BYTE, 0, col_array);
|
||||||
|
glDrawArrays(GL_POLYGON, 0, wtb->totvert);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
glShadeModel(GL_FLAT);
|
glShadeModel(GL_FLAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for each AA step */
|
/* for each AA step */
|
||||||
if(wtb->outline) {
|
if(wtb->outline) {
|
||||||
|
float quad_strip[WIDGET_SIZE_MAX*2+2][2]; /* + 2 because the last pair is wrapped */
|
||||||
|
float quad_strip_emboss[WIDGET_SIZE_MAX*2][2]; /* only for emboss */
|
||||||
|
|
||||||
|
widget_verts_to_quad_strip(wtb, wtb->totvert, quad_strip);
|
||||||
|
|
||||||
|
if(wtb->emboss) {
|
||||||
|
widget_verts_to_quad_strip_open(wtb, wtb->halfwayvert, quad_strip_emboss);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
for(j=0; j<8; j++) {
|
for(j=0; j<8; j++) {
|
||||||
glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f);
|
glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f);
|
||||||
|
|
||||||
/* outline */
|
/* outline */
|
||||||
glColor4ub(wcol->outline[0], wcol->outline[1], wcol->outline[2], 32);
|
glColor4ub(wcol->outline[0], wcol->outline[1], wcol->outline[2], 32);
|
||||||
glBegin(GL_QUAD_STRIP);
|
|
||||||
for(a=0; a<wtb->totvert; a++) {
|
glVertexPointer(2, GL_FLOAT, 0, quad_strip);
|
||||||
glVertex2fv(wtb->outer_v[a]);
|
glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert*2 + 2);
|
||||||
glVertex2fv(wtb->inner_v[a]);
|
|
||||||
}
|
|
||||||
glVertex2fv(wtb->outer_v[0]);
|
|
||||||
glVertex2fv(wtb->inner_v[0]);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
/* emboss bottom shadow */
|
/* emboss bottom shadow */
|
||||||
if(wtb->emboss) {
|
if(wtb->emboss) {
|
||||||
glColor4f(1.0f, 1.0f, 1.0f, 0.02f);
|
glColor4f(1.0f, 1.0f, 1.0f, 0.02f);
|
||||||
glBegin(GL_QUAD_STRIP);
|
|
||||||
for(a=0; a<wtb->halfwayvert; a++) {
|
glVertexPointer(2, GL_FLOAT, 0, quad_strip_emboss);
|
||||||
glVertex2fv(wtb->outer_v[a]);
|
glDrawArrays(GL_QUAD_STRIP, 0, wtb->halfwayvert*2);
|
||||||
glVertex2f(wtb->outer_v[a][0], wtb->outer_v[a][1]-1.0f);
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f);
|
glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decoration */
|
/* decoration */
|
||||||
@@ -1611,7 +1677,8 @@ static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float
|
|||||||
uiWidgetBase wtb;
|
uiWidgetBase wtb;
|
||||||
rcti rect1= *rect;
|
rcti rect1= *rect;
|
||||||
float alpha, alphastep;
|
float alpha, alphastep;
|
||||||
int step, tot, a;
|
int step, totvert;
|
||||||
|
float quad_strip[WIDGET_SIZE_MAX*2][2];
|
||||||
|
|
||||||
/* prevent tooltips to not show round shadow */
|
/* prevent tooltips to not show round shadow */
|
||||||
if( 2.0f*radout > 0.2f*(rect1.ymax-rect1.ymin) )
|
if( 2.0f*radout > 0.2f*(rect1.ymax-rect1.ymin) )
|
||||||
@@ -1620,31 +1687,32 @@ static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float
|
|||||||
rect1.ymax -= 2.0f*radout;
|
rect1.ymax -= 2.0f*radout;
|
||||||
|
|
||||||
/* inner part */
|
/* inner part */
|
||||||
tot= round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & 12, 0.0f);
|
totvert= round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (WIDGET_BOTTOM_RIGHT | WIDGET_BOTTOM_LEFT), 0.0f);
|
||||||
|
|
||||||
/* inverse linear shadow alpha */
|
/* inverse linear shadow alpha */
|
||||||
alpha= 0.15;
|
alpha= 0.15;
|
||||||
alphastep= 0.67;
|
alphastep= 0.67;
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
for(step= 1; step<=radout; step++, alpha*=alphastep) {
|
for(step= 1; step<=radout; step++, alpha*=alphastep) {
|
||||||
round_box_shadow_edges(wtb.outer_v, &rect1, radin, 15, (float)step);
|
round_box_shadow_edges(wtb.outer_v, &rect1, radin, WIDGET_ALL_CORNERS, (float)step);
|
||||||
|
|
||||||
glColor4f(0.0f, 0.0f, 0.0f, alpha);
|
glColor4f(0.0f, 0.0f, 0.0f, alpha);
|
||||||
|
|
||||||
glBegin(GL_QUAD_STRIP);
|
widget_verts_to_quad_strip_open(&wtb, totvert, quad_strip);
|
||||||
for(a=0; a<tot; a++) {
|
|
||||||
glVertex2fv(wtb.outer_v[a]);
|
glVertexPointer(2, GL_FLOAT, 0, quad_strip);
|
||||||
glVertex2fv(wtb.inner_v[a]);
|
glDrawArrays(GL_QUAD_STRIP, 0, totvert*2);
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int direction)
|
static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int direction)
|
||||||
{
|
{
|
||||||
uiWidgetBase wtb;
|
uiWidgetBase wtb;
|
||||||
int roundboxalign= 15;
|
int roundboxalign= WIDGET_ALL_CORNERS;
|
||||||
|
|
||||||
widget_init(&wtb);
|
widget_init(&wtb);
|
||||||
|
|
||||||
@@ -1654,11 +1722,11 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
|
|||||||
//rect->ymax += 4.0;
|
//rect->ymax += 4.0;
|
||||||
}
|
}
|
||||||
else if (direction == UI_DOWN) {
|
else if (direction == UI_DOWN) {
|
||||||
roundboxalign= 12;
|
roundboxalign= (WIDGET_BOTTOM_RIGHT | WIDGET_BOTTOM_LEFT);
|
||||||
rect->ymin -= 4.0;
|
rect->ymin -= 4.0;
|
||||||
}
|
}
|
||||||
else if (direction == UI_TOP) {
|
else if (direction == UI_TOP) {
|
||||||
roundboxalign= 3;
|
roundboxalign= WIDGET_TOP_LEFT | WIDGET_TOP_RIGHT;
|
||||||
rect->ymax += 4.0;
|
rect->ymax += 4.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2008,7 +2076,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
|
|||||||
widget_init(&wtb);
|
widget_init(&wtb);
|
||||||
|
|
||||||
/* fully rounded */
|
/* fully rounded */
|
||||||
round_box_edges(&wtb, 15, rect, rad);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, rect, rad);
|
||||||
|
|
||||||
/* setup temp colors */
|
/* setup temp colors */
|
||||||
wcol_tmp.outline[0]= wcol_tmp.outline[1]= wcol_tmp.outline[2]= 0;
|
wcol_tmp.outline[0]= wcol_tmp.outline[1]= wcol_tmp.outline[2]= 0;
|
||||||
@@ -2107,16 +2175,14 @@ void ui_draw_link_bezier(rcti *rect)
|
|||||||
if(ui_link_bezier_points(rect, coord_array, LINK_RESOL)) {
|
if(ui_link_bezier_points(rect, coord_array, LINK_RESOL)) {
|
||||||
/* we can reuse the dist variable here to increment the GL curve eval amount*/
|
/* we can reuse the dist variable here to increment the GL curve eval amount*/
|
||||||
// const float dist= 1.0f/(float)LINK_RESOL; // UNUSED
|
// const float dist= 1.0f/(float)LINK_RESOL; // UNUSED
|
||||||
int i;
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glEnable(GL_LINE_SMOOTH);
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
|
||||||
glBegin(GL_LINE_STRIP);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
for(i=0; i<=LINK_RESOL; i++) {
|
glVertexPointer(2, GL_FLOAT, 0, coord_array);
|
||||||
glVertex2fv(coord_array[i]);
|
glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL);
|
||||||
}
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_LINE_SMOOTH);
|
glDisable(GL_LINE_SMOOTH);
|
||||||
@@ -2148,7 +2214,7 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat
|
|||||||
if(horizontal)
|
if(horizontal)
|
||||||
SWAP(short, wcol->shadetop, wcol->shadedown);
|
SWAP(short, wcol->shadetop, wcol->shadedown);
|
||||||
|
|
||||||
round_box_edges(&wtb, 15, rect, rad);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, rect, rad);
|
||||||
widgetbase_draw(&wtb, wcol);
|
widgetbase_draw(&wtb, wcol);
|
||||||
|
|
||||||
/* slider */
|
/* slider */
|
||||||
@@ -2176,7 +2242,7 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat
|
|||||||
if (state & UI_SCROLL_NO_OUTLINE)
|
if (state & UI_SCROLL_NO_OUTLINE)
|
||||||
SWAP(short, outline, wtb.outline);
|
SWAP(short, outline, wtb.outline);
|
||||||
|
|
||||||
round_box_edges(&wtb, 15, slider, rad);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, slider, rad);
|
||||||
|
|
||||||
if(state & UI_SCROLL_ARROWS) {
|
if(state & UI_SCROLL_ARROWS) {
|
||||||
if(wcol->item[0] > 48) wcol->item[0]-= 48;
|
if(wcol->item[0] > 48) wcol->item[0]-= 48;
|
||||||
@@ -2343,7 +2409,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
|
|||||||
|
|
||||||
/* left part of slider, always rounded */
|
/* left part of slider, always rounded */
|
||||||
rect1.xmax= rect1.xmin + ceil(offs+1.0f);
|
rect1.xmax= rect1.xmin + ceil(offs+1.0f);
|
||||||
round_box_edges(&wtb1, roundboxalign & ~6, &rect1, offs);
|
round_box_edges(&wtb1, roundboxalign & ~(WIDGET_TOP_RIGHT | WIDGET_BOTTOM_RIGHT), &rect1, offs);
|
||||||
wtb1.outline= 0;
|
wtb1.outline= 0;
|
||||||
widgetbase_draw(&wtb1, wcol);
|
widgetbase_draw(&wtb1, wcol);
|
||||||
|
|
||||||
@@ -2354,7 +2420,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
|
|||||||
offs*= (rect1.xmax + offs - rect->xmax)/offs;
|
offs*= (rect1.xmax + offs - rect->xmax)/offs;
|
||||||
else
|
else
|
||||||
offs= 0.0f;
|
offs= 0.0f;
|
||||||
round_box_edges(&wtb1, roundboxalign & ~9, &rect1, offs);
|
round_box_edges(&wtb1, roundboxalign & ~(WIDGET_TOP_LEFT | WIDGET_BOTTOM_LEFT), &rect1, offs);
|
||||||
|
|
||||||
widgetbase_draw(&wtb1, wcol);
|
widgetbase_draw(&wtb1, wcol);
|
||||||
VECCOPY(wcol->outline, outline);
|
VECCOPY(wcol->outline, outline);
|
||||||
@@ -2436,7 +2502,7 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
|
|||||||
wtb.outline= 0;
|
wtb.outline= 0;
|
||||||
|
|
||||||
/* rounded */
|
/* rounded */
|
||||||
round_box_edges(&wtb, 15, rect, 10.0f);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, rect, 10.0f);
|
||||||
widgetbase_draw(&wtb, wcol);
|
widgetbase_draw(&wtb, wcol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2499,7 +2565,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int
|
|||||||
widget_init(&wtb);
|
widget_init(&wtb);
|
||||||
|
|
||||||
/* half rounded */
|
/* half rounded */
|
||||||
round_box_edges(&wtb, 15, rect, rad);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, rect, rad);
|
||||||
|
|
||||||
widgetbase_draw(&wtb, wcol);
|
widgetbase_draw(&wtb, wcol);
|
||||||
}
|
}
|
||||||
@@ -2526,7 +2592,7 @@ static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta
|
|||||||
|
|
||||||
/* rounded, but no outline */
|
/* rounded, but no outline */
|
||||||
wtb.outline= 0;
|
wtb.outline= 0;
|
||||||
round_box_edges(&wtb, 15, rect, 4.0f);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, rect, 4.0f);
|
||||||
|
|
||||||
widgetbase_draw(&wtb, wcol);
|
widgetbase_draw(&wtb, wcol);
|
||||||
}
|
}
|
||||||
@@ -2550,7 +2616,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
|
|||||||
recttemp.ymax-= delta;
|
recttemp.ymax-= delta;
|
||||||
|
|
||||||
/* half rounded */
|
/* half rounded */
|
||||||
round_box_edges(&wtb, 15, &recttemp, 4.0f);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, &recttemp, 4.0f);
|
||||||
|
|
||||||
/* decoration */
|
/* decoration */
|
||||||
if(state & UI_SELECT) {
|
if(state & UI_SELECT) {
|
||||||
@@ -2650,12 +2716,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
|
|||||||
UI_GetThemeColor3ubv(TH_BACK, col);
|
UI_GetThemeColor3ubv(TH_BACK, col);
|
||||||
glColor3ubv(col);
|
glColor3ubv(col);
|
||||||
|
|
||||||
round_box__edges(&wtb, 15, rect, 0.0f, 4.0);
|
round_box__edges(&wtb, WIDGET_ALL_CORNERS, rect, 0.0f, 4.0);
|
||||||
widgetbase_outline(&wtb);
|
widgetbase_outline(&wtb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* outline */
|
/* outline */
|
||||||
round_box_edges(&wtb, 15, rect, 5.0f);
|
round_box_edges(&wtb, WIDGET_ALL_CORNERS, rect, 5.0f);
|
||||||
wtb.outline= 1;
|
wtb.outline= 1;
|
||||||
wtb.inner= 0;
|
wtb.inner= 0;
|
||||||
widgetbase_draw(&wtb, &wt->wcol);
|
widgetbase_draw(&wtb, &wt->wcol);
|
||||||
@@ -2836,37 +2902,27 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
|
|||||||
|
|
||||||
switch(but->flag & UI_BUT_ALIGN) {
|
switch(but->flag & UI_BUT_ALIGN) {
|
||||||
case UI_BUT_ALIGN_TOP:
|
case UI_BUT_ALIGN_TOP:
|
||||||
return (12);
|
return WIDGET_BOTTOM_LEFT | WIDGET_BOTTOM_RIGHT;
|
||||||
break;
|
|
||||||
case UI_BUT_ALIGN_DOWN:
|
case UI_BUT_ALIGN_DOWN:
|
||||||
return (3);
|
return WIDGET_TOP_LEFT | WIDGET_TOP_RIGHT;
|
||||||
break;
|
|
||||||
case UI_BUT_ALIGN_LEFT:
|
case UI_BUT_ALIGN_LEFT:
|
||||||
return (6);
|
return WIDGET_TOP_RIGHT | WIDGET_BOTTOM_RIGHT;
|
||||||
break;
|
|
||||||
case UI_BUT_ALIGN_RIGHT:
|
case UI_BUT_ALIGN_RIGHT:
|
||||||
return (9);
|
return WIDGET_TOP_LEFT | WIDGET_BOTTOM_LEFT;
|
||||||
break;
|
|
||||||
|
|
||||||
case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT:
|
case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT:
|
||||||
return (1);
|
return WIDGET_TOP_LEFT;
|
||||||
break;
|
|
||||||
case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT:
|
case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT:
|
||||||
return (2);
|
return WIDGET_TOP_RIGHT;
|
||||||
break;
|
|
||||||
case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT:
|
case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT:
|
||||||
return (8);
|
return WIDGET_BOTTOM_LEFT;
|
||||||
break;
|
|
||||||
case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT:
|
case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT:
|
||||||
return (4);
|
return WIDGET_BOTTOM_RIGHT;
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (0);
|
return 0;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 15;
|
|
||||||
|
return WIDGET_ALL_CORNERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* conversion from old to new buttons, so still messy */
|
/* conversion from old to new buttons, so still messy */
|
||||||
@@ -3104,14 +3160,14 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
|
|||||||
uiWidgetType *wt= widget_type(UI_WTYPE_BOX);
|
uiWidgetType *wt= widget_type(UI_WTYPE_BOX);
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
widget_softshadow(rect, 15, 5.0f, 8.0f);
|
widget_softshadow(rect, WIDGET_ALL_CORNERS, 5.0f, 8.0f);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
wt->state(wt, 0);
|
wt->state(wt, 0);
|
||||||
if(block)
|
if(block)
|
||||||
wt->draw(&wt->wcol, rect, block->flag, 15);
|
wt->draw(&wt->wcol, rect, block->flag, WIDGET_ALL_CORNERS);
|
||||||
else
|
else
|
||||||
wt->draw(&wt->wcol, rect, 0, 15);
|
wt->draw(&wt->wcol, rect, 0, WIDGET_ALL_CORNERS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,20 @@ void ED_base_object_activate(bContext *C, Base *base)
|
|||||||
|
|
||||||
/********************** Selection Operators **********************/
|
/********************** Selection Operators **********************/
|
||||||
|
|
||||||
|
static int objects_selectable_poll(bContext *C)
|
||||||
|
{
|
||||||
|
/* we don't check for linked scenes here, selection is
|
||||||
|
still allowed then for inspection of scene */
|
||||||
|
Object *obact= CTX_data_active_object(C);
|
||||||
|
|
||||||
|
if(CTX_data_edit_object(C))
|
||||||
|
return 0;
|
||||||
|
if(obact && obact->mode)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/************************ Select by Type *************************/
|
/************************ Select by Type *************************/
|
||||||
|
|
||||||
static int object_select_by_type_exec(bContext *C, wmOperator *op)
|
static int object_select_by_type_exec(bContext *C, wmOperator *op)
|
||||||
@@ -159,7 +173,7 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot)
|
|||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->invoke= WM_menu_invoke;
|
ot->invoke= WM_menu_invoke;
|
||||||
ot->exec= object_select_by_type_exec;
|
ot->exec= object_select_by_type_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -341,7 +355,7 @@ void OBJECT_OT_select_linked(wmOperatorType *ot)
|
|||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->invoke= WM_menu_invoke;
|
ot->invoke= WM_menu_invoke;
|
||||||
ot->exec= object_select_linked_exec;
|
ot->exec= object_select_linked_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -667,7 +681,7 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
|
|||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->invoke= WM_menu_invoke;
|
ot->invoke= WM_menu_invoke;
|
||||||
ot->exec= object_select_grouped_exec;
|
ot->exec= object_select_grouped_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -716,7 +730,7 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot)
|
|||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
/*ot->invoke = XXX - need a int grid popup*/
|
/*ot->invoke = XXX - need a int grid popup*/
|
||||||
ot->exec= object_select_by_layer_exec;
|
ot->exec= object_select_by_layer_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -754,7 +768,7 @@ void OBJECT_OT_select_inverse(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->exec= object_select_inverse_exec;
|
ot->exec= object_select_inverse_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -815,7 +829,7 @@ void OBJECT_OT_select_all(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->exec= object_select_all_exec;
|
ot->exec= object_select_all_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -864,7 +878,7 @@ void OBJECT_OT_select_same_group(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->exec= object_select_same_group_exec;
|
ot->exec= object_select_same_group_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -917,7 +931,7 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->exec= object_select_mirror_exec;
|
ot->exec= object_select_mirror_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -974,7 +988,7 @@ void OBJECT_OT_select_name(wmOperatorType *ot)
|
|||||||
|
|
||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
ot->exec= object_select_name_exec;
|
ot->exec= object_select_name_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
@@ -1022,7 +1036,7 @@ void OBJECT_OT_select_random(wmOperatorType *ot)
|
|||||||
/* api callbacks */
|
/* api callbacks */
|
||||||
/*ot->invoke= object_select_random_invoke XXX - need a number popup ;*/
|
/*ot->invoke= object_select_random_invoke XXX - need a number popup ;*/
|
||||||
ot->exec = object_select_random_exec;
|
ot->exec = object_select_random_exec;
|
||||||
ot->poll= ED_operator_objectmode;
|
ot->poll= objects_selectable_poll;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
|
|||||||
@@ -3483,8 +3483,8 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
|
|||||||
|
|
||||||
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 1);
|
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 1);
|
||||||
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 0);
|
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 0);
|
||||||
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 1);
|
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 1);
|
||||||
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 0);
|
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 0);
|
||||||
|
|
||||||
WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", UPARROWKEY, KM_PRESS, 0, 0);
|
WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", UPARROWKEY, KM_PRESS, 0, 0);
|
||||||
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "next", 0);
|
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "next", 0);
|
||||||
|
|||||||
@@ -322,8 +322,8 @@ static int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
|
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h)
|
|||||||
TreeElement *te= lb->first;
|
TreeElement *te= lb->first;
|
||||||
while(te) {
|
while(te) {
|
||||||
TreeStoreElem *tselem= TREESTORE(te);
|
TreeStoreElem *tselem= TREESTORE(te);
|
||||||
if((tselem->flag & TSE_CLOSED)==0)
|
if(TSELEM_OPEN(tselem,soops))
|
||||||
outliner_height(soops, &te->subtree, h);
|
outliner_height(soops, &te->subtree, h);
|
||||||
(*h) += UI_UNIT_Y;
|
(*h) += UI_UNIT_Y;
|
||||||
te= te->next;
|
te= te->next;
|
||||||
@@ -112,7 +112,7 @@ static void outliner_width(SpaceOops *soops, ListBase *lb, int *w)
|
|||||||
// TreeStoreElem *tselem= TREESTORE(te);
|
// TreeStoreElem *tselem= TREESTORE(te);
|
||||||
|
|
||||||
// XXX fixme... te->xend is not set yet
|
// XXX fixme... te->xend is not set yet
|
||||||
if(tselem->flag & TSE_CLOSED) {
|
if(!TSELEM_OPEN(tselem,soops)) {
|
||||||
if (te->xend > *w)
|
if (te->xend > *w)
|
||||||
*w = te->xend;
|
*w = te->xend;
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start
|
|||||||
if(startx+100 > *w)
|
if(startx+100 > *w)
|
||||||
*w = startx+100;
|
*w = startx+100;
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0)
|
if(TSELEM_OPEN(tselem,soops))
|
||||||
outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X);
|
outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X);
|
||||||
te= te->next;
|
te= te->next;
|
||||||
}
|
}
|
||||||
@@ -519,7 +519,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
|
if(TSELEM_OPEN(tselem,soops)) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,7 +560,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
|
|||||||
ptr= &te->rnaptr;
|
ptr= &te->rnaptr;
|
||||||
prop= te->directdata;
|
prop= te->directdata;
|
||||||
|
|
||||||
if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0))
|
if(!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem,soops))) )
|
||||||
uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1);
|
uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1);
|
||||||
}
|
}
|
||||||
else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
|
else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
|
||||||
@@ -571,7 +571,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree);
|
if(TSELEM_OPEN(tselem,soops)) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,7 +828,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
|
if(TSELEM_OPEN(tselem,soops)) outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,7 +871,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0) outliner_buttons(C, block, ar, soops, &te->subtree);
|
if(TSELEM_OPEN(tselem,soops)) outliner_buttons(C, block, ar, soops, &te->subtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1237,6 +1237,18 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
|||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
/* start by highlighting search matches
|
||||||
|
* we don't expand items when searching in the datablocks but we
|
||||||
|
* still want to highlight any filter matches.
|
||||||
|
*/
|
||||||
|
if ( (SEARCHING_OUTLINER(soops) || (soops->outlinevis==SO_DATABLOCKS && soops->search_string[0]!=0)) &&
|
||||||
|
(tselem->flag & TSE_SEARCHMATCH))
|
||||||
|
{
|
||||||
|
/* TODO - add search highlight colour to theme? */
|
||||||
|
glColor4f(0.2f, 0.5f, 0.2f, 0.3f);
|
||||||
|
glRecti(startx, *starty+1, ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* colors for active/selected data */
|
/* colors for active/selected data */
|
||||||
if(tselem->type==0) {
|
if(tselem->type==0) {
|
||||||
if(te->idcode==ID_SCE) {
|
if(te->idcode==ID_SCE) {
|
||||||
@@ -1317,10 +1329,10 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
|||||||
icon_x = startx+5*ufac;
|
icon_x = startx+5*ufac;
|
||||||
|
|
||||||
// icons a bit higher
|
// icons a bit higher
|
||||||
if(tselem->flag & TSE_CLOSED)
|
if(TSELEM_OPEN(tselem,soops))
|
||||||
UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT);
|
|
||||||
else
|
|
||||||
UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN);
|
UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN);
|
||||||
|
else
|
||||||
|
UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT);
|
||||||
}
|
}
|
||||||
offsx+= UI_UNIT_X;
|
offsx+= UI_UNIT_X;
|
||||||
|
|
||||||
@@ -1356,7 +1368,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
|||||||
offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name));
|
offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name));
|
||||||
|
|
||||||
/* closed item, we draw the icons, not when it's a scene, or master-server list though */
|
/* closed item, we draw the icons, not when it's a scene, or master-server list though */
|
||||||
if(tselem->flag & TSE_CLOSED) {
|
if(!TSELEM_OPEN(tselem,soops)) {
|
||||||
if(te->subtree.first) {
|
if(te->subtree.first) {
|
||||||
if(tselem->type==0 && te->idcode==ID_SCE);
|
if(tselem->type==0 && te->idcode==ID_SCE);
|
||||||
else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so dont draw */
|
else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so dont draw */
|
||||||
@@ -1382,7 +1394,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
|||||||
te->ys= (float)*starty;
|
te->ys= (float)*starty;
|
||||||
te->xend= startx+offsx;
|
te->xend= startx+offsx;
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
*starty-= UI_UNIT_Y;
|
*starty-= UI_UNIT_Y;
|
||||||
|
|
||||||
for(ten= te->subtree.first; ten; ten= ten->next)
|
for(ten= te->subtree.first; ten; ten= ten->next)
|
||||||
@@ -1415,7 +1427,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
|
|||||||
|
|
||||||
*starty-= UI_UNIT_Y;
|
*starty-= UI_UNIT_Y;
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0)
|
if(TSELEM_OPEN(tselem,soops))
|
||||||
outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty);
|
outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1439,12 +1451,12 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
|
|||||||
tselem= TREESTORE(te);
|
tselem= TREESTORE(te);
|
||||||
|
|
||||||
/* selection status */
|
/* selection status */
|
||||||
if((tselem->flag & TSE_CLOSED)==0)
|
if(TSELEM_OPEN(tselem,soops))
|
||||||
if(tselem->type == TSE_RNA_STRUCT)
|
if(tselem->type == TSE_RNA_STRUCT)
|
||||||
glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1);
|
glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1);
|
||||||
|
|
||||||
*starty-= UI_UNIT_Y;
|
*starty-= UI_UNIT_Y;
|
||||||
if((tselem->flag & TSE_CLOSED)==0) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
|
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
|
||||||
if(tselem->type == TSE_RNA_STRUCT)
|
if(tselem->type == TSE_RNA_STRUCT)
|
||||||
fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y);
|
fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y);
|
||||||
@@ -1465,7 +1477,7 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb,
|
|||||||
glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
|
glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
|
||||||
}
|
}
|
||||||
*starty-= UI_UNIT_Y;
|
*starty-= UI_UNIT_Y;
|
||||||
if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty);
|
if(TSELEM_OPEN(tselem,soops)) outliner_draw_selection(ar, soops, &te->subtree, starty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -687,7 +687,7 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te,
|
|||||||
te->ys= (float)(*starty);
|
te->ys= (float)(*starty);
|
||||||
*starty-= UI_UNIT_Y;
|
*starty-= UI_UNIT_Y;
|
||||||
|
|
||||||
if((tselem->flag & TSE_CLOSED)==0) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
TreeElement *ten;
|
TreeElement *ten;
|
||||||
for(ten= te->subtree.first; ten; ten= ten->next) {
|
for(ten= te->subtree.first; ten; ten= ten->next) {
|
||||||
outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty);
|
outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty);
|
||||||
@@ -910,7 +910,7 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase
|
|||||||
}
|
}
|
||||||
else tselem->flag |= TSE_CLOSED;
|
else tselem->flag |= TSE_CLOSED;
|
||||||
|
|
||||||
if(tselem->flag & TSE_CLOSED); else tree_element_show_hierarchy(scene, soops, &te->subtree);
|
if(TSELEM_OPEN(tselem,soops)) tree_element_show_hierarchy(scene, soops, &te->subtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1175,7 +1175,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* go over sub-tree */
|
/* go over sub-tree */
|
||||||
if ((tselem->flag & TSE_CLOSED)==0)
|
if (TSELEM_OPEN(tselem,soops))
|
||||||
do_outliner_drivers_editop(soops, &te->subtree, reports, mode);
|
do_outliner_drivers_editop(soops, &te->subtree, reports, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1343,7 +1343,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* go over sub-tree */
|
/* go over sub-tree */
|
||||||
if ((tselem->flag & TSE_CLOSED)==0)
|
if (TSELEM_OPEN(tselem,soops))
|
||||||
do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
|
do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,6 +126,27 @@ typedef struct TreeElement {
|
|||||||
#define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5f)
|
#define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5f)
|
||||||
|
|
||||||
|
|
||||||
|
/* Outliner Searching --
|
||||||
|
|
||||||
|
Are we looking for something in the outliner?
|
||||||
|
If so finding matches in child items makes it more useful
|
||||||
|
|
||||||
|
- We want to flag parents to act as being open to filter child matches
|
||||||
|
- and also flag matches so we can highlight them
|
||||||
|
- Flags are stored in TreeStoreElem->flag
|
||||||
|
- Flag options defined in DNA_outliner_types.h
|
||||||
|
- SO_SEARCH_RECURSIVE defined in DNA_space_types.h
|
||||||
|
|
||||||
|
- NOT in datablocks view - searching all datablocks takes way too long
|
||||||
|
to be useful
|
||||||
|
- not searching into RNA items helps but isn't the complete solution
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SEARCHING_OUTLINER(sov) (sov->search_flags & SO_SEARCH_RECURSIVE)
|
||||||
|
|
||||||
|
/* is the currrent element open? if so we also show children */
|
||||||
|
#define TSELEM_OPEN(telm,sv) ( (telm->flag & TSE_CLOSED)==0 || (SEARCHING_OUTLINER(sv) && (telm->flag & TSE_CHILDSEARCH)) )
|
||||||
|
|
||||||
/* outliner_tree.c ----------------------------------------------- */
|
/* outliner_tree.c ----------------------------------------------- */
|
||||||
|
|
||||||
void outliner_free_tree(ListBase *lb);
|
void outliner_free_tree(ListBase *lb);
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *se
|
|||||||
change |= 1;
|
change |= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((tselem->flag & TSE_CLOSED)==0) {
|
else if (TSELEM_OPEN(tselem,soops)) {
|
||||||
/* Only try selecting sub-elements if we haven't hit the right element yet
|
/* Only try selecting sub-elements if we haven't hit the right element yet
|
||||||
*
|
*
|
||||||
* Hack warning:
|
* Hack warning:
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((tselem->flag & TSE_CLOSED)==0) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
set_operation_types(soops, &te->subtree,
|
set_operation_types(soops, &te->subtree,
|
||||||
scenelevel, objectlevel, idlevel, datalevel);
|
scenelevel, objectlevel, idlevel, datalevel);
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ static void outliner_do_libdata_operation(bContext *C, Scene *scene, SpaceOops *
|
|||||||
operation_cb(C, scene, te, tsep, tselem);
|
operation_cb(C, scene, te, tsep, tselem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((tselem->flag & TSE_CLOSED)==0) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
outliner_do_libdata_operation(C, scene, soops, &te->subtree, operation_cb);
|
outliner_do_libdata_operation(C, scene, soops, &te->subtree, operation_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,7 +397,7 @@ void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soop
|
|||||||
operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem);
|
operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((tselem->flag & TSE_CLOSED)==0) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb);
|
outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -504,7 +504,7 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li
|
|||||||
operation_cb(event, te, tselem);
|
operation_cb(event, te, tselem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((tselem->flag & TSE_CLOSED)==0) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb);
|
outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -857,7 +857,7 @@ static void outliner_do_id_set_operation(SpaceOops *soops, int type, ListBase *l
|
|||||||
operation_cb(te, tselem, tsep, newid);
|
operation_cb(te, tselem, tsep, newid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((tselem->flag & TSE_CLOSED)==0) {
|
if (TSELEM_OPEN(tselem,soops)) {
|
||||||
outliner_do_id_set_operation(soops, type, &te->subtree, newid, operation_cb);
|
outliner_do_id_set_operation(soops, type, &te->subtree, newid, operation_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -827,6 +827,10 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
|||||||
check_persistant(soops, te, id, type, index);
|
check_persistant(soops, te, id, type, index);
|
||||||
tselem= TREESTORE(te);
|
tselem= TREESTORE(te);
|
||||||
|
|
||||||
|
/* if we are searching for something expand to see child elements */
|
||||||
|
if(SEARCHING_OUTLINER(soops))
|
||||||
|
tselem->flag |= TSE_CHILDSEARCH;
|
||||||
|
|
||||||
te->parent= parent;
|
te->parent= parent;
|
||||||
te->index= index; // for data arays
|
te->index= index; // for data arays
|
||||||
if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP));
|
if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP));
|
||||||
@@ -981,6 +985,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
|||||||
else
|
else
|
||||||
te->name= (char*)RNA_struct_ui_name(ptr->type);
|
te->name= (char*)RNA_struct_ui_name(ptr->type);
|
||||||
|
|
||||||
|
/* If searching don't expand RNA entries */
|
||||||
|
if(SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA",te->name)==0) tselem->flag &= ~TSE_CHILDSEARCH;
|
||||||
|
|
||||||
iterprop= RNA_struct_iterator_property(ptr->type);
|
iterprop= RNA_struct_iterator_property(ptr->type);
|
||||||
tot= RNA_property_collection_length(ptr, iterprop);
|
tot= RNA_property_collection_length(ptr, iterprop);
|
||||||
|
|
||||||
@@ -989,7 +996,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
|||||||
if(!tselem->used)
|
if(!tselem->used)
|
||||||
tselem->flag &= ~TSE_CLOSED;
|
tselem->flag &= ~TSE_CLOSED;
|
||||||
|
|
||||||
if(!(tselem->flag & TSE_CLOSED)) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
for(a=0; a<tot; a++)
|
for(a=0; a<tot; a++)
|
||||||
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_PROPERTY, a);
|
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_PROPERTY, a);
|
||||||
}
|
}
|
||||||
@@ -1010,11 +1017,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
|||||||
te->directdata= prop;
|
te->directdata= prop;
|
||||||
te->rnaptr= *ptr;
|
te->rnaptr= *ptr;
|
||||||
|
|
||||||
|
/* If searching don't expand RNA entries */
|
||||||
|
if(SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA",te->name)==0) tselem->flag &= ~TSE_CHILDSEARCH;
|
||||||
|
|
||||||
if(proptype == PROP_POINTER) {
|
if(proptype == PROP_POINTER) {
|
||||||
pptr= RNA_property_pointer_get(ptr, prop);
|
pptr= RNA_property_pointer_get(ptr, prop);
|
||||||
|
|
||||||
if(pptr.data) {
|
if(pptr.data) {
|
||||||
if(!(tselem->flag & TSE_CLOSED))
|
if(TSELEM_OPEN(tselem,soops))
|
||||||
outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1);
|
outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1);
|
||||||
else
|
else
|
||||||
te->flag |= TE_LAZY_CLOSED;
|
te->flag |= TE_LAZY_CLOSED;
|
||||||
@@ -1023,7 +1033,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
|||||||
else if(proptype == PROP_COLLECTION) {
|
else if(proptype == PROP_COLLECTION) {
|
||||||
tot= RNA_property_collection_length(ptr, prop);
|
tot= RNA_property_collection_length(ptr, prop);
|
||||||
|
|
||||||
if(!(tselem->flag & TSE_CLOSED)) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
for(a=0; a<tot; a++) {
|
for(a=0; a<tot; a++) {
|
||||||
RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
|
RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
|
||||||
outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, a);
|
outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, a);
|
||||||
@@ -1035,7 +1045,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
|||||||
else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
|
else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
|
||||||
tot= RNA_property_array_length(ptr, prop);
|
tot= RNA_property_array_length(ptr, prop);
|
||||||
|
|
||||||
if(!(tselem->flag & TSE_CLOSED)) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
for(a=0; a<tot; a++)
|
for(a=0; a<tot; a++)
|
||||||
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a);
|
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a);
|
||||||
}
|
}
|
||||||
@@ -1068,7 +1078,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
|||||||
te->directdata= idv;
|
te->directdata= idv;
|
||||||
te->name= km->idname;
|
te->name= km->idname;
|
||||||
|
|
||||||
if(!(tselem->flag & TSE_CLOSED)) {
|
if(TSELEM_OPEN(tselem,soops)) {
|
||||||
a= 0;
|
a= 0;
|
||||||
|
|
||||||
for (kmi= km->items.first; kmi; kmi= kmi->next, a++) {
|
for (kmi= km->items.first; kmi; kmi= kmi->next, a++) {
|
||||||
@@ -1368,7 +1378,10 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
|
|||||||
*/
|
*/
|
||||||
tselem= TREESTORE(te);
|
tselem= TREESTORE(te);
|
||||||
|
|
||||||
if ((tselem->flag & TSE_CLOSED) || outliner_filter_tree(soops, &te->subtree)==0) {
|
/* flag as not a found item */
|
||||||
|
tselem->flag &= ~TSE_SEARCHMATCH;
|
||||||
|
|
||||||
|
if ((!TSELEM_OPEN(tselem,soops)) || outliner_filter_tree(soops, &te->subtree)==0) {
|
||||||
outliner_free_tree(&te->subtree);
|
outliner_free_tree(&te->subtree);
|
||||||
BLI_remlink(lb, te);
|
BLI_remlink(lb, te);
|
||||||
|
|
||||||
@@ -1377,6 +1390,11 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
tselem= TREESTORE(te);
|
||||||
|
|
||||||
|
/* flag as a found item - we can then highlight it */
|
||||||
|
tselem->flag |= TSE_SEARCHMATCH;
|
||||||
|
|
||||||
/* filter subtree too */
|
/* filter subtree too */
|
||||||
outliner_filter_tree(soops, &te->subtree);
|
outliner_filter_tree(soops, &te->subtree);
|
||||||
}
|
}
|
||||||
@@ -1399,6 +1417,14 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
|
|||||||
TreeStoreElem *tselem;
|
TreeStoreElem *tselem;
|
||||||
int show_opened= (soops->treestore==NULL); /* on first view, we open scenes */
|
int show_opened= (soops->treestore==NULL); /* on first view, we open scenes */
|
||||||
|
|
||||||
|
/* Are we looking for something - we want to tag parents to filter child matches
|
||||||
|
- NOT in datablocks view - searching all datablocks takes way too long to be useful
|
||||||
|
- this variable is only set once per tree build */
|
||||||
|
if(soops->search_string[0]!=0 && soops->outlinevis!=SO_DATABLOCKS)
|
||||||
|
soops->search_flags |= SO_SEARCH_RECURSIVE;
|
||||||
|
else
|
||||||
|
soops->search_flags &= ~SO_SEARCH_RECURSIVE;
|
||||||
|
|
||||||
if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW))
|
if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
|
|||||||
int GPU_texture_target(GPUTexture *tex);
|
int GPU_texture_target(GPUTexture *tex);
|
||||||
int GPU_texture_opengl_width(GPUTexture *tex);
|
int GPU_texture_opengl_width(GPUTexture *tex);
|
||||||
int GPU_texture_opengl_height(GPUTexture *tex);
|
int GPU_texture_opengl_height(GPUTexture *tex);
|
||||||
|
int GPU_texture_opengl_bindcode(GPUTexture *tex);
|
||||||
|
|
||||||
/* GPU Framebuffer
|
/* GPU Framebuffer
|
||||||
- this is a wrapper for an OpenGL framebuffer object (FBO). in practice
|
- this is a wrapper for an OpenGL framebuffer object (FBO). in practice
|
||||||
@@ -179,6 +180,7 @@ typedef struct GPUVertexAttribs {
|
|||||||
int type;
|
int type;
|
||||||
int glindex;
|
int glindex;
|
||||||
int gltexco;
|
int gltexco;
|
||||||
|
int attribid;
|
||||||
char name[32];
|
char name[32];
|
||||||
} layer[GPU_MAX_ATTRIB];
|
} layer[GPU_MAX_ATTRIB];
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
#ifndef __GPU_MATERIAL__
|
#ifndef __GPU_MATERIAL__
|
||||||
#define __GPU_MATERIAL__
|
#define __GPU_MATERIAL__
|
||||||
|
|
||||||
|
#include "DNA_listBase.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -46,6 +48,7 @@ struct ImageUser;
|
|||||||
struct Material;
|
struct Material;
|
||||||
struct Object;
|
struct Object;
|
||||||
struct Lamp;
|
struct Lamp;
|
||||||
|
struct Image;
|
||||||
struct bNode;
|
struct bNode;
|
||||||
struct LinkNode;
|
struct LinkNode;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
@@ -72,7 +75,6 @@ typedef enum GPUType {
|
|||||||
GPU_VEC4 = 4,
|
GPU_VEC4 = 4,
|
||||||
GPU_MAT3 = 9,
|
GPU_MAT3 = 9,
|
||||||
GPU_MAT4 = 16,
|
GPU_MAT4 = 16,
|
||||||
GPU_TEX1D = 1001,
|
|
||||||
GPU_TEX2D = 1002,
|
GPU_TEX2D = 1002,
|
||||||
GPU_SHADOW2D = 1003,
|
GPU_SHADOW2D = 1003,
|
||||||
GPU_ATTRIB = 3001
|
GPU_ATTRIB = 3001
|
||||||
@@ -107,10 +109,10 @@ typedef struct GPUNodeStack {
|
|||||||
|
|
||||||
GPUNodeLink *GPU_attribute(int type, const char *name);
|
GPUNodeLink *GPU_attribute(int type, const char *name);
|
||||||
GPUNodeLink *GPU_uniform(float *num);
|
GPUNodeLink *GPU_uniform(float *num);
|
||||||
GPUNodeLink *GPU_dynamic_uniform(float *num);
|
GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data);
|
||||||
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser);
|
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser);
|
||||||
GPUNodeLink *GPU_texture(int size, float *pixels);
|
GPUNodeLink *GPU_texture(int size, float *pixels);
|
||||||
GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex);
|
GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, int dynamictype, void *data);
|
||||||
GPUNodeLink *GPU_socket(GPUNodeStack *sock);
|
GPUNodeLink *GPU_socket(GPUNodeStack *sock);
|
||||||
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
|
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
|
||||||
|
|
||||||
@@ -153,6 +155,72 @@ typedef struct GPUShadeResult {
|
|||||||
void GPU_shadeinput_set(GPUMaterial *mat, struct Material *ma, GPUShadeInput *shi);
|
void GPU_shadeinput_set(GPUMaterial *mat, struct Material *ma, GPUShadeInput *shi);
|
||||||
void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr);
|
void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr);
|
||||||
|
|
||||||
|
/* Export GLSL shader */
|
||||||
|
|
||||||
|
typedef enum GPUDynamicType {
|
||||||
|
GPU_DYNAMIC_NONE = 0,
|
||||||
|
GPU_DYNAMIC_OBJECT_VIEWMAT = 1,
|
||||||
|
GPU_DYNAMIC_OBJECT_MAT = 2,
|
||||||
|
GPU_DYNAMIC_OBJECT_VIEWIMAT = 3,
|
||||||
|
GPU_DYNAMIC_OBJECT_IMAT = 4,
|
||||||
|
GPU_DYNAMIC_OBJECT_COLOR = 5,
|
||||||
|
GPU_DYNAMIC_LAMP_FIRST = 6,
|
||||||
|
GPU_DYNAMIC_LAMP_DYNVEC = 6,
|
||||||
|
GPU_DYNAMIC_LAMP_DYNCO = 7,
|
||||||
|
GPU_DYNAMIC_LAMP_DYNIMAT = 8,
|
||||||
|
GPU_DYNAMIC_LAMP_DYNPERSMAT = 9,
|
||||||
|
GPU_DYNAMIC_LAMP_DYNENERGY = 10,
|
||||||
|
GPU_DYNAMIC_LAMP_DYNCOL = 11,
|
||||||
|
GPU_DYNAMIC_LAMP_LAST = 11,
|
||||||
|
GPU_DYNAMIC_SAMPLER_2DBUFFER = 12,
|
||||||
|
GPU_DYNAMIC_SAMPLER_2DIMAGE = 13,
|
||||||
|
GPU_DYNAMIC_SAMPLER_2DSHADOW = 14,
|
||||||
|
} GPUDynamicType;
|
||||||
|
|
||||||
|
typedef enum GPUDataType {
|
||||||
|
GPU_DATA_NONE = 0,
|
||||||
|
GPU_DATA_1I = 1, // 1 integer
|
||||||
|
GPU_DATA_1F = 2,
|
||||||
|
GPU_DATA_2F = 3,
|
||||||
|
GPU_DATA_3F = 4,
|
||||||
|
GPU_DATA_4F = 5,
|
||||||
|
GPU_DATA_9F = 6,
|
||||||
|
GPU_DATA_16F = 7,
|
||||||
|
GPU_DATA_4UB = 8,
|
||||||
|
} GPUDataType;
|
||||||
|
|
||||||
|
/* this structure gives information of each uniform found in the shader */
|
||||||
|
typedef struct GPUInputUniform {
|
||||||
|
struct GPUInputUniform *next, *prev;
|
||||||
|
char varname[32]; /* name of uniform in shader */
|
||||||
|
GPUDynamicType type; /* type of uniform, data format and calculation derive from it */
|
||||||
|
GPUDataType datatype; /* type of uniform data */
|
||||||
|
struct Object *lamp; /* when type=GPU_DYNAMIC_LAMP_... or GPU_DYNAMIC_SAMPLER_2DSHADOW */
|
||||||
|
struct Image *image; /* when type=GPU_DYNAMIC_SAMPLER_2DIMAGE */
|
||||||
|
int texnumber; /* when type=GPU_DYNAMIC_SAMPLER, texture number: 0.. */
|
||||||
|
unsigned char *texpixels; /* for internally generated texture, pixel data in RGBA format */
|
||||||
|
int texsize; /* size in pixel of the texture in texpixels buffer: for 2D textures, this is S and T size (square texture) */
|
||||||
|
} GPUInputUniform;
|
||||||
|
|
||||||
|
typedef struct GPUInputAttribute {
|
||||||
|
struct GPUInputAttribute *next, *prev;
|
||||||
|
char varname[32]; /* name of attribute in shader */
|
||||||
|
int type; /* from CustomData.type, data type derives from it */
|
||||||
|
GPUDataType datatype; /* type of attribute data */
|
||||||
|
const char *name; /* layer name */
|
||||||
|
int number; /* generic attribute number */
|
||||||
|
} GPUInputAttribute;
|
||||||
|
|
||||||
|
typedef struct GPUShaderExport {
|
||||||
|
ListBase uniforms;
|
||||||
|
ListBase attributes;
|
||||||
|
char *vertex;
|
||||||
|
char *fragment;
|
||||||
|
} GPUShaderExport;
|
||||||
|
|
||||||
|
GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma);
|
||||||
|
void GPU_free_shader_export(GPUShaderExport *shader);
|
||||||
|
|
||||||
/* Lamps */
|
/* Lamps */
|
||||||
|
|
||||||
GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
|
GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
|
||||||
|
|||||||
@@ -64,101 +64,9 @@ extern char datatoc_gpu_shader_vertex_glsl[];
|
|||||||
|
|
||||||
/* structs and defines */
|
/* structs and defines */
|
||||||
|
|
||||||
typedef enum GPUDataSource {
|
|
||||||
GPU_SOURCE_VEC_UNIFORM,
|
|
||||||
GPU_SOURCE_BUILTIN,
|
|
||||||
GPU_SOURCE_TEX_PIXEL,
|
|
||||||
GPU_SOURCE_TEX,
|
|
||||||
GPU_SOURCE_ATTRIB
|
|
||||||
} GPUDataSource;
|
|
||||||
|
|
||||||
static const char* GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4",
|
static const char* GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4",
|
||||||
NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4"};
|
NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4"};
|
||||||
|
|
||||||
struct GPUNode {
|
|
||||||
struct GPUNode *next, *prev;
|
|
||||||
|
|
||||||
const char *name;
|
|
||||||
int tag;
|
|
||||||
|
|
||||||
ListBase inputs;
|
|
||||||
ListBase outputs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GPUNodeLink {
|
|
||||||
GPUNodeStack *socket;
|
|
||||||
|
|
||||||
int attribtype;
|
|
||||||
const char *attribname;
|
|
||||||
|
|
||||||
int image;
|
|
||||||
|
|
||||||
int texture;
|
|
||||||
int texturesize;
|
|
||||||
|
|
||||||
void *ptr1, *ptr2;
|
|
||||||
|
|
||||||
int dynamic;
|
|
||||||
|
|
||||||
int type;
|
|
||||||
int users;
|
|
||||||
|
|
||||||
GPUTexture *dynamictex;
|
|
||||||
|
|
||||||
GPUBuiltin builtin;
|
|
||||||
|
|
||||||
struct GPUOutput *output;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct GPUOutput {
|
|
||||||
struct GPUOutput *next, *prev;
|
|
||||||
|
|
||||||
GPUNode *node;
|
|
||||||
int type; /* data type = length of vector/matrix */
|
|
||||||
GPUNodeLink *link; /* output link */
|
|
||||||
int id; /* unique id as created by code generator */
|
|
||||||
} GPUOutput;
|
|
||||||
|
|
||||||
typedef struct GPUInput {
|
|
||||||
struct GPUInput *next, *prev;
|
|
||||||
|
|
||||||
GPUNode *node;
|
|
||||||
|
|
||||||
int type; /* datatype */
|
|
||||||
int source; /* data source */
|
|
||||||
|
|
||||||
int id; /* unique id as created by code generator */
|
|
||||||
int texid; /* number for multitexture */
|
|
||||||
int attribid; /* id for vertex attributes */
|
|
||||||
int bindtex; /* input is responsible for binding the texture? */
|
|
||||||
int definetex; /* input is responsible for defining the pixel? */
|
|
||||||
int textarget; /* GL_TEXTURE_* */
|
|
||||||
int textype; /* datatype */
|
|
||||||
|
|
||||||
struct Image *ima; /* image */
|
|
||||||
struct ImageUser *iuser;/* image user */
|
|
||||||
float *dynamicvec; /* vector data in case it is dynamic */
|
|
||||||
GPUTexture *tex; /* input texture, only set at runtime */
|
|
||||||
int shaderloc; /* id from opengl */
|
|
||||||
char shadername[32]; /* name in shader */
|
|
||||||
|
|
||||||
float vec[16]; /* vector data */
|
|
||||||
GPUNodeLink *link;
|
|
||||||
int dynamictex; /* dynamic? */
|
|
||||||
int attribtype; /* attribute type */
|
|
||||||
char attribname[32]; /* attribute name */
|
|
||||||
int attribfirst; /* this is the first one that is bound */
|
|
||||||
GPUBuiltin builtin; /* builtin uniform */
|
|
||||||
} GPUInput;
|
|
||||||
|
|
||||||
struct GPUPass {
|
|
||||||
struct GPUPass *next, *prev;
|
|
||||||
|
|
||||||
ListBase inputs;
|
|
||||||
struct GPUOutput *output;
|
|
||||||
struct GPUShader *shader;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* GLSL code parsing for finding function definitions.
|
/* GLSL code parsing for finding function definitions.
|
||||||
* These are stored in a hash for lookup when creating a material. */
|
* These are stored in a hash for lookup when creating a material. */
|
||||||
|
|
||||||
@@ -245,8 +153,6 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
|
|||||||
|
|
||||||
if(!type && gpu_str_prefix(code, "sampler2DShadow"))
|
if(!type && gpu_str_prefix(code, "sampler2DShadow"))
|
||||||
type= GPU_SHADOW2D;
|
type= GPU_SHADOW2D;
|
||||||
if(!type && gpu_str_prefix(code, "sampler1D"))
|
|
||||||
type= GPU_TEX1D;
|
|
||||||
if(!type && gpu_str_prefix(code, "sampler2D"))
|
if(!type && gpu_str_prefix(code, "sampler2D"))
|
||||||
type= GPU_TEX2D;
|
type= GPU_TEX2D;
|
||||||
|
|
||||||
@@ -298,9 +204,7 @@ static char *gpu_generate_function_prototyps(GHash *hash)
|
|||||||
else if(function->paramqual[a] == FUNCTION_QUAL_INOUT)
|
else if(function->paramqual[a] == FUNCTION_QUAL_INOUT)
|
||||||
BLI_dynstr_append(ds, "inout ");
|
BLI_dynstr_append(ds, "inout ");
|
||||||
|
|
||||||
if(function->paramtype[a] == GPU_TEX1D)
|
if(function->paramtype[a] == GPU_TEX2D)
|
||||||
BLI_dynstr_append(ds, "sampler1D");
|
|
||||||
else if(function->paramtype[a] == GPU_TEX2D)
|
|
||||||
BLI_dynstr_append(ds, "sampler2D");
|
BLI_dynstr_append(ds, "sampler2D");
|
||||||
else if(function->paramtype[a] == GPU_SHADOW2D)
|
else if(function->paramtype[a] == GPU_SHADOW2D)
|
||||||
BLI_dynstr_append(ds, "sampler2DShadow");
|
BLI_dynstr_append(ds, "sampler2DShadow");
|
||||||
@@ -542,7 +446,6 @@ static void codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
|
|||||||
/* create exactly one sampler for each texture */
|
/* create exactly one sampler for each texture */
|
||||||
if (codegen_input_has_texture(input) && input->bindtex)
|
if (codegen_input_has_texture(input) && input->bindtex)
|
||||||
BLI_dynstr_appendf(ds, "uniform %s samp%d;\n",
|
BLI_dynstr_appendf(ds, "uniform %s samp%d;\n",
|
||||||
(input->textype == GPU_TEX1D)? "sampler1D":
|
|
||||||
(input->textype == GPU_TEX2D)? "sampler2D": "sampler2DShadow",
|
(input->textype == GPU_TEX2D)? "sampler2D": "sampler2DShadow",
|
||||||
input->texid);
|
input->texid);
|
||||||
}
|
}
|
||||||
@@ -947,6 +850,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
|
|||||||
input->textarget = GL_TEXTURE_2D;
|
input->textarget = GL_TEXTURE_2D;
|
||||||
input->textype = type;
|
input->textype = type;
|
||||||
input->dynamictex = 1;
|
input->dynamictex = 1;
|
||||||
|
input->dynamicdata = link->ptr2;
|
||||||
MEM_freeN(link);
|
MEM_freeN(link);
|
||||||
}
|
}
|
||||||
else if(link->texture) {
|
else if(link->texture) {
|
||||||
@@ -955,14 +859,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
|
|||||||
input->source = GPU_SOURCE_TEX;
|
input->source = GPU_SOURCE_TEX;
|
||||||
input->textype = type;
|
input->textype = type;
|
||||||
|
|
||||||
if (type == GPU_TEX1D) {
|
//input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
|
||||||
input->tex = GPU_texture_create_1D(link->texturesize, link->ptr1, NULL);
|
input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, NULL);
|
||||||
input->textarget = GL_TEXTURE_1D;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
|
|
||||||
input->textarget = GL_TEXTURE_2D;
|
input->textarget = GL_TEXTURE_2D;
|
||||||
}
|
|
||||||
|
|
||||||
MEM_freeN(link->ptr1);
|
MEM_freeN(link->ptr1);
|
||||||
MEM_freeN(link);
|
MEM_freeN(link);
|
||||||
@@ -993,8 +892,11 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
|
|||||||
input->source = GPU_SOURCE_VEC_UNIFORM;
|
input->source = GPU_SOURCE_VEC_UNIFORM;
|
||||||
|
|
||||||
memcpy(input->vec, link->ptr1, type*sizeof(float));
|
memcpy(input->vec, link->ptr1, type*sizeof(float));
|
||||||
if(link->dynamic)
|
if(link->dynamic) {
|
||||||
input->dynamicvec= link->ptr1;
|
input->dynamicvec= link->ptr1;
|
||||||
|
input->dynamictype= link->dynamictype;
|
||||||
|
input->dynamicdata= link->ptr2;
|
||||||
|
}
|
||||||
MEM_freeN(link);
|
MEM_freeN(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1102,12 +1004,12 @@ static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *a
|
|||||||
input->attribfirst = 1;
|
input->attribfirst = 1;
|
||||||
|
|
||||||
attribs->layer[a].type = input->attribtype;
|
attribs->layer[a].type = input->attribtype;
|
||||||
attribs->layer[a].glindex = input->attribid;
|
attribs->layer[a].attribid = input->attribid;
|
||||||
BLI_strncpy(attribs->layer[a].name, input->attribname,
|
BLI_strncpy(attribs->layer[a].name, input->attribname,
|
||||||
sizeof(attribs->layer[a].name));
|
sizeof(attribs->layer[a].name));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
input->attribid = attribs->layer[a].glindex;
|
input->attribid = attribs->layer[a].attribid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1148,13 +1050,15 @@ GPUNodeLink *GPU_uniform(float *num)
|
|||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUNodeLink *GPU_dynamic_uniform(float *num)
|
GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
|
||||||
{
|
{
|
||||||
GPUNodeLink *link = GPU_node_link_create(0);
|
GPUNodeLink *link = GPU_node_link_create(0);
|
||||||
|
|
||||||
link->ptr1= num;
|
link->ptr1= num;
|
||||||
link->ptr2= NULL;
|
link->ptr2= data;
|
||||||
link->dynamic= 1;
|
link->dynamic= 1;
|
||||||
|
link->dynamictype = dynamictype;
|
||||||
|
|
||||||
|
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
@@ -1181,12 +1085,14 @@ GPUNodeLink *GPU_texture(int size, float *pixels)
|
|||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex)
|
GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data)
|
||||||
{
|
{
|
||||||
GPUNodeLink *link = GPU_node_link_create(0);
|
GPUNodeLink *link = GPU_node_link_create(0);
|
||||||
|
|
||||||
link->dynamic = 1;
|
link->dynamic = 1;
|
||||||
link->dynamictex = tex;
|
link->dynamictex = tex;
|
||||||
|
link->dynamictype = dynamictype;
|
||||||
|
link->ptr2 = data;
|
||||||
|
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
@@ -1389,8 +1295,6 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
|
|||||||
fragmentcode = code_generate_fragment(nodes, outlink->output, name);
|
fragmentcode = code_generate_fragment(nodes, outlink->output, name);
|
||||||
vertexcode = code_generate_vertex(nodes);
|
vertexcode = code_generate_vertex(nodes);
|
||||||
shader = GPU_shader_create(vertexcode, fragmentcode, datatoc_gpu_shader_material_glsl); /*FUNCTION_LIB);*/
|
shader = GPU_shader_create(vertexcode, fragmentcode, datatoc_gpu_shader_material_glsl); /*FUNCTION_LIB);*/
|
||||||
MEM_freeN(fragmentcode);
|
|
||||||
MEM_freeN(vertexcode);
|
|
||||||
|
|
||||||
/* failed? */
|
/* failed? */
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
@@ -1405,6 +1309,9 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
|
|||||||
|
|
||||||
pass->output = outlink->output;
|
pass->output = outlink->output;
|
||||||
pass->shader = shader;
|
pass->shader = shader;
|
||||||
|
pass->fragmentcode = fragmentcode;
|
||||||
|
pass->vertexcode = vertexcode;
|
||||||
|
pass->libcode = datatoc_gpu_shader_material_glsl;
|
||||||
|
|
||||||
/* extract dynamic inputs and throw away nodes */
|
/* extract dynamic inputs and throw away nodes */
|
||||||
GPU_nodes_extract_dynamic_inputs(pass, nodes);
|
GPU_nodes_extract_dynamic_inputs(pass, nodes);
|
||||||
@@ -1417,6 +1324,10 @@ void GPU_pass_free(GPUPass *pass)
|
|||||||
{
|
{
|
||||||
GPU_shader_free(pass->shader);
|
GPU_shader_free(pass->shader);
|
||||||
GPU_inputs_free(&pass->inputs);
|
GPU_inputs_free(&pass->inputs);
|
||||||
|
if (pass->fragmentcode)
|
||||||
|
MEM_freeN(pass->fragmentcode);
|
||||||
|
if (pass->vertexcode)
|
||||||
|
MEM_freeN(pass->vertexcode);
|
||||||
MEM_freeN(pass);
|
MEM_freeN(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,12 +39,15 @@
|
|||||||
#define __GPU_CODEGEN_H__
|
#define __GPU_CODEGEN_H__
|
||||||
|
|
||||||
#include "DNA_listBase.h"
|
#include "DNA_listBase.h"
|
||||||
|
#include "GPU_material.h"
|
||||||
|
#include "GL/glew.h"
|
||||||
|
|
||||||
struct ListBase;
|
struct ListBase;
|
||||||
struct GPUShader;
|
struct GPUShader;
|
||||||
struct GPUOutput;
|
struct GPUOutput;
|
||||||
struct GPUNode;
|
struct GPUNode;
|
||||||
struct GPUVertexAttribs;
|
struct GPUVertexAttribs;
|
||||||
|
struct GPUFrameBuffer;
|
||||||
|
|
||||||
#define MAX_FUNCTION_NAME 64
|
#define MAX_FUNCTION_NAME 64
|
||||||
#define MAX_PARAMETER 32
|
#define MAX_PARAMETER 32
|
||||||
@@ -68,7 +71,105 @@ GPUFunction *GPU_lookup_function(const char *name);
|
|||||||
at the end if used.
|
at the end if used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct GPUPass;
|
typedef enum GPUDataSource {
|
||||||
|
GPU_SOURCE_VEC_UNIFORM,
|
||||||
|
GPU_SOURCE_BUILTIN,
|
||||||
|
GPU_SOURCE_TEX_PIXEL,
|
||||||
|
GPU_SOURCE_TEX,
|
||||||
|
GPU_SOURCE_ATTRIB
|
||||||
|
} GPUDataSource;
|
||||||
|
|
||||||
|
struct GPUNode {
|
||||||
|
struct GPUNode *next, *prev;
|
||||||
|
|
||||||
|
const char *name;
|
||||||
|
int tag;
|
||||||
|
|
||||||
|
ListBase inputs;
|
||||||
|
ListBase outputs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GPUNodeLink {
|
||||||
|
GPUNodeStack *socket;
|
||||||
|
|
||||||
|
int attribtype;
|
||||||
|
const char *attribname;
|
||||||
|
|
||||||
|
int image;
|
||||||
|
|
||||||
|
int texture;
|
||||||
|
int texturesize;
|
||||||
|
|
||||||
|
void *ptr1, *ptr2;
|
||||||
|
|
||||||
|
int dynamic;
|
||||||
|
int dynamictype;
|
||||||
|
|
||||||
|
int type;
|
||||||
|
int users;
|
||||||
|
|
||||||
|
GPUTexture *dynamictex;
|
||||||
|
|
||||||
|
GPUBuiltin builtin;
|
||||||
|
|
||||||
|
struct GPUOutput *output;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct GPUOutput {
|
||||||
|
struct GPUOutput *next, *prev;
|
||||||
|
|
||||||
|
GPUNode *node;
|
||||||
|
int type; /* data type = length of vector/matrix */
|
||||||
|
GPUNodeLink *link; /* output link */
|
||||||
|
int id; /* unique id as created by code generator */
|
||||||
|
} GPUOutput;
|
||||||
|
|
||||||
|
typedef struct GPUInput {
|
||||||
|
struct GPUInput *next, *prev;
|
||||||
|
|
||||||
|
GPUNode *node;
|
||||||
|
|
||||||
|
int type; /* datatype */
|
||||||
|
int source; /* data source */
|
||||||
|
|
||||||
|
int id; /* unique id as created by code generator */
|
||||||
|
int texid; /* number for multitexture */
|
||||||
|
int attribid; /* id for vertex attributes */
|
||||||
|
int bindtex; /* input is responsible for binding the texture? */
|
||||||
|
int definetex; /* input is responsible for defining the pixel? */
|
||||||
|
int textarget; /* GL_TEXTURE_* */
|
||||||
|
int textype; /* datatype */
|
||||||
|
|
||||||
|
struct Image *ima; /* image */
|
||||||
|
struct ImageUser *iuser;/* image user */
|
||||||
|
float *dynamicvec; /* vector data in case it is dynamic */
|
||||||
|
int dynamictype; /* origin of the dynamic uniform (GPUDynamicType) */
|
||||||
|
void *dynamicdata; /* data source of the dynamic uniform */
|
||||||
|
GPUTexture *tex; /* input texture, only set at runtime */
|
||||||
|
int shaderloc; /* id from opengl */
|
||||||
|
char shadername[32]; /* name in shader */
|
||||||
|
|
||||||
|
float vec[16]; /* vector data */
|
||||||
|
GPUNodeLink *link;
|
||||||
|
int dynamictex; /* dynamic? */
|
||||||
|
int attribtype; /* attribute type */
|
||||||
|
char attribname[32]; /* attribute name */
|
||||||
|
int attribfirst; /* this is the first one that is bound */
|
||||||
|
GPUBuiltin builtin; /* builtin uniform */
|
||||||
|
} GPUInput;
|
||||||
|
|
||||||
|
struct GPUPass {
|
||||||
|
struct GPUPass *next, *prev;
|
||||||
|
|
||||||
|
ListBase inputs;
|
||||||
|
struct GPUOutput *output;
|
||||||
|
struct GPUShader *shader;
|
||||||
|
char *fragmentcode;
|
||||||
|
char *vertexcode;
|
||||||
|
const char *libcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct GPUPass GPUPass;
|
typedef struct GPUPass GPUPass;
|
||||||
|
|
||||||
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
|
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
|
|||||||
|
|
||||||
if (tex->target != GL_TEXTURE_1D) {
|
if (tex->target != GL_TEXTURE_1D) {
|
||||||
/* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */
|
/* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */
|
||||||
GLenum wrapmode = (depth)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER;
|
GLenum wrapmode = (depth || tex->h == 1)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER;
|
||||||
glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode);
|
glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode);
|
||||||
glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode);
|
glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode);
|
||||||
|
|
||||||
@@ -685,6 +685,11 @@ int GPU_texture_opengl_height(GPUTexture *tex)
|
|||||||
return tex->h;
|
return tex->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GPU_texture_opengl_bindcode(GPUTexture *tex)
|
||||||
|
{
|
||||||
|
return tex->bindcode;
|
||||||
|
}
|
||||||
|
|
||||||
GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
|
GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
|
||||||
{
|
{
|
||||||
return tex->fb;
|
return tex->fb;
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ static void gpu_material_set_attrib_id(GPUMaterial *material)
|
|||||||
* removed by the glsl compiler by dead code elimination */
|
* removed by the glsl compiler by dead code elimination */
|
||||||
|
|
||||||
for(a=0, b=0; a<attribs->totlayer; a++) {
|
for(a=0, b=0; a<attribs->totlayer; a++) {
|
||||||
sprintf(name, "att%d", attribs->layer[a].glindex);
|
sprintf(name, "att%d", attribs->layer[a].attribid);
|
||||||
attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
|
attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
|
||||||
|
|
||||||
if(attribs->layer[a].glindex >= 0) {
|
if(attribs->layer[a].glindex >= 0) {
|
||||||
@@ -386,12 +386,12 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode
|
|||||||
/* from get_lamp_visibility */
|
/* from get_lamp_visibility */
|
||||||
if(lamp->type==LA_SUN || lamp->type==LA_HEMI) {
|
if(lamp->type==LA_SUN || lamp->type==LA_HEMI) {
|
||||||
mat->dynproperty |= DYN_LAMP_VEC;
|
mat->dynproperty |= DYN_LAMP_VEC;
|
||||||
GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec), lv, dist, &visifac);
|
GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac);
|
||||||
return visifac;
|
return visifac;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mat->dynproperty |= DYN_LAMP_CO;
|
mat->dynproperty |= DYN_LAMP_CO;
|
||||||
GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), lv, dist, &visifac);
|
GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac);
|
||||||
|
|
||||||
if(lamp->type==LA_AREA)
|
if(lamp->type==LA_AREA)
|
||||||
return visifac;
|
return visifac;
|
||||||
@@ -426,11 +426,11 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode
|
|||||||
if(lamp->type == LA_SPOT) {
|
if(lamp->type == LA_SPOT) {
|
||||||
if(lamp->mode & LA_SQUARE) {
|
if(lamp->mode & LA_SQUARE) {
|
||||||
mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT;
|
mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT;
|
||||||
GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec), GPU_dynamic_uniform((float*)lamp->dynimat), *lv, &inpr);
|
GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), GPU_dynamic_uniform((float*)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), *lv, &inpr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mat->dynproperty |= DYN_LAMP_VEC;
|
mat->dynproperty |= DYN_LAMP_VEC;
|
||||||
GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec), *lv, &inpr);
|
GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), *lv, &inpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac);
|
GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac);
|
||||||
@@ -646,7 +646,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
|
|||||||
float area[4][4]= {{0.0f}}, areasize= 0.0f;
|
float area[4][4]= {{0.0f}}, areasize= 0.0f;
|
||||||
|
|
||||||
mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO;
|
mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO;
|
||||||
GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), GPU_dynamic_uniform(lamp->dynvec), vn, GPU_uniform((float*)area),
|
GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn, GPU_uniform((float*)area),
|
||||||
GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp);
|
GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,13 +684,13 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
|
|||||||
|
|
||||||
GPU_link(mat, "test_shadowbuf",
|
GPU_link(mat, "test_shadowbuf",
|
||||||
GPU_builtin(GPU_VIEW_POSITION),
|
GPU_builtin(GPU_VIEW_POSITION),
|
||||||
GPU_dynamic_texture(lamp->tex),
|
GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
|
||||||
GPU_dynamic_uniform((float*)lamp->dynpersmat),
|
GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
|
||||||
GPU_uniform(&lamp->bias), inp, &shadfac);
|
GPU_uniform(&lamp->bias), inp, &shadfac);
|
||||||
|
|
||||||
if(lamp->mode & LA_ONLYSHADOW) {
|
if(lamp->mode & LA_ONLYSHADOW) {
|
||||||
GPU_link(mat, "shade_only_shadow", i, shadfac,
|
GPU_link(mat, "shade_only_shadow", i, shadfac,
|
||||||
GPU_dynamic_uniform(&lamp->dynenergy), &shadfac);
|
GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), &shadfac);
|
||||||
|
|
||||||
if(!(lamp->mode & LA_NO_DIFF))
|
if(!(lamp->mode & LA_NO_DIFF))
|
||||||
GPU_link(mat, "shade_only_shadow_diffuse", shadfac, shi->rgb,
|
GPU_link(mat, "shade_only_shadow_diffuse", shadfac, shi->rgb,
|
||||||
@@ -719,7 +719,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
|
|||||||
if(GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
|
if(GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
|
||||||
if(!(lamp->mode & LA_NO_DIFF)) {
|
if(!(lamp->mode & LA_NO_DIFF)) {
|
||||||
GPUNodeLink *rgb;
|
GPUNodeLink *rgb;
|
||||||
GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol), &rgb);
|
GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &rgb);
|
||||||
add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
|
add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -729,7 +729,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
|
|||||||
(GPU_link_changed(shi->spec) || ma->spec != 0.0f)) {
|
(GPU_link_changed(shi->spec) || ma->spec != 0.0f)) {
|
||||||
if(lamp->type == LA_HEMI) {
|
if(lamp->type == LA_HEMI) {
|
||||||
GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
|
GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
|
||||||
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol);
|
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol);
|
||||||
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
|
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -752,11 +752,11 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
|
|||||||
if(ma->mode & MA_RAMP_SPEC) {
|
if(ma->mode & MA_RAMP_SPEC) {
|
||||||
GPUNodeLink *spec;
|
GPUNodeLink *spec;
|
||||||
do_specular_ramp(shi, specfac, t, &spec);
|
do_specular_ramp(shi, specfac, t, &spec);
|
||||||
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), spec, &outcol);
|
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), spec, &outcol);
|
||||||
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
|
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol);
|
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol);
|
||||||
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
|
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1676,3 +1676,187 @@ int GPU_lamp_shadow_layer(GPULamp *lamp)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* export the GLSL shader */
|
||||||
|
|
||||||
|
GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
|
||||||
|
{
|
||||||
|
static struct {
|
||||||
|
GPUBuiltin gputype;
|
||||||
|
GPUDynamicType dynamictype;
|
||||||
|
GPUDataType datatype;
|
||||||
|
} builtins[] = {
|
||||||
|
{ GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F },
|
||||||
|
{ GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
|
||||||
|
{ GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
|
||||||
|
{ GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
|
||||||
|
{ GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
GPUShaderExport *shader = NULL;
|
||||||
|
GPUPass *pass;
|
||||||
|
GPUInput *input;
|
||||||
|
GPUMaterial *mat;
|
||||||
|
GPUInputUniform *uniform;
|
||||||
|
GPUInputAttribute *attribute;
|
||||||
|
GLint lastbindcode;
|
||||||
|
int i, liblen, fraglen;
|
||||||
|
|
||||||
|
if(!GPU_glsl_support())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
mat = GPU_material_from_blender(scene, ma);
|
||||||
|
pass = (mat)? mat->pass: NULL;
|
||||||
|
|
||||||
|
if(pass && pass->fragmentcode && pass->vertexcode) {
|
||||||
|
shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport");
|
||||||
|
|
||||||
|
for(input = pass->inputs.first; input; input = input->next) {
|
||||||
|
uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
|
||||||
|
|
||||||
|
if(input->ima) {
|
||||||
|
/* image sampler uniform */
|
||||||
|
uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE;
|
||||||
|
uniform->datatype = GPU_DATA_1I;
|
||||||
|
uniform->image = input->ima;
|
||||||
|
uniform->texnumber = input->texid;
|
||||||
|
BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
|
||||||
|
}
|
||||||
|
else if(input->tex) {
|
||||||
|
/* generated buffer */
|
||||||
|
uniform->texnumber = input->texid;
|
||||||
|
uniform->datatype = GPU_DATA_1I;
|
||||||
|
BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
|
||||||
|
|
||||||
|
switch(input->textype) {
|
||||||
|
case GPU_SHADOW2D:
|
||||||
|
uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW;
|
||||||
|
uniform->lamp = input->dynamicdata;
|
||||||
|
break;
|
||||||
|
case GPU_TEX2D:
|
||||||
|
if(GPU_texture_opengl_bindcode(input->tex)) {
|
||||||
|
uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex));
|
||||||
|
uniform->texsize = GPU_texture_opengl_width(input->tex) * GPU_texture_opengl_height(input->tex);
|
||||||
|
uniform->texpixels = MEM_mallocN(uniform->texsize*4, "RGBApixels");
|
||||||
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, lastbindcode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uniform->type = input->dynamictype;
|
||||||
|
BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
|
||||||
|
switch(input->type) {
|
||||||
|
case 1:
|
||||||
|
uniform->datatype = GPU_DATA_1F;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
uniform->datatype = GPU_DATA_2F;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
uniform->datatype = GPU_DATA_3F;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
uniform->datatype = GPU_DATA_4F;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
uniform->datatype = GPU_DATA_9F;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
uniform->datatype = GPU_DATA_16F;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uniform->type >= GPU_DYNAMIC_LAMP_FIRST && uniform->type <= GPU_DYNAMIC_LAMP_LAST)
|
||||||
|
uniform->lamp = input->dynamicdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uniform->type != GPU_DYNAMIC_NONE)
|
||||||
|
BLI_addtail(&shader->uniforms, uniform);
|
||||||
|
else
|
||||||
|
MEM_freeN(uniform);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process builtin uniform */
|
||||||
|
for(i=0; builtins[i].gputype; i++) {
|
||||||
|
if(mat->builtins & builtins[i].gputype) {
|
||||||
|
uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
|
||||||
|
uniform->type = builtins[i].dynamictype;
|
||||||
|
uniform->datatype = builtins[i].datatype;
|
||||||
|
BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname));
|
||||||
|
BLI_addtail(&shader->uniforms, uniform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now link fragement shader with library shader
|
||||||
|
// TBD: remove the function that are not used in the main function
|
||||||
|
liblen = (pass->libcode) ? strlen(pass->libcode) : 0;
|
||||||
|
fraglen = strlen(pass->fragmentcode);
|
||||||
|
shader->fragment = (char *)MEM_mallocN(liblen+fraglen+1, "GPUFragShader");
|
||||||
|
if(pass->libcode)
|
||||||
|
memcpy(shader->fragment, pass->libcode, liblen);
|
||||||
|
memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen);
|
||||||
|
shader->fragment[liblen+fraglen] = 0;
|
||||||
|
|
||||||
|
// export the attribute
|
||||||
|
for(i=0; i<mat->attribs.totlayer; i++) {
|
||||||
|
attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute");
|
||||||
|
attribute->type = mat->attribs.layer[i].type;
|
||||||
|
attribute->number = mat->attribs.layer[i].glindex;
|
||||||
|
BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid);
|
||||||
|
|
||||||
|
switch(attribute->type) {
|
||||||
|
case CD_TANGENT:
|
||||||
|
attribute->datatype = GPU_DATA_4F;
|
||||||
|
break;
|
||||||
|
case CD_MTFACE:
|
||||||
|
attribute->datatype = GPU_DATA_2F;
|
||||||
|
attribute->name = mat->attribs.layer[i].name;
|
||||||
|
break;
|
||||||
|
case CD_MCOL:
|
||||||
|
attribute->datatype = GPU_DATA_4UB;
|
||||||
|
attribute->name = mat->attribs.layer[i].name;
|
||||||
|
break;
|
||||||
|
case CD_ORCO:
|
||||||
|
attribute->datatype = GPU_DATA_3F;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(attribute->datatype != GPU_DATA_NONE)
|
||||||
|
BLI_addtail(&shader->attributes, attribute);
|
||||||
|
else
|
||||||
|
MEM_freeN(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
// export the vertex shader
|
||||||
|
shader->vertex = BLI_strdup(pass->vertexcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU_free_shader_export(GPUShaderExport *shader)
|
||||||
|
{
|
||||||
|
GPUInputUniform *uniform;
|
||||||
|
|
||||||
|
if(shader == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(uniform = shader->uniforms.first; uniform; uniform=uniform->next)
|
||||||
|
if(uniform->texpixels)
|
||||||
|
MEM_freeN(uniform->texpixels);
|
||||||
|
|
||||||
|
BLI_freelistN(&shader->uniforms);
|
||||||
|
BLI_freelistN(&shader->attributes);
|
||||||
|
|
||||||
|
if(shader->vertex)
|
||||||
|
MEM_freeN(shader->vertex);
|
||||||
|
if(shader->fragment)
|
||||||
|
MEM_freeN(shader->fragment);
|
||||||
|
|
||||||
|
MEM_freeN(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -308,22 +308,22 @@ void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
|
|||||||
outdot = -dot(dir, nor);
|
outdot = -dot(dir, nor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void curves_vec(float fac, vec3 vec, sampler1D curvemap, out vec3 outvec)
|
void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
|
||||||
{
|
{
|
||||||
outvec.x = texture1D(curvemap, (vec.x + 1.0)*0.5).x;
|
outvec.x = texture2D(curvemap, vec2((vec.x + 1.0)*0.5, 0.0)).x;
|
||||||
outvec.y = texture1D(curvemap, (vec.y + 1.0)*0.5).y;
|
outvec.y = texture2D(curvemap, vec2((vec.y + 1.0)*0.5, 0.0)).y;
|
||||||
outvec.z = texture1D(curvemap, (vec.z + 1.0)*0.5).z;
|
outvec.z = texture2D(curvemap, vec2((vec.z + 1.0)*0.5, 0.0)).z;
|
||||||
|
|
||||||
if (fac != 1.0)
|
if (fac != 1.0)
|
||||||
outvec = (outvec*fac) + (vec*(1.0-fac));
|
outvec = (outvec*fac) + (vec*(1.0-fac));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void curves_rgb(float fac, vec4 col, sampler1D curvemap, out vec4 outcol)
|
void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol)
|
||||||
{
|
{
|
||||||
outcol.r = texture1D(curvemap, texture1D(curvemap, col.r).a).r;
|
outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
|
||||||
outcol.g = texture1D(curvemap, texture1D(curvemap, col.g).a).g;
|
outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
|
||||||
outcol.b = texture1D(curvemap, texture1D(curvemap, col.b).a).b;
|
outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
|
||||||
|
|
||||||
if (fac != 1.0)
|
if (fac != 1.0)
|
||||||
outcol = (outcol*fac) + (col*(1.0-fac));
|
outcol = (outcol*fac) + (col*(1.0-fac));
|
||||||
@@ -635,9 +635,9 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
|
|||||||
outcol.b= col1.b + fac*(2.0*(col2.b) - 1.0);
|
outcol.b= col1.b + fac*(2.0*(col2.b) - 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void valtorgb(float fac, sampler1D colormap, out vec4 outcol, out float outalpha)
|
void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
|
||||||
{
|
{
|
||||||
outcol = texture1D(colormap, fac);
|
outcol = texture2D(colormap, vec2(fac, 0.0));
|
||||||
outalpha = outcol.a;
|
outalpha = outcol.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1320,9 +1320,9 @@ void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out
|
|||||||
visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
|
visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lamp_falloff_curve(float lampdist, sampler1D curvemap, float dist, out float visifac)
|
void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
|
||||||
{
|
{
|
||||||
visifac = texture1D(curvemap, dist/lampdist).x;
|
visifac = texture2D(curvemap, vec2(dist/lampdist, 0.0)).x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
|
void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,8 @@ typedef struct TreeStore {
|
|||||||
#define TSE_CLOSED 1
|
#define TSE_CLOSED 1
|
||||||
#define TSE_SELECTED 2
|
#define TSE_SELECTED 2
|
||||||
#define TSE_TEXTBUT 4
|
#define TSE_TEXTBUT 4
|
||||||
|
#define TSE_CHILDSEARCH 8
|
||||||
|
#define TSE_SEARCHMATCH 16
|
||||||
|
|
||||||
/* TreeStoreElem types in BIF_outliner.h */
|
/* TreeStoreElem types in BIF_outliner.h */
|
||||||
|
|
||||||
|
|||||||
@@ -861,6 +861,7 @@ enum {
|
|||||||
/* outliner search flags (SpaceOops->search_flags) */
|
/* outliner search flags (SpaceOops->search_flags) */
|
||||||
#define SO_FIND_CASE_SENSITIVE (1<<0)
|
#define SO_FIND_CASE_SENSITIVE (1<<0)
|
||||||
#define SO_FIND_COMPLETE (1<<1)
|
#define SO_FIND_COMPLETE (1<<1)
|
||||||
|
#define SO_SEARCH_RECURSIVE (1<<2)
|
||||||
|
|
||||||
/* headerbuttons: 450-499 */
|
/* headerbuttons: 450-499 */
|
||||||
|
|
||||||
|
|||||||
@@ -978,7 +978,11 @@ StructRNA *ID_code_to_RNA_type(short idcode);
|
|||||||
|
|
||||||
|
|
||||||
/* macro which inserts the function name */
|
/* macro which inserts the function name */
|
||||||
|
#ifdef __GNUC__
|
||||||
# define RNA_warning(format, args...) _RNA_warning("%s: " format "\n", __func__, ##args)
|
# define RNA_warning(format, args...) _RNA_warning("%s: " format "\n", __func__, ##args)
|
||||||
|
#else /* MSVC doesnt support variable length args in macros */
|
||||||
|
# define RNA_warning _RNA_warning
|
||||||
|
#endif
|
||||||
|
|
||||||
void _RNA_warning(const char *format, ...)
|
void _RNA_warning(const char *format, ...)
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|||||||
@@ -5383,6 +5383,11 @@ void _RNA_warning(const char *format, ...)
|
|||||||
vprintf(format, args);
|
vprintf(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
|
/* gcc macro adds '\n', but cant use for other compilers */
|
||||||
|
#ifndef __GNUC__
|
||||||
|
fputc('\n', stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_PYTHON
|
#ifdef WITH_PYTHON
|
||||||
{
|
{
|
||||||
extern void PyC_LineSpit(void);
|
extern void PyC_LineSpit(void);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
Import ('env')
|
Import ('env')
|
||||||
|
|
||||||
incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes'
|
incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes'
|
||||||
incs += ' ../imbuf ../blenloader ../render/extern/include ../windowmanager'
|
incs += ' ../imbuf ../blenloader ../gpu ../render/extern/include ../windowmanager'
|
||||||
incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include'
|
incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include'
|
||||||
incs += ' #intern/audaspace/intern ' + env['BF_PYTHON_INC']
|
incs += ' #intern/audaspace/intern ' + env['BF_PYTHON_INC']
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ set(INC
|
|||||||
../../makesdna
|
../../makesdna
|
||||||
../../makesrna
|
../../makesrna
|
||||||
../../windowmanager
|
../../windowmanager
|
||||||
|
../../gpu
|
||||||
../../../../intern/guardedalloc
|
../../../../intern/guardedalloc
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ set(INC_SYS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
|
gpu.c
|
||||||
bpy.c
|
bpy.c
|
||||||
bpy_app.c
|
bpy_app.c
|
||||||
bpy_app_handlers.c
|
bpy_app_handlers.c
|
||||||
@@ -58,6 +60,7 @@ set(SRC
|
|||||||
bpy_util.c
|
bpy_util.c
|
||||||
stubs.c
|
stubs.c
|
||||||
|
|
||||||
|
gpu.h
|
||||||
bpy.h
|
bpy.h
|
||||||
bpy_app.h
|
bpy_app.h
|
||||||
bpy_app_handlers.h
|
bpy_app_handlers.h
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "RNA_types.h"
|
#include "RNA_types.h"
|
||||||
|
|
||||||
#include "bpy.h"
|
#include "bpy.h"
|
||||||
|
#include "gpu.h"
|
||||||
#include "bpy_rna.h"
|
#include "bpy_rna.h"
|
||||||
#include "bpy_util.h"
|
#include "bpy_util.h"
|
||||||
#include "bpy_traceback.h"
|
#include "bpy_traceback.h"
|
||||||
@@ -181,6 +182,7 @@ static struct _inittab bpy_internal_modules[]= {
|
|||||||
#ifdef WITH_AUDASPACE
|
#ifdef WITH_AUDASPACE
|
||||||
{(char *)"aud", AUD_initPython},
|
{(char *)"aud", AUD_initPython},
|
||||||
#endif
|
#endif
|
||||||
|
{(char *)"gpu", GPU_initPython},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
294
source/blender/python/intern/gpu.c
Normal file
294
source/blender/python/intern/gpu.c
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2006 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): Benoit Bolsee.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/python/intern/gpu.c
|
||||||
|
* \ingroup pythonintern
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* python redefines */
|
||||||
|
#ifdef _POSIX_C_SOURCE
|
||||||
|
#undef _POSIX_C_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include "GPU_material.h"
|
||||||
|
|
||||||
|
#include "DNA_scene_types.h"
|
||||||
|
#include "DNA_image_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_lamp_types.h"
|
||||||
|
#include "DNA_object_types.h"
|
||||||
|
#include "DNA_ID.h"
|
||||||
|
#include "DNA_customdata_types.h"
|
||||||
|
|
||||||
|
#include "BLI_listbase.h"
|
||||||
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
|
||||||
|
#include "bpy_rna.h"
|
||||||
|
|
||||||
|
#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(M_gpu_doc,
|
||||||
|
"This module provides access to the GLSL shader.");
|
||||||
|
|
||||||
|
static struct PyModuleDef gpumodule = {
|
||||||
|
PyModuleDef_HEAD_INIT,
|
||||||
|
"gpu", /* name of module */
|
||||||
|
M_gpu_doc, /* module documentation */
|
||||||
|
-1, /* size of per-interpreter state of the module,
|
||||||
|
or -1 if the module keeps state in global variables. */
|
||||||
|
NULL, NULL, NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
PyMODINIT_FUNC
|
||||||
|
PyInit_gpu(void)
|
||||||
|
{
|
||||||
|
PyObject* m;
|
||||||
|
|
||||||
|
m = PyModule_Create(&gpumodule);
|
||||||
|
if(m == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// device constants
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWMAT);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_MAT);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNVEC);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCO);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNIMAT);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNPERSMAT);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNENERGY);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCOL);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DBUFFER);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DIMAGE);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DSHADOW);
|
||||||
|
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1I);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1F);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_2F);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_3F);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4F);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_9F);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_16F);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4UB);
|
||||||
|
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, CD_MTFACE);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, CD_ORCO);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, CD_TANGENT);
|
||||||
|
PY_MODULE_ADD_CONSTANT(m, CD_MCOL);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PY_DICT_ADD_STRING(d,s,f) \
|
||||||
|
val = PyUnicode_FromString(s->f); \
|
||||||
|
PyDict_SetItemString(d, #f, val); \
|
||||||
|
Py_DECREF(val)
|
||||||
|
|
||||||
|
#define PY_DICT_ADD_LONG(d,s,f) \
|
||||||
|
val = PyLong_FromLong(s->f); \
|
||||||
|
PyDict_SetItemString(d, #f, val); \
|
||||||
|
Py_DECREF(val)
|
||||||
|
|
||||||
|
#define PY_DICT_ADD_ID(d,s,f) \
|
||||||
|
RNA_id_pointer_create((struct ID*)s->f, &tptr); \
|
||||||
|
val = pyrna_struct_CreatePyObject(&tptr); \
|
||||||
|
PyDict_SetItemString(d, #f, val); \
|
||||||
|
Py_DECREF(val)
|
||||||
|
|
||||||
|
#define PY_OBJ_ADD_ID(d,s,f) \
|
||||||
|
val = PyUnicode_FromString(&s->f->id.name[2]); \
|
||||||
|
PyObject_SetAttrString(d, #f, val); \
|
||||||
|
Py_DECREF(val)
|
||||||
|
|
||||||
|
#define PY_OBJ_ADD_LONG(d,s,f) \
|
||||||
|
val = PyLong_FromLong(s->f); \
|
||||||
|
PyObject_SetAttrString(d, #f, val); \
|
||||||
|
Py_DECREF(val)
|
||||||
|
|
||||||
|
#define PY_OBJ_ADD_STRING(d,s,f) \
|
||||||
|
val = PyUnicode_FromString(s->f); \
|
||||||
|
PyObject_SetAttrString(d, #f, val); \
|
||||||
|
Py_DECREF(val)
|
||||||
|
|
||||||
|
static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
PyObject* pyscene;
|
||||||
|
PyObject* pymat;
|
||||||
|
PyObject* as_pointer;
|
||||||
|
PyObject* pointer;
|
||||||
|
PyObject* noargs;
|
||||||
|
PyObject* result;
|
||||||
|
PyObject* dict;
|
||||||
|
PyObject* val;
|
||||||
|
PyObject* seq;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
Scene *scene;
|
||||||
|
PointerRNA tptr;
|
||||||
|
Material *material;
|
||||||
|
GPUShaderExport *shader;
|
||||||
|
GPUInputUniform *uniform;
|
||||||
|
GPUInputAttribute *attribute;
|
||||||
|
|
||||||
|
static const char *kwlist[] = {"scene", "material", NULL};
|
||||||
|
|
||||||
|
if(!PyArg_ParseTupleAndKeywords(args, kwds, "OO:export_shader", (char**)(kwlist), &pyscene, &pymat))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!strcmp(Py_TYPE(pyscene)->tp_name, "Scene") &&
|
||||||
|
(as_pointer = PyObject_GetAttrString(pyscene, "as_pointer")) != NULL &&
|
||||||
|
PyCallable_Check(as_pointer)) {
|
||||||
|
// must be a scene object
|
||||||
|
noargs = PyTuple_New(0);
|
||||||
|
pointer = PyObject_CallObject(as_pointer, noargs);
|
||||||
|
Py_DECREF(noargs);
|
||||||
|
if (!pointer) {
|
||||||
|
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
scene = (Scene*)PyLong_AsVoidPtr(pointer);
|
||||||
|
Py_DECREF(pointer);
|
||||||
|
if (!scene) {
|
||||||
|
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() first argument should be of Scene type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(Py_TYPE(pymat)->tp_name, "Material") &&
|
||||||
|
(as_pointer = PyObject_GetAttrString(pymat, "as_pointer")) != NULL &&
|
||||||
|
PyCallable_Check(as_pointer)) {
|
||||||
|
// must be a material object
|
||||||
|
noargs = PyTuple_New(0);
|
||||||
|
pointer = PyObject_CallObject(as_pointer, noargs);
|
||||||
|
Py_DECREF(noargs);
|
||||||
|
if (!pointer) {
|
||||||
|
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
material = (Material*)PyLong_AsVoidPtr(pointer);
|
||||||
|
Py_DECREF(pointer);
|
||||||
|
if (!material) {
|
||||||
|
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() second argument should be of Material type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// we can call our internal function at last:
|
||||||
|
shader = GPU_shader_export(scene, material);
|
||||||
|
if (!shader) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "cannot export shader");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// build a dictionary
|
||||||
|
result = PyDict_New();
|
||||||
|
if (shader->fragment) {
|
||||||
|
PY_DICT_ADD_STRING(result,shader,fragment);
|
||||||
|
}
|
||||||
|
if (shader->vertex) {
|
||||||
|
PY_DICT_ADD_STRING(result,shader,vertex);
|
||||||
|
}
|
||||||
|
seq = PyList_New(BLI_countlist(&shader->uniforms));
|
||||||
|
for (i=0, uniform=shader->uniforms.first; uniform; uniform=uniform->next, i++) {
|
||||||
|
dict = PyDict_New();
|
||||||
|
PY_DICT_ADD_STRING(dict,uniform,varname);
|
||||||
|
PY_DICT_ADD_LONG(dict,uniform,datatype);
|
||||||
|
PY_DICT_ADD_LONG(dict,uniform,type);
|
||||||
|
if (uniform->lamp) {
|
||||||
|
PY_DICT_ADD_ID(dict,uniform,lamp);
|
||||||
|
}
|
||||||
|
if (uniform->image) {
|
||||||
|
PY_DICT_ADD_ID(dict,uniform,image);
|
||||||
|
}
|
||||||
|
if (uniform->type == GPU_DYNAMIC_SAMPLER_2DBUFFER ||
|
||||||
|
uniform->type == GPU_DYNAMIC_SAMPLER_2DIMAGE ||
|
||||||
|
uniform->type == GPU_DYNAMIC_SAMPLER_2DSHADOW) {
|
||||||
|
PY_DICT_ADD_LONG(dict,uniform,texnumber);
|
||||||
|
}
|
||||||
|
if (uniform->texpixels) {
|
||||||
|
val = PyByteArray_FromStringAndSize((const char *)uniform->texpixels, uniform->texsize);
|
||||||
|
PyDict_SetItemString(dict, "texpixels", val);
|
||||||
|
Py_DECREF(val);
|
||||||
|
PY_DICT_ADD_LONG(dict,uniform,texsize);
|
||||||
|
}
|
||||||
|
PyList_SET_ITEM(seq, i, dict);
|
||||||
|
}
|
||||||
|
PyDict_SetItemString(result, "uniforms", seq);
|
||||||
|
Py_DECREF(seq);
|
||||||
|
|
||||||
|
seq = PyList_New(BLI_countlist(&shader->attributes));
|
||||||
|
for (i=0, attribute=shader->attributes.first; attribute; attribute=attribute->next, i++) {
|
||||||
|
dict = PyDict_New();
|
||||||
|
PY_DICT_ADD_STRING(dict,attribute,varname);
|
||||||
|
PY_DICT_ADD_LONG(dict,attribute,datatype);
|
||||||
|
PY_DICT_ADD_LONG(dict,attribute,type);
|
||||||
|
PY_DICT_ADD_LONG(dict,attribute,number);
|
||||||
|
if (attribute->name) {
|
||||||
|
if (attribute->name[0] != 0) {
|
||||||
|
PY_DICT_ADD_STRING(dict,attribute,name);
|
||||||
|
} else {
|
||||||
|
val = PyLong_FromLong(0);
|
||||||
|
PyDict_SetItemString(dict, "name", val);
|
||||||
|
Py_DECREF(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyList_SET_ITEM(seq, i, dict);
|
||||||
|
}
|
||||||
|
PyDict_SetItemString(result, "attributes", seq);
|
||||||
|
Py_DECREF(seq);
|
||||||
|
|
||||||
|
GPU_free_shader_export(shader);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef meth_export_shader[] = {{ "export_shader", (PyCFunction)GPU_export_shader, METH_VARARGS | METH_KEYWORDS,
|
||||||
|
"export_shader(scene,material)\n\n"
|
||||||
|
"Returns the GLSL shader that produces the visual effect of material in scene.\n\n"
|
||||||
|
":return: Dictionary defining the shader, uniforms and attributes.\n"
|
||||||
|
":rtype: Dict"}};
|
||||||
|
|
||||||
|
PyObject* GPU_initPython(void)
|
||||||
|
{
|
||||||
|
PyObject* module = PyInit_gpu();
|
||||||
|
PyModule_AddObject(module, "export_shader", (PyObject *)PyCFunction_New(meth_export_shader, NULL));
|
||||||
|
PyDict_SetItemString(PyImport_GetModuleDict(), "gpu", module);
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
41
source/blender/python/intern/gpu.h
Normal file
41
source/blender/python/intern/gpu.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This shader is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This shader is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this shader; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): Benoit Bolsee.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/python/intern/gpu.h
|
||||||
|
* \ingroup pythonintern
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initalizes the gpu Python module.
|
||||||
|
*/
|
||||||
|
PyObject* GPU_initPython(void);
|
||||||
|
|
||||||
Reference in New Issue
Block a user