forked from bartvdbraak/blender
svn merge -r 16320:16369 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
commit
d2c13039ed
@ -90,6 +90,7 @@ IF(UNIX)
|
||||
bf_soundsystem
|
||||
bf_kernel
|
||||
bf_nodes
|
||||
bf_gpu
|
||||
bf_imbuf
|
||||
bf_avi
|
||||
kx_network
|
||||
|
@ -143,7 +143,6 @@ BF_FTGL_LIB = 'extern_ftgl'
|
||||
|
||||
WITH_BF_GAMEENGINE='true'
|
||||
WITH_BF_PLAYER='true'
|
||||
WITH_BF_GLEXT= '1'
|
||||
|
||||
WITH_BF_ODE = 'false'
|
||||
BF_ODE = LIBDIR + '/ode'
|
||||
|
2
extern/glew/SConscript
vendored
2
extern/glew/SConscript
vendored
@ -9,4 +9,4 @@ sources = ['src/glew.c']
|
||||
defs = ''
|
||||
incs = 'include'
|
||||
|
||||
env.BlenderLib ( 'extern_glew', sources, Split(incs), Split(defs), libtype=['intern', 'player'], priority=[25, 50])
|
||||
env.BlenderLib ( 'extern_glew', sources, Split(incs), Split(defs), libtype=['blender', 'player'], priority=[50, 50])
|
||||
|
7
extern/glew/include/GL/glew.h
vendored
7
extern/glew/include/GL/glew.h
vendored
@ -58,8 +58,11 @@
|
||||
** version 1.2.1 Specification.
|
||||
*/
|
||||
|
||||
/* added this here for blender, should be moved elsewhere */
|
||||
#define BLENDER_CHANGES
|
||||
|
||||
#ifdef BLENDER_CHANGES
|
||||
#define GLEW_STATIC
|
||||
#endif
|
||||
|
||||
#ifndef __glew_h__
|
||||
#define __glew_h__
|
||||
@ -1805,6 +1808,7 @@ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuin
|
||||
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v);
|
||||
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
|
||||
|
||||
#ifndef BLENDER_CHANGES
|
||||
#define glAttachShader GLEW_GET_FUN(__glewAttachShader)
|
||||
#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation)
|
||||
#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate)
|
||||
@ -1898,6 +1902,7 @@ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint si
|
||||
#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv)
|
||||
#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv)
|
||||
#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer)
|
||||
#endif
|
||||
|
||||
#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0)
|
||||
|
||||
|
2
extern/glew/src/glew.c
vendored
2
extern/glew/src/glew.c
vendored
@ -1836,6 +1836,7 @@ static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT)
|
||||
{
|
||||
GLboolean r = GL_FALSE;
|
||||
|
||||
#ifndef BLENDER_CHANGES
|
||||
r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r;
|
||||
r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r;
|
||||
r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r;
|
||||
@ -1929,6 +1930,7 @@ static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT)
|
||||
r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r;
|
||||
r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r;
|
||||
r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -917,8 +917,12 @@ GHOST_TUns8* GHOST_SystemWin32::getClipboard(int flag) const
|
||||
char *buffer;
|
||||
char *temp_buff;
|
||||
|
||||
if ( OpenClipboard(NULL) ) {
|
||||
if ( IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL) ) {
|
||||
HANDLE hData = GetClipboardData( CF_TEXT );
|
||||
if (hData == NULL) {
|
||||
CloseClipboard();
|
||||
return NULL;
|
||||
}
|
||||
buffer = (char*)GlobalLock( hData );
|
||||
|
||||
temp_buff = (char*) malloc(strlen(buffer)+1);
|
||||
|
@ -58,8 +58,8 @@
|
||||
#ifndef MEM_MALLOCN_H
|
||||
#define MEM_MALLOCN_H
|
||||
|
||||
/* Needed for FILE* */
|
||||
#include "stdio.h"
|
||||
#include "stdio.h" /* needed for FILE* */
|
||||
#include "BLO_sys_types.h" /* needed for uintptr_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -123,6 +123,12 @@ extern "C" {
|
||||
/** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
|
||||
void MEM_set_memory_debug(void);
|
||||
|
||||
/* Memory usage stats
|
||||
* - MEM_get_memory_in_use is all memory
|
||||
* - MEM_get_mapped_memory_in_use is a subset of all memory */
|
||||
uintptr_t MEM_get_memory_in_use(void);
|
||||
uintptr_t MEM_get_mapped_memory_in_use(void);
|
||||
int MEM_get_memory_blocks_in_use(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -49,8 +49,6 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLO_sys_types.h" // needed for intptr_t
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Data definition */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -113,8 +111,8 @@ static const char *check_memlist(MemHead *memh);
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
|
||||
volatile int totblock= 0;
|
||||
volatile uintptr_t mem_in_use= 0, mmap_in_use= 0;
|
||||
static volatile int totblock= 0;
|
||||
static volatile uintptr_t mem_in_use= 0, mmap_in_use= 0;
|
||||
|
||||
static volatile struct localListBase _membase;
|
||||
static volatile struct localListBase *membase = &_membase;
|
||||
@ -698,4 +696,19 @@ static const char *check_memlist(MemHead *memh)
|
||||
return(name);
|
||||
}
|
||||
|
||||
uintptr_t MEM_get_memory_in_use(void)
|
||||
{
|
||||
return mem_in_use;
|
||||
}
|
||||
|
||||
uintptr_t MEM_get_mapped_memory_in_use(void)
|
||||
{
|
||||
return mmap_in_use;
|
||||
}
|
||||
|
||||
int MEM_get_memory_blocks_in_use(void)
|
||||
{
|
||||
return totblock;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define __MEM_Allocator_h_included__ 1
|
||||
|
||||
#include "guardedalloc/MEM_guardedalloc.h"
|
||||
#include "guardedalloc/BLO_sys_types.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER < 1300 // 1200 == VC++ 6.0 according to boost
|
||||
|
@ -61,11 +61,8 @@ class MEM_CacheLimiter;
|
||||
|
||||
#ifndef __MEM_cache_limiter_c_api_h_included__
|
||||
extern "C" {
|
||||
extern void MEM_CacheLimiter_set_maximum(int m);
|
||||
extern int MEM_CacheLimiter_get_maximum();
|
||||
// this is rather _ugly_!
|
||||
extern int mem_in_use;
|
||||
extern int mmap_in_use;
|
||||
extern void MEM_CacheLimiter_set_maximum(intptr_t m);
|
||||
extern intptr_t MEM_CacheLimiter_get_maximum();
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -141,7 +138,10 @@ public:
|
||||
delete handle;
|
||||
}
|
||||
void enforce_limits() {
|
||||
int max = MEM_CacheLimiter_get_maximum();
|
||||
intptr_t max = MEM_CacheLimiter_get_maximum();
|
||||
intptr_t mem_in_use= MEM_get_memory_in_use();
|
||||
intptr_t mmap_in_use= MEM_get_mapped_memory_in_use();
|
||||
|
||||
if (max == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -27,18 +27,18 @@
|
||||
#include "MEM_CacheLimiter.h"
|
||||
#include "MEM_CacheLimiterC-Api.h"
|
||||
|
||||
static int & get_max()
|
||||
static intptr_t & get_max()
|
||||
{
|
||||
static int m = 32*1024*1024;
|
||||
static intptr_t m = 32*1024*1024;
|
||||
return m;
|
||||
}
|
||||
|
||||
void MEM_CacheLimiter_set_maximum(int m)
|
||||
void MEM_CacheLimiter_set_maximum(intptr_t m)
|
||||
{
|
||||
get_max() = m;
|
||||
}
|
||||
|
||||
int MEM_CacheLimiter_get_maximum()
|
||||
intptr_t MEM_CacheLimiter_get_maximum()
|
||||
{
|
||||
return get_max();
|
||||
}
|
||||
|
@ -51,6 +51,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
GEN_Map(const GEN_Map& map)
|
||||
{
|
||||
m_num_buckets = map.m_num_buckets;
|
||||
m_buckets = new Entry *[m_num_buckets];
|
||||
|
||||
for (int i = 0; i < m_num_buckets; ++i) {
|
||||
m_buckets[i] = 0;
|
||||
|
||||
for(Entry *entry = map.m_buckets[i]; entry; entry=entry->m_next)
|
||||
insert(entry->m_key, entry->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
int size() {
|
||||
int count=0;
|
||||
for (int i=0;i<m_num_buckets;i++)
|
||||
|
@ -212,6 +212,7 @@ public:
|
||||
MT_Matrix4x4 transposed() const;
|
||||
void transpose();
|
||||
|
||||
MT_Matrix4x4 inverse() const;
|
||||
void invert();
|
||||
|
||||
protected:
|
||||
|
@ -52,14 +52,14 @@ GEN_INLINE void MT_Matrix4x4::invert() {
|
||||
}
|
||||
}
|
||||
|
||||
/* We do things slightly different here, because the invert() modifies
|
||||
* the buffer itself. This makes it impossible to make this op right
|
||||
* away. Like other, still missing facilities, I will repair this
|
||||
* later. */
|
||||
/* GEN_INLINE T_Matrix4x4 MT_Matrix4x4::inverse() const */
|
||||
/* { */
|
||||
/* } */
|
||||
GEN_INLINE MT_Matrix4x4 MT_Matrix4x4::inverse() const
|
||||
{
|
||||
MT_Matrix4x4 invmat = *this;
|
||||
|
||||
invmat.invert();
|
||||
|
||||
return invmat;
|
||||
}
|
||||
|
||||
GEN_INLINE MT_Matrix4x4& MT_Matrix4x4::operator*=(const MT_Matrix4x4& m)
|
||||
{
|
||||
|
@ -54,6 +54,7 @@ extern "C" {
|
||||
/* The __intXX are built-in types of the visual complier! So we don't
|
||||
* need to include anything else here. */
|
||||
|
||||
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
@ -102,6 +103,7 @@ typedef unsigned long uintptr_t;
|
||||
|
||||
#endif /* ifdef platform for types */
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef htonl
|
||||
#define htonl(x) correctByteOrder(x)
|
||||
|
@ -506,6 +506,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\blenkernel\intern\subsurf_ccg.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\blenkernel\intern\suggestions.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\blenkernel\intern\text.c">
|
||||
</File>
|
||||
@ -723,6 +726,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\blenkernel\BKE_subsurf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\blenkernel\BKE_suggestions.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\blenkernel\BKE_text.h">
|
||||
</File>
|
||||
|
@ -126,7 +126,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\sdl\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
PreprocessorDefinitions="JANCODEPANCO;WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG;USE_SUMO_SOLID;WITH_GLEXT"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
@ -179,7 +179,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\sdl\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
@ -232,7 +232,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\sdl\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
PreprocessorDefinitions="JANCODEPANCO;WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG;USE_SUMO_SOLID;WITH_GLEXT"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
@ -285,7 +285,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\sdl\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 66 KiB |
814
release/scripts/bpymodules/BPyTextPlugin.py
Normal file
814
release/scripts/bpymodules/BPyTextPlugin.py
Normal file
@ -0,0 +1,814 @@
|
||||
"""The BPyTextPlugin Module
|
||||
|
||||
Use get_cached_descriptor(txt) to retrieve information about the script held in
|
||||
the txt Text object.
|
||||
|
||||
Use print_cache_for(txt) to print the information to the console.
|
||||
|
||||
Use line, cursor = current_line(txt) to get the logical line and cursor position
|
||||
|
||||
Use get_targets(line, cursor) to find out what precedes the cursor:
|
||||
aaa.bbb.cc|c.ddd -> ['aaa', 'bbb', 'cc']
|
||||
|
||||
Use resolve_targets(txt, targets) to turn a target list into a usable object if
|
||||
one is found to match.
|
||||
"""
|
||||
|
||||
import bpy, sys, os
|
||||
import __builtin__, tokenize
|
||||
from Blender.sys import time
|
||||
from tokenize import generate_tokens, TokenError, \
|
||||
COMMENT, DEDENT, INDENT, NAME, NEWLINE, NL, STRING, NUMBER
|
||||
|
||||
class Definition():
|
||||
"""Describes a definition or defined object through its name, line number
|
||||
and docstring. This is the base class for definition based descriptors.
|
||||
"""
|
||||
|
||||
def __init__(self, name, lineno, doc=''):
|
||||
self.name = name
|
||||
self.lineno = lineno
|
||||
self.doc = doc
|
||||
|
||||
class ScriptDesc():
|
||||
"""Describes a script through lists of further descriptor objects (classes,
|
||||
defs, vars) and dictionaries to built-in types (imports). If a script has
|
||||
not been fully parsed, its incomplete flag will be set. The time of the last
|
||||
parse is held by the time field and the name of the text object from which
|
||||
it was parsed, the name field.
|
||||
"""
|
||||
|
||||
def __init__(self, name, imports, classes, defs, vars, incomplete=False):
|
||||
self.name = name
|
||||
self.imports = imports
|
||||
self.classes = classes
|
||||
self.defs = defs
|
||||
self.vars = vars
|
||||
self.incomplete = incomplete
|
||||
self.parse_due = 0
|
||||
|
||||
def set_delay(self, delay):
|
||||
self.parse_due = time() + delay
|
||||
|
||||
class ClassDesc(Definition):
|
||||
"""Describes a class through lists of further descriptor objects (defs and
|
||||
vars). The name of the class is held by the name field and the line on
|
||||
which it is defined is held in lineno.
|
||||
"""
|
||||
|
||||
def __init__(self, name, parents, defs, vars, lineno, doc=''):
|
||||
Definition.__init__(self, name, lineno, doc)
|
||||
self.parents = parents
|
||||
self.defs = defs
|
||||
self.vars = vars
|
||||
|
||||
class FunctionDesc(Definition):
|
||||
"""Describes a function through its name and list of parameters (name,
|
||||
params) and the line on which it is defined (lineno).
|
||||
"""
|
||||
|
||||
def __init__(self, name, params, lineno, doc=''):
|
||||
Definition.__init__(self, name, lineno, doc)
|
||||
self.params = params
|
||||
|
||||
class VarDesc(Definition):
|
||||
"""Describes a variable through its name and type (if ascertainable) and the
|
||||
line on which it is defined (lineno). If no type can be determined, type
|
||||
will equal None.
|
||||
"""
|
||||
|
||||
def __init__(self, name, type, lineno):
|
||||
Definition.__init__(self, name, lineno)
|
||||
self.type = type # None for unknown (supports: dict/list/str)
|
||||
|
||||
# Context types
|
||||
CTX_UNSET = -1
|
||||
CTX_NORMAL = 0
|
||||
CTX_SINGLE_QUOTE = 1
|
||||
CTX_DOUBLE_QUOTE = 2
|
||||
CTX_COMMENT = 3
|
||||
|
||||
# Python keywords
|
||||
KEYWORDS = ['and', 'del', 'from', 'not', 'while', 'as', 'elif', 'global',
|
||||
'or', 'with', 'assert', 'else', 'if', 'pass', 'yield',
|
||||
'break', 'except', 'import', 'print', 'class', 'exec', 'in',
|
||||
'raise', 'continue', 'finally', 'is', 'return', 'def', 'for',
|
||||
'lambda', 'try' ]
|
||||
|
||||
# Module file extensions
|
||||
MODULE_EXTS = ['.py', '.pyc', '.pyo', '.pyw', '.pyd']
|
||||
|
||||
ModuleType = type(__builtin__)
|
||||
NoneScriptDesc = ScriptDesc('', dict(), dict(), dict(), dict(), True)
|
||||
|
||||
_modules = {}
|
||||
_modules_updated = 0
|
||||
_parse_cache = dict()
|
||||
|
||||
def _load_module_names():
|
||||
"""Searches the sys.path for module files and lists them, along with
|
||||
sys.builtin_module_names, in the global dict _modules.
|
||||
"""
|
||||
|
||||
global _modules
|
||||
|
||||
for n in sys.builtin_module_names:
|
||||
_modules[n] = None
|
||||
for p in sys.path:
|
||||
if p == '': p = os.curdir
|
||||
if not os.path.isdir(p): continue
|
||||
for f in os.listdir(p):
|
||||
for ext in MODULE_EXTS:
|
||||
if f.endswith(ext):
|
||||
_modules[f[:-len(ext)]] = None
|
||||
break
|
||||
|
||||
_load_module_names()
|
||||
|
||||
def _trim_doc(doc):
|
||||
"""Trims the quotes from a quoted STRING token (eg. "'''text'''" -> "text")
|
||||
"""
|
||||
|
||||
l = len(doc)
|
||||
i = 0
|
||||
while i < l/2 and (doc[i] == "'" or doc[i] == '"'):
|
||||
i += 1
|
||||
return doc[i:-i]
|
||||
|
||||
def resolve_targets(txt, targets):
|
||||
"""Attempts to return a useful object for the locally or externally defined
|
||||
entity described by targets. If the object is local (defined in txt), a
|
||||
Definition instance is returned. If the object is external (imported or
|
||||
built in), the object itself is returned. If no object can be found, None is
|
||||
returned.
|
||||
"""
|
||||
|
||||
count = len(targets)
|
||||
if count==0: return None
|
||||
|
||||
obj = None
|
||||
local = None
|
||||
i = 1
|
||||
|
||||
desc = get_cached_descriptor(txt)
|
||||
b = targets[0].find('(')
|
||||
if b==-1: b = None # Trick to let us use [:b] and get the whole string
|
||||
|
||||
if desc.classes.has_key(targets[0][:b]):
|
||||
local = desc.classes[targets[0][:b]]
|
||||
elif desc.defs.has_key(targets[0]):
|
||||
local = desc.defs[targets[0]]
|
||||
elif desc.vars.has_key(targets[0]):
|
||||
obj = desc.vars[targets[0]].type
|
||||
|
||||
if local:
|
||||
while i < count:
|
||||
b = targets[i].find('(')
|
||||
if b==-1: b = None
|
||||
if hasattr(local, 'classes') and local.classes.has_key(targets[i][:b]):
|
||||
local = local.classes[targets[i][:b]]
|
||||
elif hasattr(local, 'defs') and local.defs.has_key(targets[i]):
|
||||
local = local.defs[targets[i]]
|
||||
elif hasattr(local, 'vars') and local.vars.has_key(targets[i]):
|
||||
obj = local.vars[targets[i]].type
|
||||
local = None
|
||||
i += 1
|
||||
break
|
||||
else:
|
||||
local = None
|
||||
break
|
||||
i += 1
|
||||
|
||||
if local: return local
|
||||
|
||||
if not obj:
|
||||
if desc.imports.has_key(targets[0]):
|
||||
obj = desc.imports[targets[0]]
|
||||
else:
|
||||
builtins = get_builtins()
|
||||
if builtins.has_key(targets[0]):
|
||||
obj = builtins[targets[0]]
|
||||
|
||||
while obj and i < count:
|
||||
if hasattr(obj, targets[i]):
|
||||
obj = getattr(obj, targets[i])
|
||||
else:
|
||||
obj = None
|
||||
break
|
||||
i += 1
|
||||
|
||||
return obj
|
||||
|
||||
def get_cached_descriptor(txt, force_parse=0):
|
||||
"""Returns the cached ScriptDesc for the specified Text object 'txt'. If the
|
||||
script has not been parsed in the last 'period' seconds it will be reparsed
|
||||
to obtain this descriptor.
|
||||
|
||||
Specifying TP_AUTO for the period (default) will choose a period based on the
|
||||
size of the Text object. Larger texts are parsed less often.
|
||||
"""
|
||||
|
||||
global _parse_cache
|
||||
|
||||
parse = True
|
||||
key = hash(txt)
|
||||
if not force_parse and _parse_cache.has_key(key):
|
||||
desc = _parse_cache[key]
|
||||
if desc.parse_due > time():
|
||||
parse = desc.incomplete
|
||||
|
||||
if parse:
|
||||
desc = parse_text(txt)
|
||||
|
||||
return desc
|
||||
|
||||
def parse_text(txt):
|
||||
"""Parses an entire script's text and returns a ScriptDesc instance
|
||||
containing information about the script.
|
||||
|
||||
If the text is not a valid Python script (for example if brackets are left
|
||||
open), parsing may fail to complete. However, if this occurs, no exception
|
||||
is thrown. Instead the returned ScriptDesc instance will have its incomplete
|
||||
flag set and information processed up to this point will still be accessible.
|
||||
"""
|
||||
|
||||
start_time = time()
|
||||
txt.reset()
|
||||
tokens = generate_tokens(txt.readline) # Throws TokenError
|
||||
|
||||
curl, cursor = txt.getCursorPos()
|
||||
linen = curl + 1 # Token line numbers are one-based
|
||||
|
||||
imports = dict()
|
||||
imp_step = 0
|
||||
|
||||
classes = dict()
|
||||
cls_step = 0
|
||||
|
||||
defs = dict()
|
||||
def_step = 0
|
||||
|
||||
vars = dict()
|
||||
var1_step = 0
|
||||
var2_step = 0
|
||||
var3_step = 0
|
||||
var_accum = dict()
|
||||
var_forflag = False
|
||||
|
||||
indent = 0
|
||||
prev_type = -1
|
||||
prev_text = ''
|
||||
incomplete = False
|
||||
|
||||
while True:
|
||||
try:
|
||||
type, text, start, end, line = tokens.next()
|
||||
except StopIteration:
|
||||
break
|
||||
except (TokenError, IndentationError):
|
||||
incomplete = True
|
||||
break
|
||||
|
||||
# Skip all comments and line joining characters
|
||||
if type == COMMENT or type == NL:
|
||||
continue
|
||||
|
||||
#################
|
||||
## Indentation ##
|
||||
#################
|
||||
|
||||
if type == INDENT:
|
||||
indent += 1
|
||||
elif type == DEDENT:
|
||||
indent -= 1
|
||||
|
||||
#########################
|
||||
## Module importing... ##
|
||||
#########################
|
||||
|
||||
imp_store = False
|
||||
|
||||
# Default, look for 'from' or 'import' to start
|
||||
if imp_step == 0:
|
||||
if text == 'from':
|
||||
imp_tmp = []
|
||||
imp_step = 1
|
||||
elif text == 'import':
|
||||
imp_from = None
|
||||
imp_tmp = []
|
||||
imp_step = 2
|
||||
|
||||
# Found a 'from', create imp_from in form '???.???...'
|
||||
elif imp_step == 1:
|
||||
if text == 'import':
|
||||
imp_from = '.'.join(imp_tmp)
|
||||
imp_tmp = []
|
||||
imp_step = 2
|
||||
elif type == NAME:
|
||||
imp_tmp.append(text)
|
||||
elif text != '.':
|
||||
imp_step = 0 # Invalid syntax
|
||||
|
||||
# Found 'import', imp_from is populated or None, create imp_name
|
||||
elif imp_step == 2:
|
||||
if text == 'as':
|
||||
imp_name = '.'.join(imp_tmp)
|
||||
imp_step = 3
|
||||
elif type == NAME or text == '*':
|
||||
imp_tmp.append(text)
|
||||
elif text != '.':
|
||||
imp_name = '.'.join(imp_tmp)
|
||||
imp_symb = imp_name
|
||||
imp_store = True
|
||||
|
||||
# Found 'as', change imp_symb to this value and go back to step 2
|
||||
elif imp_step == 3:
|
||||
if type == NAME:
|
||||
imp_symb = text
|
||||
else:
|
||||
imp_store = True
|
||||
|
||||
# Both imp_name and imp_symb have now been populated so we can import
|
||||
if imp_store:
|
||||
|
||||
# Handle special case of 'import *'
|
||||
if imp_name == '*':
|
||||
parent = get_module(imp_from)
|
||||
imports.update(parent.__dict__)
|
||||
|
||||
else:
|
||||
# Try importing the name as a module
|
||||
try:
|
||||
if imp_from:
|
||||
module = get_module(imp_from +'.'+ imp_name)
|
||||
else:
|
||||
module = get_module(imp_name)
|
||||
except (ImportError, ValueError, AttributeError, TypeError):
|
||||
# Try importing name as an attribute of the parent
|
||||
try:
|
||||
module = __import__(imp_from, globals(), locals(), [imp_name])
|
||||
imports[imp_symb] = getattr(module, imp_name)
|
||||
except (ImportError, ValueError, AttributeError, TypeError):
|
||||
pass
|
||||
else:
|
||||
imports[imp_symb] = module
|
||||
|
||||
# More to import from the same module?
|
||||
if text == ',':
|
||||
imp_tmp = []
|
||||
imp_step = 2
|
||||
else:
|
||||
imp_step = 0
|
||||
|
||||
###################
|
||||
## Class parsing ##
|
||||
###################
|
||||
|
||||
# If we are inside a class then def and variable parsing should be done
|
||||
# for the class. Otherwise the definitions are considered global
|
||||
|
||||
# Look for 'class'
|
||||
if cls_step == 0:
|
||||
if text == 'class':
|
||||
cls_name = None
|
||||
cls_lineno = start[0]
|
||||
cls_indent = indent
|
||||
cls_step = 1
|
||||
|
||||
# Found 'class', look for cls_name followed by '(' parents ')'
|
||||
elif cls_step == 1:
|
||||
if not cls_name:
|
||||
if type == NAME:
|
||||
cls_name = text
|
||||
cls_sline = False
|
||||
cls_parents = dict()
|
||||
cls_defs = dict()
|
||||
cls_vars = dict()
|
||||
elif type == NAME:
|
||||
if classes.has_key(text):
|
||||
parent = classes[text]
|
||||
cls_parents[text] = parent
|
||||
cls_defs.update(parent.defs)
|
||||
cls_vars.update(parent.vars)
|
||||
elif text == ':':
|
||||
cls_step = 2
|
||||
|
||||
# Found 'class' name ... ':', now check if it's a single line statement
|
||||
elif cls_step == 2:
|
||||
if type == NEWLINE:
|
||||
cls_sline = False
|
||||
else:
|
||||
cls_sline = True
|
||||
cls_doc = ''
|
||||
cls_step = 3
|
||||
|
||||
elif cls_step == 3:
|
||||
if not cls_doc and type == STRING:
|
||||
cls_doc = _trim_doc(text)
|
||||
if cls_sline:
|
||||
if type == NEWLINE:
|
||||
classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc)
|
||||
cls_step = 0
|
||||
else:
|
||||
if type == DEDENT and indent <= cls_indent:
|
||||
classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc)
|
||||
cls_step = 0
|
||||
|
||||
#################
|
||||
## Def parsing ##
|
||||
#################
|
||||
|
||||
# Look for 'def'
|
||||
if def_step == 0:
|
||||
if text == 'def':
|
||||
def_name = None
|
||||
def_lineno = start[0]
|
||||
def_step = 1
|
||||
|
||||
# Found 'def', look for def_name followed by '('
|
||||
elif def_step == 1:
|
||||
if type == NAME:
|
||||
def_name = text
|
||||
def_params = []
|
||||
elif def_name and text == '(':
|
||||
def_step = 2
|
||||
|
||||
# Found 'def' name '(', now identify the parameters upto ')'
|
||||
# TODO: Handle ellipsis '...'
|
||||
elif def_step == 2:
|
||||
if type == NAME:
|
||||
def_params.append(text)
|
||||
elif text == ':':
|
||||
def_step = 3
|
||||
|
||||
# Found 'def' ... ':', now check if it's a single line statement
|
||||
elif def_step == 3:
|
||||
if type == NEWLINE:
|
||||
def_sline = False
|
||||
else:
|
||||
def_sline = True
|
||||
def_doc = ''
|
||||
def_step = 4
|
||||
|
||||
elif def_step == 4:
|
||||
if type == STRING:
|
||||
def_doc = _trim_doc(text)
|
||||
newdef = None
|
||||
if def_sline:
|
||||
if type == NEWLINE:
|
||||
newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc)
|
||||
else:
|
||||
if type == NAME:
|
||||
newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc)
|
||||
if newdef:
|
||||
if cls_step > 0: # Parsing a class
|
||||
cls_defs[def_name] = newdef
|
||||
else:
|
||||
defs[def_name] = newdef
|
||||
def_step = 0
|
||||
|
||||
##########################
|
||||
## Variable assignation ##
|
||||
##########################
|
||||
|
||||
if cls_step > 0: # Parsing a class
|
||||
# Look for 'self.???'
|
||||
if var1_step == 0:
|
||||
if text == 'self':
|
||||
var1_step = 1
|
||||
elif var1_step == 1:
|
||||
if text == '.':
|
||||
var_name = None
|
||||
var1_step = 2
|
||||
else:
|
||||
var1_step = 0
|
||||
elif var1_step == 2:
|
||||
if type == NAME:
|
||||
var_name = text
|
||||
if cls_vars.has_key(var_name):
|
||||
var_step = 0
|
||||
else:
|
||||
var1_step = 3
|
||||
elif var1_step == 3:
|
||||
if text == '=':
|
||||
var1_step = 4
|
||||
elif text != ',':
|
||||
var1_step = 0
|
||||
elif var1_step == 4:
|
||||
var_type = None
|
||||
if type == NUMBER:
|
||||
close = end[1]
|
||||
if text.find('.') != -1: var_type = float
|
||||
else: var_type = int
|
||||
elif type == STRING:
|
||||
close = end[1]
|
||||
var_type = str
|
||||
elif text == '[':
|
||||
close = line.find(']', end[1])
|
||||
var_type = list
|
||||
elif text == '(':
|
||||
close = line.find(')', end[1])
|
||||
var_type = tuple
|
||||
elif text == '{':
|
||||
close = line.find('}', end[1])
|
||||
var_type = dict
|
||||
elif text == 'dict':
|
||||
close = line.find(')', end[1])
|
||||
var_type = dict
|
||||
if var_type and close+1 < len(line):
|
||||
if line[close+1] != ' ' and line[close+1] != '\t':
|
||||
var_type = None
|
||||
cls_vars[var_name] = VarDesc(var_name, var_type, start[0])
|
||||
var1_step = 0
|
||||
|
||||
elif def_step > 0: # Parsing a def
|
||||
# Look for 'global ???[,???]'
|
||||
if var2_step == 0:
|
||||
if text == 'global':
|
||||
var2_step = 1
|
||||
elif var2_step == 1:
|
||||
if type == NAME:
|
||||
if not vars.has_key(text):
|
||||
vars[text] = VarDesc(text, None, start[0])
|
||||
elif text != ',' and type != NL:
|
||||
var2_step == 0
|
||||
|
||||
else: # In global scope
|
||||
if var3_step == 0:
|
||||
# Look for names
|
||||
if text == 'for':
|
||||
var_accum = dict()
|
||||
var_forflag = True
|
||||
elif text == '=' or (var_forflag and text == 'in'):
|
||||
var_forflag = False
|
||||
var3_step = 1
|
||||
elif type == NAME:
|
||||
if prev_text != '.' and not vars.has_key(text):
|
||||
var_accum[text] = VarDesc(text, None, start[0])
|
||||
elif not text in [',', '(', ')', '[', ']']:
|
||||
var_accum = dict()
|
||||
var_forflag = False
|
||||
elif var3_step == 1:
|
||||
if len(var_accum) != 1:
|
||||
var_type = None
|
||||
vars.update(var_accum)
|
||||
else:
|
||||
var_name = var_accum.keys()[0]
|
||||
var_type = None
|
||||
if type == NUMBER:
|
||||
if text.find('.') != -1: var_type = float
|
||||
else: var_type = int
|
||||
elif type == STRING: var_type = str
|
||||
elif text == '[': var_type = list
|
||||
elif text == '(': var_type = tuple
|
||||
elif text == '{': var_type = dict
|
||||
vars[var_name] = VarDesc(var_name, var_type, start[0])
|
||||
var3_step = 0
|
||||
|
||||
#######################
|
||||
## General utilities ##
|
||||
#######################
|
||||
|
||||
prev_type = type
|
||||
prev_text = text
|
||||
|
||||
desc = ScriptDesc(txt.name, imports, classes, defs, vars, incomplete)
|
||||
desc.set_delay(10 * (time()-start_time) + 0.05)
|
||||
|
||||
global _parse_cache
|
||||
_parse_cache[hash(txt)] = desc
|
||||
return desc
|
||||
|
||||
def get_modules(since=1):
|
||||
"""Returns the set of built-in modules and any modules that have been
|
||||
imported into the system upto 'since' seconds ago.
|
||||
"""
|
||||
|
||||
global _modules, _modules_updated
|
||||
|
||||
t = time()
|
||||
if _modules_updated < t - since:
|
||||
_modules.update(sys.modules)
|
||||
_modules_updated = t
|
||||
return _modules.keys()
|
||||
|
||||
def suggest_cmp(x, y):
|
||||
"""Use this method when sorting a list of suggestions.
|
||||
"""
|
||||
|
||||
return cmp(x[0].upper(), y[0].upper())
|
||||
|
||||
def get_module(name):
|
||||
"""Returns the module specified by its name. The module itself is imported
|
||||
by this method and, as such, any initialization code will be executed.
|
||||
"""
|
||||
|
||||
mod = __import__(name)
|
||||
components = name.split('.')
|
||||
for comp in components[1:]:
|
||||
mod = getattr(mod, comp)
|
||||
return mod
|
||||
|
||||
def type_char(v):
|
||||
"""Returns the character used to signify the type of a variable. Use this
|
||||
method to identify the type character for an item in a suggestion list.
|
||||
|
||||
The following values are returned:
|
||||
'm' if the parameter is a module
|
||||
'f' if the parameter is callable
|
||||
'v' if the parameter is variable or otherwise indeterminable
|
||||
|
||||
"""
|
||||
|
||||
if isinstance(v, ModuleType):
|
||||
return 'm'
|
||||
elif callable(v):
|
||||
return 'f'
|
||||
else:
|
||||
return 'v'
|
||||
|
||||
def get_context(txt):
|
||||
"""Establishes the context of the cursor in the given Blender Text object
|
||||
|
||||
Returns one of:
|
||||
CTX_NORMAL - Cursor is in a normal context
|
||||
CTX_SINGLE_QUOTE - Cursor is inside a single quoted string
|
||||
CTX_DOUBLE_QUOTE - Cursor is inside a double quoted string
|
||||
CTX_COMMENT - Cursor is inside a comment
|
||||
|
||||
"""
|
||||
|
||||
l, cursor = txt.getCursorPos()
|
||||
lines = txt.asLines(0, l+1)
|
||||
|
||||
# FIXME: This method is too slow in large files for it to be called as often
|
||||
# as it is. So for lines below the 1000th line we do this... (quorn)
|
||||
if l > 1000: return CTX_NORMAL
|
||||
|
||||
# Detect context (in string or comment)
|
||||
in_str = CTX_NORMAL
|
||||
for line in lines:
|
||||
if l == 0:
|
||||
end = cursor
|
||||
else:
|
||||
end = len(line)
|
||||
l -= 1
|
||||
|
||||
# Comments end at new lines
|
||||
if in_str == CTX_COMMENT:
|
||||
in_str = CTX_NORMAL
|
||||
|
||||
for i in range(end):
|
||||
if in_str == 0:
|
||||
if line[i] == "'": in_str = CTX_SINGLE_QUOTE
|
||||
elif line[i] == '"': in_str = CTX_DOUBLE_QUOTE
|
||||
elif line[i] == '#': in_str = CTX_COMMENT
|
||||
else:
|
||||
if in_str == CTX_SINGLE_QUOTE:
|
||||
if line[i] == "'":
|
||||
in_str = CTX_NORMAL
|
||||
# In again if ' escaped, out again if \ escaped, and so on
|
||||
for a in range(i-1, -1, -1):
|
||||
if line[a] == '\\': in_str = 1-in_str
|
||||
else: break
|
||||
elif in_str == CTX_DOUBLE_QUOTE:
|
||||
if line[i] == '"':
|
||||
in_str = CTX_NORMAL
|
||||
# In again if " escaped, out again if \ escaped, and so on
|
||||
for a in range(i-1, -1, -1):
|
||||
if line[i-a] == '\\': in_str = 2-in_str
|
||||
else: break
|
||||
|
||||
return in_str
|
||||
|
||||
def current_line(txt):
|
||||
"""Extracts the Python script line at the cursor in the Blender Text object
|
||||
provided and cursor position within this line as the tuple pair (line,
|
||||
cursor).
|
||||
"""
|
||||
|
||||
lineindex, cursor = txt.getCursorPos()
|
||||
lines = txt.asLines()
|
||||
line = lines[lineindex]
|
||||
|
||||
# Join previous lines to this line if spanning
|
||||
i = lineindex - 1
|
||||
while i > 0:
|
||||
earlier = lines[i].rstrip()
|
||||
if earlier.endswith('\\'):
|
||||
line = earlier[:-1] + ' ' + line
|
||||
cursor += len(earlier)
|
||||
i -= 1
|
||||
|
||||
# Join later lines while there is an explicit joining character
|
||||
i = lineindex
|
||||
while i < len(lines)-1 and lines[i].rstrip().endswith('\\'):
|
||||
later = lines[i+1].strip()
|
||||
line = line + ' ' + later[:-1]
|
||||
i += 1
|
||||
|
||||
return line, cursor
|
||||
|
||||
def get_targets(line, cursor):
|
||||
"""Parses a period separated string of valid names preceding the cursor and
|
||||
returns them as a list in the same order.
|
||||
"""
|
||||
|
||||
brk = 0
|
||||
targets = []
|
||||
j = cursor
|
||||
i = j-1
|
||||
while i >= 0:
|
||||
if line[i] == ')': brk += 1
|
||||
elif brk:
|
||||
if line[i] == '(': brk -= 1
|
||||
else:
|
||||
if line[i] == '.':
|
||||
targets.insert(0, line[i+1:j]); j=i
|
||||
elif not (line[i].isalnum() or line[i] == '_' or line[i] == '.'):
|
||||
break
|
||||
i -= 1
|
||||
targets.insert(0, line[i+1:j])
|
||||
return targets
|
||||
|
||||
def get_defs(txt):
|
||||
"""Returns a dictionary which maps definition names in the source code to
|
||||
a list of their parameter names.
|
||||
|
||||
The line 'def doit(one, two, three): print one' for example, results in the
|
||||
mapping 'doit' : [ 'one', 'two', 'three' ]
|
||||
"""
|
||||
|
||||
return get_cached_descriptor(txt).defs
|
||||
|
||||
def get_vars(txt):
|
||||
"""Returns a dictionary of variable names found in the specified Text
|
||||
object. This method locates all names followed directly by an equal sign:
|
||||
'a = ???' or indirectly as part of a tuple/list assignment or inside a
|
||||
'for ??? in ???:' block.
|
||||
"""
|
||||
|
||||
return get_cached_descriptor(txt).vars
|
||||
|
||||
def get_imports(txt):
|
||||
"""Returns a dictionary which maps symbol names in the source code to their
|
||||
respective modules.
|
||||
|
||||
The line 'from Blender import Text as BText' for example, results in the
|
||||
mapping 'BText' : <module 'Blender.Text' (built-in)>
|
||||
|
||||
Note that this method imports the modules to provide this mapping as as such
|
||||
will execute any initilization code found within.
|
||||
"""
|
||||
|
||||
return get_cached_descriptor(txt).imports
|
||||
|
||||
def get_builtins():
|
||||
"""Returns a dictionary of built-in modules, functions and variables."""
|
||||
|
||||
return __builtin__.__dict__
|
||||
|
||||
|
||||
#################################
|
||||
## Debugging utility functions ##
|
||||
#################################
|
||||
|
||||
def print_cache_for(txt, period=sys.maxint):
|
||||
"""Prints out the data cached for a given Text object. If no period is
|
||||
given the text will not be reparsed and the cached version will be returned.
|
||||
Otherwise if the period has expired the text will be reparsed.
|
||||
"""
|
||||
|
||||
desc = get_cached_descriptor(txt, period)
|
||||
print '================================================'
|
||||
print 'Name:', desc.name, '('+str(hash(txt))+')'
|
||||
print '------------------------------------------------'
|
||||
print 'Defs:'
|
||||
for name, ddesc in desc.defs.items():
|
||||
print ' ', name, ddesc.params, ddesc.lineno
|
||||
print ' ', ddesc.doc
|
||||
print '------------------------------------------------'
|
||||
print 'Vars:'
|
||||
for name, vdesc in desc.vars.items():
|
||||
print ' ', name, vdesc.type, vdesc.lineno
|
||||
print '------------------------------------------------'
|
||||
print 'Imports:'
|
||||
for name, item in desc.imports.items():
|
||||
print ' ', name.ljust(15), item
|
||||
print '------------------------------------------------'
|
||||
print 'Classes:'
|
||||
for clsnme, clsdsc in desc.classes.items():
|
||||
print ' *********************************'
|
||||
print ' Name:', clsnme
|
||||
print ' ', clsdsc.doc
|
||||
print ' ---------------------------------'
|
||||
print ' Defs:'
|
||||
for name, ddesc in clsdsc.defs.items():
|
||||
print ' ', name, ddesc.params, ddesc.lineno
|
||||
print ' ', ddesc.doc
|
||||
print ' ---------------------------------'
|
||||
print ' Vars:'
|
||||
for name, vdesc in clsdsc.vars.items():
|
||||
print ' ', name, vdesc.type, vdesc.lineno
|
||||
print ' *********************************'
|
||||
print '================================================'
|
@ -121,25 +121,29 @@ def rem_unused_materials(me):
|
||||
material_users= dict( [(i,0) for i in xrange(len_materials)] )
|
||||
|
||||
for f in me.faces:
|
||||
f_mat = f.mat
|
||||
# Make sure the face index isnt too big. this happens sometimes.
|
||||
if f.mat >= len_materials:
|
||||
f.mat=0
|
||||
material_users[f.mat] += 1
|
||||
if f_mat >= len_materials:
|
||||
f_mat = f.mat = 0
|
||||
material_users[f_mat] += 1
|
||||
|
||||
mat_idx_subtract= 0
|
||||
reindex_mapping= dict( [(i,0) for i in xrange(len_materials)] )
|
||||
i= len_materials
|
||||
while i:
|
||||
i-=1
|
||||
# mat_idx_subtract= 0
|
||||
# reindex_mapping= dict( [(i,0) for i in xrange(len_materials)] )
|
||||
|
||||
reindex_mapping_ls = range(len_materials)
|
||||
for i in range(len_materials-1, -1, -1):
|
||||
if material_users[i] == 0:
|
||||
mat_idx_subtract+=1
|
||||
reindex_mapping[i]= mat_idx_subtract
|
||||
materials.pop(i)
|
||||
del reindex_mapping_ls[i]
|
||||
del materials[i]
|
||||
rem_materials+=1
|
||||
|
||||
reindex_mapping= {}
|
||||
|
||||
for i, mat in enumerate(reindex_mapping_ls):
|
||||
reindex_mapping[mat] = i
|
||||
|
||||
for f in me.faces:
|
||||
f.mat= f.mat - reindex_mapping[f.mat]
|
||||
f.mat= reindex_mapping[f.mat]
|
||||
|
||||
me.materials= materials
|
||||
return rem_materials
|
||||
|
69
release/scripts/scripttemplate_text_plugin.py
Normal file
69
release/scripts/scripttemplate_text_plugin.py
Normal file
@ -0,0 +1,69 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Text Plugin'
|
||||
Blender: 246
|
||||
Group: 'ScriptTemplate'
|
||||
Tooltip: 'Add a new text for writing a text plugin'
|
||||
"""
|
||||
|
||||
from Blender import Window
|
||||
import bpy
|
||||
|
||||
script_data = \
|
||||
'''#!BPY
|
||||
"""
|
||||
Name: 'My Plugin Script'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Ctrl+Alt+U'
|
||||
Tooltip: 'Put some useful info here'
|
||||
"""
|
||||
|
||||
# Add a licence here if you wish to re-distribute, we recommend the GPL
|
||||
|
||||
from Blender import Window, sys
|
||||
import BPyTextPlugin, bpy
|
||||
|
||||
def my_script_util(txt):
|
||||
# This function prints out statistical information about a script
|
||||
|
||||
desc = BPyTextPlugin.get_cached_descriptor(txt)
|
||||
print '---------------------------------------'
|
||||
print 'Script Name:', desc.name
|
||||
print 'Classes:', len(desc.classes)
|
||||
print ' ', desc.classes.keys()
|
||||
print 'Functions:', len(desc.defs)
|
||||
print ' ', desc.defs.keys()
|
||||
print 'Variables:', len(desc.vars)
|
||||
print ' ', desc.vars.keys()
|
||||
|
||||
def main():
|
||||
|
||||
# Gets the active text object, there can be many in one blend file.
|
||||
txt = bpy.data.texts.active
|
||||
|
||||
# Silently return if the script has been run with no active text
|
||||
if not txt:
|
||||
return
|
||||
|
||||
# Text plug-ins should run quickly so we time it here
|
||||
Window.WaitCursor(1)
|
||||
t = sys.time()
|
||||
|
||||
# Run our utility function
|
||||
my_script_util(txt)
|
||||
|
||||
# Timing the script is a good way to be aware on any speed hits when scripting
|
||||
print 'Plugin script finished in %.2f seconds' % (sys.time()-t)
|
||||
Window.WaitCursor(0)
|
||||
|
||||
|
||||
# This lets you import the script without running it
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
'''
|
||||
|
||||
new_text = bpy.data.texts.new('textplugin_template.py')
|
||||
new_text.write(script_data)
|
||||
bpy.data.texts.active = new_text
|
||||
Window.RedrawAll()
|
@ -94,6 +94,8 @@ output = Blender.Text.New(output_filename)
|
||||
|
||||
output.write(header + "\n\n")
|
||||
|
||||
output.write("%s\n\n" % Blender.Get('buildinfo'))
|
||||
|
||||
output.write("Platform: %s\n========\n\n" % sys.platform)
|
||||
|
||||
output.write("Python:\n======\n\n")
|
||||
|
64
release/scripts/textplugin_functiondocs.py
Normal file
64
release/scripts/textplugin_functiondocs.py
Normal file
@ -0,0 +1,64 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Function Documentation | Ctrl I'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Ctrl+I'
|
||||
Tooltip: 'Attempts to display documentation about the function preceding the cursor.'
|
||||
"""
|
||||
|
||||
# Only run if we have the required modules
|
||||
try:
|
||||
import bpy
|
||||
from BPyTextPlugin import *
|
||||
except ImportError:
|
||||
OK = False
|
||||
else:
|
||||
OK = True
|
||||
|
||||
def main():
|
||||
txt = bpy.data.texts.active
|
||||
if not txt:
|
||||
return
|
||||
|
||||
(line, c) = current_line(txt)
|
||||
|
||||
# Check we are in a normal context
|
||||
if get_context(txt) != CTX_NORMAL:
|
||||
return
|
||||
|
||||
# Identify the name under the cursor
|
||||
llen = len(line)
|
||||
while c<llen and (line[c].isalnum() or line[c]=='_'):
|
||||
c += 1
|
||||
|
||||
targets = get_targets(line, c)
|
||||
|
||||
# If no name under cursor, look backward to see if we're in function parens
|
||||
if len(targets) == 0 or targets[0] == '':
|
||||
# Look backwards for first '(' without ')'
|
||||
b = 0
|
||||
found = False
|
||||
for i in range(c-1, -1, -1):
|
||||
if line[i] == ')': b += 1
|
||||
elif line[i] == '(':
|
||||
b -= 1
|
||||
if b < 0:
|
||||
found = True
|
||||
c = i
|
||||
break
|
||||
if found: targets = get_targets(line, c)
|
||||
if len(targets) == 0 or targets[0] == '':
|
||||
return
|
||||
|
||||
obj = resolve_targets(txt, targets)
|
||||
if not obj: return
|
||||
|
||||
if isinstance(obj, Definition): # Local definition
|
||||
txt.showDocs(obj.doc)
|
||||
elif hasattr(obj, '__doc__') and obj.__doc__:
|
||||
txt.showDocs(obj.__doc__)
|
||||
|
||||
# Check we are running as a script and not imported as a module
|
||||
if __name__ == "__main__" and OK:
|
||||
main()
|
91
release/scripts/textplugin_imports.py
Normal file
91
release/scripts/textplugin_imports.py
Normal file
@ -0,0 +1,91 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Import Complete|Space'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Space'
|
||||
Tooltip: 'Lists modules when import or from is typed'
|
||||
"""
|
||||
|
||||
# Only run if we have the required modules
|
||||
try:
|
||||
import bpy, sys
|
||||
from BPyTextPlugin import *
|
||||
except ImportError:
|
||||
OK = False
|
||||
else:
|
||||
OK = True
|
||||
|
||||
def main():
|
||||
txt = bpy.data.texts.active
|
||||
if not txt:
|
||||
return
|
||||
|
||||
line, c = current_line(txt)
|
||||
|
||||
# Check we are in a normal context
|
||||
if get_context(txt) != CTX_NORMAL:
|
||||
return
|
||||
|
||||
pos = line.rfind('from ', 0, c)
|
||||
|
||||
# No 'from' found
|
||||
if pos == -1:
|
||||
# Check instead for straight 'import xxxx'
|
||||
pos2 = line.rfind('import ', 0, c)
|
||||
if pos2 != -1:
|
||||
pos2 += 7
|
||||
for i in range(pos2, c):
|
||||
if line[i]==',' or (line[i]==' ' and line[i-1]==','):
|
||||
pos2 = i+1
|
||||
elif not line[i].isalnum() and line[i] != '_':
|
||||
return
|
||||
items = [(m, 'm') for m in get_modules()]
|
||||
items.sort(cmp = suggest_cmp)
|
||||
txt.suggest(items, line[pos2:c].strip())
|
||||
return
|
||||
|
||||
# Found 'from xxxxx' before cursor
|
||||
immediate = True
|
||||
pos += 5
|
||||
for i in range(pos, c):
|
||||
if not line[i].isalnum() and line[i] != '_' and line[i] != '.':
|
||||
immediate = False
|
||||
break
|
||||
|
||||
# Immediate 'from' followed by at most a module name
|
||||
if immediate:
|
||||
items = [(m, 'm') for m in get_modules()]
|
||||
items.sort(cmp = suggest_cmp)
|
||||
txt.suggest(items, line[pos:c])
|
||||
return
|
||||
|
||||
# Found 'from' earlier, suggest import if not already there
|
||||
pos2 = line.rfind('import ', pos, c)
|
||||
|
||||
# No 'import' found after 'from' so suggest it
|
||||
if pos2 == -1:
|
||||
txt.suggest([('import', 'k')], '')
|
||||
return
|
||||
|
||||
# Immediate 'import' before cursor and after 'from...'
|
||||
for i in range(pos2+7, c):
|
||||
if line[i]==',' or (line[i]==' ' and line[i-1]==','):
|
||||
pass
|
||||
elif not line[i].isalnum() and line[i] != '_':
|
||||
return
|
||||
between = line[pos:pos2-1].strip()
|
||||
try:
|
||||
mod = get_module(between)
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
items = [('*', 'k')]
|
||||
for (k,v) in mod.__dict__.items():
|
||||
items.append((k, type_char(v)))
|
||||
items.sort(cmp = suggest_cmp)
|
||||
txt.suggest(items, '')
|
||||
|
||||
# Check we are running as a script and not imported as a module
|
||||
if __name__ == "__main__" and OK:
|
||||
main()
|
90
release/scripts/textplugin_membersuggest.py
Normal file
90
release/scripts/textplugin_membersuggest.py
Normal file
@ -0,0 +1,90 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Member Suggest | .'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Period'
|
||||
Tooltip: 'Lists members of the object preceding the cursor in the current text space'
|
||||
"""
|
||||
|
||||
# Only run if we have the required modules
|
||||
try:
|
||||
import bpy
|
||||
from BPyTextPlugin import *
|
||||
except ImportError:
|
||||
OK = False
|
||||
else:
|
||||
OK = True
|
||||
|
||||
def main():
|
||||
txt = bpy.data.texts.active
|
||||
if not txt:
|
||||
return
|
||||
|
||||
(line, c) = current_line(txt)
|
||||
|
||||
# Check we are in a normal context
|
||||
if get_context(txt) != CTX_NORMAL:
|
||||
return
|
||||
|
||||
targets = get_targets(line, c)
|
||||
|
||||
if targets[0] == '': # Check if we are looking at a constant [] {} '' etc.
|
||||
i = c - len('.'.join(targets)) - 1
|
||||
if i >= 0:
|
||||
if line[i] == '"' or line[i] == "'":
|
||||
targets[0] = 'str'
|
||||
elif line[i] == '}':
|
||||
targets[0] = 'dict'
|
||||
elif line[i] == ']': # Could be array elem x[y] or list [y]
|
||||
i = line.rfind('[', 0, i) - 1
|
||||
while i >= 0:
|
||||
if line[i].isalnum() or line[i] == '_':
|
||||
break
|
||||
elif line[i] != ' ' and line[i] != '\t':
|
||||
i = -1
|
||||
break
|
||||
i -= 1
|
||||
if i < 0:
|
||||
targets[0] = 'list'
|
||||
|
||||
obj = resolve_targets(txt, targets[:-1])
|
||||
if not obj:
|
||||
return
|
||||
|
||||
items = []
|
||||
|
||||
if isinstance(obj, VarDesc):
|
||||
obj = obj.type
|
||||
|
||||
if isinstance(obj, Definition): # Locally defined
|
||||
if hasattr(obj, 'classes'):
|
||||
items.extend([(s, 'f') for s in obj.classes.keys()])
|
||||
if hasattr(obj, 'defs'):
|
||||
items.extend([(s, 'f') for s in obj.defs.keys()])
|
||||
if hasattr(obj, 'vars'):
|
||||
items.extend([(s, 'v') for s in obj.vars.keys()])
|
||||
|
||||
else: # Otherwise we have an imported or builtin object
|
||||
try:
|
||||
attr = obj.__dict__.keys()
|
||||
except AttributeError:
|
||||
attr = dir(obj)
|
||||
else:
|
||||
if not attr: attr = dir(obj)
|
||||
|
||||
for k in attr:
|
||||
try:
|
||||
v = getattr(obj, k)
|
||||
except (AttributeError, TypeError): # Some attributes are not readable
|
||||
pass
|
||||
else:
|
||||
items.append((k, type_char(v)))
|
||||
|
||||
if items != []:
|
||||
items.sort(cmp = suggest_cmp)
|
||||
txt.suggest(items, targets[-1])
|
||||
|
||||
# Check we are running as a script and not imported as a module
|
||||
if __name__ == "__main__" and OK:
|
||||
main()
|
142
release/scripts/textplugin_outliner.py
Normal file
142
release/scripts/textplugin_outliner.py
Normal file
@ -0,0 +1,142 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Code Outline | Ctrl T'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Ctrl+T'
|
||||
Tooltip: 'Provides a menu for jumping to class and functions definitions.'
|
||||
"""
|
||||
|
||||
# Only run if we have the required modules
|
||||
try:
|
||||
import bpy
|
||||
from BPyTextPlugin import *
|
||||
from Blender import Draw
|
||||
except ImportError:
|
||||
OK = False
|
||||
else:
|
||||
OK = True
|
||||
|
||||
def make_menu(items, eventoffs):
|
||||
n = len(items)
|
||||
if n < 20:
|
||||
return [(items[i], i+1+eventoffs) for i in range(len(items))]
|
||||
|
||||
letters = []
|
||||
check = 'abcdefghijklmnopqrstuvwxyz_' # Names cannot start 0-9
|
||||
for c in check:
|
||||
for item in items:
|
||||
if item[0].lower() == c:
|
||||
letters.append(c)
|
||||
break
|
||||
|
||||
entries = {}
|
||||
i = 0
|
||||
for item in items:
|
||||
i += 1
|
||||
c = item[0].lower()
|
||||
entries.setdefault(c, []).append((item, i+eventoffs))
|
||||
|
||||
subs = []
|
||||
for c in letters:
|
||||
subs.append((c, entries[c]))
|
||||
|
||||
return subs
|
||||
|
||||
def find_word(txt, word):
|
||||
i = 0
|
||||
txt.reset()
|
||||
while True:
|
||||
try:
|
||||
line = txt.readline()
|
||||
except StopIteration:
|
||||
break
|
||||
c = line.find(word)
|
||||
if c != -1:
|
||||
txt.setCursorPos(i, c)
|
||||
break
|
||||
i += 1
|
||||
|
||||
def main():
|
||||
txt = bpy.data.texts.active
|
||||
if not txt:
|
||||
return
|
||||
|
||||
# Identify word under cursor
|
||||
if get_context(txt) == CTX_NORMAL:
|
||||
line, c = current_line(txt)
|
||||
start = c-1
|
||||
end = c
|
||||
while start >= 0:
|
||||
if not line[start].lower() in 'abcdefghijklmnopqrstuvwxyz0123456789_':
|
||||
break
|
||||
start -= 1
|
||||
while end < len(line):
|
||||
if not line[end].lower() in 'abcdefghijklmnopqrstuvwxyz0123456789_':
|
||||
break
|
||||
end += 1
|
||||
word = line[start+1:end]
|
||||
if word in KEYWORDS:
|
||||
word = None
|
||||
else:
|
||||
word = None
|
||||
|
||||
script = get_cached_descriptor(txt)
|
||||
items = []
|
||||
desc = None
|
||||
|
||||
tmp = script.classes.keys()
|
||||
tmp.sort(cmp = suggest_cmp)
|
||||
class_menu = make_menu(tmp, len(items))
|
||||
class_menu_length = len(tmp)
|
||||
items.extend(tmp)
|
||||
|
||||
tmp = script.defs.keys()
|
||||
tmp.sort(cmp = suggest_cmp)
|
||||
defs_menu = make_menu(tmp, len(items))
|
||||
defs_menu_length = len(tmp)
|
||||
items.extend(tmp)
|
||||
|
||||
tmp = script.vars.keys()
|
||||
tmp.sort(cmp = suggest_cmp)
|
||||
vars_menu = make_menu(tmp, len(items))
|
||||
vars_menu_length = len(tmp)
|
||||
items.extend(tmp)
|
||||
|
||||
menu = [('Script %t', 0),
|
||||
('Classes', class_menu),
|
||||
('Functions', defs_menu),
|
||||
('Variables', vars_menu)]
|
||||
if word:
|
||||
menu.extend([None, ('Locate', [(word, -10)])])
|
||||
|
||||
i = Draw.PupTreeMenu(menu)
|
||||
if i == -1:
|
||||
return
|
||||
|
||||
# Chosen to search for word under cursor
|
||||
if i == -10:
|
||||
if script.classes.has_key(word):
|
||||
desc = script.classes[word]
|
||||
elif script.defs.has_key(word):
|
||||
desc = script.defs[word]
|
||||
elif script.vars.has_key(word):
|
||||
desc = script.vars[word]
|
||||
else:
|
||||
find_word(txt, word)
|
||||
return
|
||||
else:
|
||||
i -= 1
|
||||
if i < class_menu_length:
|
||||
desc = script.classes[items[i]]
|
||||
elif i < class_menu_length + defs_menu_length:
|
||||
desc = script.defs[items[i]]
|
||||
elif i < class_menu_length + defs_menu_length + vars_menu_length:
|
||||
desc = script.vars[items[i]]
|
||||
|
||||
if desc:
|
||||
txt.setCursorPos(desc.lineno-1, 0)
|
||||
|
||||
# Check we are running as a script and not imported as a module
|
||||
if __name__ == "__main__" and OK:
|
||||
main()
|
94
release/scripts/textplugin_suggest.py
Normal file
94
release/scripts/textplugin_suggest.py
Normal file
@ -0,0 +1,94 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Suggest All | Ctrl Space'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Ctrl+Space'
|
||||
Tooltip: 'Performs suggestions based on the context of the cursor'
|
||||
"""
|
||||
|
||||
# Only run if we have the required modules
|
||||
try:
|
||||
import bpy
|
||||
from BPyTextPlugin import *
|
||||
except ImportError:
|
||||
OK = False
|
||||
else:
|
||||
OK = True
|
||||
|
||||
def check_membersuggest(line, c):
|
||||
pos = line.rfind('.', 0, c)
|
||||
if pos == -1:
|
||||
return False
|
||||
for s in line[pos+1:c]:
|
||||
if not s.isalnum() and s != '_':
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_imports(line, c):
|
||||
pos = line.rfind('import ', 0, c)
|
||||
if pos > -1:
|
||||
for s in line[pos+7:c]:
|
||||
if not s.isalnum() and s != '_':
|
||||
return False
|
||||
return True
|
||||
pos = line.rfind('from ', 0, c)
|
||||
if pos > -1:
|
||||
for s in line[pos+5:c]:
|
||||
if not s.isalnum() and s != '_':
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
txt = bpy.data.texts.active
|
||||
if not txt:
|
||||
return
|
||||
|
||||
line, c = current_line(txt)
|
||||
|
||||
# Check we are in a normal context
|
||||
if get_context(txt) != CTX_NORMAL:
|
||||
return
|
||||
|
||||
# Check the character preceding the cursor and execute the corresponding script
|
||||
|
||||
if check_membersuggest(line, c):
|
||||
import textplugin_membersuggest
|
||||
textplugin_membersuggest.main()
|
||||
return
|
||||
|
||||
elif check_imports(line, c):
|
||||
import textplugin_imports
|
||||
textplugin_imports.main()
|
||||
return
|
||||
|
||||
# Otherwise we suggest globals, keywords, etc.
|
||||
list = []
|
||||
targets = get_targets(line, c)
|
||||
desc = get_cached_descriptor(txt)
|
||||
|
||||
for k in KEYWORDS:
|
||||
list.append((k, 'k'))
|
||||
|
||||
for k, v in get_builtins().items():
|
||||
list.append((k, type_char(v)))
|
||||
|
||||
for k, v in desc.imports.items():
|
||||
list.append((k, type_char(v)))
|
||||
|
||||
for k, v in desc.classes.items():
|
||||
list.append((k, 'f'))
|
||||
|
||||
for k, v in desc.defs.items():
|
||||
list.append((k, 'f'))
|
||||
|
||||
for k, v in desc.vars.items():
|
||||
list.append((k, 'v'))
|
||||
|
||||
list.sort(cmp = suggest_cmp)
|
||||
txt.suggest(list, targets[-1])
|
||||
|
||||
# Check we are running as a script and not imported as a module
|
||||
if __name__ == "__main__" and OK:
|
||||
main()
|
123
release/scripts/textplugin_templates.py
Normal file
123
release/scripts/textplugin_templates.py
Normal file
@ -0,0 +1,123 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Template Completion | Tab'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Tab'
|
||||
Tooltip: 'Completes templates based on the text preceding the cursor'
|
||||
"""
|
||||
|
||||
# Only run if we have the required modules
|
||||
try:
|
||||
import bpy
|
||||
from BPyTextPlugin import *
|
||||
from Blender import Text
|
||||
except ImportError:
|
||||
OK = False
|
||||
else:
|
||||
OK = True
|
||||
|
||||
templates = {
|
||||
'ie':
|
||||
'if ${1:cond}:\n'
|
||||
'\t${2}\n'
|
||||
'else:\n'
|
||||
'\t${3}\n',
|
||||
'iei':
|
||||
'if ${1:cond}:\n'
|
||||
'\t${2}\n'
|
||||
'elif:\n'
|
||||
'\t${3}\n'
|
||||
'else:\n'
|
||||
'\t${4}\n',
|
||||
'def':
|
||||
'def ${1:name}(${2:params}):\n'
|
||||
'\t"""(${2}) - ${3:comment}"""\n'
|
||||
'\t${4}',
|
||||
'cls':
|
||||
'class ${1:name}(${2:parent}):\n'
|
||||
'\t"""${3:docs}"""\n'
|
||||
'\t\n'
|
||||
'\tdef __init__(self, ${4:params}):\n'
|
||||
'\t\t"""Creates a new ${1}"""\n'
|
||||
'\t\t${5}',
|
||||
'class':
|
||||
'class ${1:name}(${2:parent}):\n'
|
||||
'\t"""${3:docs}"""\n'
|
||||
'\t\n'
|
||||
'\tdef __init__(self, ${4:params}):\n'
|
||||
'\t\t"""Creates a new ${1}"""\n'
|
||||
'\t\t${5}'
|
||||
}
|
||||
|
||||
def main():
|
||||
txt = bpy.data.texts.active
|
||||
if not txt:
|
||||
return
|
||||
|
||||
row, c = txt.getCursorPos()
|
||||
line = txt.asLines(row, row+1)[0]
|
||||
indent=0
|
||||
while indent<c and (line[indent]==' ' or line[indent]=='\t'):
|
||||
indent += 1
|
||||
|
||||
# Check we are in a normal context
|
||||
if get_context(txt) != CTX_NORMAL:
|
||||
return
|
||||
|
||||
targets = get_targets(line, c-1);
|
||||
if len(targets) != 1: return
|
||||
|
||||
color = (0, 192, 32)
|
||||
|
||||
for trigger, template in templates.items():
|
||||
if trigger != targets[0]: continue
|
||||
inserts = {}
|
||||
txt.delete(-len(trigger)-1)
|
||||
y, x = txt.getCursorPos()
|
||||
first = None
|
||||
|
||||
# Insert template text and parse for insertion points
|
||||
count = len(template); i = 0
|
||||
while i < count:
|
||||
if i<count-1 and template[i]=='$' and template[i+1]=='{':
|
||||
i += 2
|
||||
e = template.find('}', i)
|
||||
item = template[i:e].split(':')
|
||||
if len(item)<2: item.append('')
|
||||
if not inserts.has_key(item[0]):
|
||||
inserts[item[0]] = (item[1], [(x, y)])
|
||||
else:
|
||||
inserts[item[0]][1].append((x, y))
|
||||
item[1] = inserts[item[0]][0]
|
||||
if not first: first = (item[1], x, y)
|
||||
txt.insert(item[1])
|
||||
x += len(item[1])
|
||||
i = e
|
||||
else:
|
||||
txt.insert(template[i])
|
||||
if template[i] == '\n':
|
||||
txt.insert(line[:indent])
|
||||
y += 1
|
||||
x = indent
|
||||
else:
|
||||
x += 1
|
||||
i += 1
|
||||
|
||||
# Insert markers at insertion points
|
||||
for id, (text, points) in inserts.items():
|
||||
for x, y in points:
|
||||
txt.setCursorPos(y, x)
|
||||
txt.setSelectPos(y, x+len(text))
|
||||
txt.markSelection((hash(text)+int(id)) & 0xFFFF, color,
|
||||
Text.TMARK_TEMP | Text.TMARK_EDITALL)
|
||||
if first:
|
||||
text, x, y = first
|
||||
txt.setCursorPos(y, x)
|
||||
txt.setSelectPos(y, x+len(text))
|
||||
break
|
||||
|
||||
|
||||
# Check we are running as a script and not imported as a module
|
||||
if __name__ == "__main__" and OK:
|
||||
main()
|
@ -104,6 +104,8 @@ COMLIB += $(NAN_OPENNL)/lib/$(DEBUG_DIR)libopennl.a
|
||||
COMLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a
|
||||
COMLIB += $(OCGDIR)/blender/avi/$(DEBUG_DIR)libavi.a
|
||||
COMLIB += $(NAN_JPEG)/lib/libjpeg.a
|
||||
COMLIB += $(OCGDIR)/blender/gpu/$(DEBUG_DIR)libgpu.a
|
||||
COMLIB += $(NAN_GLEW)/lib/libglew.a
|
||||
|
||||
ifneq ($(NAN_NO_KETSJI),true)
|
||||
COMLIB += $(OCGDIR)/gameengine/bloutines/$(DEBUG_DIR)libbloutines.a
|
||||
@ -157,7 +159,6 @@ COMLIB += $(NAN_BMFONT)/lib/$(DEBUG_DIR)libbmfont.a
|
||||
COMLIB += $(NAN_PNG)/lib/libpng.a
|
||||
COMLIB += $(OCGDIR)/blender/yafray/$(DEBUG_DIR)libyafrayexport.a
|
||||
COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a
|
||||
COMLIB += $(NAN_GLEW)/lib/libglew.a
|
||||
|
||||
ifeq ($(WITH_QUICKTIME), true)
|
||||
COMLIB += $(OCGDIR)/blender/blenderqt/$(DEBUG_DIR)libblenderqt.a
|
||||
|
@ -24,7 +24,7 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
SUBDIRS(avi nodes blenkernel blenlib blenloader blenpluginapi imbuf imbuf/intern/cineon makesdna python radiosity readblenfile render src yafray)
|
||||
SUBDIRS(avi nodes blenkernel blenlib blenloader blenpluginapi imbuf imbuf/intern/cineon gpu makesdna python radiosity readblenfile render src yafray)
|
||||
|
||||
IF(WITH_INTERNATIONAL)
|
||||
SUBDIRS(ftfont)
|
||||
|
@ -33,7 +33,7 @@ include nan_definitions.mk
|
||||
DIRS = blenloader readblenfile
|
||||
DIRS += avi imbuf render radiosity blenlib blenkernel blenpluginapi
|
||||
DIRS += makesdna src yafray
|
||||
DIRS += python nodes
|
||||
DIRS += python nodes gpu
|
||||
|
||||
ifeq ($(WITH_FREETYPE2), true)
|
||||
DIRS += ftfont
|
||||
|
@ -7,6 +7,7 @@ SConscript(['avi/SConscript',
|
||||
'blenlib/SConscript',
|
||||
'blenloader/SConscript',
|
||||
'blenpluginapi/SConscript',
|
||||
'gpu/SConscript',
|
||||
'imbuf/SConscript',
|
||||
'imbuf/intern/cineon/SConscript',
|
||||
'makesdna/SConscript',
|
||||
|
@ -55,6 +55,7 @@ struct EditMesh;
|
||||
struct ModifierData;
|
||||
struct MCol;
|
||||
struct ColorBand;
|
||||
struct GPUVertexAttribs;
|
||||
|
||||
/* number of sub-elements each mesh element has (for interpolation) */
|
||||
#define SUB_ELEMS_VERT 0
|
||||
@ -198,7 +199,8 @@ struct DerivedMesh {
|
||||
*
|
||||
* Also called for *final* editmode DerivedMeshes
|
||||
*/
|
||||
void (*drawFacesSolid)(DerivedMesh *dm, int (*setMaterial)(int));
|
||||
void (*drawFacesSolid)(DerivedMesh *dm,
|
||||
int (*setMaterial)(int, void *attribs));
|
||||
|
||||
/* Draw all faces
|
||||
* o If useTwoSided, draw front and back using col arrays
|
||||
@ -215,6 +217,13 @@ struct DerivedMesh {
|
||||
int (*setDrawOptions)(struct MTFace *tface,
|
||||
struct MCol *mcol, int matnr));
|
||||
|
||||
/* Draw all faces with GLSL materials
|
||||
* o setMaterial is called for every different material nr
|
||||
* o Only if setMaterial returns true
|
||||
*/
|
||||
void (*drawFacesGLSL)(DerivedMesh *dm,
|
||||
int (*setMaterial)(int, void *attribs));
|
||||
|
||||
/* Draw mapped faces (no color, or texture)
|
||||
* o Only if !setDrawOptions or
|
||||
* setDrawOptions(userData, mapped-face-index, drawSmooth_r)
|
||||
@ -241,6 +250,15 @@ struct DerivedMesh {
|
||||
int index),
|
||||
void *userData);
|
||||
|
||||
/* Draw mapped faces with GLSL materials
|
||||
* o setMaterial is called for every different material nr
|
||||
* o setDrawOptions is called for every face
|
||||
* o Only if setMaterial and setDrawOptions return true
|
||||
*/
|
||||
void (*drawMappedFacesGLSL)(DerivedMesh *dm,
|
||||
int (*setMaterial)(int, void *attribs),
|
||||
int (*setDrawOptions)(void *userData, int index), void *userData);
|
||||
|
||||
/* Draw mapped edges as lines
|
||||
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge)
|
||||
* returns true
|
||||
@ -440,6 +458,35 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb);
|
||||
/* determines required DerivedMesh data according to view and edit modes */
|
||||
CustomDataMask get_viewedit_datamask();
|
||||
|
||||
/* convert layers requested by a GLSL material to actually available layers in
|
||||
* the DerivedMesh, with both a pointer for arrays and an offset for editmesh */
|
||||
typedef struct DMVertexAttribs {
|
||||
struct {
|
||||
struct MTFace *array;
|
||||
int emOffset, glIndex;
|
||||
} tface[MAX_MTFACE];
|
||||
|
||||
struct {
|
||||
struct MCol *array;
|
||||
int emOffset, glIndex;
|
||||
} mcol[MAX_MCOL];
|
||||
|
||||
struct {
|
||||
float (*array)[3];
|
||||
int emOffset, glIndex;
|
||||
} tang;
|
||||
|
||||
struct {
|
||||
float (*array)[3];
|
||||
int emOffset, glIndex;
|
||||
} orco;
|
||||
|
||||
int tottface, totmcol, tottang, totorco;
|
||||
} DMVertexAttribs;
|
||||
|
||||
void DM_vertex_attributes_from_gpu(DerivedMesh *dm,
|
||||
struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
|
||||
|
||||
void DM_add_tangent_layer(DerivedMesh *dm);
|
||||
|
||||
#endif
|
||||
|
@ -115,10 +115,6 @@ void free_editArmature(void);
|
||||
void docenter_new(void);
|
||||
int saveover(char *str);
|
||||
|
||||
/* image.c */
|
||||
#include "DNA_image_types.h"
|
||||
void free_realtime_image(Image *ima); // has to become a callback, opengl stuff
|
||||
|
||||
/* ipo.c */
|
||||
void copy_view3d_lock(short val); // was a hack, to make scene layer ipo's possible
|
||||
|
||||
|
@ -57,6 +57,7 @@ void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf);
|
||||
void curvemapping_premultiply(struct CurveMapping *cumap, int restore);
|
||||
int curvemapping_RGBA_does_something(struct CurveMapping *cumap);
|
||||
void curvemapping_initialize(struct CurveMapping *cumap);
|
||||
void curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -218,8 +218,15 @@ typedef struct Global {
|
||||
#define G_FILE_NO_UI (1 << 10)
|
||||
#define G_FILE_GAME_TO_IPO (1 << 11)
|
||||
#define G_FILE_GAME_MAT (1 << 12)
|
||||
#define G_FILE_DIAPLAY_LISTS (1 << 13)
|
||||
#define G_FILE_DISPLAY_LISTS (1 << 13)
|
||||
#define G_FILE_SHOW_PHYSICS (1 << 14)
|
||||
#define G_FILE_GAME_MAT_GLSL (1 << 15)
|
||||
#define G_FILE_GLSL_NO_LIGHTS (1 << 16)
|
||||
#define G_FILE_GLSL_NO_SHADERS (1 << 17)
|
||||
#define G_FILE_GLSL_NO_SHADOWS (1 << 18)
|
||||
#define G_FILE_GLSL_NO_RAMPS (1 << 19)
|
||||
#define G_FILE_GLSL_NO_NODES (1 << 20)
|
||||
#define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21)
|
||||
|
||||
/* G.windowstate */
|
||||
#define G_WINDOWSTATE_USERDEF 0
|
||||
|
@ -68,7 +68,6 @@ void mball_to_mesh(struct ListBase *lb, struct Mesh *me);
|
||||
void nurbs_to_mesh(struct Object *ob);
|
||||
void free_dverts(struct MDeformVert *dvert, int totvert);
|
||||
void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
|
||||
int update_realtime_texture(struct MTFace *tface, double time);
|
||||
void mesh_delete_material_index(struct Mesh *me, int index);
|
||||
void mesh_set_smooth_flag(struct Object *meshOb, int enableSmooth);
|
||||
|
||||
|
@ -47,6 +47,9 @@ struct rctf;
|
||||
struct ListBase;
|
||||
struct RenderData;
|
||||
struct Scene;
|
||||
struct GPUMaterial;
|
||||
struct GPUNode;
|
||||
struct GPUNodeStack;
|
||||
|
||||
#define SOCK_IN 1
|
||||
#define SOCK_OUT 2
|
||||
@ -91,6 +94,9 @@ typedef struct bNodeType {
|
||||
void *pynode; /* holds pointer to python script */
|
||||
void *pydict; /* holds pointer to python script dictionary (scope)*/
|
||||
|
||||
/* gpu */
|
||||
int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out);
|
||||
|
||||
} bNodeType;
|
||||
|
||||
/* node->exec, now in use for composites (#define for break is same as ready yes) */
|
||||
@ -252,6 +258,8 @@ void nodeShaderSynchronizeID(struct bNode *node, int copyto);
|
||||
extern void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *);
|
||||
void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *));
|
||||
|
||||
void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
|
||||
|
||||
|
||||
/* ************** COMPOSITE NODES *************** */
|
||||
|
||||
|
93
source/blender/blenkernel/BKE_suggestions.h
Normal file
93
source/blender/blenkernel/BKE_suggestions.h
Normal file
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008, Blender Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef BKE_SUGGESTIONS_H
|
||||
#define BKE_SUGGESTIONS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ****************************************************************************
|
||||
Suggestions should be added in sorted order although a linear sorting method is
|
||||
implemented. The list is then divided up based on the prefix provided by
|
||||
update_suggestions:
|
||||
|
||||
Example:
|
||||
Prefix: ab
|
||||
aaa <-- first
|
||||
aab
|
||||
aba <-- firstmatch
|
||||
abb <-- lastmatch
|
||||
baa
|
||||
bab <-- last
|
||||
**************************************************************************** */
|
||||
|
||||
struct Text;
|
||||
|
||||
typedef struct SuggItem {
|
||||
struct SuggItem *prev, *next;
|
||||
char *name;
|
||||
char type;
|
||||
} SuggItem;
|
||||
|
||||
typedef struct SuggList {
|
||||
SuggItem *first, *last;
|
||||
SuggItem *firstmatch, *lastmatch;
|
||||
SuggItem *selected;
|
||||
int top;
|
||||
} SuggList;
|
||||
|
||||
/* Free all text tool memory */
|
||||
void free_texttools();
|
||||
|
||||
/* Used to identify which Text object the current tools should appear against */
|
||||
void texttool_text_set_active(Text *text);
|
||||
void texttool_text_clear();
|
||||
short texttool_text_is_active(Text *text);
|
||||
|
||||
/* Suggestions */
|
||||
void texttool_suggest_add(const char *name, char type);
|
||||
void texttool_suggest_prefix(const char *prefix);
|
||||
void texttool_suggest_clear();
|
||||
SuggItem *texttool_suggest_first();
|
||||
SuggItem *texttool_suggest_last();
|
||||
void texttool_suggest_select(SuggItem *sel);
|
||||
SuggItem *texttool_suggest_selected();
|
||||
int *texttool_suggest_top();
|
||||
|
||||
/* Documentation */
|
||||
void texttool_docs_show(const char *docs);
|
||||
char *texttool_docs_get();
|
||||
void texttool_docs_clear();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -52,20 +52,24 @@ void txt_free_cut_buffer (void);
|
||||
char* txt_to_buf (struct Text *text);
|
||||
void txt_clean_text (struct Text *text);
|
||||
void txt_order_cursors (struct Text *text);
|
||||
int txt_find_string (struct Text *text, char *findstr);
|
||||
int txt_find_string (struct Text *text, char *findstr, int wrap);
|
||||
int txt_has_sel (struct Text *text);
|
||||
int txt_get_span (struct TextLine *from, struct TextLine *to);
|
||||
void txt_move_up (struct Text *text, short sel);
|
||||
void txt_move_down (struct Text *text, short sel);
|
||||
void txt_move_left (struct Text *text, short sel);
|
||||
void txt_move_right (struct Text *text, short sel);
|
||||
void txt_jump_left (struct Text *text, short sel);
|
||||
void txt_jump_right (struct Text *text, short sel);
|
||||
void txt_move_bof (struct Text *text, short sel);
|
||||
void txt_move_eof (struct Text *text, short sel);
|
||||
void txt_move_bol (struct Text *text, short sel);
|
||||
void txt_move_eol (struct Text *text, short sel);
|
||||
void txt_move_toline (struct Text *text, unsigned int line, short sel);
|
||||
void txt_move_to (struct Text *text, unsigned int line, unsigned int ch, short sel);
|
||||
void txt_pop_sel (struct Text *text);
|
||||
void txt_delete_char (struct Text *text);
|
||||
void txt_delete_word (struct Text *text);
|
||||
void txt_copy_sel (struct Text *text);
|
||||
void txt_sel_all (struct Text *text);
|
||||
void txt_sel_line (struct Text *text);
|
||||
@ -80,8 +84,10 @@ void txt_do_undo (struct Text *text);
|
||||
void txt_do_redo (struct Text *text);
|
||||
void txt_split_curline (struct Text *text);
|
||||
void txt_backspace_char (struct Text *text);
|
||||
void txt_backspace_word (struct Text *text);
|
||||
int txt_add_char (struct Text *text, char add);
|
||||
void txt_find_panel (struct SpaceText *st, int again);
|
||||
int txt_replace_char (struct Text *text, char add);
|
||||
void find_and_replace (struct SpaceText *st, short mode);
|
||||
void run_python_script (struct SpaceText *st);
|
||||
int jumptoline_interactive (struct SpaceText *st);
|
||||
void txt_export_to_object (struct Text *text);
|
||||
@ -94,6 +100,17 @@ int setcurr_tab (struct Text *text);
|
||||
void convert_tabs (struct SpaceText *st, int tab);
|
||||
void txt_copy_clipboard (struct Text *text);
|
||||
void txt_paste_clipboard (struct Text *text);
|
||||
|
||||
void txt_add_marker (struct Text *text, struct TextLine *line, int start, int end, char color[4], int group, int flags);
|
||||
short txt_clear_marker_region (struct Text *text, struct TextLine *line, int start, int end, int group, int flags);
|
||||
short txt_clear_markers (struct Text *text, int group, int flags);
|
||||
struct TextMarker *txt_find_marker (struct Text *text, struct TextLine *line, int curs, int group, int flags);
|
||||
struct TextMarker *txt_find_marker_region (struct Text *text, struct TextLine *line, int start, int end, int group, int flags);
|
||||
struct TextMarker *txt_prev_marker (struct Text *text, struct TextMarker *marker);
|
||||
struct TextMarker *txt_next_marker (struct Text *text, struct TextMarker *marker);
|
||||
struct TextMarker *txt_prev_marker_color (struct Text *text, struct TextMarker *marker);
|
||||
struct TextMarker *txt_next_marker_color (struct Text *text, struct TextMarker *marker);
|
||||
|
||||
/* Undo opcodes */
|
||||
|
||||
/* Simple main cursor movement */
|
||||
@ -135,6 +152,14 @@ void txt_paste_clipboard (struct Text *text);
|
||||
#define UNDO_COMMENT 034
|
||||
#define UNDO_UNCOMMENT 035
|
||||
|
||||
/* Find and replace flags */
|
||||
#define TXT_FIND_WRAP 0x01
|
||||
#define TXT_FIND_ALLTEXTS 0x02
|
||||
|
||||
/* Marker flags */
|
||||
#define TMARK_TEMP 0x01 /* Remove on non-editing events, don't save */
|
||||
#define TMARK_EDITALL 0x02 /* Edit all markers of the same group as one */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -53,6 +53,7 @@ void free_plugin_tex(struct PluginTex *pit);
|
||||
void init_colorband(struct ColorBand *coba, int rangetype);
|
||||
struct ColorBand *add_colorband(int rangetype);
|
||||
int do_colorband(struct ColorBand *coba, float in, float out[4]);
|
||||
void colorband_table_RGBA(struct ColorBand *coba, float **array, int *size);
|
||||
|
||||
void default_tex(struct Tex *tex);
|
||||
struct Tex *add_texture(char *name);
|
||||
|
@ -55,6 +55,8 @@
|
||||
#define ELEM7(a, b, c, d, e, f, g, h) ( ELEM3(a, b, c, d) || ELEM4(a, e, f, g, h) )
|
||||
#define ELEM8(a, b, c, d, e, f, g, h, i) ( ELEM4(a, b, c, d, e) || ELEM4(a, f, g, h, i) )
|
||||
#define ELEM9(a, b, c, d, e, f, g, h, i, j) ( ELEM4(a, b, c, d, e) || ELEM5(a, f, g, h, i, j) )
|
||||
#define ELEM10(a, b, c, d, e, f, g, h, i, j, k) ( ELEM4(a, b, c, d, e) || ELEM6(a, f, g, h, i, j, k) )
|
||||
#define ELEM11(a, b, c, d, e, f, g, h, i, j, k, l) ( ELEM4(a, b, c, d, e) || ELEM7(a, f, g, h, i, j, k, l) )
|
||||
|
||||
/* shift around elements */
|
||||
#define SHIFT3(type, a, b, c) { type tmp; tmp = a; a = c; c = b; b = tmp; }
|
||||
|
@ -32,7 +32,7 @@ SET(INC
|
||||
../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern
|
||||
../../../intern/iksolver/extern ../blenloader ../quicktime
|
||||
../../../intern/bmfont ../../../extern/bullet2/src
|
||||
../nodes
|
||||
../nodes ../../../extern/glew/include ../gpu
|
||||
${SDL_INC}
|
||||
${ZLIB_INC}
|
||||
${PYTHON_INC}
|
||||
|
@ -10,6 +10,7 @@ incs += ' #/intern/iksolver/extern ../blenloader ../quicktime'
|
||||
incs += ' #/extern/bullet2/src'
|
||||
incs += ' #/intern/bmfont'
|
||||
incs += ' #/intern/opennl/extern'
|
||||
incs += ' ../gpu #/extern/glew/include'
|
||||
|
||||
incs += ' ' + env['BF_PYTHON_INC']
|
||||
incs += ' ' + env['BF_OPENGL_INC']
|
||||
|
@ -176,10 +176,6 @@ void free_editMesh(struct EditMesh *em){}
|
||||
void docenter_new(void){}
|
||||
int saveover(char *str){ return 0;}
|
||||
|
||||
/* image.c */
|
||||
#include "DNA_image_types.h"
|
||||
void free_realtime_image(Image *ima){} // has to become a callback, opengl stuff
|
||||
|
||||
/* ipo.c */
|
||||
void copy_view3d_lock(short val){} // was a hack, to make scene layer ipo's possible
|
||||
|
||||
|
@ -87,6 +87,10 @@
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
///////////////////////////////////
|
||||
///////////////////////////////////
|
||||
|
||||
@ -405,6 +409,8 @@ void DM_swap_face_data(DerivedMesh *dm, int index, int *corner_indices)
|
||||
CustomData_swap(&dm->faceData, index, corner_indices);
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3])
|
||||
{
|
||||
DerivedMesh *dm = CDDM_from_mesh(me, ob);
|
||||
@ -868,6 +874,162 @@ static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void
|
||||
emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
|
||||
}
|
||||
|
||||
static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
|
||||
int (*setMaterial)(int, void *attribs),
|
||||
int (*setDrawOptions)(void *userData, int index), void *userData)
|
||||
{
|
||||
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
|
||||
EditMesh *em= emdm->em;
|
||||
float (*vertexCos)[3]= emdm->vertexCos;
|
||||
float (*vertexNos)[3]= emdm->vertexNos;
|
||||
EditVert *eve;
|
||||
EditFace *efa;
|
||||
DMVertexAttribs attribs;
|
||||
GPUVertexAttribs gattribs;
|
||||
MTFace *tf;
|
||||
int transp, new_transp, orig_transp, tfoffset;
|
||||
int i, b, matnr, new_matnr, dodraw, layer;
|
||||
|
||||
dodraw = 0;
|
||||
matnr = -1;
|
||||
|
||||
transp = GPU_get_material_blend_mode();
|
||||
orig_transp = transp;
|
||||
layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE);
|
||||
tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset;
|
||||
|
||||
memset(&attribs, 0, sizeof(attribs));
|
||||
|
||||
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
for (i=0,eve=em->verts.first; eve; eve= eve->next)
|
||||
eve->tmp.l = (long) i++;
|
||||
|
||||
#define PASSATTRIB(efa, eve, vert) { \
|
||||
if(attribs.totorco) { \
|
||||
float *orco = attribs.orco.array[eve->tmp.l]; \
|
||||
glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \
|
||||
} \
|
||||
for(b = 0; b < attribs.tottface; b++) { \
|
||||
MTFace *tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset); \
|
||||
glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
|
||||
} \
|
||||
for(b = 0; b < attribs.totmcol; b++) { \
|
||||
MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \
|
||||
GLubyte col[4]; \
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
|
||||
glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
|
||||
} \
|
||||
if(attribs.tottang) { \
|
||||
float *tang = attribs.tang.array[i*4 + vert]; \
|
||||
glVertexAttrib3fvARB(attribs.tang.glIndex, tang); \
|
||||
} \
|
||||
}
|
||||
|
||||
for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
|
||||
int drawSmooth= (efa->flag & ME_SMOOTH);
|
||||
|
||||
if(setDrawOptions && !setDrawOptions(userData, i))
|
||||
continue;
|
||||
|
||||
new_matnr = efa->mat_nr + 1;
|
||||
if(new_matnr != matnr) {
|
||||
dodraw = setMaterial(matnr = new_matnr, &gattribs);
|
||||
if(dodraw)
|
||||
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
|
||||
}
|
||||
|
||||
if(tfoffset != -1) {
|
||||
tf = (MTFace*)((char*)efa->data)+tfoffset;
|
||||
new_transp = tf->transp;
|
||||
|
||||
if(new_transp != transp) {
|
||||
if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
|
||||
GPU_set_material_blend_mode(orig_transp);
|
||||
else
|
||||
GPU_set_material_blend_mode(new_transp);
|
||||
transp = new_transp;
|
||||
}
|
||||
}
|
||||
|
||||
if(dodraw) {
|
||||
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
|
||||
if (!drawSmooth) {
|
||||
if(vertexCos) glNormal3fv(emdm->faceNos[i]);
|
||||
else glNormal3fv(efa->n);
|
||||
|
||||
PASSATTRIB(efa, efa->v1, 0);
|
||||
if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
|
||||
else glVertex3fv(efa->v1->co);
|
||||
|
||||
PASSATTRIB(efa, efa->v2, 1);
|
||||
if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
|
||||
else glVertex3fv(efa->v2->co);
|
||||
|
||||
PASSATTRIB(efa, efa->v3, 2);
|
||||
if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
|
||||
else glVertex3fv(efa->v3->co);
|
||||
|
||||
if(efa->v4) {
|
||||
PASSATTRIB(efa, efa->v4, 3);
|
||||
if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
|
||||
else glVertex3fv(efa->v4->co);
|
||||
}
|
||||
} else {
|
||||
PASSATTRIB(efa, efa->v1, 0);
|
||||
if(vertexCos) {
|
||||
glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
|
||||
glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
|
||||
}
|
||||
else {
|
||||
glNormal3fv(efa->v1->no);
|
||||
glVertex3fv(efa->v1->co);
|
||||
}
|
||||
|
||||
PASSATTRIB(efa, efa->v2, 1);
|
||||
if(vertexCos) {
|
||||
glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
|
||||
glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
|
||||
}
|
||||
else {
|
||||
glNormal3fv(efa->v2->no);
|
||||
glVertex3fv(efa->v2->co);
|
||||
}
|
||||
|
||||
PASSATTRIB(efa, efa->v3, 2);
|
||||
if(vertexCos) {
|
||||
glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
|
||||
glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
|
||||
}
|
||||
else {
|
||||
glNormal3fv(efa->v3->no);
|
||||
glVertex3fv(efa->v3->co);
|
||||
}
|
||||
|
||||
if(efa->v4) {
|
||||
PASSATTRIB(efa, efa->v4, 3);
|
||||
if(vertexCos) {
|
||||
glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
|
||||
glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
|
||||
}
|
||||
else {
|
||||
glNormal3fv(efa->v4->no);
|
||||
glVertex3fv(efa->v4->co);
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void emDM_drawFacesGLSL(DerivedMesh *dm,
|
||||
int (*setMaterial)(int, void *attribs))
|
||||
{
|
||||
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
|
||||
}
|
||||
|
||||
static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
|
||||
{
|
||||
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
|
||||
@ -1073,6 +1235,43 @@ void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
|
||||
}
|
||||
}
|
||||
|
||||
static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
|
||||
{
|
||||
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
|
||||
EditMesh *em= emdm->em;
|
||||
EditFace *efa;
|
||||
char *data, *emdata;
|
||||
void *datalayer;
|
||||
int index, offset, size;
|
||||
|
||||
datalayer = DM_get_face_data_layer(dm, type);
|
||||
if(datalayer)
|
||||
return datalayer;
|
||||
|
||||
/* layers are store per face for editmesh, we convert to a temporary
|
||||
* data layer array in the derivedmesh when these are requested */
|
||||
if(type == CD_MTFACE || type == CD_MCOL) {
|
||||
index = CustomData_get_layer_index(&em->fdata, type);
|
||||
|
||||
if(index != -1) {
|
||||
offset = em->fdata.layers[index].offset;
|
||||
size = CustomData_sizeof(type);
|
||||
|
||||
DM_add_face_layer(dm, type, CD_CALLOC, NULL);
|
||||
index = CustomData_get_layer_index(&dm->faceData, type);
|
||||
dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
|
||||
|
||||
data = datalayer = DM_get_face_data_layer(dm, type);
|
||||
for(efa=em->faces.first; efa; efa=efa->next, data+=size) {
|
||||
emdata = CustomData_em_get(&em->fdata, efa->data, type);
|
||||
memcpy(data, emdata, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return datalayer;
|
||||
}
|
||||
|
||||
static void emDM_release(DerivedMesh *dm)
|
||||
{
|
||||
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
|
||||
@ -1108,6 +1307,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
|
||||
emdm->dm.copyVertArray = emDM_copyVertArray;
|
||||
emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
|
||||
emdm->dm.copyFaceArray = emDM_copyFaceArray;
|
||||
emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
|
||||
|
||||
emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
|
||||
emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
|
||||
@ -1118,7 +1318,9 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
|
||||
emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
|
||||
emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
|
||||
emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
|
||||
emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
|
||||
emdm->dm.drawFacesTex = emDM_drawFacesTex;
|
||||
emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
|
||||
emdm->dm.drawUVEdges = emDM_drawUVEdges;
|
||||
|
||||
emdm->dm.release = emDM_release;
|
||||
@ -1548,7 +1750,7 @@ static void vDM_drawUVEdges(DerivedMesh *dm)
|
||||
}
|
||||
|
||||
/* draw all VerseFaces */
|
||||
static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
|
||||
static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseFace *vface;
|
||||
@ -1648,6 +1850,8 @@ static void vDM_drawMappedFacesTex(
|
||||
int (*setDrawParams)(void *userData, int index),
|
||||
void *userData)
|
||||
{
|
||||
/* not supported yet */
|
||||
vDM_drawFacesTex(dm, NULL);
|
||||
}
|
||||
|
||||
/**/
|
||||
@ -1789,19 +1993,23 @@ CustomDataMask get_viewedit_datamask()
|
||||
ScrArea *sa;
|
||||
|
||||
/* check if we need tfaces & mcols due to face select or texture paint */
|
||||
if(FACESEL_PAINT_TEST || G.f & G_TEXTUREPAINT) {
|
||||
if(FACESEL_PAINT_TEST || G.f & G_TEXTUREPAINT)
|
||||
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
|
||||
} else {
|
||||
/* check if we need tfaces & mcols due to view mode */
|
||||
for(sa = G.curscreen->areabase.first; sa; sa = sa->next) {
|
||||
if(sa->spacetype == SPACE_VIEW3D) {
|
||||
View3D *view = sa->spacedata.first;
|
||||
if(view->drawtype == OB_SHADED) {
|
||||
/* this includes normals for mesh_create_shadedColors */
|
||||
mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL | CD_MASK_ORCO;
|
||||
}
|
||||
if((view->drawtype == OB_TEXTURE) || ((view->drawtype == OB_SOLID) && (view->flag2 & V3D_SOLID_TEX))) {
|
||||
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
|
||||
|
||||
/* check if we need tfaces & mcols due to view mode */
|
||||
for(sa = G.curscreen->areabase.first; sa; sa = sa->next) {
|
||||
if(sa->spacetype == SPACE_VIEW3D) {
|
||||
View3D *view = sa->spacedata.first;
|
||||
if(view->drawtype == OB_SHADED) {
|
||||
/* this includes normals for mesh_create_shadedColors */
|
||||
mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL | CD_MASK_ORCO;
|
||||
}
|
||||
if((view->drawtype == OB_TEXTURE) || ((view->drawtype == OB_SOLID) && (view->flag2 & V3D_SOLID_TEX))) {
|
||||
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
|
||||
|
||||
if((G.fileflags & G_FILE_GAME_MAT) &&
|
||||
(G.fileflags & G_FILE_GAME_MAT_GLSL)) {
|
||||
mask |= CD_MASK_ORCO;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1814,13 +2022,41 @@ CustomDataMask get_viewedit_datamask()
|
||||
return mask;
|
||||
}
|
||||
|
||||
static DerivedMesh *create_orco_dm(Object *ob, Mesh *me)
|
||||
static float *get_editmesh_orco_verts(EditMesh *em)
|
||||
{
|
||||
EditVert *eve;
|
||||
float *orco;
|
||||
int a, totvert;
|
||||
|
||||
/* these may not really be the orco's, but it's only for preview.
|
||||
* could be solver better once, but isn't simple */
|
||||
|
||||
totvert= 0;
|
||||
for(eve=em->verts.first; eve; eve=eve->next)
|
||||
totvert++;
|
||||
|
||||
orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco");
|
||||
|
||||
for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3)
|
||||
VECCOPY(orco+a, eve->co);
|
||||
|
||||
return orco;
|
||||
}
|
||||
|
||||
static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em)
|
||||
{
|
||||
DerivedMesh *dm;
|
||||
float (*orco)[3];
|
||||
|
||||
dm= CDDM_from_mesh(me, ob);
|
||||
orco= (float(*)[3])get_mesh_orco_verts(ob);
|
||||
if(em) {
|
||||
dm= CDDM_from_editmesh(em, me);
|
||||
orco= (float(*)[3])get_editmesh_orco_verts(em);
|
||||
}
|
||||
else {
|
||||
dm= CDDM_from_mesh(me, ob);
|
||||
orco= (float(*)[3])get_mesh_orco_verts(ob);
|
||||
}
|
||||
|
||||
CDDM_apply_vert_coords(dm, orco);
|
||||
CDDM_calc_normals(dm);
|
||||
MEM_freeN(orco);
|
||||
@ -1828,7 +2064,7 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me)
|
||||
return dm;
|
||||
}
|
||||
|
||||
static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
|
||||
static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm)
|
||||
{
|
||||
float (*orco)[3], (*layerorco)[3];
|
||||
int totvert;
|
||||
@ -1843,8 +2079,10 @@ static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
|
||||
else
|
||||
dm->getVertCos(dm, orco);
|
||||
}
|
||||
else
|
||||
orco= (float(*)[3])get_mesh_orco_verts(ob);
|
||||
else {
|
||||
if(em) orco= (float(*)[3])get_editmesh_orco_verts(em);
|
||||
else orco= (float(*)[3])get_mesh_orco_verts(ob);
|
||||
}
|
||||
|
||||
transform_mesh_orco_verts(ob->data, orco, totvert, 0);
|
||||
|
||||
@ -1971,7 +2209,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
if(dm && mti->requiredDataMask) {
|
||||
mask = mti->requiredDataMask(md);
|
||||
if(mask & CD_MASK_ORCO)
|
||||
add_orco_dm(ob, dm, orcodm);
|
||||
add_orco_dm(ob, NULL, dm, orcodm);
|
||||
}
|
||||
|
||||
/* How to apply modifier depends on (a) what we already have as
|
||||
@ -2024,7 +2262,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
mask= (CustomDataMask)curr->link;
|
||||
if(mask & CD_MASK_ORCO) {
|
||||
if(!orcodm)
|
||||
orcodm= create_orco_dm(ob, me);
|
||||
orcodm= create_orco_dm(ob, me, NULL);
|
||||
|
||||
mask &= ~CD_MASK_ORCO;
|
||||
DM_set_only_copy(orcodm, mask);
|
||||
@ -2105,10 +2343,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
|
||||
/* add an orco layer if needed */
|
||||
if(dataMask & CD_MASK_ORCO) {
|
||||
add_orco_dm(ob, finaldm, orcodm);
|
||||
add_orco_dm(ob, NULL, finaldm, orcodm);
|
||||
|
||||
if(deform_r && *deform_r)
|
||||
add_orco_dm(ob, *deform_r, NULL);
|
||||
add_orco_dm(ob, NULL, *deform_r, NULL);
|
||||
}
|
||||
|
||||
*final_r = finaldm;
|
||||
@ -2161,7 +2399,8 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
|
||||
EditMesh *em = G.editMesh;
|
||||
ModifierData *md;
|
||||
float (*deformedVerts)[3] = NULL;
|
||||
DerivedMesh *dm;
|
||||
CustomDataMask mask;
|
||||
DerivedMesh *dm, *orcodm = NULL;
|
||||
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
|
||||
LinkNode *datamasks, *curr;
|
||||
|
||||
@ -2186,6 +2425,13 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
|
||||
if(!editmesh_modifier_is_enabled(md, dm))
|
||||
continue;
|
||||
|
||||
/* add an orco layer if needed by this modifier */
|
||||
if(dm && mti->requiredDataMask) {
|
||||
mask = mti->requiredDataMask(md);
|
||||
if(mask & CD_MASK_ORCO)
|
||||
add_orco_dm(ob, em, dm, orcodm);
|
||||
}
|
||||
|
||||
/* How to apply modifier depends on (a) what we already have as
|
||||
* a result of previous modifiers (could be a DerivedMesh or just
|
||||
* deformed vertices) and (b) what type the modifier is.
|
||||
@ -2236,6 +2482,23 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
|
||||
}
|
||||
}
|
||||
|
||||
/* create an orco derivedmesh in parallel */
|
||||
mask= (CustomDataMask)curr->link;
|
||||
if(mask & CD_MASK_ORCO) {
|
||||
if(!orcodm)
|
||||
orcodm= create_orco_dm(ob, ob->data, em);
|
||||
|
||||
mask &= ~CD_MASK_ORCO;
|
||||
DM_set_only_copy(orcodm, mask);
|
||||
ndm = mti->applyModifierEM(md, ob, em, orcodm);
|
||||
|
||||
if(ndm) {
|
||||
/* if the modifier returned a new dm, release the old one */
|
||||
if(orcodm && orcodm != ndm) orcodm->release(orcodm);
|
||||
orcodm = ndm;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the DerivedMesh to only copy needed data */
|
||||
DM_set_only_copy(dm, (CustomDataMask)curr->link);
|
||||
|
||||
@ -2294,6 +2557,13 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
|
||||
deformedVerts = NULL;
|
||||
}
|
||||
|
||||
/* add an orco layer if needed */
|
||||
if(dataMask & CD_MASK_ORCO)
|
||||
add_orco_dm(ob, em, *final_r, orcodm);
|
||||
|
||||
if(orcodm)
|
||||
orcodm->release(orcodm);
|
||||
|
||||
if(deformedVerts)
|
||||
MEM_freeN(deformedVerts);
|
||||
}
|
||||
@ -2588,7 +2858,7 @@ void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_c
|
||||
old->release(old);
|
||||
|
||||
if(dataMask & CD_MASK_ORCO)
|
||||
add_orco_dm(ob, *dm, NULL);
|
||||
add_orco_dm(ob, NULL, *dm, NULL);
|
||||
|
||||
/* Restore the original verts */
|
||||
me->mr->newlvl= BLI_countlist(&me->mr->levels);
|
||||
@ -2817,6 +3087,8 @@ int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**defo
|
||||
return numleft;
|
||||
}
|
||||
|
||||
/* ******************* GLSL ******************** */
|
||||
|
||||
void DM_add_tangent_layer(DerivedMesh *dm)
|
||||
{
|
||||
/* mesh vars */
|
||||
@ -2937,4 +3209,89 @@ void DM_add_tangent_layer(DerivedMesh *dm)
|
||||
MEM_freeN(vtangents);
|
||||
}
|
||||
|
||||
void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs)
|
||||
{
|
||||
CustomData *vdata, *fdata, *tfdata = NULL;
|
||||
int a, b, layer;
|
||||
|
||||
/* From the layers requested by the GLSL shader, figure out which ones are
|
||||
* actually available for this derivedmesh, and retrieve the pointers */
|
||||
|
||||
memset(attribs, 0, sizeof(DMVertexAttribs));
|
||||
|
||||
vdata = &dm->vertData;
|
||||
fdata = &dm->faceData;
|
||||
|
||||
/* ugly hack, editmesh derivedmesh doesn't copy face data, this way we
|
||||
* can use offsets instead */
|
||||
if(dm->release == emDM_release)
|
||||
tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata;
|
||||
else
|
||||
tfdata = fdata;
|
||||
|
||||
/* add a tangent layer if necessary */
|
||||
for(b = 0; b < gattribs->totlayer; b++)
|
||||
if(gattribs->layer[b].type == CD_TANGENT)
|
||||
if(CustomData_get_layer_index(fdata, CD_TANGENT) == -1)
|
||||
DM_add_tangent_layer(dm);
|
||||
|
||||
for(b = 0; b < gattribs->totlayer; b++) {
|
||||
if(gattribs->layer[b].type == CD_MTFACE) {
|
||||
/* uv coordinates */
|
||||
if(gattribs->layer[b].name[0])
|
||||
layer = CustomData_get_named_layer_index(tfdata, CD_MTFACE,
|
||||
gattribs->layer[b].name);
|
||||
else
|
||||
layer = CustomData_get_active_layer_index(tfdata, CD_MTFACE);
|
||||
|
||||
if(layer != -1) {
|
||||
a = attribs->tottface++;
|
||||
|
||||
attribs->tface[a].array = tfdata->layers[layer].data;
|
||||
attribs->tface[a].emOffset = tfdata->layers[layer].offset;
|
||||
attribs->tface[a].glIndex = gattribs->layer[b].glindex;
|
||||
}
|
||||
}
|
||||
else if(gattribs->layer[b].type == CD_MCOL) {
|
||||
/* vertex colors */
|
||||
if(gattribs->layer[b].name[0])
|
||||
layer = CustomData_get_named_layer_index(tfdata, CD_MCOL,
|
||||
gattribs->layer[b].name);
|
||||
else
|
||||
layer = CustomData_get_active_layer_index(tfdata, CD_MCOL);
|
||||
|
||||
if(layer != -1) {
|
||||
a = attribs->totmcol++;
|
||||
|
||||
attribs->mcol[a].array = tfdata->layers[layer].data;
|
||||
attribs->mcol[a].emOffset = tfdata->layers[layer].offset;
|
||||
attribs->mcol[a].glIndex = gattribs->layer[b].glindex;
|
||||
}
|
||||
}
|
||||
else if(gattribs->layer[b].type == CD_TANGENT) {
|
||||
/* tangents */
|
||||
layer = CustomData_get_layer_index(fdata, CD_TANGENT);
|
||||
|
||||
if(layer != -1) {
|
||||
attribs->tottang = 1;
|
||||
|
||||
attribs->tang.array = fdata->layers[layer].data;
|
||||
attribs->tang.emOffset = fdata->layers[layer].offset;
|
||||
attribs->tang.glIndex = gattribs->layer[b].glindex;
|
||||
}
|
||||
}
|
||||
else if(gattribs->layer[b].type == CD_ORCO) {
|
||||
/* original coordinates */
|
||||
layer = CustomData_get_layer_index(vdata, CD_ORCO);
|
||||
|
||||
if(layer != -1) {
|
||||
attribs->totorco = 1;
|
||||
|
||||
attribs->orco.array = vdata->layers[layer].data;
|
||||
attribs->orco.emOffset = vdata->layers[layer].offset;
|
||||
attribs->orco.glIndex = gattribs->layer[b].glindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ include nan_compile.mk
|
||||
CFLAGS += $(LEVEL_1_C_WARNINGS)
|
||||
|
||||
# OpenGL and Python
|
||||
CPPFLAGS += -I$(NAN_GLEW)/include
|
||||
CPPFLAGS += -I$(OPENGL_HEADERS)
|
||||
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
|
||||
|
||||
@ -74,6 +75,9 @@ CPPFLAGS += -I$(NAN_ZLIB)/include
|
||||
#path to nodes
|
||||
CPPFLAGS += -I../../nodes
|
||||
|
||||
#path to gpu
|
||||
CPPFLAGS += -I../../gpu
|
||||
|
||||
# path to our own external headerfiles
|
||||
CPPFLAGS += -I..
|
||||
|
||||
|
@ -347,6 +347,8 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
|
||||
VECCOPY(pchan->loc, chan->loc);
|
||||
VECCOPY(pchan->size, chan->size);
|
||||
QUATCOPY(pchan->quat, chan->quat);
|
||||
Mat4CpyMat4(pchan->chan_mat, (float(*)[4])chan->chan_mat);
|
||||
Mat4CpyMat4(pchan->pose_mat, (float(*)[4])chan->pose_mat);
|
||||
pchan->flag= chan->flag;
|
||||
|
||||
con= chan->constraints.first;
|
||||
|
@ -303,7 +303,7 @@ static void group_duplilist(ListBase *lb, Object *ob, int level, int animated)
|
||||
DupliObject *dob;
|
||||
Group *group;
|
||||
GroupObject *go;
|
||||
float mat[4][4];
|
||||
float mat[4][4], tmat[4][4];
|
||||
|
||||
if(ob->dup_group==NULL) return;
|
||||
group= ob->dup_group;
|
||||
@ -320,7 +320,15 @@ static void group_duplilist(ListBase *lb, Object *ob, int level, int animated)
|
||||
/* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
|
||||
if(go->ob!=ob) {
|
||||
|
||||
Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
|
||||
/* Group Dupli Offset, should apply after everything else */
|
||||
if (group->dupli_ofs[0] || group->dupli_ofs[1] || group->dupli_ofs[2]) {
|
||||
Mat4CpyMat4(tmat, go->ob->obmat);
|
||||
VecSubf(tmat[3], tmat[3], group->dupli_ofs);
|
||||
Mat4MulMat4(mat, tmat, ob->obmat);
|
||||
} else {
|
||||
Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
|
||||
}
|
||||
|
||||
dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated);
|
||||
dob->no_draw= (dob->origlay & group->layer)==0;
|
||||
|
||||
@ -1059,7 +1067,8 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist,
|
||||
}
|
||||
}
|
||||
|
||||
/* note; group dupli's already set transform matrix. see note in group_duplilist() */
|
||||
/* Returns a list of DupliObject
|
||||
* note; group dupli's already set transform matrix. see note in group_duplilist() */
|
||||
ListBase *object_duplilist(Scene *sce, Object *ob)
|
||||
{
|
||||
ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist");
|
||||
|
@ -525,6 +525,7 @@ typedef struct UndoElem {
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
char name[MAXUNDONAME];
|
||||
MemFile memfile;
|
||||
uintptr_t undosize;
|
||||
} UndoElem;
|
||||
|
||||
static ListBase undobase={NULL, NULL};
|
||||
@ -555,6 +556,7 @@ static int read_undosave(UndoElem *uel)
|
||||
/* name can be a dynamic string */
|
||||
void BKE_write_undo(char *name)
|
||||
{
|
||||
uintptr_t maxmem, totmem, memused;
|
||||
int nr, success;
|
||||
UndoElem *uel;
|
||||
|
||||
@ -616,8 +618,36 @@ void BKE_write_undo(char *name)
|
||||
|
||||
if(curundo->prev) prevfile= &(curundo->prev->memfile);
|
||||
|
||||
memused= MEM_get_memory_in_use();
|
||||
success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
|
||||
curundo->undosize= MEM_get_memory_in_use() - memused;
|
||||
}
|
||||
|
||||
if(U.undomemory != 0) {
|
||||
/* limit to maximum memory (afterwards, we can't know in advance) */
|
||||
totmem= 0;
|
||||
maxmem= ((uintptr_t)U.undomemory)*1024*1024;
|
||||
|
||||
/* keep at least two (original + other) */
|
||||
uel= undobase.last;
|
||||
while(uel && uel->prev) {
|
||||
totmem+= uel->undosize;
|
||||
if(totmem>maxmem) break;
|
||||
uel= uel->prev;
|
||||
}
|
||||
|
||||
if(uel) {
|
||||
if(uel->prev && uel->prev->prev)
|
||||
uel= uel->prev;
|
||||
|
||||
while(undobase.first!=uel) {
|
||||
UndoElem *first= undobase.first;
|
||||
BLI_remlink(&undobase, first);
|
||||
/* the merge is because of compression */
|
||||
BLO_merge_memfile(&first->memfile, &first->next->memfile);
|
||||
MEM_freeN(first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,10 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
@ -243,7 +247,7 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
|
||||
static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
|
||||
{
|
||||
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
|
||||
MVert *mvert = cddm->mvert;
|
||||
@ -271,7 +275,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
|
||||
|| new_shademodel != shademodel) {
|
||||
glEnd();
|
||||
|
||||
drawCurrentMat = setMaterial(matnr = new_matnr);
|
||||
drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
|
||||
|
||||
glShadeModel(shademodel = new_shademodel);
|
||||
glBegin(glmode = new_glmode);
|
||||
@ -556,6 +560,134 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void
|
||||
cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
|
||||
}
|
||||
|
||||
static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
|
||||
{
|
||||
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
|
||||
GPUVertexAttribs gattribs;
|
||||
DMVertexAttribs attribs;
|
||||
MVert *mvert = cddm->mvert;
|
||||
MFace *mface = cddm->mface;
|
||||
MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
|
||||
float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
|
||||
int a, b, dodraw, smoothnormal, matnr, new_matnr;
|
||||
int transp, new_transp, orig_transp;
|
||||
int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
|
||||
|
||||
matnr = -1;
|
||||
smoothnormal = 0;
|
||||
dodraw = 0;
|
||||
transp = GPU_get_material_blend_mode();
|
||||
orig_transp = transp;
|
||||
|
||||
memset(&attribs, 0, sizeof(attribs));
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for(a = 0; a < dm->numFaceData; a++, mface++) {
|
||||
new_matnr = mface->mat_nr + 1;
|
||||
|
||||
if(new_matnr != matnr) {
|
||||
glEnd();
|
||||
|
||||
dodraw = setMaterial(matnr = new_matnr, &gattribs);
|
||||
if(dodraw)
|
||||
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
}
|
||||
|
||||
if(!dodraw) {
|
||||
continue;
|
||||
}
|
||||
else if(setDrawOptions) {
|
||||
orig = index[a];
|
||||
|
||||
if(orig == ORIGINDEX_NONE)
|
||||
continue;
|
||||
else if(!setDrawOptions(userData, orig))
|
||||
continue;
|
||||
}
|
||||
|
||||
if(tf) {
|
||||
new_transp = tf[a].transp;
|
||||
|
||||
if(new_transp != transp) {
|
||||
glEnd();
|
||||
|
||||
if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
|
||||
GPU_set_material_blend_mode(orig_transp);
|
||||
else
|
||||
GPU_set_material_blend_mode(new_transp);
|
||||
transp = new_transp;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
}
|
||||
}
|
||||
|
||||
smoothnormal = (mface->flag & ME_SMOOTH);
|
||||
|
||||
if(!smoothnormal) {
|
||||
if(nors) {
|
||||
glNormal3fv(nors[a]);
|
||||
}
|
||||
else {
|
||||
/* TODO ideally a normal layer should always be available */
|
||||
float nor[3];
|
||||
if(mface->v4) {
|
||||
CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
|
||||
mvert[mface->v3].co, mvert[mface->v4].co,
|
||||
nor);
|
||||
} else {
|
||||
CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
|
||||
mvert[mface->v3].co, nor);
|
||||
}
|
||||
glNormal3fv(nor);
|
||||
}
|
||||
}
|
||||
|
||||
#define PASSVERT(index, vert) { \
|
||||
if(attribs.totorco) \
|
||||
glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \
|
||||
for(b = 0; b < attribs.tottface; b++) { \
|
||||
MTFace *tf = &attribs.tface[b].array[a]; \
|
||||
glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
|
||||
} \
|
||||
for(b = 0; b < attribs.totmcol; b++) { \
|
||||
MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \
|
||||
GLubyte col[4]; \
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
|
||||
glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
|
||||
} \
|
||||
if(attribs.tottang) { \
|
||||
float *tang = attribs.tang.array[a*4 + vert]; \
|
||||
glVertexAttrib3fvARB(attribs.tang.glIndex, tang); \
|
||||
} \
|
||||
if(smoothnormal) \
|
||||
glNormal3sv(mvert[index].no); \
|
||||
glVertex3fv(mvert[index].co); \
|
||||
}
|
||||
|
||||
PASSVERT(mface->v1, 0);
|
||||
PASSVERT(mface->v2, 1);
|
||||
PASSVERT(mface->v3, 2);
|
||||
if(mface->v4)
|
||||
PASSVERT(mface->v4, 3)
|
||||
else
|
||||
PASSVERT(mface->v3, 2)
|
||||
|
||||
#undef PASSVERT
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
|
||||
static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
|
||||
{
|
||||
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
|
||||
}
|
||||
|
||||
static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
|
||||
{
|
||||
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
|
||||
@ -713,8 +845,10 @@ static CDDerivedMesh *cdDM_create(const char *desc)
|
||||
dm->drawFacesSolid = cdDM_drawFacesSolid;
|
||||
dm->drawFacesColored = cdDM_drawFacesColored;
|
||||
dm->drawFacesTex = cdDM_drawFacesTex;
|
||||
dm->drawFacesGLSL = cdDM_drawFacesGLSL;
|
||||
dm->drawMappedFaces = cdDM_drawMappedFaces;
|
||||
dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
|
||||
dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
|
||||
|
||||
dm->foreachMappedVert = cdDM_foreachMappedVert;
|
||||
dm->foreachMappedEdge = cdDM_foreachMappedEdge;
|
||||
|
@ -730,3 +730,24 @@ void curvemapping_initialize(CurveMapping *cumap)
|
||||
curvemap_make_table(cumap->cm+a, &cumap->clipr);
|
||||
}
|
||||
}
|
||||
|
||||
void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size)
|
||||
{
|
||||
int a;
|
||||
|
||||
*size = CM_TABLE+1;
|
||||
*array = MEM_callocN(sizeof(float)*(*size)*4, "CurveMapping");
|
||||
curvemapping_initialize(cumap);
|
||||
|
||||
for(a=0; a<*size; a++) {
|
||||
if(cumap->cm[0].table)
|
||||
(*array)[a*4+0]= cumap->cm[0].table[a].y;
|
||||
if(cumap->cm[1].table)
|
||||
(*array)[a*4+1]= cumap->cm[1].table[a].y;
|
||||
if(cumap->cm[2].table)
|
||||
(*array)[a*4+2]= cumap->cm[2].table[a].y;
|
||||
if(cumap->cm[3].table)
|
||||
(*array)[a*4+3]= cumap->cm[3].table[a].y;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "DNA_packedFile_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
@ -77,15 +78,15 @@
|
||||
|
||||
#include "RE_pipeline.h"
|
||||
|
||||
/* bad level; call to free_realtime_image */
|
||||
#include "BKE_bad_level_calls.h"
|
||||
|
||||
/* for stamp drawing to an image */
|
||||
#include "BMF_Api.h"
|
||||
|
||||
#include "blendef.h"
|
||||
#include "BSE_time.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_draw.h"
|
||||
|
||||
#include "BLO_sys_types.h" // for intptr_t support
|
||||
|
||||
/* max int, to indicate we don't store sequences in ibuf */
|
||||
@ -240,7 +241,7 @@ static void image_free_buffers(Image *ima)
|
||||
ima->rr= NULL;
|
||||
}
|
||||
|
||||
free_realtime_image(ima);
|
||||
GPU_free_image(ima);
|
||||
|
||||
ima->ok= IMA_OK;
|
||||
}
|
||||
@ -620,7 +621,7 @@ void free_old_images()
|
||||
This gives textures a "second chance" to be used before dying.
|
||||
*/
|
||||
if(ima->bindcode || ima->repbind) {
|
||||
free_realtime_image(ima);
|
||||
GPU_free_image(ima);
|
||||
ima->lastused = ctime;
|
||||
}
|
||||
/* Otherwise, just kill the buffers */
|
||||
|
@ -1392,6 +1392,14 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
|
||||
else if(icu->adrcode & MA_MAP8) mtex= ma->mtex[7];
|
||||
else if(icu->adrcode & MA_MAP9) mtex= ma->mtex[8];
|
||||
else if(icu->adrcode & MA_MAP10) mtex= ma->mtex[9];
|
||||
else if(icu->adrcode & MA_MAP12) mtex= ma->mtex[11];
|
||||
else if(icu->adrcode & MA_MAP11) mtex= ma->mtex[10];
|
||||
else if(icu->adrcode & MA_MAP13) mtex= ma->mtex[12];
|
||||
else if(icu->adrcode & MA_MAP14) mtex= ma->mtex[13];
|
||||
else if(icu->adrcode & MA_MAP15) mtex= ma->mtex[14];
|
||||
else if(icu->adrcode & MA_MAP16) mtex= ma->mtex[15];
|
||||
else if(icu->adrcode & MA_MAP17) mtex= ma->mtex[16];
|
||||
else if(icu->adrcode & MA_MAP18) mtex= ma->mtex[17];
|
||||
|
||||
if(mtex) {
|
||||
poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
|
||||
@ -1481,7 +1489,14 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
|
||||
else if(icu->adrcode & MA_MAP8) mtex= wo->mtex[7];
|
||||
else if(icu->adrcode & MA_MAP9) mtex= wo->mtex[8];
|
||||
else if(icu->adrcode & MA_MAP10) mtex= wo->mtex[9];
|
||||
|
||||
else if(icu->adrcode & MA_MAP11) mtex= wo->mtex[10];
|
||||
else if(icu->adrcode & MA_MAP12) mtex= wo->mtex[11];
|
||||
else if(icu->adrcode & MA_MAP13) mtex= wo->mtex[12];
|
||||
else if(icu->adrcode & MA_MAP14) mtex= wo->mtex[13];
|
||||
else if(icu->adrcode & MA_MAP15) mtex= wo->mtex[14];
|
||||
else if(icu->adrcode & MA_MAP16) mtex= wo->mtex[15];
|
||||
else if(icu->adrcode & MA_MAP17) mtex= wo->mtex[16];
|
||||
else if(icu->adrcode & MA_MAP18) mtex= wo->mtex[17];
|
||||
if(mtex) {
|
||||
poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
|
||||
}
|
||||
@ -1526,6 +1541,14 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
|
||||
else if(icu->adrcode & MA_MAP8) mtex= la->mtex[7];
|
||||
else if(icu->adrcode & MA_MAP9) mtex= la->mtex[8];
|
||||
else if(icu->adrcode & MA_MAP10) mtex= la->mtex[9];
|
||||
else if(icu->adrcode & MA_MAP11) mtex= la->mtex[10];
|
||||
else if(icu->adrcode & MA_MAP12) mtex= la->mtex[11];
|
||||
else if(icu->adrcode & MA_MAP13) mtex= la->mtex[12];
|
||||
else if(icu->adrcode & MA_MAP14) mtex= la->mtex[13];
|
||||
else if(icu->adrcode & MA_MAP15) mtex= la->mtex[14];
|
||||
else if(icu->adrcode & MA_MAP16) mtex= la->mtex[15];
|
||||
else if(icu->adrcode & MA_MAP17) mtex= la->mtex[16];
|
||||
else if(icu->adrcode & MA_MAP18) mtex= la->mtex[17];
|
||||
|
||||
if(mtex) {
|
||||
poin= give_mtex_poin(mtex, icu->adrcode & (MA_MAP1-1) );
|
||||
|
@ -61,6 +61,8 @@
|
||||
|
||||
#include "BPY_extern.h"
|
||||
|
||||
#include "GPU_material.h"
|
||||
|
||||
/* used in UI and render */
|
||||
Material defmaterial;
|
||||
|
||||
@ -96,6 +98,9 @@ void free_material(Material *ma)
|
||||
ntreeFreeTree(ma->nodetree);
|
||||
MEM_freeN(ma->nodetree);
|
||||
}
|
||||
|
||||
if(ma->gpumaterial.first)
|
||||
GPU_material_free(ma);
|
||||
}
|
||||
|
||||
void init_material(Material *ma)
|
||||
@ -208,6 +213,8 @@ Material *copy_material(Material *ma)
|
||||
man->nodetree= ntreeCopyTree(ma->nodetree, 0); /* 0 == full new tree */
|
||||
}
|
||||
|
||||
man->gpumaterial.first= man->gpumaterial.last= NULL;
|
||||
|
||||
return man;
|
||||
}
|
||||
|
||||
|
@ -79,45 +79,6 @@
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
int update_realtime_texture(MTFace *tface, double time)
|
||||
{
|
||||
Image *ima;
|
||||
int inc = 0;
|
||||
float diff;
|
||||
int newframe;
|
||||
|
||||
ima = tface->tpage;
|
||||
|
||||
if (!ima)
|
||||
return 0;
|
||||
|
||||
if (ima->lastupdate<0)
|
||||
ima->lastupdate = 0;
|
||||
|
||||
if (ima->lastupdate>time)
|
||||
ima->lastupdate=(float)time;
|
||||
|
||||
if(ima->tpageflag & IMA_TWINANIM) {
|
||||
if(ima->twend >= ima->xrep*ima->yrep) ima->twend= ima->xrep*ima->yrep-1;
|
||||
|
||||
/* check: is the bindcode not in the array? Then free. (still to do) */
|
||||
|
||||
diff = (float)(time-ima->lastupdate);
|
||||
|
||||
inc = (int)(diff*(float)ima->animspeed);
|
||||
|
||||
ima->lastupdate+=((float)inc/(float)ima->animspeed);
|
||||
|
||||
newframe = ima->lastframe+inc;
|
||||
|
||||
if (newframe > (int)ima->twend)
|
||||
newframe = (int)ima->twsta-1 + (newframe-ima->twend)%(ima->twend-ima->twsta);
|
||||
|
||||
ima->lastframe = newframe;
|
||||
}
|
||||
return inc;
|
||||
}
|
||||
|
||||
void mesh_update_customdata_pointers(Mesh *me)
|
||||
{
|
||||
me->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
|
||||
|
@ -68,6 +68,9 @@
|
||||
|
||||
#include "SHD_node.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
static ListBase empty_list = {NULL, NULL};
|
||||
ListBase node_all_composit = {NULL, NULL};
|
||||
ListBase node_all_shaders = {NULL, NULL};
|
||||
@ -2352,6 +2355,117 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
||||
ntreeEndExecTree(ntree);
|
||||
}
|
||||
|
||||
/* GPU material from shader nodes */
|
||||
|
||||
static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
|
||||
{
|
||||
bNodeSocket *sock;
|
||||
int i;
|
||||
|
||||
for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
|
||||
memset(&gs[i], 0, sizeof(gs[i]));
|
||||
|
||||
QUATCOPY(gs[i].vec, ns[i]->vec);
|
||||
gs[i].link= ns[i]->data;
|
||||
|
||||
if (sock->type == SOCK_VALUE)
|
||||
gs[i].type= GPU_FLOAT;
|
||||
else if (sock->type == SOCK_VECTOR)
|
||||
gs[i].type= GPU_VEC3;
|
||||
else if (sock->type == SOCK_RGBA)
|
||||
gs[i].type= GPU_VEC4;
|
||||
else
|
||||
gs[i].type= GPU_NONE;
|
||||
|
||||
gs[i].name = "";
|
||||
gs[i].hasinput= ns[i]->hasinput;
|
||||
gs[i].hasoutput= ns[i]->hasinput;
|
||||
gs[i].sockettype= ns[i]->sockettype;
|
||||
}
|
||||
|
||||
gs[i].type= GPU_NONE;
|
||||
}
|
||||
|
||||
static void data_from_gpu_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
|
||||
{
|
||||
bNodeSocket *sock;
|
||||
int i;
|
||||
|
||||
for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
|
||||
ns[i]->data= gs[i].link;
|
||||
ns[i]->hasinput= gs[i].hasinput;
|
||||
ns[i]->hasoutput= gs[i].hasoutput;
|
||||
ns[i]->sockettype= gs[i].sockettype;
|
||||
}
|
||||
}
|
||||
|
||||
static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *gnode, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
bNode *node;
|
||||
bNodeTree *ntree= (bNodeTree *)gnode->id;
|
||||
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
|
||||
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
|
||||
GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
|
||||
int doit = 0;
|
||||
|
||||
if(ntree==NULL) return;
|
||||
|
||||
stack+= gnode->stack_index;
|
||||
|
||||
for(node= ntree->nodes.first; node; node= node->next) {
|
||||
if(node->typeinfo->gpufunc) {
|
||||
group_node_get_stack(node, stack, nsin, nsout, in, out);
|
||||
|
||||
doit = 0;
|
||||
|
||||
/* for groups, only execute outputs for edited group */
|
||||
if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
|
||||
if(gnode->flag & NODE_GROUP_EDIT)
|
||||
if(node->flag & NODE_DO_OUTPUT)
|
||||
doit = 1;
|
||||
}
|
||||
else
|
||||
doit = 1;
|
||||
|
||||
if(doit) {
|
||||
gpu_from_node_stack(&node->inputs, nsin, gpuin);
|
||||
gpu_from_node_stack(&node->outputs, nsout, gpuout);
|
||||
if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
|
||||
data_from_gpu_stack(&node->outputs, nsout, gpuout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
|
||||
{
|
||||
bNode *node;
|
||||
bNodeStack *stack;
|
||||
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
|
||||
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
|
||||
GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
|
||||
|
||||
if((ntree->init & NTREE_EXEC_INIT)==0)
|
||||
ntreeBeginExecTree(ntree);
|
||||
|
||||
stack= ntree->stack;
|
||||
|
||||
for(node= ntree->nodes.first; node; node= node->next) {
|
||||
if(node->typeinfo->gpufunc) {
|
||||
node_get_stack(node, stack, nsin, nsout);
|
||||
gpu_from_node_stack(&node->inputs, nsin, gpuin);
|
||||
gpu_from_node_stack(&node->outputs, nsout, gpuout);
|
||||
if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
|
||||
data_from_gpu_stack(&node->outputs, nsout, gpuout);
|
||||
}
|
||||
else if(node->type==NODE_GROUP && node->id) {
|
||||
node_get_stack(node, stack, nsin, nsout);
|
||||
gpu_node_group_execute(stack, mat, node, nsin, nsout);
|
||||
}
|
||||
}
|
||||
|
||||
ntreeEndExecTree(ntree);
|
||||
}
|
||||
|
||||
/* **************** call to switch lamploop for material node ************ */
|
||||
|
||||
|
@ -112,6 +112,8 @@
|
||||
|
||||
#include "BPY_extern.h"
|
||||
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include "blendef.h"
|
||||
|
||||
/* Local function protos */
|
||||
@ -267,6 +269,7 @@ void free_object(Object *ob)
|
||||
MEM_freeN(ob->pd);
|
||||
}
|
||||
if(ob->soft) sbFree(ob->soft);
|
||||
if(ob->gpulamp.first) GPU_lamp_free(ob);
|
||||
}
|
||||
|
||||
static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin)
|
||||
@ -917,7 +920,7 @@ Object *add_only_object(int type, char *name)
|
||||
QuatOne(ob->dquat);
|
||||
#endif
|
||||
|
||||
ob->col[0]= ob->col[1]= ob->col[2]= 0.0;
|
||||
ob->col[0]= ob->col[1]= ob->col[2]= 1.0;
|
||||
ob->col[3]= 1.0;
|
||||
|
||||
ob->loc[0]= ob->loc[1]= ob->loc[2]= 0.0;
|
||||
@ -1216,6 +1219,7 @@ Object *copy_object(Object *ob)
|
||||
obn->vnode = NULL;
|
||||
#endif
|
||||
|
||||
obn->gpulamp.first = obn->gpulamp.last = NULL;
|
||||
|
||||
return obn;
|
||||
}
|
||||
|
@ -76,6 +76,8 @@
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BSE_headerbuttons.h"
|
||||
|
||||
#include "blendef.h"
|
||||
|
@ -61,6 +61,10 @@
|
||||
|
||||
#include "BIF_gl.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include "CCGSubSurf.h"
|
||||
|
||||
typedef struct _VertData {
|
||||
@ -1599,7 +1603,7 @@ static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
|
||||
}
|
||||
|
||||
/* Only used by non-editmesh types */
|
||||
static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
|
||||
static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
|
||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
|
||||
@ -1621,7 +1625,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
|
||||
mat_nr= 0;
|
||||
}
|
||||
|
||||
if (!setMaterial(mat_nr+1))
|
||||
if (!setMaterial(mat_nr+1, NULL))
|
||||
continue;
|
||||
|
||||
glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
|
||||
@ -1666,6 +1670,168 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
|
||||
|
||||
ccgFaceIterator_free(fi);
|
||||
}
|
||||
|
||||
/* Only used by non-editmesh types */
|
||||
static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
|
||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
|
||||
GPUVertexAttribs gattribs;
|
||||
DMVertexAttribs attribs;
|
||||
MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
|
||||
int gridSize = ccgSubSurf_getGridSize(ss);
|
||||
int gridFaces = gridSize - 1;
|
||||
int edgeSize = ccgSubSurf_getEdgeSize(ss);
|
||||
int transp, orig_transp, new_transp;
|
||||
char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
|
||||
int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
|
||||
|
||||
doDraw = 0;
|
||||
numVerts = 0;
|
||||
matnr = -1;
|
||||
transp = GPU_get_material_blend_mode();
|
||||
orig_transp = transp;
|
||||
|
||||
memset(&attribs, 0, sizeof(attribs));
|
||||
|
||||
#define PASSATTRIB(dx, dy, vert) { \
|
||||
if(attribs.totorco) { \
|
||||
index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \
|
||||
glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \
|
||||
} \
|
||||
for(b = 0; b < attribs.tottface; b++) { \
|
||||
MTFace *tf = &attribs.tface[b].array[a]; \
|
||||
glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
|
||||
} \
|
||||
for(b = 0; b < attribs.totmcol; b++) { \
|
||||
MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \
|
||||
GLubyte col[4]; \
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
|
||||
glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
|
||||
} \
|
||||
if(attribs.tottang) { \
|
||||
float *tang = attribs.tang.array[a*4 + vert]; \
|
||||
glVertexAttrib3fvARB(attribs.tang.glIndex, tang); \
|
||||
} \
|
||||
}
|
||||
|
||||
totface = ccgSubSurf_getNumFaces(ss);
|
||||
for(a = 0, i = 0; i < totface; i++) {
|
||||
CCGFace *f = ccgdm->faceMap[i].face;
|
||||
int S, x, y, drawSmooth;
|
||||
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
|
||||
int origIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
|
||||
|
||||
numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
|
||||
|
||||
if(faceFlags) {
|
||||
drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
|
||||
new_matnr= faceFlags[index*4 + 1] + 1;
|
||||
}
|
||||
else {
|
||||
drawSmooth = 1;
|
||||
new_matnr= 1;
|
||||
}
|
||||
|
||||
if(new_matnr != matnr) {
|
||||
doDraw = setMaterial(matnr = new_matnr, &gattribs);
|
||||
if(doDraw)
|
||||
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
|
||||
}
|
||||
|
||||
if(!doDraw || (setDrawOptions && !setDrawOptions(userData, origIndex))) {
|
||||
a += gridFaces*gridFaces*numVerts;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(tf) {
|
||||
new_transp = tf[i].transp;
|
||||
|
||||
if(new_transp != transp) {
|
||||
if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
|
||||
GPU_set_material_blend_mode(orig_transp);
|
||||
else
|
||||
GPU_set_material_blend_mode(new_transp);
|
||||
transp = new_transp;
|
||||
}
|
||||
}
|
||||
|
||||
glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
|
||||
for (S=0; S<numVerts; S++) {
|
||||
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
|
||||
VertData *vda, *vdb;
|
||||
|
||||
if (drawSmooth) {
|
||||
for (y=0; y<gridFaces; y++) {
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (x=0; x<gridFaces; x++) {
|
||||
vda = &faceGridData[(y+0)*gridSize + x];
|
||||
vdb = &faceGridData[(y+1)*gridSize + x];
|
||||
|
||||
PASSATTRIB(0, 0, 0);
|
||||
glNormal3fv(vda->no);
|
||||
glVertex3fv(vda->co);
|
||||
|
||||
PASSATTRIB(0, 1, 1);
|
||||
glNormal3fv(vdb->no);
|
||||
glVertex3fv(vdb->co);
|
||||
|
||||
if(x != gridFaces-1)
|
||||
a++;
|
||||
}
|
||||
|
||||
vda = &faceGridData[(y+0)*gridSize + x];
|
||||
vdb = &faceGridData[(y+1)*gridSize + x];
|
||||
|
||||
PASSATTRIB(0, 0, 3);
|
||||
glNormal3fv(vda->no);
|
||||
glVertex3fv(vda->co);
|
||||
|
||||
PASSATTRIB(0, 1, 2);
|
||||
glNormal3fv(vdb->no);
|
||||
glVertex3fv(vdb->co);
|
||||
|
||||
glEnd();
|
||||
|
||||
a++;
|
||||
}
|
||||
} else {
|
||||
glBegin(GL_QUADS);
|
||||
for (y=0; y<gridFaces; y++) {
|
||||
for (x=0; x<gridFaces; x++) {
|
||||
float *aco = faceGridData[(y+0)*gridSize + x].co;
|
||||
float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
|
||||
float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
|
||||
float *dco = faceGridData[(y+1)*gridSize + x].co;
|
||||
|
||||
ccgDM_glNormalFast(aco, bco, cco, dco);
|
||||
|
||||
PASSATTRIB(0, 1, 1);
|
||||
glVertex3fv(dco);
|
||||
PASSATTRIB(1, 1, 2);
|
||||
glVertex3fv(cco);
|
||||
PASSATTRIB(1, 0, 3);
|
||||
glVertex3fv(bco);
|
||||
PASSATTRIB(0, 0, 0);
|
||||
glVertex3fv(aco);
|
||||
|
||||
a++;
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef PASSATTRIB
|
||||
|
||||
ccgFaceIterator_free(fi);
|
||||
}
|
||||
|
||||
static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
|
||||
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
|
||||
}
|
||||
|
||||
static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
|
||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
@ -2143,8 +2309,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
|
||||
ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
|
||||
ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
|
||||
ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
|
||||
ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
|
||||
ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
|
||||
ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
|
||||
ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
|
||||
ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
|
||||
|
||||
ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
|
||||
|
254
source/blender/blenkernel/intern/suggestions.c
Normal file
254
source/blender/blenkernel/intern/suggestions.c
Normal file
@ -0,0 +1,254 @@
|
||||
/**
|
||||
* $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008, Blender Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Ian Thompson.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "DNA_text_types.h"
|
||||
#include "BKE_text.h"
|
||||
#include "BKE_suggestions.h"
|
||||
|
||||
/**********************/
|
||||
/* Static definitions */
|
||||
/**********************/
|
||||
|
||||
static Text *activeToolText = NULL;
|
||||
static SuggList suggestions = {NULL, NULL, NULL, NULL, NULL};
|
||||
static char *documentation = NULL;
|
||||
static int doc_lines = 0;
|
||||
|
||||
static int txttl_cmp(const char *first, const char *second, int len) {
|
||||
int cmp, i;
|
||||
for (cmp=0, i=0; i<len; i++) {
|
||||
if (cmp= toupper(first[i])-toupper(second[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
static void txttl_free_suggest() {
|
||||
SuggItem *item, *prev;
|
||||
for (item = suggestions.last; item; item=prev) {
|
||||
prev = item->prev;
|
||||
MEM_freeN(item);
|
||||
}
|
||||
suggestions.first = suggestions.last = NULL;
|
||||
suggestions.firstmatch = suggestions.lastmatch = NULL;
|
||||
suggestions.selected = NULL;
|
||||
suggestions.top = 0;
|
||||
}
|
||||
|
||||
static void txttl_free_docs() {
|
||||
if (documentation) {
|
||||
MEM_freeN(documentation);
|
||||
documentation = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* General tool functions */
|
||||
/**************************/
|
||||
|
||||
void free_texttools() {
|
||||
txttl_free_suggest();
|
||||
txttl_free_docs();
|
||||
}
|
||||
|
||||
void texttool_text_set_active(Text *text) {
|
||||
if (activeToolText == text) return;
|
||||
texttool_text_clear();
|
||||
activeToolText = text;
|
||||
}
|
||||
|
||||
void texttool_text_clear() {
|
||||
free_texttools();
|
||||
activeToolText = NULL;
|
||||
}
|
||||
|
||||
short texttool_text_is_active(Text *text) {
|
||||
return activeToolText==text ? 1 : 0;
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/* Suggestion list methods */
|
||||
/***************************/
|
||||
|
||||
void texttool_suggest_add(const char *name, char type) {
|
||||
SuggItem *newitem, *item;
|
||||
int len, cmp;
|
||||
|
||||
newitem = MEM_mallocN(sizeof(SuggItem) + strlen(name) + 1, "SuggestionItem");
|
||||
if (!newitem) {
|
||||
printf("Failed to allocate memory for suggestion.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
newitem->name = (char *) (newitem + 1);
|
||||
len = strlen(name);
|
||||
strncpy(newitem->name, name, len);
|
||||
newitem->name[len] = '\0';
|
||||
newitem->type = type;
|
||||
newitem->prev = newitem->next = NULL;
|
||||
|
||||
/* Perform simple linear search for ordered storage */
|
||||
if (!suggestions.first || !suggestions.last) {
|
||||
suggestions.first = suggestions.last = newitem;
|
||||
} else {
|
||||
cmp = -1;
|
||||
for (item=suggestions.last; item; item=item->prev) {
|
||||
cmp = txttl_cmp(name, item->name, len);
|
||||
|
||||
/* Newitem comes after this item, insert here */
|
||||
if (cmp >= 0) {
|
||||
newitem->prev = item;
|
||||
if (item->next)
|
||||
item->next->prev = newitem;
|
||||
newitem->next = item->next;
|
||||
item->next = newitem;
|
||||
|
||||
/* At last item, set last pointer here */
|
||||
if (item == suggestions.last)
|
||||
suggestions.last = newitem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Reached beginning of list, insert before first */
|
||||
if (cmp < 0) {
|
||||
newitem->next = suggestions.first;
|
||||
suggestions.first->prev = newitem;
|
||||
suggestions.first = newitem;
|
||||
}
|
||||
}
|
||||
suggestions.firstmatch = suggestions.lastmatch = suggestions.selected = NULL;
|
||||
suggestions.top= 0;
|
||||
}
|
||||
|
||||
void texttool_suggest_prefix(const char *prefix) {
|
||||
SuggItem *match, *first, *last;
|
||||
int cmp, len = strlen(prefix), top = 0;
|
||||
|
||||
if (!suggestions.first) return;
|
||||
if (len==0) {
|
||||
suggestions.selected = suggestions.firstmatch = suggestions.first;
|
||||
suggestions.lastmatch = suggestions.last;
|
||||
return;
|
||||
}
|
||||
|
||||
first = last = NULL;
|
||||
for (match=suggestions.first; match; match=match->next) {
|
||||
cmp = txttl_cmp(prefix, match->name, len);
|
||||
if (cmp==0) {
|
||||
if (!first) {
|
||||
first = match;
|
||||
suggestions.top = top;
|
||||
}
|
||||
} else if (cmp<0) {
|
||||
if (!last) {
|
||||
last = match->prev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
top++;
|
||||
}
|
||||
if (first) {
|
||||
if (!last) last = suggestions.last;
|
||||
suggestions.firstmatch = first;
|
||||
suggestions.lastmatch = last;
|
||||
suggestions.selected = first;
|
||||
} else {
|
||||
suggestions.firstmatch = NULL;
|
||||
suggestions.lastmatch = NULL;
|
||||
suggestions.selected = NULL;
|
||||
suggestions.top = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void texttool_suggest_clear() {
|
||||
txttl_free_suggest();
|
||||
}
|
||||
|
||||
SuggItem *texttool_suggest_first() {
|
||||
return suggestions.firstmatch;
|
||||
}
|
||||
|
||||
SuggItem *texttool_suggest_last() {
|
||||
return suggestions.lastmatch;
|
||||
}
|
||||
|
||||
void texttool_suggest_select(SuggItem *sel) {
|
||||
suggestions.selected = sel;
|
||||
}
|
||||
|
||||
SuggItem *texttool_suggest_selected() {
|
||||
return suggestions.selected;
|
||||
}
|
||||
|
||||
int *texttool_suggest_top() {
|
||||
return &suggestions.top;
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Documentation methods */
|
||||
/*************************/
|
||||
|
||||
void texttool_docs_show(const char *docs) {
|
||||
int len;
|
||||
|
||||
if (!docs) return;
|
||||
|
||||
len = strlen(docs);
|
||||
|
||||
if (documentation) {
|
||||
MEM_freeN(documentation);
|
||||
documentation = NULL;
|
||||
}
|
||||
|
||||
/* Ensure documentation ends with a '\n' */
|
||||
if (docs[len-1] != '\n') {
|
||||
documentation = MEM_mallocN(len+2, "Documentation");
|
||||
strncpy(documentation, docs, len);
|
||||
documentation[len++] = '\n';
|
||||
} else {
|
||||
documentation = MEM_mallocN(len+1, "Documentation");
|
||||
strncpy(documentation, docs, len);
|
||||
}
|
||||
documentation[len] = '\0';
|
||||
}
|
||||
|
||||
char *texttool_docs_get() {
|
||||
return documentation;
|
||||
}
|
||||
|
||||
void texttool_docs_clear() {
|
||||
txttl_free_docs();
|
||||
}
|
@ -30,6 +30,8 @@
|
||||
*/
|
||||
|
||||
#include <string.h> /* strstr */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@ -81,12 +83,19 @@ The st->top determines at what line the top of the text is displayed.
|
||||
If the user moves the cursor the st containing that cursor should
|
||||
be popped ... other st's retain their own top location.
|
||||
|
||||
*/ /***************/
|
||||
Markers
|
||||
--
|
||||
The mrk->flags define the behaviour and relationships between markers. The
|
||||
upper two bytes are used to hold a group ID, the lower two are normal flags. If
|
||||
TMARK_EDITALL is set the group ID defines which other markers should be edited.
|
||||
|
||||
The mrk->clr field is used to visually group markers where the flags may not
|
||||
match. A template system, for example, may allow editing of repeating tokens
|
||||
(in one group) but include other marked positions (in another group) all in the
|
||||
same template with the same colour.
|
||||
|
||||
/****************/ /*
|
||||
Undo
|
||||
|
||||
Undo
|
||||
--
|
||||
Undo/Redo works by storing
|
||||
events in a queue, and a pointer
|
||||
to the current position in the
|
||||
@ -145,6 +154,7 @@ void free_text(Text *text)
|
||||
}
|
||||
|
||||
BLI_freelistN(&text->lines);
|
||||
BLI_freelistN(&text->markers);
|
||||
|
||||
if(text->name) MEM_freeN(text->name);
|
||||
MEM_freeN(text->undo_buf);
|
||||
@ -169,10 +179,11 @@ Text *add_empty_text(char *name)
|
||||
ta->flags= TXT_ISDIRTY | TXT_ISTMP | TXT_ISMEM;
|
||||
|
||||
ta->lines.first= ta->lines.last= NULL;
|
||||
ta->markers.first= ta->markers.last= NULL;
|
||||
|
||||
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= (char*) MEM_mallocN(1, "textline_string");
|
||||
tmp->format= (char*) MEM_mallocN(2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
tmp->line[0]=0;
|
||||
tmp->len= 0;
|
||||
@ -209,11 +220,12 @@ static void cleanup_textline(TextLine * tl)
|
||||
int reopen_text(Text *text)
|
||||
{
|
||||
FILE *fp;
|
||||
int i, llen, len;
|
||||
int i, llen, len, res;
|
||||
unsigned char *buffer;
|
||||
TextLine *tmp;
|
||||
char sfile[FILE_MAXFILE];
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
struct stat st;
|
||||
|
||||
if (!text || !text->name) return 0;
|
||||
|
||||
@ -242,7 +254,7 @@ int reopen_text(Text *text)
|
||||
text->undo_len= TXT_INIT_UNDO;
|
||||
text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
|
||||
|
||||
text->flags= TXT_ISDIRTY | TXT_ISTMP;
|
||||
text->flags= TXT_ISTMP;
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
len= ftell(fp);
|
||||
@ -257,6 +269,9 @@ int reopen_text(Text *text)
|
||||
|
||||
fclose(fp);
|
||||
|
||||
res= stat(str, &st);
|
||||
text->mtime= st.st_mtime;
|
||||
|
||||
text->nlines=0;
|
||||
i=0;
|
||||
llen=0;
|
||||
@ -264,7 +279,7 @@ int reopen_text(Text *text)
|
||||
if (buffer[i]=='\n') {
|
||||
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= (char*) MEM_mallocN(llen+1, "textline_string");
|
||||
tmp->format= (char*) MEM_mallocN(llen+2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
if(llen) memcpy(tmp->line, &buffer[i-llen], llen);
|
||||
tmp->line[llen]=0;
|
||||
@ -284,7 +299,7 @@ int reopen_text(Text *text)
|
||||
if (llen!=0 || text->nlines==0) {
|
||||
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= (char*) MEM_mallocN(llen+1, "textline_string");
|
||||
tmp->format= (char*) MEM_mallocN(llen+2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
if(llen) memcpy(tmp->line, &buffer[i-llen], llen);
|
||||
|
||||
@ -307,12 +322,13 @@ int reopen_text(Text *text)
|
||||
Text *add_text(char *file)
|
||||
{
|
||||
FILE *fp;
|
||||
int i, llen, len;
|
||||
int i, llen, len, res;
|
||||
unsigned char *buffer;
|
||||
TextLine *tmp;
|
||||
Text *ta;
|
||||
char sfile[FILE_MAXFILE];
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
struct stat st;
|
||||
|
||||
BLI_strncpy(str, file, FILE_MAXDIR+FILE_MAXFILE);
|
||||
if (G.scene) /* can be NULL (bg mode) */
|
||||
@ -326,6 +342,7 @@ Text *add_text(char *file)
|
||||
ta->id.us= 1;
|
||||
|
||||
ta->lines.first= ta->lines.last= NULL;
|
||||
ta->markers.first= ta->markers.last= NULL;
|
||||
ta->curl= ta->sell= NULL;
|
||||
|
||||
/* ta->flags= TXT_ISTMP | TXT_ISEXT; */
|
||||
@ -349,6 +366,9 @@ Text *add_text(char *file)
|
||||
|
||||
fclose(fp);
|
||||
|
||||
res= stat(str, &st);
|
||||
ta->mtime= st.st_mtime;
|
||||
|
||||
ta->nlines=0;
|
||||
i=0;
|
||||
llen=0;
|
||||
@ -356,7 +376,7 @@ Text *add_text(char *file)
|
||||
if (buffer[i]=='\n') {
|
||||
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= (char*) MEM_mallocN(llen+1, "textline_string");
|
||||
tmp->format= (char*) MEM_mallocN(llen+2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
if(llen) memcpy(tmp->line, &buffer[i-llen], llen);
|
||||
tmp->line[llen]=0;
|
||||
@ -376,7 +396,7 @@ Text *add_text(char *file)
|
||||
if (llen!=0 || ta->nlines==0) {
|
||||
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= (char*) MEM_mallocN(llen+1, "textline_string");
|
||||
tmp->format= (char*) MEM_mallocN(llen+2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
if(llen) memcpy(tmp->line, &buffer[i-llen], llen);
|
||||
|
||||
@ -410,6 +430,7 @@ Text *copy_text(Text *ta)
|
||||
tan->flags = ta->flags | TXT_ISDIRTY | TXT_ISTMP;
|
||||
|
||||
tan->lines.first= tan->lines.last= NULL;
|
||||
tan->markers.first= tan->markers.last= NULL;
|
||||
tan->curl= tan->sell= NULL;
|
||||
|
||||
tan->nlines= ta->nlines;
|
||||
@ -419,7 +440,7 @@ Text *copy_text(Text *ta)
|
||||
while (line) {
|
||||
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= MEM_mallocN(line->len+1, "textline_string");
|
||||
tmp->format= MEM_mallocN(line->len+2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
strcpy(tmp->line, line->line);
|
||||
|
||||
@ -440,14 +461,14 @@ Text *copy_text(Text *ta)
|
||||
/* Editing utility functions */
|
||||
/*****************************/
|
||||
|
||||
static void make_new_line (TextLine *line, char *newline, char *newformat)
|
||||
static void make_new_line (TextLine *line, char *newline)
|
||||
{
|
||||
if (line->line) MEM_freeN(line->line);
|
||||
if (line->format) MEM_freeN(line->format);
|
||||
|
||||
line->line= newline;
|
||||
line->len= strlen(newline);
|
||||
line->format= newformat;
|
||||
line->format= NULL;
|
||||
}
|
||||
|
||||
static TextLine *txt_new_line(char *str)
|
||||
@ -458,7 +479,7 @@ static TextLine *txt_new_line(char *str)
|
||||
|
||||
tmp= (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= MEM_mallocN(strlen(str)+1, "textline_string");
|
||||
tmp->format= MEM_mallocN(strlen(str)+2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
strcpy(tmp->line, str);
|
||||
|
||||
@ -476,7 +497,7 @@ static TextLine *txt_new_linen(char *str, int n)
|
||||
|
||||
tmp= (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
|
||||
tmp->line= MEM_mallocN(n+1, "textline_string");
|
||||
tmp->format= MEM_mallocN(n+2, "Syntax_format");
|
||||
tmp->format= NULL;
|
||||
|
||||
BLI_strncpy(tmp->line, str, n+1);
|
||||
|
||||
@ -553,6 +574,19 @@ static void txt_make_dirty (Text *text)
|
||||
if (text->compiled) BPY_free_compiled_text(text);
|
||||
}
|
||||
|
||||
/* 0:whitespace, 1:punct, 2:alphanumeric */
|
||||
static short txt_char_type (char ch)
|
||||
{
|
||||
if (ch <= ' ') return 0;
|
||||
if (ch <= '/') return 1;
|
||||
if (ch <= '9') return 2;
|
||||
if (ch <= '@') return 1;
|
||||
if (ch <= 'Z') return 2;
|
||||
if (ch <= '`') return 1;
|
||||
if (ch <= 'z') return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* Cursor utility functions */
|
||||
/****************************/
|
||||
@ -606,8 +640,7 @@ void txt_move_up(Text *text, short sel)
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP);
|
||||
}
|
||||
} else {
|
||||
*charp= 0;
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP);
|
||||
txt_move_bol(text, sel);
|
||||
}
|
||||
|
||||
if(!sel) txt_pop_sel(text);
|
||||
@ -632,8 +665,7 @@ void txt_move_down(Text *text, short sel)
|
||||
} else
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN);
|
||||
} else {
|
||||
*charp= (*linep)->len;
|
||||
if(!undoing) txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN);
|
||||
txt_move_eol(text, sel);
|
||||
}
|
||||
|
||||
if(!sel) txt_pop_sel(text);
|
||||
@ -689,6 +721,68 @@ void txt_move_right(Text *text, short sel)
|
||||
if(!sel) txt_pop_sel(text);
|
||||
}
|
||||
|
||||
void txt_jump_left(Text *text, short sel)
|
||||
{
|
||||
TextLine **linep, *oldl;
|
||||
int *charp, oldc, count, i;
|
||||
unsigned char oldu;
|
||||
|
||||
if (!text) return;
|
||||
if(sel) txt_curs_sel(text, &linep, &charp);
|
||||
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
|
||||
if (!*linep) return;
|
||||
|
||||
oldl= *linep;
|
||||
oldc= *charp;
|
||||
oldu= undoing;
|
||||
undoing= 1; /* Don't push individual moves to undo stack */
|
||||
|
||||
count= 0;
|
||||
for (i=0; i<3; i++) {
|
||||
if (count < 2) {
|
||||
while (*charp>0 && txt_char_type((*linep)->line[*charp-1])==i) {
|
||||
txt_move_left(text, sel);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count==0) txt_move_left(text, sel);
|
||||
|
||||
undoing= oldu;
|
||||
if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
|
||||
}
|
||||
|
||||
void txt_jump_right(Text *text, short sel)
|
||||
{
|
||||
TextLine **linep, *oldl;
|
||||
int *charp, oldc, count, i;
|
||||
unsigned char oldu;
|
||||
|
||||
if (!text) return;
|
||||
if(sel) txt_curs_sel(text, &linep, &charp);
|
||||
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
|
||||
if (!*linep) return;
|
||||
|
||||
oldl= *linep;
|
||||
oldc= *charp;
|
||||
oldu= undoing;
|
||||
undoing= 1; /* Don't push individual moves to undo stack */
|
||||
|
||||
count= 0;
|
||||
for (i=0; i<3; i++) {
|
||||
if (count < 2) {
|
||||
while (*charp<(*linep)->len && txt_char_type((*linep)->line[*charp])==i) {
|
||||
txt_move_right(text, sel);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count==0) txt_move_right(text, sel);
|
||||
|
||||
undoing= oldu;
|
||||
if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
|
||||
}
|
||||
|
||||
void txt_move_bol (Text *text, short sel)
|
||||
{
|
||||
TextLine **linep;
|
||||
@ -760,6 +854,11 @@ void txt_move_eof (Text *text, short sel)
|
||||
}
|
||||
|
||||
void txt_move_toline (Text *text, unsigned int line, short sel)
|
||||
{
|
||||
txt_move_to(text, line, 0, sel);
|
||||
}
|
||||
|
||||
void txt_move_to (Text *text, unsigned int line, unsigned int ch, short sel)
|
||||
{
|
||||
TextLine **linep, *oldl;
|
||||
int *charp, oldc;
|
||||
@ -777,7 +876,9 @@ void txt_move_toline (Text *text, unsigned int line, short sel)
|
||||
if ((*linep)->next) *linep= (*linep)->next;
|
||||
else break;
|
||||
}
|
||||
*charp= 0;
|
||||
if (ch>(*linep)->len)
|
||||
ch= (*linep)->len;
|
||||
*charp= ch;
|
||||
|
||||
if(!sel) txt_pop_sel(text);
|
||||
if(!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
|
||||
@ -865,7 +966,9 @@ int txt_has_sel(Text *text)
|
||||
static void txt_delete_sel (Text *text)
|
||||
{
|
||||
TextLine *tmpl;
|
||||
char *buf, *format;
|
||||
TextMarker *mrk;
|
||||
char *buf;
|
||||
int move, lineno;
|
||||
|
||||
if (!text) return;
|
||||
if (!text->curl) return;
|
||||
@ -882,13 +985,33 @@ static void txt_delete_sel (Text *text)
|
||||
}
|
||||
|
||||
buf= MEM_mallocN(text->curc+(text->sell->len - text->selc)+1, "textline_string");
|
||||
format= MEM_mallocN(text->curc+(text->sell->len - text->selc)+2, "Syntax_format");
|
||||
|
||||
if (text->curl != text->sell) {
|
||||
txt_clear_marker_region(text, text->curl, text->curc, text->curl->len, 0, 0);
|
||||
move= txt_get_span(text->curl, text->sell);
|
||||
} else {
|
||||
mrk= txt_find_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
|
||||
if (mrk && (mrk->start > text->curc || mrk->end < text->selc))
|
||||
txt_clear_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
|
||||
move= 0;
|
||||
}
|
||||
|
||||
mrk= txt_find_marker_region(text, text->sell, text->selc-1, text->sell->len, 0, 0);
|
||||
if (mrk) {
|
||||
lineno= mrk->lineno;
|
||||
do {
|
||||
mrk->lineno -= move;
|
||||
if (mrk->start > text->curc) mrk->start -= text->selc - text->curc;
|
||||
mrk->end -= text->selc - text->curc;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
|
||||
strncpy(buf, text->curl->line, text->curc);
|
||||
strcpy(buf+text->curc, text->sell->line + text->selc);
|
||||
buf[text->curc+(text->sell->len - text->selc)]=0;
|
||||
|
||||
make_new_line(text->curl, buf, format);
|
||||
make_new_line(text->curl, buf);
|
||||
|
||||
tmpl= text->sell;
|
||||
while (tmpl != text->curl) {
|
||||
@ -995,22 +1118,31 @@ char *txt_to_buf (Text *text)
|
||||
return buf;
|
||||
}
|
||||
|
||||
int txt_find_string(Text *text, char *findstr)
|
||||
int txt_find_string(Text *text, char *findstr, int wrap)
|
||||
{
|
||||
TextLine *tl, *startl;
|
||||
char *s= NULL;
|
||||
int oldcl, oldsl, oldcc, oldsc;
|
||||
|
||||
if (!text || !text->curl || !text->sell) return 0;
|
||||
|
||||
txt_order_cursors(text);
|
||||
|
||||
oldcl= txt_get_span(text->lines.first, text->curl);
|
||||
oldsl= txt_get_span(text->lines.first, text->sell);
|
||||
tl= startl= text->sell;
|
||||
oldcc= text->curc;
|
||||
oldsc= text->selc;
|
||||
|
||||
s= strstr(&tl->line[text->selc], findstr);
|
||||
while (!s) {
|
||||
tl= tl->next;
|
||||
if (!tl)
|
||||
tl= text->lines.first;
|
||||
if (!tl) {
|
||||
if (wrap)
|
||||
tl= text->lines.first;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
s= strstr(tl->line, findstr);
|
||||
if (tl==startl)
|
||||
@ -1018,10 +1150,10 @@ int txt_find_string(Text *text, char *findstr)
|
||||
}
|
||||
|
||||
if (s) {
|
||||
text->curl= text->sell= tl;
|
||||
text->curc= (int) (s-tl->line);
|
||||
text->selc= text->curc + strlen(findstr);
|
||||
|
||||
int newl= txt_get_span(text->lines.first, tl);
|
||||
int newc= (int)(s-tl->line);
|
||||
txt_move_to(text, newl, newc, 0);
|
||||
txt_move_to(text, newl, newc + strlen(findstr), 1);
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
@ -1621,7 +1753,6 @@ void txt_do_undo(Text *text)
|
||||
|
||||
case UNDO_SWAP:
|
||||
txt_curs_swap(text);
|
||||
txt_do_undo(text); /* swaps should appear transparent */
|
||||
break;
|
||||
|
||||
case UNDO_DBLOCK:
|
||||
@ -1737,6 +1868,19 @@ void txt_do_undo(Text *text)
|
||||
break;
|
||||
}
|
||||
|
||||
/* next undo step may need evaluating */
|
||||
if (text->undo_pos>=0) {
|
||||
switch (text->undo_buf[text->undo_pos]) {
|
||||
case UNDO_STO:
|
||||
txt_do_undo(text);
|
||||
txt_do_redo(text); /* selections need restoring */
|
||||
break;
|
||||
case UNDO_SWAP:
|
||||
txt_do_undo(text); /* swaps should appear transparent */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
undoing= 0;
|
||||
}
|
||||
|
||||
@ -1810,7 +1954,7 @@ void txt_do_redo(Text *text)
|
||||
|
||||
case UNDO_SWAP:
|
||||
txt_curs_swap(text);
|
||||
txt_do_undo(text); /* swaps should appear transparent a*/
|
||||
txt_do_redo(text); /* swaps should appear transparent a*/
|
||||
break;
|
||||
|
||||
case UNDO_CTO:
|
||||
@ -1947,22 +2091,37 @@ void txt_do_redo(Text *text)
|
||||
void txt_split_curline (Text *text)
|
||||
{
|
||||
TextLine *ins;
|
||||
char *left, *right, *fleft, *fright;
|
||||
TextMarker *mrk;
|
||||
char *left, *right;
|
||||
int lineno= -1;
|
||||
|
||||
if (!text) return;
|
||||
if (!text->curl) return;
|
||||
|
||||
txt_delete_sel(text);
|
||||
|
||||
/* Move markers */
|
||||
|
||||
lineno= txt_get_span(text->lines.first, text->curl);
|
||||
mrk= text->markers.first;
|
||||
while (mrk) {
|
||||
if (mrk->lineno==lineno && mrk->start>text->curc) {
|
||||
mrk->lineno++;
|
||||
mrk->start -= text->curc;
|
||||
mrk->end -= text->curc;
|
||||
} else if (mrk->lineno > lineno) {
|
||||
mrk->lineno++;
|
||||
}
|
||||
mrk= mrk->next;
|
||||
}
|
||||
|
||||
/* Make the two half strings */
|
||||
|
||||
left= MEM_mallocN(text->curc+1, "textline_string");
|
||||
fleft= MEM_mallocN(text->curc+2, "Syntax_format");
|
||||
if (text->curc) memcpy(left, text->curl->line, text->curc);
|
||||
left[text->curc]=0;
|
||||
|
||||
right= MEM_mallocN(text->curl->len - text->curc+1, "textline_string");
|
||||
fright= MEM_mallocN(text->curl->len - text->curc+2, "Syntax_format");
|
||||
if (text->curl->len - text->curc) memcpy(right, text->curl->line+text->curc, text->curl->len-text->curc);
|
||||
right[text->curl->len - text->curc]=0;
|
||||
|
||||
@ -1973,11 +2132,11 @@ void txt_split_curline (Text *text)
|
||||
|
||||
ins= MEM_mallocN(sizeof(TextLine), "textline");
|
||||
ins->line= left;
|
||||
ins->format= fleft;
|
||||
ins->format= NULL;
|
||||
ins->len= text->curc;
|
||||
|
||||
text->curl->line= right;
|
||||
text->curl->format= fright;
|
||||
text->curl->format= NULL;
|
||||
text->curl->len= text->curl->len - text->curc;
|
||||
|
||||
BLI_insertlinkbefore(&text->lines, text->curl, ins);
|
||||
@ -1993,9 +2152,23 @@ void txt_split_curline (Text *text)
|
||||
|
||||
static void txt_delete_line (Text *text, TextLine *line)
|
||||
{
|
||||
TextMarker *mrk=NULL, *nxt;
|
||||
int lineno= -1;
|
||||
|
||||
if (!text) return;
|
||||
if (!text->curl) return;
|
||||
|
||||
lineno= txt_get_span(text->lines.first, line);
|
||||
mrk= text->markers.first;
|
||||
while (mrk) {
|
||||
nxt= mrk->next;
|
||||
if (mrk->lineno==lineno)
|
||||
BLI_freelinkN(&text->markers, mrk);
|
||||
else if (mrk->lineno > lineno)
|
||||
mrk->lineno--;
|
||||
mrk= nxt;
|
||||
}
|
||||
|
||||
BLI_remlink (&text->lines, line);
|
||||
|
||||
if (line->line) MEM_freeN(line->line);
|
||||
@ -2009,19 +2182,33 @@ static void txt_delete_line (Text *text, TextLine *line)
|
||||
|
||||
static void txt_combine_lines (Text *text, TextLine *linea, TextLine *lineb)
|
||||
{
|
||||
char *tmp, *format;
|
||||
char *tmp;
|
||||
TextMarker *mrk= NULL;
|
||||
int lineno=-1;
|
||||
|
||||
if (!text) return;
|
||||
|
||||
if(!linea || !lineb) return;
|
||||
|
||||
mrk= txt_find_marker_region(text, lineb, 0, lineb->len, 0, 0);
|
||||
if (mrk) {
|
||||
lineno= mrk->lineno;
|
||||
do {
|
||||
mrk->lineno--;
|
||||
mrk->start += linea->len;
|
||||
mrk->end += linea->len;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
if (lineno==-1) lineno= txt_get_span(text->lines.first, lineb);
|
||||
if (!mrk) mrk= text->markers.first;
|
||||
|
||||
tmp= MEM_mallocN(linea->len+lineb->len+1, "textline_string");
|
||||
format= MEM_mallocN(linea->len+lineb->len+1, "Syntax_format");
|
||||
|
||||
strcpy(tmp, linea->line);
|
||||
strcat(tmp, lineb->line);
|
||||
|
||||
make_new_line(linea, tmp, format);
|
||||
make_new_line(linea, tmp);
|
||||
|
||||
txt_delete_line(text, lineb);
|
||||
|
||||
@ -2037,8 +2224,9 @@ void txt_delete_char (Text *text)
|
||||
if (!text->curl) return;
|
||||
|
||||
if (txt_has_sel(text)) { /* deleting a selection */
|
||||
txt_delete_sel(text);
|
||||
return;
|
||||
txt_delete_sel(text);
|
||||
txt_make_dirty(text);
|
||||
return;
|
||||
}
|
||||
else if (text->curc== text->curl->len) { /* Appending two lines */
|
||||
if (text->curl->next) {
|
||||
@ -2048,6 +2236,25 @@ void txt_delete_char (Text *text)
|
||||
} else { /* Just deleting a char */
|
||||
int i= text->curc;
|
||||
|
||||
TextMarker *mrk= txt_find_marker_region(text, text->curl, i-1, text->curl->len, 0, 0);
|
||||
if (mrk) {
|
||||
int lineno= mrk->lineno;
|
||||
if (mrk->end==i) {
|
||||
if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
|
||||
txt_clear_markers(text, mrk->group, TMARK_TEMP);
|
||||
} else {
|
||||
TextMarker *nxt= mrk->next;
|
||||
BLI_freelinkN(&text->markers, mrk);
|
||||
}
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (mrk->start>i) mrk->start--;
|
||||
mrk->end--;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
|
||||
c= text->curl->line[i];
|
||||
while(i< text->curl->len) {
|
||||
text->curl->line[i]= text->curl->line[i+1];
|
||||
@ -2064,6 +2271,12 @@ void txt_delete_char (Text *text)
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_DEL, c);
|
||||
}
|
||||
|
||||
void txt_delete_word (Text *text)
|
||||
{
|
||||
txt_jump_right(text, 1);
|
||||
txt_delete_sel(text);
|
||||
}
|
||||
|
||||
void txt_backspace_char (Text *text)
|
||||
{
|
||||
char c='\n';
|
||||
@ -2072,8 +2285,9 @@ void txt_backspace_char (Text *text)
|
||||
if (!text->curl) return;
|
||||
|
||||
if (txt_has_sel(text)) { /* deleting a selection */
|
||||
txt_delete_sel(text);
|
||||
return;
|
||||
txt_delete_sel(text);
|
||||
txt_make_dirty(text);
|
||||
return;
|
||||
}
|
||||
else if (text->curc==0) { /* Appending two lines */
|
||||
if (!text->curl->prev) return;
|
||||
@ -2085,17 +2299,36 @@ void txt_backspace_char (Text *text)
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
else { /* Just backspacing a char */
|
||||
int i= text->curc-1;
|
||||
int i= text->curc-1;
|
||||
|
||||
c= text->curl->line[i];
|
||||
while(i< text->curl->len) {
|
||||
text->curl->line[i]= text->curl->line[i+1];
|
||||
i++;
|
||||
}
|
||||
text->curl->len--;
|
||||
text->curc--;
|
||||
TextMarker *mrk= txt_find_marker_region(text, text->curl, i, text->curl->len, 0, 0);
|
||||
if (mrk) {
|
||||
int lineno= mrk->lineno;
|
||||
if (mrk->start==i+1) {
|
||||
if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
|
||||
txt_clear_markers(text, mrk->group, TMARK_TEMP);
|
||||
} else {
|
||||
TextMarker *nxt= mrk->next;
|
||||
BLI_freelinkN(&text->markers, mrk);
|
||||
}
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (mrk->start>i) mrk->start--;
|
||||
mrk->end--;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
|
||||
txt_pop_sel(text);
|
||||
c= text->curl->line[i];
|
||||
while(i< text->curl->len) {
|
||||
text->curl->line[i]= text->curl->line[i+1];
|
||||
i++;
|
||||
}
|
||||
text->curl->len--;
|
||||
text->curc--;
|
||||
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
|
||||
txt_make_dirty(text);
|
||||
@ -2104,10 +2337,17 @@ void txt_backspace_char (Text *text)
|
||||
if(!undoing) txt_undo_add_charop(text, UNDO_BS, c);
|
||||
}
|
||||
|
||||
void txt_backspace_word (Text *text)
|
||||
{
|
||||
txt_jump_left(text, 1);
|
||||
txt_delete_sel(text);
|
||||
}
|
||||
|
||||
int txt_add_char (Text *text, char add)
|
||||
{
|
||||
int len;
|
||||
char *tmp, *format;
|
||||
int len, lineno;
|
||||
char *tmp;
|
||||
TextMarker *mrk;
|
||||
|
||||
if (!text) return 0;
|
||||
if (!text->curl) return 0;
|
||||
@ -2119,8 +2359,17 @@ int txt_add_char (Text *text, char add)
|
||||
|
||||
txt_delete_sel(text);
|
||||
|
||||
mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0, 0);
|
||||
if (mrk) {
|
||||
lineno= mrk->lineno;
|
||||
do {
|
||||
if (mrk->start>text->curc) mrk->start++;
|
||||
mrk->end++;
|
||||
mrk= mrk->next;
|
||||
} while (mrk && mrk->lineno==lineno);
|
||||
}
|
||||
|
||||
tmp= MEM_mallocN(text->curl->len+2, "textline_string");
|
||||
format= MEM_mallocN(text->curl->len+4, "Syntax_format");
|
||||
|
||||
if(text->curc) memcpy(tmp, text->curl->line, text->curc);
|
||||
tmp[text->curc]= add;
|
||||
@ -2128,7 +2377,7 @@ int txt_add_char (Text *text, char add)
|
||||
len= text->curl->len - text->curc;
|
||||
if(len>0) memcpy(tmp+text->curc+1, text->curl->line+text->curc, len);
|
||||
tmp[text->curl->len+1]=0;
|
||||
make_new_line(text->curl, tmp, format);
|
||||
make_new_line(text->curl, tmp);
|
||||
|
||||
text->curc++;
|
||||
|
||||
@ -2141,10 +2390,42 @@ int txt_add_char (Text *text, char add)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int txt_replace_char (Text *text, char add)
|
||||
{
|
||||
char del;
|
||||
|
||||
if (!text) return 0;
|
||||
if (!text->curl) return 0;
|
||||
|
||||
/* If text is selected or we're at the end of the line just use txt_add_char */
|
||||
if (text->curc==text->curl->len || txt_has_sel(text) || add=='\n') {
|
||||
TextMarker *mrk;
|
||||
int i= txt_add_char(text, add);
|
||||
mrk= txt_find_marker(text, text->curl, text->curc, 0, 0);
|
||||
if (mrk && mrk->end==text->curc) mrk->end--;
|
||||
return i;
|
||||
}
|
||||
|
||||
del= text->curl->line[text->curc];
|
||||
text->curl->line[text->curc]= (unsigned char) add;
|
||||
text->curc++;
|
||||
txt_pop_sel(text);
|
||||
|
||||
txt_make_dirty(text);
|
||||
txt_clean_text(text);
|
||||
|
||||
/* Should probably create a new op for this */
|
||||
if(!undoing) {
|
||||
txt_undo_add_charop(text, UNDO_DEL, del);
|
||||
txt_undo_add_charop(text, UNDO_INSERT, add);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void indent(Text *text)
|
||||
{
|
||||
int len, num;
|
||||
char *tmp, *format;
|
||||
char *tmp;
|
||||
char add = '\t';
|
||||
|
||||
if (!text) return;
|
||||
@ -2155,7 +2436,6 @@ void indent(Text *text)
|
||||
while (TRUE)
|
||||
{
|
||||
tmp= MEM_mallocN(text->curl->len+2, "textline_string");
|
||||
format= MEM_mallocN(text->curl->len+3, "Syntax_format");
|
||||
|
||||
text->curc = 0;
|
||||
if(text->curc) memcpy(tmp, text->curl->line, text->curc);
|
||||
@ -2165,7 +2445,7 @@ void indent(Text *text)
|
||||
if(len>0) memcpy(tmp+text->curc+1, text->curl->line+text->curc, len);
|
||||
tmp[text->curl->len+1]=0;
|
||||
|
||||
make_new_line(text->curl, tmp, format);
|
||||
make_new_line(text->curl, tmp);
|
||||
|
||||
text->curc++;
|
||||
|
||||
@ -2246,7 +2526,7 @@ void unindent(Text *text)
|
||||
void comment(Text *text)
|
||||
{
|
||||
int len, num;
|
||||
char *tmp, *format;
|
||||
char *tmp;
|
||||
char add = '#';
|
||||
|
||||
if (!text) return;
|
||||
@ -2257,7 +2537,6 @@ void comment(Text *text)
|
||||
while (TRUE)
|
||||
{
|
||||
tmp= MEM_mallocN(text->curl->len+2, "textline_string");
|
||||
format = MEM_mallocN(text->curl->len+3, "Syntax_format");
|
||||
|
||||
text->curc = 0;
|
||||
if(text->curc) memcpy(tmp, text->curl->line, text->curc);
|
||||
@ -2267,7 +2546,7 @@ void comment(Text *text)
|
||||
if(len>0) memcpy(tmp+text->curc+1, text->curl->line+text->curc, len);
|
||||
tmp[text->curl->len+1]=0;
|
||||
|
||||
make_new_line(text->curl, tmp, format);
|
||||
make_new_line(text->curl, tmp);
|
||||
|
||||
text->curc++;
|
||||
|
||||
@ -2398,3 +2677,148 @@ int setcurr_tab (Text *text)
|
||||
return i;
|
||||
}
|
||||
|
||||
/*********************************/
|
||||
/* Text marker utility functions */
|
||||
/*********************************/
|
||||
|
||||
static int color_match(TextMarker *a, TextMarker *b) {
|
||||
return (a->color[0]==b->color[0] &&
|
||||
a->color[1]==b->color[1] &&
|
||||
a->color[2]==b->color[2] &&
|
||||
a->color[3]==b->color[3]);
|
||||
}
|
||||
|
||||
/* Creates and adds a marker to the list maintaining sorted order */
|
||||
void txt_add_marker(Text *text, TextLine *line, int start, int end, char color[4], int group, int flags) {
|
||||
TextMarker *tmp, *marker;
|
||||
|
||||
marker= MEM_mallocN(sizeof(TextMarker), "text_marker");
|
||||
|
||||
marker->lineno= txt_get_span(text->lines.first, line);
|
||||
marker->start= MIN2(start, end);
|
||||
marker->end= MAX2(start, end);
|
||||
marker->group= group;
|
||||
marker->flags= flags;
|
||||
|
||||
marker->color[0]= color[0];
|
||||
marker->color[1]= color[1];
|
||||
marker->color[2]= color[2];
|
||||
marker->color[3]= color[3];
|
||||
|
||||
for (tmp=text->markers.last; tmp; tmp=tmp->prev)
|
||||
if (tmp->lineno < marker->lineno || (tmp->lineno==marker->lineno && tmp->start < marker->start))
|
||||
break;
|
||||
|
||||
if (tmp) BLI_insertlinkafter(&text->markers, tmp, marker);
|
||||
else BLI_addhead(&text->markers, marker);
|
||||
}
|
||||
|
||||
/* Returns the first matching marker on the specified line between two points.
|
||||
If the group or flags fields are non-zero the returned flag must be in the
|
||||
specified group and have at least the specified flags set. */
|
||||
TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags) {
|
||||
TextMarker *marker, *next;
|
||||
int lineno= txt_get_span(text->lines.first, line);
|
||||
|
||||
for (marker=text->markers.first; marker; marker=next) {
|
||||
next= marker->next;
|
||||
|
||||
if (group && marker->group != group) continue;
|
||||
else if ((marker->flags & flags) != flags) continue;
|
||||
else if (marker->lineno < lineno) continue;
|
||||
else if (marker->lineno > lineno) break;
|
||||
|
||||
if ((marker->start==marker->end && start<=marker->start && marker->start<=end) ||
|
||||
(marker->start<end && marker->end>start))
|
||||
return marker;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Clears all markers on the specified line between two points. If the group or
|
||||
flags fields are non-zero the returned flag must be in the specified group
|
||||
and have at least the specified flags set. */
|
||||
short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags) {
|
||||
TextMarker *marker, *next;
|
||||
int lineno= txt_get_span(text->lines.first, line);
|
||||
short cleared= 0;
|
||||
|
||||
for (marker=text->markers.first; marker; marker=next) {
|
||||
next= marker->next;
|
||||
|
||||
if (group && marker->group != group) continue;
|
||||
else if ((marker->flags & flags) != flags) continue;
|
||||
else if (marker->lineno < lineno) continue;
|
||||
else if (marker->lineno > lineno) break;
|
||||
|
||||
if ((marker->start==marker->end && start<=marker->start && marker->start<=end) ||
|
||||
(marker->start<end && marker->end>start)) {
|
||||
BLI_freelinkN(&text->markers, marker);
|
||||
cleared= 1;
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
/* Clears all markers in the specified group (if given) with at least the
|
||||
specified flags set. Useful for clearing temporary markers (group=0,
|
||||
flags=TMARK_TEMP) */
|
||||
short txt_clear_markers(Text *text, int group, int flags) {
|
||||
TextMarker *marker, *next;
|
||||
short cleared= 0;
|
||||
|
||||
for (marker=text->markers.first; marker; marker=next) {
|
||||
next= marker->next;
|
||||
|
||||
if ((!group || marker->group==group) &&
|
||||
(marker->flags & flags) == flags) {
|
||||
BLI_freelinkN(&text->markers, marker);
|
||||
cleared= 1;
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
/* Finds the marker at the specified line and cursor position with at least the
|
||||
specified flags set in the given group (if non-zero). */
|
||||
TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int group, int flags) {
|
||||
TextMarker *marker;
|
||||
int lineno= txt_get_span(text->lines.first, line);
|
||||
|
||||
for (marker=text->markers.first; marker; marker=marker->next) {
|
||||
if (group && marker->group != group) continue;
|
||||
else if ((marker->flags & flags) != flags) continue;
|
||||
else if (marker->lineno < lineno) continue;
|
||||
else if (marker->lineno > lineno) break;
|
||||
|
||||
if (marker->start <= curs && curs <= marker->end)
|
||||
return marker;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Finds the previous marker in the same group. If no other is found, the same
|
||||
marker will be returned */
|
||||
TextMarker *txt_prev_marker(Text *text, TextMarker *marker) {
|
||||
TextMarker *tmp= marker;
|
||||
while (tmp) {
|
||||
if (tmp->prev) tmp= tmp->prev;
|
||||
else tmp= text->markers.last;
|
||||
if (tmp->group == marker->group)
|
||||
return tmp;
|
||||
}
|
||||
return NULL; /* Only if marker==NULL */
|
||||
}
|
||||
|
||||
/* Finds the next marker in the same group. If no other is found, the same
|
||||
marker will be returned */
|
||||
TextMarker *txt_next_marker(Text *text, TextMarker *marker) {
|
||||
TextMarker *tmp= marker;
|
||||
while (tmp) {
|
||||
if (tmp->next) tmp= tmp->next;
|
||||
else tmp= text->markers.first;
|
||||
if (tmp->group == marker->group)
|
||||
return tmp;
|
||||
}
|
||||
return NULL; /* Only if marker==NULL */
|
||||
}
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_color_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
@ -390,6 +391,17 @@ int do_colorband(ColorBand *coba, float in, float out[4])
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
void colorband_table_RGBA(ColorBand *coba, float **array, int *size)
|
||||
{
|
||||
int a;
|
||||
|
||||
*size = CM_TABLE+1;
|
||||
*array = MEM_callocN(sizeof(float)*(*size)*4, "ColorBand");
|
||||
|
||||
for(a=0; a<*size; a++)
|
||||
do_colorband(coba, (float)a/(float)CM_TABLE, &(*array)[a*4]);
|
||||
}
|
||||
|
||||
/* ******************* TEX ************************ */
|
||||
|
||||
void free_texture(Tex *tex)
|
||||
|
@ -260,6 +260,7 @@ void Vec2Mulf(float *v1, float f);
|
||||
void Vec2Addf(float *v, float *v1, float *v2);
|
||||
void Vec2Subf(float *v, float *v1, float *v2);
|
||||
void Vec2Copyf(float *v1, float *v2);
|
||||
void Vec2Lerpf(float *target, float *a, float *b, float t);
|
||||
|
||||
void AxisAngleToQuat(float *q, float *axis, float angle);
|
||||
void vectoquat(float *vec, short axis, short upflag, float *q);
|
||||
|
@ -73,7 +73,6 @@ extern ListBase fillvertbase;
|
||||
* @attention Defined in scanfill.c
|
||||
*/
|
||||
extern ListBase filledgebase;
|
||||
extern int totblock;
|
||||
|
||||
extern char btempdir[]; /* creator.c temp dir used instead of U.tempdir, set with BLI_where_is_temp( btempdir, 1 ); */
|
||||
|
||||
|
@ -2113,6 +2113,14 @@ void VecLerpf(float *target, float *a, float *b, float t)
|
||||
target[2]= s*a[2] + t*b[2];
|
||||
}
|
||||
|
||||
void Vec2Lerpf(float *target, float *a, float *b, float t)
|
||||
{
|
||||
float s = 1.0f-t;
|
||||
|
||||
target[0]= s*a[0] + t*b[0];
|
||||
target[1]= s*a[1] + t*b[1];
|
||||
}
|
||||
|
||||
void VecMidf(float *v, float *v1, float *v2)
|
||||
{
|
||||
v[0]= 0.5f*(v1[0]+ v2[0]);
|
||||
|
@ -49,6 +49,7 @@ extern "C" {
|
||||
/* The __intXX are built-in types of the visual complier! So we don't
|
||||
* need to include anything else here. */
|
||||
|
||||
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
@ -59,13 +60,23 @@ typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
#ifndef _INTPTR_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else
|
||||
typedef long intptr_t;
|
||||
#endif
|
||||
#define _INTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef _UINTPTR_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else
|
||||
typedef unsigned long uintptr_t;
|
||||
#endif
|
||||
#define _UINTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
@ -87,6 +98,7 @@ typedef unsigned long uintptr_t;
|
||||
|
||||
#endif /* ifdef platform for types */
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define htonl(x) correctByteOrder(x)
|
||||
#define ntohl(x) correctByteOrder(x)
|
||||
|
@ -1141,6 +1141,8 @@ void blo_make_image_pointer_map(FileData *fd)
|
||||
Link *ibuf= ima->ibufs.first;
|
||||
for(; ibuf; ibuf= ibuf->next)
|
||||
oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
|
||||
if(ima->gputexture)
|
||||
oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0);
|
||||
}
|
||||
for(; sce; sce= sce->id.next) {
|
||||
if(sce->nodetree) {
|
||||
@ -1175,8 +1177,11 @@ void blo_end_image_pointer_map(FileData *fd)
|
||||
if(NULL==newimaadr(fd, ibuf)) { /* so was restored */
|
||||
BLI_remlink(&ima->ibufs, ibuf);
|
||||
ima->bindcode= 0;
|
||||
ima->gputexture= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ima->gputexture= newimaadr(fd, ima->gputexture);
|
||||
}
|
||||
for(; sce; sce= sce->id.next) {
|
||||
if(sce->nodetree) {
|
||||
@ -2276,6 +2281,7 @@ static void direct_link_text(FileData *fd, Text *text)
|
||||
*/
|
||||
|
||||
link_list(fd, &text->lines);
|
||||
link_list(fd, &text->markers);
|
||||
|
||||
text->curl= newdataadr(fd, text->curl);
|
||||
text->sell= newdataadr(fd, text->sell);
|
||||
@ -2342,8 +2348,10 @@ static void direct_link_image(FileData *fd, Image *ima)
|
||||
ima->ibufs.first= ima->ibufs.last= NULL;
|
||||
|
||||
/* if not restored, we keep the binded opengl index */
|
||||
if(ima->ibufs.first==NULL)
|
||||
if(ima->ibufs.first==NULL) {
|
||||
ima->bindcode= 0;
|
||||
ima->gputexture= NULL;
|
||||
}
|
||||
|
||||
ima->anim= NULL;
|
||||
ima->rr= NULL;
|
||||
@ -2554,6 +2562,7 @@ static void direct_link_material(FileData *fd, Material *ma)
|
||||
direct_link_nodetree(fd, ma->nodetree);
|
||||
|
||||
ma->preview = direct_link_preview_image(fd, ma->preview);
|
||||
ma->gpumaterial.first = ma->gpumaterial.last = NULL;
|
||||
}
|
||||
|
||||
/* ************ READ PARTICLE SETTINGS ***************** */
|
||||
@ -3393,6 +3402,7 @@ static void direct_link_object(FileData *fd, Object *ob)
|
||||
ob->bb= NULL;
|
||||
ob->derivedDeform= NULL;
|
||||
ob->derivedFinal= NULL;
|
||||
ob->gpulamp.first= ob->gpulamp.last= NULL;
|
||||
}
|
||||
|
||||
/* ************ READ SCENE ***************** */
|
||||
|
@ -1853,6 +1853,7 @@ static void write_texts(WriteData *wd, ListBase *idbase)
|
||||
{
|
||||
Text *text;
|
||||
TextLine *tmp;
|
||||
TextMarker *mrk;
|
||||
|
||||
text= idbase->first;
|
||||
while(text) {
|
||||
@ -1876,7 +1877,16 @@ static void write_texts(WriteData *wd, ListBase *idbase)
|
||||
writedata(wd, DATA, tmp->len+1, tmp->line);
|
||||
tmp= tmp->next;
|
||||
}
|
||||
|
||||
/* write markers */
|
||||
mrk= text->markers.first;
|
||||
while (mrk) {
|
||||
writestruct(wd, DATA, "TextMarker", 1, mrk);
|
||||
mrk= mrk->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
text= text->id.next;
|
||||
}
|
||||
|
||||
|
34
source/blender/gpu/CMakeLists.txt
Normal file
34
source/blender/gpu/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
# $Id: CMakeLists.txt 14444 2008-04-16 22:40:48Z hos $
|
||||
# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2006, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Jacques Beaurain.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
FILE(GLOB SRC intern/*.c)
|
||||
|
||||
SET(INC
|
||||
. ../blenlib ../blenkernel ../makesdna ../include
|
||||
../../../extern/glew/include ../../../intern/guardedalloc ../imbuf)
|
||||
|
||||
BLENDERLIB(bf_gpu "${SRC}" "${INC}")
|
||||
|
116
source/blender/gpu/GPU_draw.h
Normal file
116
source/blender/gpu/GPU_draw.h
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef GPU_GAME_H
|
||||
#define GPU_GAME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct MTFace;
|
||||
struct Image;
|
||||
struct Scene;
|
||||
struct Object;
|
||||
|
||||
/* OpenGL drawing functions related to shading. These are also
|
||||
* shared with the game engine, where there were previously
|
||||
* duplicates of some of these functions. */
|
||||
|
||||
/* Initialize
|
||||
* - sets the default Blender opengl state, if in doubt, check
|
||||
* the contents of this function
|
||||
* - this is called when starting Blender, for opengl rendering,
|
||||
* and for switching back from the game engine for example. */
|
||||
|
||||
void GPU_state_init(void);
|
||||
|
||||
/* Material drawing
|
||||
* - first the state is initialized by a particular object and
|
||||
* it's materials
|
||||
* - after this, materials can be quickly enabled by their number,
|
||||
* GPU_enable_material returns 0 if drawing should be skipped
|
||||
* - after drawing, the material must be disabled again */
|
||||
|
||||
void GPU_set_object_materials(struct Scene *scene, struct Object *ob,
|
||||
int glsl, int *do_alpha_pass);
|
||||
int GPU_enable_material(int nr, void *attribs);
|
||||
void GPU_disable_material(void);
|
||||
|
||||
void GPU_set_material_blend_mode(int blendmode);
|
||||
int GPU_get_material_blend_mode(void);
|
||||
|
||||
/* TexFace drawing
|
||||
* - this is mutually exclusive with material drawing, a mesh should
|
||||
* be drawn using one or the other
|
||||
* - passing NULL clears the state again */
|
||||
|
||||
int GPU_set_tpage(struct MTFace *tface);
|
||||
|
||||
/* Lights
|
||||
* - returns how many lights were enabled
|
||||
* - this affects fixed functions materials and texface, not glsl */
|
||||
|
||||
int GPU_default_lights(void);
|
||||
int GPU_scene_object_lights(struct Scene *scene, struct Object *ob,
|
||||
int lay, float viewmat[][4]);
|
||||
|
||||
/* Text render
|
||||
* - based on moving uv coordinates */
|
||||
|
||||
void GPU_render_text(struct MTFace *tface, int mode,
|
||||
const char *textstr, int textlen, unsigned int *col,
|
||||
float *v1, float *v2, float *v3, float *v4, int glattrib);
|
||||
|
||||
/* Mipmap settings
|
||||
* - these will free textures on changes */
|
||||
|
||||
void GPU_set_mipmap(int mipmap);
|
||||
void GPU_set_linear_mipmap(int linear);
|
||||
void GPU_paint_set_mipmap(int mipmap);
|
||||
|
||||
/* Image updates and free
|
||||
* - these deal with images bound as opengl textures */
|
||||
|
||||
void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h);
|
||||
void GPU_update_images_framechange(void);
|
||||
int GPU_update_image_time(struct Image *ima, double time);
|
||||
int GPU_verify_image(struct Image *ima, int tftile, int tfmode, int compare);
|
||||
void GPU_free_image(struct Image *ima);
|
||||
void GPU_free_images(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
144
source/blender/gpu/GPU_extensions.h
Normal file
144
source/blender/gpu/GPU_extensions.h
Normal file
@ -0,0 +1,144 @@
|
||||
/**
|
||||
* $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef GPU_EXTENSIONS_H
|
||||
#define GPU_EXTENSIONS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* GPU extensions support */
|
||||
|
||||
struct Image;
|
||||
struct ImageUser;
|
||||
|
||||
struct GPUTexture;
|
||||
typedef struct GPUTexture GPUTexture;
|
||||
|
||||
struct GPUFrameBuffer;
|
||||
typedef struct GPUFrameBuffer GPUFrameBuffer;
|
||||
|
||||
struct GPUShader;
|
||||
typedef struct GPUShader GPUShader;
|
||||
|
||||
void GPU_extensions_init(void); /* call this before running any of the functions below */
|
||||
void GPU_extensions_exit(void);
|
||||
int GPU_extensions_minimum_support(void);
|
||||
int GPU_print_error(char *str);
|
||||
|
||||
/* GPU Texture
|
||||
- always returns unsigned char RGBA textures
|
||||
- if texture with non square dimensions is created, depending on the
|
||||
graphics card capabilities the texture may actually be stored in a
|
||||
larger texture with power of two dimensions. the actual dimensions
|
||||
may be querd with GPU_texture_opengl_width/height. GPU_texture_coord_2f
|
||||
calls glTexCoord2f with the coordinates adjust for this.
|
||||
- can use reference counting:
|
||||
- reference counter after GPU_texture_create is 1
|
||||
- GPU_texture_ref increases by one
|
||||
- GPU_texture_free decreases by one, and frees if 0
|
||||
- if created with from_blender, will not free the texture
|
||||
*/
|
||||
|
||||
GPUTexture *GPU_texture_create_1D(int w, float *pixels);
|
||||
GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels);
|
||||
GPUTexture *GPU_texture_create_depth(int w, int h);
|
||||
GPUTexture *GPU_texture_from_blender(struct Image *ima,
|
||||
struct ImageUser *iuser, double time);
|
||||
void GPU_texture_free(GPUTexture *tex);
|
||||
|
||||
void GPU_texture_ref(GPUTexture *tex);
|
||||
|
||||
void GPU_texture_bind(GPUTexture *tex, int number);
|
||||
void GPU_texture_unbind(GPUTexture *tex);
|
||||
|
||||
GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
|
||||
|
||||
int GPU_texture_target(GPUTexture *tex);
|
||||
int GPU_texture_opengl_width(GPUTexture *tex);
|
||||
int GPU_texture_opengl_height(GPUTexture *tex);
|
||||
|
||||
/* GPU Framebuffer
|
||||
- this is a wrapper for an OpenGL framebuffer object (FBO). in practice
|
||||
multiple FBO's may be created, to get around limitations on the number
|
||||
of attached textures and the dimension requirements.
|
||||
- after any of the GPU_framebuffer_* functions, GPU_framebuffer_restore must
|
||||
be called before rendering to the window framebuffer again */
|
||||
|
||||
GPUFrameBuffer *GPU_framebuffer_create();
|
||||
int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex);
|
||||
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex);
|
||||
void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex);
|
||||
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex);
|
||||
void GPU_framebuffer_free(GPUFrameBuffer *fb);
|
||||
|
||||
void GPU_framebuffer_restore();
|
||||
|
||||
/* GPU Shader
|
||||
- only for fragment shaders now
|
||||
- must call texture bind before setting a texture as uniform! */
|
||||
|
||||
GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, GPUShader *lib);
|
||||
GPUShader *GPU_shader_create_lib(const char *code);
|
||||
void GPU_shader_free(GPUShader *shader);
|
||||
|
||||
void GPU_shader_bind(GPUShader *shader);
|
||||
void GPU_shader_unbind();
|
||||
|
||||
int GPU_shader_get_uniform(GPUShader *shader, char *name);
|
||||
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length,
|
||||
int arraysize, float *value);
|
||||
void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex);
|
||||
|
||||
int GPU_shader_get_attribute(GPUShader *shader, char *name);
|
||||
|
||||
/* Vertex attributes for shaders */
|
||||
|
||||
#define GPU_MAX_ATTRIB 32
|
||||
|
||||
typedef struct GPUVertexAttribs {
|
||||
struct {
|
||||
int type;
|
||||
int glindex;
|
||||
char name[32];
|
||||
} layer[GPU_MAX_ATTRIB];
|
||||
|
||||
int totlayer;
|
||||
} GPUVertexAttribs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
169
source/blender/gpu/GPU_material.h
Normal file
169
source/blender/gpu/GPU_material.h
Normal file
@ -0,0 +1,169 @@
|
||||
/**
|
||||
* $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __GPU_MATERIAL__
|
||||
#define __GPU_MATERIAL__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Image;
|
||||
struct ImageUser;
|
||||
struct Material;
|
||||
struct Object;
|
||||
struct Lamp;
|
||||
struct bNode;
|
||||
struct LinkNode;
|
||||
struct Scene;
|
||||
struct GPUVertexAttribs;
|
||||
struct GPUNode;
|
||||
struct GPUNodeLink;
|
||||
struct GPUNodeStack;
|
||||
struct GPUMaterial;
|
||||
struct GPUTexture;
|
||||
struct GPULamp;
|
||||
|
||||
typedef struct GPUNode GPUNode;
|
||||
typedef struct GPUNodeLink GPUNodeLink;
|
||||
typedef struct GPUMaterial GPUMaterial;
|
||||
typedef struct GPULamp GPULamp;
|
||||
|
||||
/* Functions to create GPU Materials nodes */
|
||||
|
||||
typedef enum GPUType {
|
||||
GPU_NONE = 0,
|
||||
GPU_FLOAT = 1,
|
||||
GPU_VEC2 = 2,
|
||||
GPU_VEC3 = 3,
|
||||
GPU_VEC4 = 4,
|
||||
GPU_MAT3 = 9,
|
||||
GPU_MAT4 = 16,
|
||||
GPU_TEX1D = 1001,
|
||||
GPU_TEX2D = 1002,
|
||||
GPU_SHADOW2D = 1003,
|
||||
GPU_ATTRIB = 3001
|
||||
} GPUType;
|
||||
|
||||
typedef enum GPUBuiltin {
|
||||
GPU_VIEW_MATRIX = 1,
|
||||
GPU_OBJECT_MATRIX = 2,
|
||||
GPU_INVERSE_VIEW_MATRIX = 4,
|
||||
GPU_INVERSE_OBJECT_MATRIX = 8,
|
||||
GPU_VIEW_POSITION = 16,
|
||||
GPU_VIEW_NORMAL = 32,
|
||||
GPU_OBCOLOR = 64
|
||||
} GPUBuiltin;
|
||||
|
||||
typedef enum GPUBlendMode {
|
||||
GPU_BLEND_SOLID = 0,
|
||||
GPU_BLEND_ADD = 1,
|
||||
GPU_BLEND_ALPHA = 2,
|
||||
GPU_BLEND_CLIP = 4
|
||||
} GPUBlendMode;
|
||||
|
||||
typedef struct GPUNodeStack {
|
||||
GPUType type;
|
||||
char *name;
|
||||
float vec[4];
|
||||
struct GPUNodeLink *link;
|
||||
short hasinput;
|
||||
short hasoutput;
|
||||
short sockettype;
|
||||
} GPUNodeStack;
|
||||
|
||||
GPUNodeLink *GPU_attribute(int type, char *name);
|
||||
GPUNodeLink *GPU_uniform(float *num);
|
||||
GPUNodeLink *GPU_dynamic_uniform(float *num);
|
||||
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser);
|
||||
GPUNodeLink *GPU_texture(int size, float *pixels);
|
||||
GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex);
|
||||
GPUNodeLink *GPU_socket(GPUNodeStack *sock);
|
||||
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
|
||||
|
||||
int GPU_link(GPUMaterial *mat, char *name, ...);
|
||||
int GPU_stack_link(GPUMaterial *mat, char *name, GPUNodeStack *in, GPUNodeStack *out, ...);
|
||||
|
||||
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
|
||||
void GPU_material_enable_alpha(GPUMaterial *material);
|
||||
GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4]);
|
||||
|
||||
/* High level functions to create and use GPU materials */
|
||||
|
||||
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma);
|
||||
void GPU_material_free(struct Material *ma);
|
||||
|
||||
void GPU_materials_free();
|
||||
|
||||
void GPU_material_bind(GPUMaterial *material, int lay, double time);
|
||||
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4]);
|
||||
void GPU_material_unbind(GPUMaterial *material);
|
||||
int GPU_material_bound(GPUMaterial *material);
|
||||
|
||||
void GPU_material_vertex_attributes(GPUMaterial *material,
|
||||
struct GPUVertexAttribs *attrib);
|
||||
|
||||
/* Exported shading */
|
||||
|
||||
typedef struct GPUShadeInput {
|
||||
GPUMaterial *gpumat;
|
||||
struct Material *mat;
|
||||
|
||||
GPUNodeLink *rgb, *specrgb, *vn, *view, *vcol, *ref;
|
||||
GPUNodeLink *alpha, *refl, *spec, *emit, *har, *amb;
|
||||
} GPUShadeInput;
|
||||
|
||||
typedef struct GPUShadeResult {
|
||||
GPUNodeLink *diff, *spec, *combined, *alpha;
|
||||
} GPUShadeResult;
|
||||
|
||||
void GPU_shadeinput_set(GPUMaterial *mat, struct Material *ma, GPUShadeInput *shi);
|
||||
void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr);
|
||||
|
||||
/* Lamps */
|
||||
|
||||
GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
|
||||
void GPU_lamp_free(struct Object *ob);
|
||||
|
||||
int GPU_lamp_has_shadow_buffer(GPULamp *lamp);
|
||||
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]);
|
||||
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
|
||||
|
||||
void GPU_lamp_update(GPULamp *lamp, float obmat[][4]);
|
||||
int GPU_lamp_shadow_layer(GPULamp *lamp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__GPU_MATERIAL__*/
|
||||
|
37
source/blender/gpu/Makefile
Normal file
37
source/blender/gpu/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL/BL DUAL 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. 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
#
|
||||
# Makes module object directory and bounces make to subdirectories.
|
||||
|
||||
SOURCEDIR = source/blender/gpu
|
||||
DIRS = intern
|
||||
|
||||
include nan_subdirs.mk
|
11
source/blender/gpu/SConscript
Normal file
11
source/blender/gpu/SConscript
Normal file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('intern/*.c')
|
||||
|
||||
incs = '../blenlib ../blenkernel ../makesdna ../include'
|
||||
incs += ' #/extern/glew/include #intern/guardedalloc ../imbuf .'
|
||||
|
||||
incs += ' ' + env['BF_OPENGL_INC']
|
||||
|
||||
env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core', 'player'], priority=[65, 20] )
|
53
source/blender/gpu/intern/Makefile
Normal file
53
source/blender/gpu/intern/Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL/BL DUAL 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. 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
#
|
||||
|
||||
LIBNAME = gpu
|
||||
DIR = $(OCGDIR)/blender/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
|
||||
CFLAGS += -funsigned-char
|
||||
endif
|
||||
|
||||
CFLAGS += $(LEVEL_1_C_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I$(OPENGL_HEADERS)
|
||||
|
||||
CPPFLAGS += -I../../blenlib
|
||||
CPPFLAGS += -I../../makesdna
|
||||
CPPFLAGS += -I../../imbuf
|
||||
CPPFLAGS += -I../../blenkernel
|
||||
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
||||
CPPFLAGS += -I$(NAN_GLEW)/include
|
||||
CPPFLAGS += -I../
|
||||
|
1439
source/blender/gpu/intern/gpu_codegen.c
Normal file
1439
source/blender/gpu/intern/gpu_codegen.c
Normal file
File diff suppressed because it is too large
Load Diff
87
source/blender/gpu/intern/gpu_codegen.h
Normal file
87
source/blender/gpu/intern/gpu_codegen.h
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* $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. 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __GPU_CODEGEN_H__
|
||||
#define __GPU_CODEGEN_H__
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
struct ListBase;
|
||||
struct GPUShader;
|
||||
struct GPUOutput;
|
||||
struct GPUNode;
|
||||
struct GPUVertexAttribs;
|
||||
|
||||
#define MAX_FUNCTION_NAME 64
|
||||
#define MAX_PARAMETER 32
|
||||
|
||||
#define FUNCTION_QUAL_IN 0
|
||||
#define FUNCTION_QUAL_OUT 1
|
||||
#define FUNCTION_QUAL_INOUT 2
|
||||
|
||||
typedef struct GPUFunction {
|
||||
char name[MAX_FUNCTION_NAME];
|
||||
int paramtype[MAX_PARAMETER];
|
||||
int paramqual[MAX_PARAMETER];
|
||||
int totparam;
|
||||
} GPUFunction;
|
||||
|
||||
GPUFunction *GPU_lookup_function(char *name);
|
||||
|
||||
/* Pass Generation
|
||||
- Takes a list of nodes and a desired output, and makes a pass. This
|
||||
will take ownership of the nodes and free them early if unused or
|
||||
at the end if used.
|
||||
*/
|
||||
|
||||
struct GPUPass;
|
||||
typedef struct GPUPass GPUPass;
|
||||
|
||||
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
|
||||
struct GPUVertexAttribs *attribs, int *builtin, const char *name);
|
||||
|
||||
struct GPUShader *GPU_pass_shader(GPUPass *pass);
|
||||
|
||||
void GPU_pass_bind(GPUPass *pass, double time);
|
||||
void GPU_pass_update_uniforms(GPUPass *pass);
|
||||
void GPU_pass_unbind(GPUPass *pass);
|
||||
|
||||
void GPU_pass_free(GPUPass *pass);
|
||||
|
||||
/* Material calls */
|
||||
|
||||
char *GPU_builtin_name(GPUBuiltin builtin);
|
||||
void gpu_material_add_node(struct GPUMaterial *material, struct GPUNode *node);
|
||||
int GPU_link_changed(struct GPUNodeLink *link);
|
||||
|
||||
#endif
|
||||
|
1167
source/blender/gpu/intern/gpu_draw.c
Normal file
1167
source/blender/gpu/intern/gpu_draw.c
Normal file
File diff suppressed because it is too large
Load Diff
987
source/blender/gpu/intern/gpu_extensions.c
Normal file
987
source/blender/gpu/intern/gpu_extensions.c
Normal file
@ -0,0 +1,987 @@
|
||||
/**
|
||||
* $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. 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Extensions support */
|
||||
|
||||
/* extensions used:
|
||||
- texture border clamp: 1.3 core
|
||||
- fragement shader: 2.0 core
|
||||
- framebuffer object: ext specification
|
||||
- multitexture 1.3 core
|
||||
- arb non power of two: 2.0 core
|
||||
- pixel buffer objects? 2.1 core
|
||||
- arb draw buffers? 2.0 core
|
||||
*/
|
||||
|
||||
struct GPUGlobal {
|
||||
GLint maxtextures;
|
||||
GLuint currentfb;
|
||||
int minimumsupport;
|
||||
} GG = {1, 0, 0};
|
||||
|
||||
void GPU_extensions_init()
|
||||
{
|
||||
glewInit();
|
||||
|
||||
/* glewIsSupported("GL_VERSION_2_0") */
|
||||
|
||||
if (GLEW_ARB_multitexture)
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &GG.maxtextures);
|
||||
|
||||
GG.minimumsupport = 1;
|
||||
if (!GLEW_ARB_multitexture) GG.minimumsupport = 0;
|
||||
if (!GLEW_ARB_vertex_shader) GG.minimumsupport = 0;
|
||||
if (!GLEW_ARB_fragment_shader) GG.minimumsupport = 0;
|
||||
}
|
||||
|
||||
int GPU_extensions_minimum_support()
|
||||
{
|
||||
return GG.minimumsupport;
|
||||
}
|
||||
|
||||
int GPU_print_error(char *str)
|
||||
{
|
||||
GLenum errCode;
|
||||
|
||||
if (G.f & G_DEBUG) {
|
||||
if ((errCode = glGetError()) != GL_NO_ERROR) {
|
||||
fprintf(stderr, "%s opengl error: %s\n", str, gluErrorString(errCode));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void GPU_print_framebuffer_error(GLenum status)
|
||||
{
|
||||
fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d\n",
|
||||
(int)status);
|
||||
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
fprintf(stderr, "Incomplete attachment.\n");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
fprintf(stderr, "Unsupported framebuffer format.\n");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||
fprintf(stderr, "Missing attachment.\n");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
||||
fprintf(stderr, "Attached images must have same dimensions.\n");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
||||
fprintf(stderr, "Attached images must have same format.\n");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||
fprintf(stderr, "Missing draw buffer.\n");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||
fprintf(stderr, "Missing read buffer.\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* GPUTexture */
|
||||
|
||||
struct GPUTexture {
|
||||
int w, h; /* width/height */
|
||||
int number; /* number for multitexture binding */
|
||||
int refcount; /* reference count */
|
||||
GLenum target; /* GL_TEXTURE_* */
|
||||
GLuint bindcode; /* opengl identifier for texture */
|
||||
int fromblender; /* we got the texture from Blender */
|
||||
|
||||
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
|
||||
int depth; /* is a depth texture? */
|
||||
};
|
||||
|
||||
#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
|
||||
static unsigned char *GPU_texture_convert_pixels(int length, float *fpixels)
|
||||
{
|
||||
unsigned char *pixels, *p;
|
||||
float *fp;
|
||||
int a, len;
|
||||
|
||||
len = 4*length;
|
||||
fp = fpixels;
|
||||
p = pixels = MEM_callocN(sizeof(unsigned char)*len, "GPUTexturePixels");
|
||||
|
||||
for (a=0; a<len; a++, p++, fp++)
|
||||
*p = FTOCHAR((*fp));
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
static int is_pow2(int n)
|
||||
{
|
||||
return ((n)&(n-1))==0;
|
||||
}
|
||||
|
||||
static int larger_pow2(int n)
|
||||
{
|
||||
if (is_pow2(n))
|
||||
return n;
|
||||
|
||||
while(!is_pow2(n))
|
||||
n= n&(n-1);
|
||||
|
||||
return n*2;
|
||||
}
|
||||
|
||||
static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
|
||||
{
|
||||
void *pixels = MEM_callocN(sizeof(char)*4*w*h, "GPUTextureEmptyPixels");
|
||||
|
||||
if (target == GL_TEXTURE_1D)
|
||||
glTexSubImage1D(target, 0, x, w, format, GL_UNSIGNED_BYTE, pixels);
|
||||
else
|
||||
glTexSubImage2D(target, 0, x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
MEM_freeN(pixels);
|
||||
}
|
||||
|
||||
static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, int depth)
|
||||
{
|
||||
GPUTexture *tex;
|
||||
GLenum type, format, internalformat;
|
||||
void *pixels = NULL;
|
||||
|
||||
if(depth && !GLEW_ARB_depth_texture)
|
||||
return NULL;
|
||||
|
||||
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
|
||||
tex->w = w;
|
||||
tex->h = h;
|
||||
tex->number = -1;
|
||||
tex->refcount = 1;
|
||||
tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D;
|
||||
tex->depth = depth;
|
||||
|
||||
glGenTextures(1, &tex->bindcode);
|
||||
|
||||
if (!tex->bindcode) {
|
||||
fprintf(stderr, "GPUTexture: texture create failed: %d\n",
|
||||
(int)glGetError());
|
||||
GPU_texture_free(tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!GLEW_ARB_texture_non_power_of_two) {
|
||||
tex->w = larger_pow2(tex->w);
|
||||
tex->h = larger_pow2(tex->h);
|
||||
}
|
||||
|
||||
tex->number = 0;
|
||||
glBindTexture(tex->target, tex->bindcode);
|
||||
|
||||
if(depth) {
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
format = GL_DEPTH_COMPONENT;
|
||||
internalformat = GL_DEPTH_COMPONENT;
|
||||
}
|
||||
else {
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
format = GL_RGBA;
|
||||
internalformat = GL_RGBA8;
|
||||
|
||||
if (fpixels)
|
||||
pixels = GPU_texture_convert_pixels(w*h, fpixels);
|
||||
}
|
||||
|
||||
if (tex->target == GL_TEXTURE_1D) {
|
||||
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, type, 0);
|
||||
|
||||
if (fpixels) {
|
||||
glTexSubImage1D(tex->target, 0, 0, w, format, type,
|
||||
pixels? pixels: fpixels);
|
||||
|
||||
if (tex->w > w)
|
||||
GPU_glTexSubImageEmpty(tex->target, format, w, 0,
|
||||
tex->w-w, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0,
|
||||
format, type, 0);
|
||||
|
||||
if (fpixels) {
|
||||
glTexSubImage2D(tex->target, 0, 0, 0, w, h,
|
||||
format, type, pixels? pixels: fpixels);
|
||||
|
||||
if (tex->w > w)
|
||||
GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h);
|
||||
if (tex->h > h)
|
||||
GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h);
|
||||
}
|
||||
}
|
||||
|
||||
if (pixels)
|
||||
MEM_freeN(pixels);
|
||||
|
||||
if(depth) {
|
||||
glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(tex->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
|
||||
glTexParameteri(tex->target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
glTexParameteri(tex->target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
|
||||
}
|
||||
else {
|
||||
glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
if (tex->target != GL_TEXTURE_1D) {
|
||||
/* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */
|
||||
GLenum wrapmode = (depth)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER;
|
||||
glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode);
|
||||
glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode);
|
||||
|
||||
#if 0
|
||||
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, double time)
|
||||
{
|
||||
GPUTexture *tex;
|
||||
GLint w, h, border, lastbindcode, bindcode;
|
||||
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
|
||||
|
||||
GPU_update_image_time(ima, time);
|
||||
bindcode = GPU_verify_image(ima, 0, 0, 0);
|
||||
|
||||
if(ima->gputexture) {
|
||||
ima->gputexture->bindcode = bindcode;
|
||||
glBindTexture(GL_TEXTURE_2D, lastbindcode);
|
||||
return ima->gputexture;
|
||||
}
|
||||
|
||||
if(!bindcode) {
|
||||
glBindTexture(GL_TEXTURE_2D, lastbindcode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
|
||||
tex->bindcode = bindcode;
|
||||
tex->number = -1;
|
||||
tex->refcount = 1;
|
||||
tex->target = GL_TEXTURE_2D;
|
||||
tex->fromblender = 1;
|
||||
|
||||
ima->gputexture= tex;
|
||||
|
||||
if (!glIsTexture(tex->bindcode)) {
|
||||
GPU_print_error("Blender Texture");
|
||||
}
|
||||
else {
|
||||
glBindTexture(GL_TEXTURE_2D, tex->bindcode);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
|
||||
|
||||
tex->w = w - border;
|
||||
tex->h = h - border;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, lastbindcode);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_create_1D(int w, float *fpixels)
|
||||
{
|
||||
GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0);
|
||||
|
||||
if (tex)
|
||||
GPU_texture_unbind(tex);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels)
|
||||
{
|
||||
GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0);
|
||||
|
||||
if (tex)
|
||||
GPU_texture_unbind(tex);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_create_depth(int w, int h)
|
||||
{
|
||||
GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1);
|
||||
|
||||
if (tex)
|
||||
GPU_texture_unbind(tex);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void GPU_texture_bind(GPUTexture *tex, int number)
|
||||
{
|
||||
GLenum arbnumber;
|
||||
|
||||
if (number >= GG.maxtextures) {
|
||||
GPU_print_error("Not enough texture slots.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(number == -1)
|
||||
return;
|
||||
|
||||
GPU_print_error("Pre Texture Bind");
|
||||
|
||||
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + number);
|
||||
if (number != 0) glActiveTextureARB(arbnumber);
|
||||
glBindTexture(tex->target, tex->bindcode);
|
||||
glEnable(tex->target);
|
||||
if (number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
tex->number = number;
|
||||
|
||||
GPU_print_error("Post Texture Bind");
|
||||
}
|
||||
|
||||
void GPU_texture_unbind(GPUTexture *tex)
|
||||
{
|
||||
GLenum arbnumber;
|
||||
|
||||
if (tex->number >= GG.maxtextures) {
|
||||
GPU_print_error("Not enough texture slots.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(tex->number == -1)
|
||||
return;
|
||||
|
||||
GPU_print_error("Pre Texture Unbind");
|
||||
|
||||
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
|
||||
if (tex->number != 0) glActiveTextureARB(arbnumber);
|
||||
glBindTexture(tex->target, 0);
|
||||
glDisable(tex->target);
|
||||
if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
tex->number = -1;
|
||||
|
||||
GPU_print_error("Post Texture Unbind");
|
||||
}
|
||||
|
||||
void GPU_texture_free(GPUTexture *tex)
|
||||
{
|
||||
tex->refcount--;
|
||||
|
||||
if (tex->refcount < 0)
|
||||
fprintf(stderr, "GPUTexture: negative refcount\n");
|
||||
|
||||
if (tex->refcount == 0) {
|
||||
if (tex->fb)
|
||||
GPU_framebuffer_texture_detach(tex->fb, tex);
|
||||
if (tex->bindcode && !tex->fromblender)
|
||||
glDeleteTextures(1, &tex->bindcode);
|
||||
|
||||
MEM_freeN(tex);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_texture_ref(GPUTexture *tex)
|
||||
{
|
||||
tex->refcount++;
|
||||
}
|
||||
|
||||
int GPU_texture_target(GPUTexture *tex)
|
||||
{
|
||||
return tex->target;
|
||||
}
|
||||
|
||||
int GPU_texture_opengl_width(GPUTexture *tex)
|
||||
{
|
||||
return tex->w;
|
||||
}
|
||||
|
||||
int GPU_texture_opengl_height(GPUTexture *tex)
|
||||
{
|
||||
return tex->h;
|
||||
}
|
||||
|
||||
GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
|
||||
{
|
||||
return tex->fb;
|
||||
}
|
||||
|
||||
/* GPUFrameBuffer */
|
||||
|
||||
struct GPUFrameBuffer {
|
||||
GLuint object;
|
||||
GPUTexture *colortex;
|
||||
GPUTexture *depthtex;
|
||||
};
|
||||
|
||||
GPUFrameBuffer *GPU_framebuffer_create()
|
||||
{
|
||||
GPUFrameBuffer *fb;
|
||||
|
||||
if (!GLEW_EXT_framebuffer_object)
|
||||
return NULL;
|
||||
|
||||
fb= MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
|
||||
glGenFramebuffersEXT(1, &fb->object);
|
||||
|
||||
if (!fb->object) {
|
||||
fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
|
||||
(int)glGetError());
|
||||
GPU_framebuffer_free(fb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
||||
int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex)
|
||||
{
|
||||
GLenum status;
|
||||
GLenum attachment;
|
||||
|
||||
if(tex->depth)
|
||||
attachment = GL_DEPTH_ATTACHMENT_EXT;
|
||||
else
|
||||
attachment = GL_COLOR_ATTACHMENT0_EXT;
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
|
||||
GG.currentfb = fb->object;
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
tex->target, tex->bindcode, 0);
|
||||
|
||||
if(tex->depth) {
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
else {
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
GPU_framebuffer_restore();
|
||||
GPU_print_framebuffer_error(status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(tex->depth)
|
||||
fb->depthtex = tex;
|
||||
else
|
||||
fb->colortex = tex;
|
||||
|
||||
tex->fb= fb;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
|
||||
{
|
||||
GLenum attachment;
|
||||
|
||||
if(!tex->fb)
|
||||
return;
|
||||
|
||||
if(GG.currentfb != tex->fb->object) {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
|
||||
GG.currentfb = tex->fb->object;
|
||||
}
|
||||
|
||||
if(tex->depth) {
|
||||
fb->depthtex = NULL;
|
||||
attachment = GL_DEPTH_ATTACHMENT_EXT;
|
||||
}
|
||||
else {
|
||||
fb->colortex = NULL;
|
||||
attachment = GL_COLOR_ATTACHMENT0_EXT;
|
||||
}
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
|
||||
tex->target, 0, 0);
|
||||
|
||||
tex->fb = NULL;
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex)
|
||||
{
|
||||
/* push attributes */
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
/* bind framebuffer */
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
|
||||
|
||||
/* push matrices and set default viewport and matrix */
|
||||
glViewport(0, 0, tex->w, tex->h);
|
||||
GG.currentfb = tex->fb->object;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex)
|
||||
{
|
||||
/* restore matrix */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
/* restore attributes */
|
||||
glPopAttrib();
|
||||
glPopAttrib();
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_free(GPUFrameBuffer *fb)
|
||||
{
|
||||
if(fb->depthtex)
|
||||
GPU_framebuffer_texture_detach(fb, fb->depthtex);
|
||||
if(fb->colortex)
|
||||
GPU_framebuffer_texture_detach(fb, fb->colortex);
|
||||
|
||||
if(fb->object) {
|
||||
glDeleteFramebuffersEXT(1, &fb->object);
|
||||
|
||||
if (GG.currentfb == fb->object) {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
GG.currentfb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(fb);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_restore()
|
||||
{
|
||||
if (GG.currentfb != 0) {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
GG.currentfb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* GPUShader */
|
||||
|
||||
struct GPUShader {
|
||||
GLhandleARB object; /* handle for full shader */
|
||||
GLhandleARB vertex; /* handle for vertex shader */
|
||||
GLhandleARB fragment; /* handle for fragment shader */
|
||||
GLhandleARB lib; /* handle for libment shader */
|
||||
int totattrib; /* total number of attributes */
|
||||
};
|
||||
|
||||
static void shader_print_errors(char *task, char *log, const char *code)
|
||||
{
|
||||
const char *c, *pos, *end = code + strlen(code);
|
||||
int line = 1;
|
||||
|
||||
fprintf(stderr, "GPUShader: %s error:\n", task);
|
||||
|
||||
if(G.f & G_DEBUG) {
|
||||
c = code;
|
||||
while ((c < end) && (pos = strchr(c, '\n'))) {
|
||||
fprintf(stderr, "%2d ", line);
|
||||
fwrite(c, (pos+1)-c, 1, stderr);
|
||||
c = pos+1;
|
||||
line++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s", c);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", log);
|
||||
}
|
||||
|
||||
GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, GPUShader *lib)
|
||||
{
|
||||
GLint status;
|
||||
GLcharARB log[5000];
|
||||
GLsizei length = 0;
|
||||
GPUShader *shader;
|
||||
|
||||
if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
|
||||
return NULL;
|
||||
|
||||
shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
|
||||
|
||||
if(vertexcode)
|
||||
shader->vertex = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
||||
if(fragcode)
|
||||
shader->fragment = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
shader->object = glCreateProgramObjectARB();
|
||||
|
||||
if (!shader->object ||
|
||||
(vertexcode && !shader->vertex) ||
|
||||
(fragcode && !shader->fragment)) {
|
||||
fprintf(stderr, "GPUShader, object creation failed.\n");
|
||||
GPU_shader_free(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(lib && lib->lib)
|
||||
glAttachObjectARB(shader->object, lib->lib);
|
||||
|
||||
if(vertexcode) {
|
||||
glAttachObjectARB(shader->object, shader->vertex);
|
||||
glShaderSourceARB(shader->vertex, 1, (const char**)&vertexcode, NULL);
|
||||
|
||||
glCompileShaderARB(shader->vertex);
|
||||
glGetObjectParameterivARB(shader->vertex, GL_OBJECT_COMPILE_STATUS_ARB, &status);
|
||||
|
||||
if (!status) {
|
||||
glValidateProgramARB(shader->vertex);
|
||||
glGetInfoLogARB(shader->vertex, sizeof(log), &length, log);
|
||||
shader_print_errors("compile", log, vertexcode);
|
||||
|
||||
GPU_shader_free(shader);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(fragcode) {
|
||||
glAttachObjectARB(shader->object, shader->fragment);
|
||||
glShaderSourceARB(shader->fragment, 1, (const char**)&fragcode, NULL);
|
||||
|
||||
glCompileShaderARB(shader->fragment);
|
||||
glGetObjectParameterivARB(shader->fragment, GL_OBJECT_COMPILE_STATUS_ARB, &status);
|
||||
|
||||
if (!status) {
|
||||
glValidateProgramARB(shader->fragment);
|
||||
glGetInfoLogARB(shader->fragment, sizeof(log), &length, log);
|
||||
shader_print_errors("compile", log, fragcode);
|
||||
|
||||
GPU_shader_free(shader);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
glLinkProgramARB(shader->object);
|
||||
glGetObjectParameterivARB(shader->object, GL_OBJECT_LINK_STATUS_ARB, &status);
|
||||
if (!status) {
|
||||
glGetInfoLogARB(shader->object, sizeof(log), &length, log);
|
||||
shader_print_errors("linking", log, fragcode);
|
||||
|
||||
GPU_shader_free(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GPUShader *GPU_shader_create_lib(const char *code)
|
||||
{
|
||||
GLint status;
|
||||
GLcharARB log[5000];
|
||||
GLsizei length = 0;
|
||||
GPUShader *shader;
|
||||
|
||||
if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
|
||||
return NULL;
|
||||
|
||||
shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
|
||||
|
||||
shader->lib = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
|
||||
if (!shader->lib) {
|
||||
fprintf(stderr, "GPUShader, object creation failed.\n");
|
||||
GPU_shader_free(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glShaderSourceARB(shader->lib, 1, (const char**)&code, NULL);
|
||||
|
||||
glCompileShaderARB(shader->lib);
|
||||
glGetObjectParameterivARB(shader->lib, GL_OBJECT_COMPILE_STATUS_ARB, &status);
|
||||
|
||||
if (!status) {
|
||||
glValidateProgramARB(shader->lib);
|
||||
glGetInfoLogARB(shader->lib, sizeof(log), &length, log);
|
||||
shader_print_errors("compile", log, code);
|
||||
|
||||
GPU_shader_free(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void GPU_shader_bind(GPUShader *shader)
|
||||
{
|
||||
GPU_print_error("Pre Shader Bind");
|
||||
glUseProgramObjectARB(shader->object);
|
||||
GPU_print_error("Post Shader Bind");
|
||||
}
|
||||
|
||||
void GPU_shader_unbind()
|
||||
{
|
||||
GPU_print_error("Pre Shader Unbind");
|
||||
glUseProgramObjectARB(0);
|
||||
GPU_print_error("Post Shader Unbind");
|
||||
}
|
||||
|
||||
void GPU_shader_free(GPUShader *shader)
|
||||
{
|
||||
if (shader->lib)
|
||||
glDeleteObjectARB(shader->lib);
|
||||
if (shader->vertex)
|
||||
glDeleteObjectARB(shader->vertex);
|
||||
if (shader->fragment)
|
||||
glDeleteObjectARB(shader->fragment);
|
||||
if (shader->object)
|
||||
glDeleteObjectARB(shader->object);
|
||||
MEM_freeN(shader);
|
||||
}
|
||||
|
||||
int GPU_shader_get_uniform(GPUShader *shader, char *name)
|
||||
{
|
||||
return glGetUniformLocationARB(shader->object, name);
|
||||
}
|
||||
|
||||
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length, int arraysize, float *value)
|
||||
{
|
||||
if(location == -1)
|
||||
return;
|
||||
|
||||
GPU_print_error("Pre Uniform Vector");
|
||||
|
||||
if (length == 1) glUniform1fvARB(location, arraysize, value);
|
||||
else if (length == 2) glUniform2fvARB(location, arraysize, value);
|
||||
else if (length == 3) glUniform3fvARB(location, arraysize, value);
|
||||
else if (length == 4) glUniform4fvARB(location, arraysize, value);
|
||||
else if (length == 9) glUniformMatrix3fvARB(location, arraysize, 0, value);
|
||||
else if (length == 16) glUniformMatrix4fvARB(location, arraysize, 0, value);
|
||||
|
||||
GPU_print_error("Post Uniform Vector");
|
||||
}
|
||||
|
||||
void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex)
|
||||
{
|
||||
GLenum arbnumber;
|
||||
|
||||
if (tex->number >= GG.maxtextures) {
|
||||
GPU_print_error("Not enough texture slots.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(tex->number == -1)
|
||||
return;
|
||||
|
||||
if(location == -1)
|
||||
return;
|
||||
|
||||
GPU_print_error("Pre Uniform Texture");
|
||||
|
||||
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
|
||||
|
||||
if (tex->number != 0) glActiveTextureARB(arbnumber);
|
||||
glBindTexture(tex->target, tex->bindcode);
|
||||
glUniform1iARB(location, tex->number);
|
||||
glEnable(tex->target);
|
||||
if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
GPU_print_error("Post Uniform Texture");
|
||||
}
|
||||
|
||||
int GPU_shader_get_attribute(GPUShader *shader, char *name)
|
||||
{
|
||||
int index;
|
||||
|
||||
GPU_print_error("Pre Get Attribute");
|
||||
|
||||
index = glGetAttribLocationARB(shader->object, name);
|
||||
|
||||
GPU_print_error("Post Get Attribute");
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* GPUPixelBuffer */
|
||||
|
||||
typedef struct GPUPixelBuffer {
|
||||
GLuint bindcode[2];
|
||||
GLuint current;
|
||||
int datasize;
|
||||
int numbuffers;
|
||||
int halffloat;
|
||||
} GPUPixelBuffer;
|
||||
|
||||
void GPU_pixelbuffer_free(GPUPixelBuffer *pb)
|
||||
{
|
||||
if (pb->bindcode[0])
|
||||
glDeleteBuffersARB(pb->numbuffers, pb->bindcode);
|
||||
MEM_freeN(pb);
|
||||
}
|
||||
|
||||
GPUPixelBuffer *gpu_pixelbuffer_create(int x, int y, int halffloat, int numbuffers)
|
||||
{
|
||||
GPUPixelBuffer *pb;
|
||||
|
||||
if (!GLEW_ARB_multitexture || !GLEW_EXT_pixel_buffer_object)
|
||||
return NULL;
|
||||
|
||||
pb = MEM_callocN(sizeof(GPUPixelBuffer), "GPUPBO");
|
||||
pb->datasize = x*y*4*((halffloat)? 16: 8);
|
||||
pb->numbuffers = numbuffers;
|
||||
pb->halffloat = halffloat;
|
||||
|
||||
glGenBuffersARB(pb->numbuffers, pb->bindcode);
|
||||
|
||||
if (!pb->bindcode[0]) {
|
||||
fprintf(stderr, "GPUPixelBuffer allocation failed\n");
|
||||
GPU_pixelbuffer_free(pb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pb;
|
||||
}
|
||||
|
||||
void GPU_pixelbuffer_texture(GPUTexture *tex, GPUPixelBuffer *pb)
|
||||
{
|
||||
void *pixels;
|
||||
int i;
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
|
||||
|
||||
for (i = 0; i < pb->numbuffers; i++) {
|
||||
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->bindcode[pb->current]);
|
||||
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->datasize, NULL,
|
||||
GL_STREAM_DRAW_ARB);
|
||||
|
||||
pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
|
||||
/*memcpy(pixels, _oImage.data(), pb->datasize);*/
|
||||
|
||||
if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
|
||||
fprintf(stderr, "Could not unmap opengl PBO\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
|
||||
}
|
||||
|
||||
static int pixelbuffer_map_into_gpu(GLuint bindcode)
|
||||
{
|
||||
void *pixels;
|
||||
|
||||
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
|
||||
pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
|
||||
|
||||
/* do stuff in pixels */
|
||||
|
||||
if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
|
||||
fprintf(stderr, "Could not unmap opengl PBO\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pixelbuffer_copy_to_texture(GPUTexture *tex, GPUPixelBuffer *pb, GLuint bindcode)
|
||||
{
|
||||
GLenum type = (pb->halffloat)? GL_HALF_FLOAT_NV: GL_UNSIGNED_BYTE;
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
|
||||
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h,
|
||||
GL_RGBA, type, NULL);
|
||||
|
||||
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
|
||||
}
|
||||
|
||||
void GPU_pixelbuffer_async_to_gpu(GPUTexture *tex, GPUPixelBuffer *pb)
|
||||
{
|
||||
int newbuffer;
|
||||
|
||||
if (pb->numbuffers == 1) {
|
||||
pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[0]);
|
||||
pixelbuffer_map_into_gpu(pb->bindcode[0]);
|
||||
}
|
||||
else {
|
||||
pb->current = (pb->current+1)%pb->numbuffers;
|
||||
newbuffer = (pb->current+1)%pb->numbuffers;
|
||||
|
||||
pixelbuffer_map_into_gpu(pb->bindcode[newbuffer]);
|
||||
pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[pb->current]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
1460
source/blender/gpu/intern/gpu_material.c
Normal file
1460
source/blender/gpu/intern/gpu_material.c
Normal file
File diff suppressed because it is too large
Load Diff
1543
source/blender/gpu/intern/gpu_shader_material.glsl
Normal file
1543
source/blender/gpu/intern/gpu_shader_material.glsl
Normal file
File diff suppressed because it is too large
Load Diff
1026
source/blender/gpu/intern/gpu_shader_material.glsl.c
Normal file
1026
source/blender/gpu/intern/gpu_shader_material.glsl.c
Normal file
File diff suppressed because it is too large
Load Diff
12
source/blender/gpu/intern/gpu_shader_vertex.glsl
Normal file
12
source/blender/gpu/intern/gpu_shader_vertex.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
varying vec3 varposition;
|
||||
varying vec3 varnormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 co = gl_ModelViewMatrix * gl_Vertex;
|
||||
|
||||
varposition = co.xyz;
|
||||
varnormal = gl_NormalMatrix * gl_Normal;
|
||||
gl_Position = gl_ProjectionMatrix * co;
|
||||
|
13
source/blender/gpu/intern/gpu_shader_vertex.glsl.c
Normal file
13
source/blender/gpu/intern/gpu_shader_vertex.glsl.c
Normal file
@ -0,0 +1,13 @@
|
||||
/* DataToC output of file <gpu_shader_vertex_glsl> */
|
||||
|
||||
int datatoc_gpu_shader_vertex_glsl_size= 217;
|
||||
char datatoc_gpu_shader_vertex_glsl[]= {
|
||||
10,118, 97,114,121,105,110,103, 32,118,101, 99, 51, 32,118, 97,114,112,111,115,105,116,105,111,110,
|
||||
59, 10,118, 97,114,121,105,110,103, 32,118,101, 99, 51, 32,118, 97,114,110,111,114,109, 97,108, 59, 10, 10,118,111,105,100, 32,
|
||||
109, 97,105,110, 40, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111, 32, 61, 32,103,108, 95, 77,111,100,101,108, 86,105,101,119,
|
||||
77, 97,116,114,105,120, 32, 42, 32,103,108, 95, 86,101,114,116,101,120, 59, 10, 10, 9,118, 97,114,112,111,115,105,116,105,111,
|
||||
110, 32, 61, 32, 99,111, 46,120,121,122, 59, 10, 9,118, 97,114,110,111,114,109, 97,108, 32, 61, 32,103,108, 95, 78,111,114,109,
|
||||
97,108, 77, 97,116,114,105,120, 32, 42, 32,103,108, 95, 78,111,114,109, 97,108, 59, 10, 9,103,108, 95, 80,111,115,105,116,105,
|
||||
111,110, 32, 61, 32,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 32, 42, 32, 99,111, 59, 10, 10,
|
||||
};
|
||||
|
@ -30,52 +30,11 @@
|
||||
#ifndef BDR_DRAWMESH_H
|
||||
#define BDR_DRAWMESH_H
|
||||
|
||||
struct Image;
|
||||
struct MTFace;
|
||||
struct Object;
|
||||
struct DerivedMesh;
|
||||
struct Mesh;
|
||||
struct EdgeHash;
|
||||
|
||||
/**
|
||||
* Enables or disable mipmapping for realtime images (textures).
|
||||
* Note that this will will destroy all texture bindings in OpenGL.
|
||||
* @see free_realtime_image()
|
||||
* @param mipmap Turn mipmapping on (mipmap!=0) or off (mipmap==0).
|
||||
*/
|
||||
void set_mipmap(int mipmap);
|
||||
|
||||
/**
|
||||
* Enables or disable linear mipmap setting for realtime images (textures).
|
||||
* Note that this will will destroy all texture bindings in OpenGL.
|
||||
* @see free_realtime_image()
|
||||
* @param mipmap Turn linear mipmapping on (linear!=0) or off (linear==0).
|
||||
*/
|
||||
void set_linear_mipmap(int linear);
|
||||
|
||||
/**
|
||||
* Returns the current setting for linear mipmapping.
|
||||
*/
|
||||
int get_linear_mipmap(void);
|
||||
|
||||
/**
|
||||
* Resets the realtime image cache variables.
|
||||
*/
|
||||
void clear_realtime_image_cache(void);
|
||||
|
||||
|
||||
void update_realtime_image(struct Image *ima, int x, int y, int w, int h);
|
||||
void free_realtime_image(struct Image *ima);
|
||||
void free_all_realtime_images(void);
|
||||
void make_repbind(struct Image *ima);
|
||||
int set_tpage(struct MTFace *tface);
|
||||
|
||||
void texpaint_enable_mipmap(void);
|
||||
void texpaint_disable_mipmap(void);
|
||||
|
||||
void draw_mesh_textured(struct Object *ob, struct DerivedMesh *dm, int facesel);
|
||||
struct EdgeHash *get_tface_mesh_marked_edge_info(struct Mesh *me);
|
||||
void init_realtime_GL(void);
|
||||
void draw_mesh_text(struct Object *ob, int glsl);
|
||||
|
||||
#endif /* BDR_DRAWMESH_H */
|
||||
|
||||
|
@ -47,8 +47,7 @@ struct EditVert;
|
||||
struct EditFace;
|
||||
struct EditEdge;
|
||||
|
||||
int set_gl_material(int nr);
|
||||
int init_gl_materials(struct Object *ob, int check_alpha);
|
||||
int draw_glsl_material(struct Object *ob, int dt);
|
||||
|
||||
void mesh_foreachScreenVert(void (*func)(void *userData, struct EditVert *eve, int x, int y, int index), void *userData, int clipVerts);
|
||||
void mesh_foreachScreenEdge(void (*func)(void *userData, struct EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts);
|
||||
|
@ -34,8 +34,8 @@ void imagepaint_redraw_tool(void);
|
||||
void imagepaint_pick(short mousebutton);
|
||||
void imagepaint_paint(short mousebutton, short texturepaint);
|
||||
|
||||
void imagepaint_undo();
|
||||
void free_imagepaint();
|
||||
void undo_imagepaint_step(int step);
|
||||
void undo_imagepaint_clear(void);
|
||||
|
||||
#endif /* BDR_IMAGEPAINT_H */
|
||||
|
||||
|
@ -33,19 +33,21 @@
|
||||
struct ScrArea;
|
||||
struct SpaceText;
|
||||
struct Text;
|
||||
struct TextLine;
|
||||
|
||||
void unlink_text(struct Text *text);
|
||||
|
||||
void free_textspace(struct SpaceText *st);
|
||||
|
||||
int txt_file_modified(struct Text *text);
|
||||
void txt_write_file(struct Text *text);
|
||||
void add_text_fs(char *file);
|
||||
|
||||
void free_txt_data(void);
|
||||
void pop_space_text(struct SpaceText *st);
|
||||
|
||||
void get_format_string(struct SpaceText *st);
|
||||
void do_brackets(void);
|
||||
void txt_format_text(struct SpaceText *st);
|
||||
void txt_format_line(struct SpaceText *st, struct TextLine *line, int do_next);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -49,20 +49,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
/* #if defined (__sun) || defined (__sun__)
|
||||
#include <GL/gl.h>
|
||||
#include <mesa/glu.h>
|
||||
#else
|
||||
*/
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
/* #endif */
|
||||
#endif
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
/*
|
||||
* these should be phased out. cpack should be replaced in
|
||||
|
@ -31,6 +31,9 @@
|
||||
#define BIF_KEYVAL_H
|
||||
|
||||
char *key_event_to_string(unsigned short event);
|
||||
int decode_key_string(char *str, unsigned short *key, unsigned short *qual);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#ifndef BIF_MESHTOOLS_H
|
||||
#define BIF_MESHTOOLS_H
|
||||
|
||||
#include "BLO_sys_types.h"
|
||||
|
||||
struct Object;
|
||||
struct EditVert;
|
||||
|
||||
|
@ -57,8 +57,8 @@ typedef enum {
|
||||
ICON_TRIA_UP,
|
||||
ICON_FONTPREVIEW,
|
||||
ICON_BLANK4,
|
||||
ICON_BLANK5,
|
||||
ICON_BLANK6,
|
||||
ICON_WORDWRAP,
|
||||
ICON_WORDWRAP_OFF,
|
||||
|
||||
ICON_ORTHO,
|
||||
ICON_PERSP,
|
||||
@ -108,7 +108,7 @@ typedef enum {
|
||||
ICON_FF,
|
||||
ICON_REW,
|
||||
ICON_PYTHON,
|
||||
ICON_BLANK11,
|
||||
ICON_PYTHON_ON,
|
||||
ICON_BLANK12,
|
||||
ICON_BLANK13,
|
||||
ICON_BLANK14,
|
||||
|
@ -83,6 +83,9 @@ struct SpaceOops;
|
||||
/* nodes handler codes */
|
||||
#define NODES_HANDLER_GREASEPENCIL 80
|
||||
|
||||
/* text handler codes */
|
||||
#define TEXT_HANDLER_FIND 90
|
||||
|
||||
/* theme codes */
|
||||
#define B_ADD_THEME 3301
|
||||
#define B_DEL_THEME 3302
|
||||
|
@ -36,8 +36,6 @@ struct rctf;
|
||||
struct ScrArea;
|
||||
struct ImBuf;
|
||||
|
||||
void default_gl_light(void);
|
||||
void init_gl_stuff(void);
|
||||
void circf(float x, float y, float rad);
|
||||
void circ(float x, float y, float rad);
|
||||
|
||||
@ -55,8 +53,8 @@ struct ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax);
|
||||
unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict, unsigned int (*indextest)(unsigned int index));
|
||||
|
||||
void drawview3dspace(struct ScrArea *sa, void *spacedata);
|
||||
void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4]);
|
||||
void draw_depth(struct ScrArea *sa, void *spacedata);
|
||||
void drawview3d_render(struct View3D *v3d, float viewmat[][4], int winx, int winy, float winmat[][4], int shadow);
|
||||
void draw_depth(struct ScrArea *sa, void *spacedata, int (*func)(void *) );
|
||||
void view3d_update_depths(struct View3D *v3d);
|
||||
|
||||
int update_time(int cfra);
|
||||
|
@ -377,6 +377,13 @@
|
||||
#define B_TEXTLINENUM 507
|
||||
#define B_TAB_NUMBERS 508
|
||||
#define B_SYNTAX 509
|
||||
#define B_WORDWRAP 510
|
||||
#define B_TEXTPLUGINS 511
|
||||
#define B_PASTEFIND 512
|
||||
#define B_PASTEREPLACE 513
|
||||
#define B_TEXTREPLACE 514
|
||||
#define B_TEXTFIND 515
|
||||
#define B_TEXTMARKALL 516
|
||||
|
||||
/* SCRIPT: 525 */
|
||||
#define B_SCRIPTBROWSE 526
|
||||
|
@ -300,6 +300,7 @@ typedef struct FreeCamera {
|
||||
#define ACT_NEW 4
|
||||
#define ACT_LINKED 8
|
||||
#define ACT_VISIBLE 16
|
||||
#define ACT_PIN 32
|
||||
|
||||
/* link codes */
|
||||
#define LINK_SENSOR 0
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#ifndef MAX_MTEX
|
||||
#define MAX_MTEX 10
|
||||
#define MAX_MTEX 18
|
||||
#endif
|
||||
|
||||
struct MTex;
|
||||
@ -58,7 +58,7 @@ typedef struct Brush {
|
||||
float alpha; /* opacity */
|
||||
|
||||
short texact, pad;
|
||||
struct MTex *mtex[10];
|
||||
struct MTex *mtex[18]; /* MAX_MTEX */
|
||||
|
||||
struct BrushClone clone;
|
||||
} Brush;
|
||||
|
@ -54,7 +54,7 @@ typedef struct Group {
|
||||
* the objects that show in the group can change depending
|
||||
* on the last used scene */
|
||||
unsigned int layer;
|
||||
int pad;
|
||||
float dupli_ofs[3];
|
||||
} Group;
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@ struct PackedFile;
|
||||
struct anim;
|
||||
struct ImBuf;
|
||||
struct RenderResult;
|
||||
struct GPUTexture;
|
||||
|
||||
|
||||
/* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
|
||||
@ -62,7 +63,8 @@ typedef struct Image {
|
||||
|
||||
char name[240]; /* file path */
|
||||
|
||||
ListBase ibufs; /* not written in file */
|
||||
ListBase ibufs; /* not written in file */
|
||||
struct GPUTexture *gputexture; /* not written in file */
|
||||
|
||||
/* sources from: */
|
||||
struct anim *anim;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user