This commit is contained in:
Daniel Genrich 2008-09-05 00:12:01 +00:00
commit d2c13039ed
320 changed files with 21723 additions and 8755 deletions

@ -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'

@ -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])

@ -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)

@ -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();
}

@ -50,6 +50,19 @@ public:
m_buckets[i] = 0;
}
}
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;

@ -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

@ -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
@ -449,4 +453,4 @@ def main():
if __name__ == '__main__':
main()
main()

@ -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")

@ -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()

@ -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()

@ -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()

@ -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()

@ -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()

@ -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 *************** */

@ -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);
}
}
}
}
@ -683,14 +713,14 @@ char *BKE_undo_menu_string(void)
UndoElem *uel;
DynStr *ds= BLI_dynstr_new();
char *menu;
BLI_dynstr_append(ds, "Global Undo History %t");
for(uel= undobase.first; uel; uel= uel->next) {
BLI_dynstr_append(ds, "|");
BLI_dynstr_append(ds, uel->name);
}
menu= BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);

@ -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)
@ -207,6 +212,8 @@ Material *copy_material(Material *ma)
if(ma->nodetree) {
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;

@ -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);
@ -256,6 +268,9 @@ int reopen_text(Text *text)
len = fread(buffer, 1, len, fp);
fclose(fp);
res= stat(str, &st);
text->mtime= st.st_mtime;
text->nlines=0;
i=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; */
@ -348,6 +365,9 @@ Text *add_text(char *file)
len = fread(buffer, 1, len, fp);
fclose(fp);
res= stat(str, &st);
ta->mtime= st.st_mtime;
ta->nlines=0;
i=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,10 +876,12 @@ 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);
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:
@ -1736,6 +1867,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);
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,21 +2182,35 @@ 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);
txt_delete_line(text, lineb);
txt_make_dirty(text);
txt_clean_text(text);
@ -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) {
@ -2047,6 +2235,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) {
@ -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;
@ -2083,19 +2297,38 @@ void txt_backspace_char (Text *text)
txt_combine_lines(text, text->curl, text->curl->next);
txt_pop_sel(text);
}
}
else { /* Just backspacing a char */
int i= text->curc-1;
int i= text->curc-1;
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);
}
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);
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;
}

@ -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}")

@ -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

@ -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

@ -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__*/

@ -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

@ -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] )

@ -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../

File diff suppressed because it is too large Load Diff

@ -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

File diff suppressed because it is too large Load Diff

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -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;

@ -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