1
1

Compare commits

...

94 Commits

Author SHA1 Message Date
afb8fffb18 Merged revisions 45967-46052 from trunk/blender 2012-04-29 00:33:24 +00:00
f306b50700 Merged revisions 45910-45967 from trunk/blender 2012-04-26 03:11:15 +00:00
ef9fbb56f7 Some style clean up on if and for statements to match trunk. 2012-04-26 02:32:00 +00:00
2dc836524f Fixing up UVs when using VBOs in the BGE as well as removing some unnecessary OpenGL commands. 2012-04-25 04:58:59 +00:00
f563a9825f Merged revisions 41228-45910 from trunk/blender 2012-04-25 00:59:49 +00:00
c17db695ec Changing the worldTransform and localTransform python attributes to use BLI_math to simplify the code. 2012-01-17 03:54:08 +00:00
Dalai Felinto
e7e5fafb93 svn merge ^/trunk/blender -r42742:43270
conflicted files I had to fix manually:
--------------------------------------
wm.py
properties_particle.py
properties_game.py
rna_scene.c
KX_BlenderInputDevice.h
BL_BlenderDataConversion.cpp
GPG_Application.cpp
BL_Material.cpp
KX_FontObject.cpp
2012-01-11 02:13:09 +00:00
Dalai Felinto
e33357e715 BGE Font Object - fix for offset
(scaling also has to be taken into account here)
2011-12-30 11:15:39 +00:00
Dalai Felinto
318c956f72 Font Object Multiline fix.
The offset was totally wrong when object had scale[1] != 1
2011-12-30 11:02:59 +00:00
63a1bd7e5a Merge with trunk to r42742 2011-12-20 00:42:05 +00:00
f3af35d593 Fixing what physics types the collision mask settings appear on. 2011-12-19 22:46:00 +00:00
9fdf48f839 Merging revisions 41297-41712(HEAD) from Trunk 2011-11-10 04:13:07 +00:00
Dalai Felinto
79bf6e05ff part 1: svn merge --non-interactive -r41228:41234 https://svn.blender.org/svnroot/bf-blender/trunk/blender/ --accept=theirs-conflict
(only source this time)
still not trunk, but almost there
2011-10-26 19:10:20 +00:00
Dalai Felinto
3b8d00b12a svn merge --non-interactive -r40843:41226 https://svn.blender.org/svnroot/bf-blender/trunk/blender 2011-10-25 07:26:19 +00:00
63ff6df171 Fixing up dynamic lights a bit to better match behavior in Trunk:
* Removed some arguments and return types for some methods
* Added a forfeit_blenderlight method to allow an inactive light to add it's light to the light pool
* Added a wrapper struct to facilitate forfeiting lights
2011-10-10 04:18:54 +00:00
Dalai Felinto
b64d62d533 remove desktop and fullscreen properties. They are both part of playerflag now
also I removed the fullscreen from the DNA completely. I don't think we need doversion that..
2011-10-07 07:43:23 +00:00
Dalai Felinto
1065f4567a svn merge -r40820:40843(HEAD) https://svn.blender.org/svnroot/bf-blender/trunk/blender 2011-10-07 06:57:18 +00:00
Dalai Felinto
4be8ce8d34 svn merge -r40631:40820(HEAD) https://svn.blender.org/svnroot/bf-blender/trunk/blenderk
40790 manually merged.
2011-10-06 04:40:18 +00:00
Dalai Felinto
cdff43b1e2 svn merge 40546-40630(HEAD) + fix wm.py
(moving import os inside the operator to be more trunk-like)
2011-09-27 19:43:49 +00:00
Dalai Felinto
3e7ccdb94e launch blenderplayer from ui not working in OSX fix - by Daniel Stokes and me 2011-09-27 06:44:32 +00:00
0dfb9dc134 Fixing spaces to tabs. 2011-09-27 05:55:05 +00:00
2e5a537d30 Grabbed the properties_game.py from my patched Trunk and attempted to get a better "merge" this time.
Also fixed up some errors from properties_scene.py from some stuff that was added after messing around in that file last time.
2011-09-27 05:43:15 +00:00
Dalai Felinto
cbe6ad6c80 for svn merging sake's: rolling back last commit (fix for properties_game). I will commit the correct fix next 2011-09-26 23:42:06 +00:00
Alex Fraser
aa798b2425 Using fully-qualified bpy.types.Panel instead of Panel. This was preventing
all panels from drawing.
2011-09-26 14:02:56 +00:00
8aa57a1adc Bringing the patch back into the branch.
The changelog:
* properties_scene.py now uses COMPAT_ENGINES properly
* fixed an error in space_logic.py
* changed cmake flag WITH_DDS to WITH_IMAGE_DDS
* fixed a crash with reading mipmap data in DDS files
* fixed an inconsistency in GPG_Application.cpp
* added a comment explaining why USER_DISABLE_VBO is set in GPG_ghost.cpp
* removed some code that was accidentally committed to refix a crash from libloaded lights
* fixed a memory leak with dynamic lights
* reapplied a fix for raycasting (seems to always disappear)

Thanks to Mitchell Stokes for the DDS fixes
2011-09-26 06:56:41 +00:00
5dd02ad3e6 Merge from trunk r40540 2011-09-26 04:52:30 +00:00
Dalai Felinto
c7ffdb06aa replacing cast from pointer from long to intptr_t (thanks Campbell) 2011-09-17 07:01:17 +00:00
Dalai Felinto
2c1c3a3766 pointers should be cast to long, not int (build fix for OSX+CMake+Make) 2011-09-14 08:04:00 +00:00
9670122f47 Merge from trunk r39703 2011-08-26 02:42:22 +00:00
6f8d327c12 Merge from trunk r39684 2011-08-24 23:26:14 +00:00
3efc060f6b Merge from trunk r39354 2011-08-13 00:39:53 +00:00
8d2270c446 VBOs now update when necessary.
VBOs are now interleaved to avoid iterating over the vertex list more than is necessary.
Removed some allocation/deallocation in the update code that was causing some slow downs.
2011-08-11 07:24:39 +00:00
9e1db42cc2 Added color to the VBOs, this also happens to fix TexFace mode. 2011-08-10 21:51:03 +00:00
4dbabf9365 Recently VBOs started acting up when using display lists. Since the two really shouldn't be used together, and since using the two together cause no performance gain, display lists are disabled when VBO is chosen as the storage type. This is also reflected in the UI. 2011-08-10 07:39:10 +00:00
f10a97713a Sorted out some problems with scrambled UVs caused by the changes made for multiple UV support. 2011-08-10 05:41:00 +00:00
f9f687aeaa RayCasting makes use of collision masks. This needed to be updated to accommodate user settable collision groups and collision masks. 2011-08-10 04:30:44 +00:00
cb72d9cc4d Fixed a crash caused by libload when no dynamic lights were allocated. Thanks to jplur for pointing it out to me on the IRC. 2011-08-09 04:11:07 +00:00
16f5be7b45 Looks like a merge from Trunk had messed up the change to have the bake menu in the game render panel. This brings it back. 2011-08-08 18:28:46 +00:00
3ea987beeb Libloaded lights now work with the dynamic light settings. 2011-08-05 07:12:55 +00:00
239bb676c8 The Desktop option is now greyed out when fullscreen is not checked rather than disappearing from the UI completely. 2011-08-05 05:40:06 +00:00
f201b94b2a Now dynamic lights from the light pool don't get converted to game objects. 2011-08-05 05:22:13 +00:00
07fac314a2 Now the Desktop option is only available when fullscreen is checked. 2011-08-05 04:47:05 +00:00
d1846fc5b1 Fixed up RAS_StorageVA so TexFace works again. 2011-08-05 02:44:55 +00:00
b5364a1e81 A couple of the doversions were in the wrong spot. This should fix some issues with the exit key not being set. 2011-08-04 21:41:41 +00:00
93912be60c Merge from trunk r38841 - r39034 2011-08-04 20:45:38 +00:00
28ae3ba755 Adding a checkbox to the UI to allow the full screen Blender Player to use the current desktop resolution instead of the resolution setting. 2011-08-03 08:02:54 +00:00
3dc7f45083 Multisampling now works in a fullscreen Blender Player. 2011-08-03 07:20:07 +00:00
7d99d8d8b3 Committing a patch from Mitchell Stokes (Moguri) to include a setting in the UI for the Blenderplayer multisampling. 2011-08-03 06:57:47 +00:00
68afca86da Merging r38247 - r38840 from Trunk 2011-07-30 00:21:26 +00:00
5d5935de34 VBOs now work properly with multiple UVs. 2011-07-29 22:54:53 +00:00
17da418eb5 Renamed RAS_IRasterizer::RAS_TEXCO_UV1 to RAS_IRasterizer::RAS_TEXCO_UV. 2011-07-29 22:05:44 +00:00
a3f65167be Adding support for more than 2 UV layers. Rather than just having two uv variables stored in various places, UVs are now stored in arrays that have a size equal to RAS_TexVert::MAX_UNIT. Most traces of the hacks used to get the second UV layer to work have been removed. The python API still needs to be updated to give access to the new layers (it was updated to still work properly for the first 2 layers). VBOs still need some extra attention as well. 2011-07-29 21:47:44 +00:00
7d44c37994 Accidentally had some extra code. MSVC didn't mind, but it was crashing gcc. 2011-07-16 07:14:47 +00:00
66e89aad50 Changing the "text" property of a KX_FontObject now changes the text. This allows for control of a FontObject through logic bricks. 2011-07-15 00:01:23 +00:00
95d0561e52 KX_FontObject now supports the x and y offset options. 2011-07-14 20:41:52 +00:00
1c1c154c9f KX_FontObject now makes use of the font's line spacing option, and correctly accounts for rotation and font size when applying the spacing. 2011-07-14 20:32:24 +00:00
fca287ebf6 The KX_FontObject text attribute is working again. 2011-07-14 08:24:15 +00:00
f2cba86090 Primitive support for the new line character added to KX_FontObjects. The line spacing is fixed, and does not work when the FontObject is rotated. Also, the text attribute has been temporarily disabled, as it needs some updating to support the multiline changes. 2011-07-14 06:16:31 +00:00
f8e1e7f1a9 Merge from trunk 2011-07-09 05:28:39 +00:00
ce5ab1c7a5 Adding the constants SOURCE_ERROR, SOURCE_EMPTY, SOURCE_READY, SOURCE_PLAYING, SOURCE_STOPPED to the video texture module. Updates to the documentation will follow after a merge with trunk 2011-07-08 23:21:13 +00:00
09d9b6b20b Updates to the documentation to reflect that worldScale is now writable, and added localTransform and worldTransform to KX_GameObject. 2011-07-07 10:54:11 +00:00
191203c295 The Transform attribute of KX_GameObject was based on world space data. I converted that one to worldTransform, and added a localTransform for local space transform information. 2011-07-07 06:02:22 +00:00
0b7be08f54 Fixed the transform attribute of KX_GameObject's set method to properly deal with negative scaling. 2011-07-07 05:46:48 +00:00
d58fae5c23 Updated the transform property on KX_GameObject so that it is now read/write, and added the corresponding set method.
Also simplified the get method by calling GetOpenGLMatrix instead of making the matrix myself.
2011-07-07 05:24:12 +00:00
a1d9c9df95 Adding a read only transform attribute to KX_GameObject that returns a 4x4 matrix representing the object's transformations. 2011-07-06 20:22:35 +00:00
9aed898fd0 Adding a worldScale attribute to KX_GameObject. This attribute scales the object independently of its parent's scale. 2011-07-06 19:31:05 +00:00
39dd22d4cf Exposing access to the upper 8 bits of Bullets collision masks in the physics properties panel.
Collision masks set what collision groups an object can collide with.
2011-07-05 00:29:37 +00:00
9285c8ec76 Fixed the VBO code so that file that was crashing it no longer crashes it. It all seems to be working now. 2011-07-03 06:12:39 +00:00
2d5214d245 The VBO code from Samuel Anjam was having some problems. These problems could have been there initially, or could have resulted from my porting of the patch. These problems were difficult to work out since I lacked sufficient knowledge of VBOs. In an attempt to resolve these problems I rewrote the VBO code from scratch (making sure to keep it contained to its own files) using Anjam's patch as a guide. Some of the bugs have been disappeared, but I have a file that still crashes the code. So for now the auto selection ignores VBOs, and I intend to flag the VBOs as "experimental". 2011-07-01 23:36:44 +00:00
ff1eb9610c Added a UI option to set the storage type (useful for debugging/testing for older hardware). Default is an auto select. This also simplifies the code to instantiate the rasterizer. 2011-06-29 09:36:23 +00:00
561a2f656f Ported the VBO code from the bb_dev25 branch.
Notes from the bb_dev25 VBO commit:
"
20409 - Patch:[#17523] BGE VBO patch by Samuel Anjam (toonist) 
20411 - Missing files from last commit (Patch:[ #17523] BGE VBO patch by Samuel Anjam (toonist))
20549 - Don' t create VBO at the same time as Display list.
20662 - Fix for: Normals are not being updated in VBO.  
20663 - BGE VBO updates

To do:
1) check if we need to update the tangent matrix as well
2) create the buffers only when necessary

"The buffers for all the texture coordinates are [currently] created unconditionally even if some are not used during the render. Which buffer is used depends on the wireframe, GLSL/multitexture and the texture coordinate used by the material. RAS_VAOpenGLRasterizer::TexCoordPtr(), RAS_VAOpenGLRasterizer::IndexPrimitivesMulti() and RAS_VAOpenGLRasterizer::IndexPrimitives() show the buffers that are actually bound to. Only those buffers should be created."

Note:
VBO doesn't necessarly means better performance than Display List. They can perform faster in Skinned objects (where DisplayList is not being used). But it uses less memory than DisplayList and is a more modern Game Engine technology.

Thanks again to Samuel Anjam (toonist) for the original patch.
"
2011-06-29 07:20:29 +00:00
d278ac611e This commit rearranges the rasterizer to use a strategy design pattern. The concrete strategies are various storage methods. Currently these are immediate mode, and vertex arrays. This will make it cleaner to add in the VBO support (rather than having it mixed in with the vertex array rasterizer).
In the process of changing the ListRasterizer to accommodate the changes to OpenGLRasterizer, a check for ATI cards no longer gets acted upon. This check may not have been necessary and would cause slow downs on ATI cards. Some testing will reveal if something needs to be added back in.
2011-06-29 05:24:56 +00:00
c2c33fca8a The last commit had a slight glitch in it from playing around with newer nvidia textures tools files. 2011-06-28 21:24:20 +00:00
e44b44bf22 Experimental DDS texture patch from Mitchell Stokes that allows DDS texture to be used uncompressed in OpenGL. Since OpenGL uses a different coordinate system than DirectX, DDS textures are upside down in OpenGL. That means this patch could cause some problems with people already using DDS textures. A UI option and a do version could address this. 2011-06-27 19:40:42 +00:00
4ecbb381c6 Adding support and UI options for dynamic spot, sun, hemi, and are lights. Currently area lights don't work in the BGE so the UI option is commented out, but everything should be ready to go if this ever changes. 2011-06-25 05:00:55 +00:00
278b972765 Distance, att1, att2, spot size, and spot blending are now all dynamic. 2011-06-23 23:18:49 +00:00
0ecf85ec27 Adding in the blender light pool to KX_Light to give it some blender lights to use with dynamic lights. Dynamic lights created via replication now light the scene. 2011-06-23 04:17:25 +00:00
566fb2037d Merge from trunk r37642 2011-06-19 19:45:46 +00:00
38c4f49c9a Moved control of the exit key away from the keyboard devices, and moved it to ketsjiengine.
Added setExitKey and getExitKey to the python API
2011-06-15 19:33:46 +00:00
b43fa53d3e Merge from trunk r37517 2011-06-15 18:10:19 +00:00
300c3a5721 Disable VBOs in the Blenderplayer.
Fixes bugs 26710, 26647, 20507
2011-06-15 17:41:06 +00:00
bbecd861eb Centralizing the exit key methods to the keyboard devices. This should make it easier to get exit key control to the python API. 2011-06-15 06:42:46 +00:00
c9d885a18a Cleaning up some duplicate code. Now the reverseTranslateTable for converting blender key codes to ketsji key codes is only defined in BL_BlenderDataConverter. 2011-06-15 06:03:25 +00:00
5d76f9cbf5 Some clean up from the last commit.
The exit key setting affects the Blenderplayer now.
2011-06-15 05:13:23 +00:00
64020dab9b Some more work on getting the exit key to work in the Blenderplayer.
Input is now restricted to keyboard events only for the exit key UI.
2011-06-15 04:46:56 +00:00
06a6b11731 Making the exit key UI element accept key presses instead of numbers. It still does not work for the Blenderplayer, and it does not limit the input to key presses (other events don't work for exiting) 2011-06-11 19:10:55 +00:00
2ff109087b Making the bake options available in Blender Game 2011-06-04 02:31:23 +00:00
fa5dd13585 ==UI==
* Added the option to change the exit key for the BGE. The UI currently just sets a number, and this feature most likely does not work for blenderplayer yet. More work on this to come.
* Removed the physics settings from the scene panel for the BGE.
* Added an Add menu in the logic brick header.
2011-06-01 02:11:39 +00:00
e78f35a751 Merge from trunk r37102 (hopefully this one is clean) 2011-05-30 05:29:33 +00:00
98d5c01b0e Some other stuff sneaked into the last merge . . . stay tuned for a new merge 2011-05-30 05:10:41 +00:00
82924486da Merge from trunk r36993 2011-05-29 09:15:37 +00:00
c372faeb25 ==UI==
* Made some options available in Blender Game that were only available in Blender Render (camera resolution, animation fps)
* Created a panel for the embedded player
* Renamed the FPS option for the standalone player to Refresh Rate
* Moved framing options to display
* Made a button to launch the blender player from within blender (only tested on windows for now)
2011-05-29 02:40:37 +00:00
33aefd19ce Merging from trunk r36889 2011-05-25 07:06:56 +00:00
a30812b3e6 Creating GSoC 2011 cucumber branch. 2011-05-23 13:19:58 +00:00
60 changed files with 1862 additions and 735 deletions

0
extern/libmv/third_party/ssba/README.libmv vendored Normal file → Executable file
View File

View File

@@ -171,6 +171,9 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
col.prop(game, "use_actor", text="Detect Actors")
col.prop(ob, "hide_render", text="Invisible")
elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
layout.prop(ob, "hide_render", text="Invisible")
elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
layout.prop(ob, "hide_render", text="Invisible")
@@ -182,8 +185,13 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
layout.operator("mesh.navmesh_reset")
layout.operator("mesh.navmesh_clear")
if physics_type not in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
layout.separator()
col = layout.column()
col.prop(game, "collision_group")
col.prop(game, "collision_mask")
class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
bl_label = "Collision Bounds"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -367,6 +375,15 @@ class RENDER_PT_game_shading(RenderButtonsPanel, Panel):
layout.prop(gs, "material_mode", expand=True)
if gs.material_mode == 'GLSL':
col = layout.column(align=True)
col.prop(gs, "dynamic_points")
col.prop(gs, "dynamic_spots")
col.prop(gs, "dynamic_suns")
col.prop(gs, "dynamic_hemis")
# When area lights work in the BGE, this should be ready
# col.prop(gs, "dynamic_areas")
split = layout.split()
col = split.column()
@@ -389,18 +406,24 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
layout = self.layout
gs = context.scene.game_settings
col = layout.column()
row = col.row()
col = row.column()
col.prop(gs, "use_frame_rate")
col.prop(gs, "restrict_animation_updates")
col = row.column()
col.prop(gs, "use_display_lists")
col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
row = layout.row()
row.prop(gs, "use_frame_rate")
row.prop(gs, "restrict_animation_updates")
row = layout.row()
row.prop(gs, "use_display_lists")
row.prop(gs, "raster_storage")
row = layout.row()
row.label("Exit Key")
row.prop(gs, "exit_key", text="", event=True)
class RENDER_PT_game_display(RenderButtonsPanel, Panel):
bl_label = "Display"
COMPAT_ENGINES = {'BLENDER_GAME'}

View File

@@ -850,6 +850,7 @@ Object *add_only_object(int type, const char *name)
/* ob->pad3 == Contact Processing Threshold */
ob->m_contactProcessingThreshold = 1.0f;
ob->obstacleRad = 1.0f;
ob->col_group = ob->col_mask = 1;
/* NT fluid sim defaults */
ob->fluidsimSettings = NULL;

View File

@@ -12894,6 +12894,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
{
/* Initialize BGE exit key to esc key */
Scene *scene;
for(scene= main->scene.first; scene; scene= scene->id.next) {
if (!scene->gm.exitkey)
scene->gm.exitkey = 218; //218 is the Blender key code for ESC
}
}
{
/* Initialize default values for collision masks */
Object *ob;
for(ob=main->object.first; ob; ob=ob->id.next)
ob->col_group = ob->col_mask = 1;
}
}
if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 6)) {

View File

@@ -66,5 +66,10 @@ endif()
add_definitions(-DGLEW_STATIC)
if(WITH_IMAGE_DDS)
add_definitions(-DWITH_DDS)
endif()
blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}")

View File

@@ -119,6 +119,8 @@ void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h, int m
void GPU_update_images_framechange(void);
int GPU_update_image_time(struct Image *ima, double time);
int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, int compare, int mipmap);
void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth, int mipmap, int use_hight_bit_depth, struct Image *ima);
void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x, int y, int mipmap, struct Image *ima, struct ImBuf *ibuf);
void GPU_free_image(struct Image *ima);
void GPU_free_images(void);
void GPU_free_images_anim(void);
@@ -135,4 +137,3 @@ void GPU_free_unused_buffers(void);
#endif
#endif

View File

@@ -173,6 +173,11 @@ typedef enum GPUDynamicType {
GPU_DYNAMIC_SAMPLER_2DBUFFER = 12,
GPU_DYNAMIC_SAMPLER_2DIMAGE = 13,
GPU_DYNAMIC_SAMPLER_2DSHADOW = 14,
GPU_DYNAMIC_LAMP_DISTANCE = 15,
GPU_DYNAMIC_LAMP_ATT1 = 16,
GPU_DYNAMIC_LAMP_ATT2 = 17,
GPU_DYNAMIC_LAMP_SPOTSIZE = 18,
GPU_DYNAMIC_LAMP_SPOTBLEND = 19,
} GPUDynamicType;
typedef enum GPUDataType {
@@ -230,6 +235,8 @@ void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]);
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2);
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
int GPU_lamp_shadow_layer(GPULamp *lamp);
#ifdef __cplusplus

View File

@@ -16,4 +16,7 @@ incs += ' ' + env['BF_OPENGL_INC']
if env['WITH_BF_SMOKE']:
defs.append('WITH_SMOKE')
if env['WITH_BF_DDS']:
defs.append('WITH_DDS')
env.BlenderLib ( 'bf_gpu', sources, Split(incs), defines = defs, libtype=['core','player'], priority=[160,110] )

View File

@@ -413,8 +413,8 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
ImBuf *ibuf = NULL;
unsigned int *bind = NULL;
int rectw, recth, tpx=0, tpy=0, y;
unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL;
float *ftilerect= NULL, *fscalerect = NULL, *frect = NULL;
unsigned int *tilerect= NULL, *rect= NULL;
float *ftilerect= NULL, *frect = NULL;
float *srgb_frect = NULL;
short texwindx, texwindy, texwinsx, texwinsy;
/* flag to determine whether high resolution format is used */
@@ -597,10 +597,37 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
rect= tilerect;
}
}
#ifdef WITH_DDS
if (ibuf->ftype & DDS)
GPU_create_gl_tex_compressed(bind, rect, rectw, recth, mipmap, ima, ibuf);
else
#endif
GPU_create_gl_tex(bind, rect, frect, rectw, recth, mipmap, use_high_bit_depth, ima);
/* clean up */
if (tilerect)
MEM_freeN(tilerect);
if (ftilerect)
MEM_freeN(ftilerect);
if (srgb_frect)
MEM_freeN(srgb_frect);
return *bind;
}
void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
{
unsigned int *scalerect = NULL;
float *fscalerect = NULL;
int tpx = rectw;
int tpy = recth;
/* scale if not a power of two. this is not strictly necessary for newer
* GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures */
if (!is_pow2_limit(rectw) || !is_pow2_limit(recth)) {
int oldw= rectw;
int oldh= recth;
rectw= smaller_pow2_limit(rectw);
recth= smaller_pow2_limit(recth);
@@ -612,9 +639,9 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
}
else {
scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, pix, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
rect= scalerect;
pix= scalerect;
}
}
@@ -626,7 +653,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (use_high_bit_depth)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
}
@@ -634,7 +661,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (use_high_bit_depth)
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, pix);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
@@ -645,21 +672,72 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
/* set to modulate with vertex color */
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
/* clean up */
if (tilerect)
MEM_freeN(tilerect);
if (ftilerect)
MEM_freeN(ftilerect);
if (scalerect)
MEM_freeN(scalerect);
if (fscalerect)
MEM_freeN(fscalerect);
if (srgb_frect)
MEM_freeN(srgb_frect);
return *bind;
}
void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x, int y, int mipmap, Image *ima, ImBuf *ibuf)
{
#ifndef WITH_DDS
// Fall back to uncompressed if DDS isn't enabled
GPU_create_gl_tex(bind, pix, NULL, x, y, mipmap, 0, ima);
#else
GLint format=0;
int offset =0, i=0;
int blocksize, width, height;
int size;
GLint err;
if (ibuf->dds_data.fourcc == FOURCC_DXT1)
format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
else if (ibuf->dds_data.fourcc == FOURCC_DXT3)
format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
else if (ibuf->dds_data.fourcc == FOURCC_DXT5)
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
else
{
printf("Unable to find a suitable DXT compression, falling back to uncompressed\n");
GPU_create_gl_tex(bind, pix, NULL, x, y, mipmap, 0, ima);
return;
}
glGenTextures(1, (GLuint *)bind);
glBindTexture(GL_TEXTURE_2D, *bind);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
height = ibuf->x;
width = ibuf->y;
blocksize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
for (i=0; i<ibuf->dds_data.nummipmaps && (width||height); ++i)
{
if (width == 0)
width = 1;
if (height == 0)
height = 1;
size = ((width+3)/4)*((height+3)/4)*blocksize;
glCompressedTexImage2D(GL_TEXTURE_2D, i, format, width, height,
0, size, ibuf->dds_data.data + offset);
err = glGetError();
if (err != GL_NO_ERROR)
printf("OpenGL error: %s\nFormat: %x\n", gluErrorString(err), format);
offset += size;
width >>= 1;
height >>= 1;
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#endif
}
static void gpu_verify_repeat(Image *ima)
{
/* set either clamp or repeat in X/Y */
@@ -1897,4 +1975,3 @@ void GPU_state_print(void)
gpu_get_print("GL_ZOOM_X", GL_ZOOM_X);
gpu_get_print("GL_ZOOM_Y", GL_ZOOM_Y);
}

View File

@@ -117,6 +117,7 @@ struct GPULamp {
float dynimat[4][4];
float spotsi, spotbl, k;
float dyndist, dynatt1, dynatt2;
float dist, att1, att2;
float bias, d, clipend;
@@ -401,13 +402,13 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode
case LA_FALLOFF_CONSTANT:
break;
case LA_FALLOFF_INVLINEAR:
GPU_link(mat, "lamp_falloff_invlinear", GPU_uniform(&lamp->dist), *dist, &visifac);
GPU_link(mat, "lamp_falloff_invlinear", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
break;
case LA_FALLOFF_INVSQUARE:
GPU_link(mat, "lamp_falloff_invsquare", GPU_uniform(&lamp->dist), *dist, &visifac);
GPU_link(mat, "lamp_falloff_invsquare", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
break;
case LA_FALLOFF_SLIDERS:
GPU_link(mat, "lamp_falloff_sliders", GPU_uniform(&lamp->dist), GPU_uniform(&lamp->att1), GPU_uniform(&lamp->att2), *dist, &visifac);
GPU_link(mat, "lamp_falloff_sliders", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob), GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac);
break;
case LA_FALLOFF_CURVE:
{
@@ -415,13 +416,13 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode
int size;
curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
GPU_link(mat, "lamp_falloff_curve", GPU_uniform(&lamp->dist), GPU_texture(size, array), *dist, &visifac);
GPU_link(mat, "lamp_falloff_curve", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), GPU_texture(size, array), *dist, &visifac);
}
break;
}
if (lamp->mode & LA_SPHERE)
GPU_link(mat, "lamp_visibility_sphere", GPU_uniform(&lamp->dist), *dist, visifac, &visifac);
GPU_link(mat, "lamp_visibility_sphere", GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, visifac, &visifac);
if (lamp->type == LA_SPOT) {
if (lamp->mode & LA_SQUARE) {
@@ -433,7 +434,7 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode
GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), *lv, &inpr);
}
GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac);
GPU_link(mat, "lamp_visibility_spot", GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), inpr, visifac, &visifac);
}
GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
@@ -1516,6 +1517,19 @@ void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener
lamp->col[2]= b* lamp->energy;
}
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2)
{
lamp->dist = distance;
lamp->att1 = att1;
lamp->att2 = att2;
}
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
{
lamp->spotsi= cos(M_PI*spotsize/360.0);
lamp->spotbl= (1.0f - lamp->spotsi)*spotblend;
}
static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
{
float temp, angle, pixsize, wsize;

View File

@@ -52,6 +52,13 @@ struct ImMetaData;
#define IB_MIPMAP_LEVELS 20
#define IB_FILENAME_SIZE 1024
typedef struct DDSData {
unsigned int fourcc; /* DDS fourcc info */
unsigned int nummipmaps; /* The number of mipmaps in the dds file */
unsigned char *data; /* The compressed image data */
unsigned int size; /* The size of the compressed data */
} DDSData;
/**
* \ingroup imbuf
* This is the abstraction of an image. ImBuf is the basic type used for all
@@ -126,6 +133,9 @@ typedef struct ImBuf {
unsigned char *encodedbuffer; /* Compressed image only used with png currently */
unsigned int encodedsize; /* Size of data written to encodedbuffer */
unsigned int encodedbuffersize; /* Size of encodedbuffer */
/* information for compressed textures */
struct DDSData dds_data;
} ImBuf;
/* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */
@@ -222,9 +232,31 @@ typedef struct ImBuf {
#define IB_PROFILE_SRGB 2
#define IB_PROFILE_CUSTOM 3
/* dds */
#ifdef WITH_DDS
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3)\
((unsigned long)(unsigned char)(ch0) | \
((unsigned long)(unsigned char)(ch1) << 8) | \
((unsigned long)(unsigned char)(ch2) << 16) | \
((unsigned long)(unsigned char)(ch3) << 24))
#endif //MAKEFOURCC
/*
* FOURCC codes for DX compressed-texture pixel formats
*/
#define FOURCC_DDS (MAKEFOURCC('D','D','S',' '))
#define FOURCC_DXT1 (MAKEFOURCC('D','X','T','1'))
#define FOURCC_DXT2 (MAKEFOURCC('D','X','T','2'))
#define FOURCC_DXT3 (MAKEFOURCC('D','X','T','3'))
#define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4'))
#define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5'))
#endif // DDS
extern const char *imb_ext_image[];
extern const char *imb_ext_image_qt[];
extern const char *imb_ext_movie[];
extern const char *imb_ext_audio[];
#endif

View File

@@ -162,6 +162,8 @@ void IMB_freeImBuf(ImBuf *ibuf)
IMB_freezbuffloatImBuf(ibuf);
freeencodedbufferImBuf(ibuf);
IMB_metadata_free(ibuf);
if (ibuf->dds_data.data != NULL)
free(ibuf->dds_data.data);
MEM_freeN(ibuf);
}
}

View File

@@ -1016,6 +1016,10 @@ uint DirectDrawSurface::mipmapCount() const
else return 1;
}
uint DirectDrawSurface::fourCC() const
{
return header.pf.fourcc;
}
uint DirectDrawSurface::width() const
{
@@ -1131,6 +1135,29 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
}
}
// It was easier to copy this function from upstream than to resync.
// This should be removed if a resync ever occurs.
void* DirectDrawSurface::readData(uint &rsize)
{
uint header_size = 128; // sizeof(DDSHeader);
if (header.hasDX10Header())
{
header_size += 20; // sizeof(DDSHeader10);
}
uint size = stream.size - header_size;
rsize = size;
unsigned char *data = new unsigned char[size];
stream.seek(header_size);
mem_read(stream, data, size);
// Maybe check if size == rsize? assert() isn't in this scope...
return data;
}
void DirectDrawSurface::readLinearImage(Image * img)
{
@@ -1523,4 +1550,3 @@ void DirectDrawSurface::printInfo() const
printf("User Version: %u\n", header.reserved[8]);
}
}

View File

@@ -158,6 +158,7 @@ public:
bool hasAlpha() const;
uint mipmapCount() const;
uint fourCC() const;
uint width() const;
uint height() const;
uint depth() const;
@@ -171,6 +172,7 @@ public:
void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m);
void* readData(uint &size);
// void mipmap(FloatImage * img, uint f, uint m);
void printInfo() const;

View File

@@ -123,6 +123,8 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
ibuf->ftype = DDS;
ibuf->profile = IB_PROFILE_SRGB;
ibuf->dds_data.fourcc = dds.fourCC();
ibuf->dds_data.nummipmaps = dds.mipmapCount();
if ((flags & IB_test) == 0) {
if (!imb_addrectImBuf(ibuf)) return(ibuf);
@@ -136,10 +138,18 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
cp[0] = pixel.r; /* set R component of col */
cp[1] = pixel.g; /* set G component of col */
cp[2] = pixel.b; /* set B component of col */
if (bits_per_pixel == 32)
if (dds.hasAlpha())
cp[3] = pixel.a; /* set A component of col */
rect[i] = col;
}
if (ibuf->dds_data.fourcc != FOURCC_DDS)
ibuf->dds_data.data = (unsigned char*)dds.readData(ibuf->dds_data.size);
else {
ibuf->dds_data.data = NULL;
ibuf->dds_data.size = 0;
}
IMB_flipy(ibuf);
}

View File

@@ -234,6 +234,9 @@ typedef struct Object {
short recalc; /* dependency flag */
float anisotropicFriction[3];
/** Collision mask settings */
unsigned short col_group, col_mask, col_pad[2];
ListBase constraints; /* object constraints */
ListBase nlastrips DNA_DEPRECATED; // XXX depreceated... old animation system
ListBase hooks DNA_DEPRECATED; // XXX depreceated... old animation system
@@ -455,6 +458,9 @@ typedef struct DupliObject {
/* controller state */
#define OB_MAX_STATES 30
/* collision masks */
#define OB_MAX_COL_MASKS 8
/* ob->gameflag */
#define OB_DYNAMIC 1
#define OB_CHILD 2

View File

@@ -624,7 +624,18 @@ typedef struct GameData {
short exitkey, pad;
short ticrate, maxlogicstep, physubstep, maxphystep;
short obstacleSimulation, pad1;
short raster_storage;
short pad3;
float levelHeight;
float pad2;
/* Dynamic Lights */
short dynpoints;
short dynspots;
short dynsuns;
short dynhemis;
short dynareas;
short light_pad[3];
} GameData;
#define STEREO_NOSTEREO 1
@@ -649,6 +660,12 @@ typedef struct GameData {
#define OBSTSIMULATION_TOI_rays 1
#define OBSTSIMULATION_TOI_cells 2
/* Render storage */
#define RAS_STORE_AUTO 0
#define RAS_STORE_IMMEDIATE 1
#define RAS_STORE_VA 2
#define RAS_STORE_VBO 3
/* GameData.flag */
#define GAME_RESTRICT_ANIM_UPDATES (1 << 0)
#define GAME_ENABLE_ALL_FRAMES (1 << 1)

View File

@@ -1052,6 +1052,64 @@ static void rna_GameObjectSettings_state_set(PointerRNA *ptr, const int *values)
}
}
static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values)
{
Object *ob= (Object*)ptr->data;
int i;
memset(values, 0, sizeof(short)*OB_MAX_COL_MASKS);
for(i=0; i<OB_MAX_COL_MASKS; i++)
values[i] = (ob->col_group & (1<<i));
}
static void rna_GameObjectSettings_col_group_set(PointerRNA *ptr, const int *values)
{
Object *ob= (Object*)ptr->data;
int i, tot= 0;
/* ensure we always have some group selected */
for(i=0; i<OB_MAX_COL_MASKS; i++)
if(values[i])
tot++;
if(tot==0)
return;
for(i=0; i<OB_MAX_COL_MASKS; i++) {
if(values[i]) ob->col_group |= (1<<i);
else ob->col_group &= ~(1<<i);
}
}
static void rna_GameObjectSettings_col_mask_get(PointerRNA *ptr, int *values)
{
Object *ob= (Object*)ptr->data;
int i;
memset(values, 0, sizeof(short)*OB_MAX_COL_MASKS);
for(i=0; i<OB_MAX_COL_MASKS; i++)
values[i] = (ob->col_mask & (1<<i));
}
static void rna_GameObjectSettings_col_mask_set(PointerRNA *ptr, const int *values)
{
Object *ob= (Object*)ptr->data;
int i, tot= 0;
/* ensure we always have some mask selected */
for(i=0; i<OB_MAX_COL_MASKS; i++)
if(values[i])
tot++;
if(tot==0)
return;
for(i=0; i<OB_MAX_COL_MASKS; i++) {
if(values[i]) ob->col_mask |= (1<<i);
else ob->col_mask &= ~(1<<i);
}
}
static void rna_GameObjectSettings_used_state_get(PointerRNA *ptr, int *values)
{
Object *ob = (Object*)ptr->data;
@@ -1412,6 +1470,8 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
int default_col_mask[8] = {1,0,0,0, 0,0,0,0};
static EnumPropertyItem body_type_items[] = {
{OB_BODY_TYPE_NO_COLLISION, "NO_COLLISION", 0, "No Collision", "Disable collision for this object"},
{OB_BODY_TYPE_STATIC, "STATIC", 0, "Static", "Stationary object"},
@@ -1516,6 +1576,18 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed");
prop= RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1);
RNA_def_property_array(prop, OB_MAX_COL_MASKS);
RNA_def_property_ui_text(prop, "Collision Group", "The collision group of the object");
RNA_def_property_boolean_funcs(prop, "rna_GameObjectSettings_col_group_get", "rna_GameObjectSettings_col_group_set");
prop= RNA_def_property(srna, "collision_mask", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "col_mask", 1);
RNA_def_property_array(prop, OB_MAX_COL_MASKS);
RNA_def_property_ui_text(prop, "Collision Mask", "The groups this object can collide with");
RNA_def_property_boolean_funcs(prop, "rna_GameObjectSettings_col_mask_get", "rna_GameObjectSettings_col_mask_set");
/* lock position */
prop = RNA_def_property(srna, "lock_location_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_X_AXIS);

View File

@@ -2356,6 +2356,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
{OBSTSIMULATION_TOI_cells, "RVO_CELLS", 0, "RVO (cells)", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem storage_items[] ={
{RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"},
{RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"},
{RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Moderate performance, requires at least OpenGL 1.1"},
{RAS_STORE_VBO, "VERTEX_BUFFER_OBJECT", 0, "Vertex Buffer Objects", "Best performance, requires at least OpenGL 1.4"},
{0, NULL, 0, NULL, NULL}};
srna = RNA_def_struct(brna, "SceneGameData", NULL);
RNA_def_struct_sdna(srna, "GameData");
RNA_def_struct_nested(brna, srna, "Scene");
@@ -2390,6 +2397,11 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_enum_funcs(prop, NULL, "rna_GameSettings_exit_key_set", NULL);
RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine");
RNA_def_property_update(prop, NC_SCENE, NULL);
prop= RNA_def_property(srna, "raster_storage", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "raster_storage");
RNA_def_property_enum_items(prop, storage_items);
RNA_def_property_ui_text(prop, "Storage", "Sets the storage mode used by the rasterizer");
RNA_def_property_update(prop, NC_SCENE, NULL);
/* Do we need it here ? (since we already have it in World */
prop = RNA_def_property(srna, "frequency", PROP_INT, PROP_NONE);
@@ -2408,6 +2420,42 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Desktop", "Uses the current desktop resultion in fullscreen mode");
RNA_def_property_update(prop, NC_SCENE, NULL);
/* Dynamic Lights */
prop = RNA_def_property(srna, "dynamic_points", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dynpoints");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_range(prop, 0, 15, 1, 1);
RNA_def_property_ui_text(prop, "Dynamic Point Lights", "Number of point lights available for dynamic use");
RNA_def_property_update(prop, NC_SCENE, NULL);
prop = RNA_def_property(srna, "dynamic_spots", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dynspots");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_range(prop, 0, 15, 1, 1);
RNA_def_property_ui_text(prop, "Dynamic Spot Lights", "Number of spot lights available for dynamic use");
RNA_def_property_update(prop, NC_SCENE, NULL);
prop = RNA_def_property(srna, "dynamic_suns", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dynsuns");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_range(prop, 0, 15, 1, 1);
RNA_def_property_ui_text(prop, "Dynamic Sun Lights", "Number of sun lights available for dynamic use");
RNA_def_property_update(prop, NC_SCENE, NULL);
prop = RNA_def_property(srna, "dynamic_hemis", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dynhemis");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_range(prop, 0, 15, 1, 1);
RNA_def_property_ui_text(prop, "Dynamic Hemi Lights", "Number of hemi lights available for dynamic use");
RNA_def_property_update(prop, NC_SCENE, NULL);
prop = RNA_def_property(srna, "dynamic_areas", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dynareas");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_range(prop, 0, 15, 1, 1);
RNA_def_property_ui_text(prop, "Dynamic Area Lights", "Number of area lights available for dynamic use");
RNA_def_property_update(prop, NC_SCENE, NULL);
/* Framing */
prop = RNA_def_property(srna, "frame_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "framing.type");

View File

@@ -57,7 +57,6 @@
#include "RAS_GLExtensionManager.h"
#include "RAS_OpenGLRasterizer.h"
#include "RAS_VAOpenGLRasterizer.h"
#include "RAS_ListRasterizer.h"
#include "NG_LoopBackNetworkDeviceInterface.h"
@@ -205,19 +204,16 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
RAS_IRasterizer* rasterizer = NULL;
if (displaylists) {
if (GLEW_VERSION_1_1 && !novertexarrays)
rasterizer = new RAS_ListRasterizer(canvas, true, true);
else
rasterizer = new RAS_ListRasterizer(canvas);
}
else if (GLEW_VERSION_1_1 && !novertexarrays)
rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
//Don't use displaylists with VBOs
//If auto starts using VBOs, make sure to check for that here
if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO)
rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage);
else
rasterizer = new RAS_OpenGLRasterizer(canvas);
rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage);
// create the inputdevices
KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
// create a networkdevice

View File

@@ -53,10 +53,9 @@
class BL_BlenderInputDevice : public SCA_IInputDevice
{
public:
BL_BlenderInputDevice()
BL_BlenderInputDevice()
{
}
virtual ~BL_BlenderInputDevice()
{

View File

@@ -777,33 +777,27 @@ bool ConvertMaterial(
// No material - old default TexFace properties
material->ras_mode |= USE_LIGHT;
}
MT_Point2 uv[4];
MT_Point2 uv2[4];
const char *uvName = "", *uv2Name = "";
uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
MT_Point2 uvs[4][MAXTEX];
/* No material, what to do? let's see what is in the UV and set the material accordingly
* light and visible is always on */
if ( validface ) {
material->tile = tface->tile;
uv[0].setValue(tface->uv[0]);
uv[1].setValue(tface->uv[1]);
uv[2].setValue(tface->uv[2]);
uvs[0][0].setValue(tface->uv[0]);
uvs[1][0].setValue(tface->uv[1]);
uvs[2][0].setValue(tface->uv[2]);
if (mface->v4)
uv[3].setValue(tface->uv[3]);
uvName = tfaceName;
uvs[3][0].setValue(tface->uv[3]);
}
else {
// nothing at all
material->alphablend = GEMAT_SOLID;
material->tile = 0;
uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
uvs[0][0]= uvs[1][0]= uvs[2][0]= uvs[3][0]= MT_Point2(0.0f, 0.0f);
}
if (validmat && validface) {
@@ -823,51 +817,43 @@ bool ConvertMaterial(
// get uv sets
if (validmat)
{
bool isFirstSet = true;
// only two sets implemented, but any of the eight
// sets can make up the two layers
for (int vind = 0; vind<material->num_enabled; vind++)
{
BL_Mapping &map = material->mapping[vind];
if (map.uvCoName.IsEmpty())
isFirstSet = false;
else
//If no UVSet is specified, try grabbing one from the UV/Image editor
if (map.uvCoName.IsEmpty() && validface)
{
uvs[0][vind].setValue(tface->uv[0]);
uvs[1][vind].setValue(tface->uv[1]);
uvs[2][vind].setValue(tface->uv[2]);
if (mface->v4)
uvs[3][vind].setValue(tface->uv[3]);
continue;
}
for (int lay=0; lay<MAX_MTFACE; lay++)
{
for (int lay=0; lay<MAX_MTFACE; lay++)
MTF_localLayer& layer = layers[lay];
if (layer.face == 0) break;
if (map.uvCoName.IsEmpty() || strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
{
MTF_localLayer& layer = layers[lay];
if (layer.face == 0) break;
MT_Point2 uvSet[4];
if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
{
MT_Point2 uvSet[4];
uvs[0][vind].setValue(layer.face->uv[0]);
uvs[1][vind].setValue(layer.face->uv[1]);
uvs[2][vind].setValue(layer.face->uv[2]);
uvSet[0].setValue(layer.face->uv[0]);
uvSet[1].setValue(layer.face->uv[1]);
uvSet[2].setValue(layer.face->uv[2]);
if (mface->v4)
uvs[3][vind].setValue(layer.face->uv[3]);
else
uvs[3][vind].setValue(0.0f, 0.0f);
if (mface->v4)
uvSet[3].setValue(layer.face->uv[3]);
else
uvSet[3].setValue(0.0f, 0.0f);
if (isFirstSet)
{
uv[0] = uvSet[0]; uv[1] = uvSet[1];
uv[2] = uvSet[2]; uv[3] = uvSet[3];
isFirstSet = false;
uvName = layer.name;
}
else if (strcmp(layer.name, uvName) != 0)
{
uv2[0] = uvSet[0]; uv2[1] = uvSet[1];
uv2[2] = uvSet[2]; uv2[3] = uvSet[3];
map.mapping |= USECUSTOMUV;
uv2Name = layer.name;
}
}
break;
}
}
}
@@ -886,8 +872,7 @@ bool ConvertMaterial(
}
material->SetConversionRGB(rgb);
material->SetConversionUV(uvName, uv);
material->SetConversionUV2(uv2Name, uv2);
material->SetConversionUV(uvs);
if (validmat)
material->matname =(mat->id.name);
@@ -967,8 +952,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
{
Material* ma = 0;
bool collider = true;
MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT];
unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
MT_Point3 pt0, pt1, pt2, pt3;
@@ -1045,13 +1029,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
rgb0 = rgb[0]; rgb1 = rgb[1];
rgb2 = rgb[2]; rgb3 = rgb[3];
bl_mat->GetConversionUV(uv);
uv0 = uv[0]; uv1 = uv[1];
uv2 = uv[2]; uv3 = uv[3];
bl_mat->GetConversionUV2(uv);
uv20 = uv[0]; uv21 = uv[1];
uv22 = uv[2]; uv23 = uv[3];
bl_mat->GetConversionUV(uvs);
/* then the KX_BlenderMaterial */
if (kx_blmat == NULL)
@@ -1108,12 +1086,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
/* set UV properties */
if (tface) {
uv0.setValue(tface->uv[0]);
uv1.setValue(tface->uv[1]);
uv2.setValue(tface->uv[2]);
uvs[0][0].setValue(tface->uv[0]);
uvs[1][0].setValue(tface->uv[1]);
uvs[2][0].setValue(tface->uv[2]);
if (mface->v4)
uv3.setValue(tface->uv[3]);
uvs[3][0].setValue(tface->uv[3]);
tile = tface->tile;
}
@@ -1232,12 +1210,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
poly->SetTwoside(twoside);
//poly->SetEdgeCode(mface->edcode);
meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
meshobj->AddVertex(poly,0,pt0,uvs[0],tan0,rgb0,no0,flat,mface->v1);
meshobj->AddVertex(poly,1,pt1,uvs[1],tan1,rgb1,no1,flat,mface->v2);
meshobj->AddVertex(poly,2,pt2,uvs[2],tan2,rgb2,no2,flat,mface->v3);
if (nverts==4)
meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
meshobj->AddVertex(poly,3,pt3,uvs[3],tan3,rgb3,no3,flat,mface->v4);
}
if (tface)
@@ -1637,6 +1615,11 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
// Get collision mask information and store it in the upper 8 bits
// The lower 8 bits are reserved for internal blender usage
objprop.m_col_group = blenderobject->col_group << 8;
objprop.m_col_mask = blenderobject->col_mask << 8;
///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
if (objprop.m_angular_rigidbody || !objprop.m_dyna )
@@ -1890,7 +1873,11 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
lightobj.m_type = RAS_LightObject::LIGHT_SUN;
} else if (la->type==LA_SPOT) {
lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
} else {
} else if (la->type==LA_HEMI) {
lightobj.m_type = RAS_LightObject::LIGHT_HEMI;
} else if (la->type==LA_AREA) {
lightobj.m_type = RAS_LightObject::LIGHT_AREA;
}else {
lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
}
@@ -2421,6 +2408,11 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
for (SETLOOPER(blenderscene, sce_iter, base))
{
Object* blenderobject = base->object;
// Skip lights from the light pool
if (strcmp(blenderobject->id.name, "__pool__") == 0)
continue;
allblobj.insert(blenderobject);
KX_GameObject* gameobj = gameobject_from_blenderobject(

View File

@@ -35,6 +35,7 @@
#endif
#include "KX_Scene.h"
#include "KX_Light.h"
#include "KX_GameObject.h"
#include "KX_BlenderSceneConverter.h"
#include "KX_IpoConvert.h"
@@ -346,6 +347,15 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
break;
}
// Lights added to the scene during the light pool initialization are now skipped when converting objects
if (blenderscene && m_useglslmat)
KX_LightObject::InitBlenderLightPool(blenderscene,
blenderscene->gm.dynpoints,
blenderscene->gm.dynspots,
blenderscene->gm.dynsuns,
blenderscene->gm.dynhemis,
blenderscene->gm.dynareas);
BL_ConvertBlenderObjects(m_maggie,
destinationscene,
m_ketsjiEngine,
@@ -441,6 +451,8 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
meshit++;
}
}
KX_LightObject::FreeBlenderLightPool();
}
// use blender materials

View File

@@ -76,7 +76,6 @@ extern "C"
#include "SCA_IActuator.h"
#include "RAS_MeshObject.h"
#include "RAS_OpenGLRasterizer.h"
#include "RAS_VAOpenGLRasterizer.h"
#include "RAS_ListRasterizer.h"
#include "RAS_GLExtensionManager.h"
#include "KX_PythonInit.h"
@@ -579,16 +578,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
if (!m_rendertools)
goto initFailed;
if (useLists) {
if (GLEW_VERSION_1_1)
m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
else
m_rasterizer = new RAS_ListRasterizer(m_canvas);
}
else if (GLEW_VERSION_1_1)
m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
//Don't use displaylists with VBOs
//If auto starts using VBOs, make sure to check for that here
if (useLists && gm->raster_storage != RAS_STORE_VBO)
m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage);
else
m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage);
/* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);

View File

@@ -93,21 +93,15 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
ras->SetTexCoordNum(0);
ras->SetAttribNum(attrib_num);
for (i=0; i<attrib_num; i++)
for (i = 0; i < attrib_num; i++)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
for (i = 0; i < attribs.totlayer; i++) {
if (attribs.layer[i].glindex > attrib_num)
continue;
if (attribs.layer[i].type == CD_MTFACE) {
if (!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
else if (!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
else
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
}
if (attribs.layer[i].type == CD_MTFACE)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV, attribs.layer[i].glindex);
else if (attribs.layer[i].type == CD_TANGENT)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
else if (attribs.layer[i].type == CD_ORCO)

View File

@@ -65,14 +65,14 @@ void BL_Material::Initialize()
num_users = 1;
share = false;
int i;
for (i=0; i<4; i++)
int i,j;
for (i = 0; i < 4; i++)
{
uv[i] = MT_Point2(0.f,1.f);
uv2[i] = MT_Point2(0.f, 1.f);
for (j = 0; j < MAXTEX; j++)
uvs[i][j] = MT_Point2(0.0,0.0);
}
for (i=0; i<MAXTEX; i++) // :(
for (i = 0; i < MAXTEX; i++) // :(
{
mapping[i].mapping = 0;
mapping[i].offsets[0] = 0.f;
@@ -114,37 +114,24 @@ void BL_Material::GetConversionRGB(unsigned int *nrgb)
*nrgb = rgb[3];
}
void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv)
void BL_Material::SetConversionUV(const MT_Point2 nuv[4][MAXTEX])
{
uvName = name;
uv[0] = *nuv++;
uv[1] = *nuv++;
uv[2] = *nuv++;
uv[3] = *nuv;
int i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < MAXTEX; ++j)
uvs[i][j] = nuv[i][j];
}
}
void BL_Material::GetConversionUV(MT_Point2 *nuv)
void BL_Material::GetConversionUV(MT_Point2 nuv[4][8])
{
*nuv++ = uv[0];
*nuv++ = uv[1];
*nuv++ = uv[2];
*nuv = uv[3];
}
void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv)
{
uv2Name = name;
uv2[0] = *nuv++;
uv2[1] = *nuv++;
uv2[2] = *nuv++;
uv2[3] = *nuv;
}
void BL_Material::GetConversionUV2(MT_Point2 *nuv)
{
*nuv++ = uv2[0];
*nuv++ = uv2[1];
*nuv++ = uv2[2];
*nuv = uv2[3];
int i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < MAXTEX; ++j)
nuv[i][j] = this->uvs[i][j];
}
}

View File

@@ -89,20 +89,13 @@ public:
EnvMap* cubemap[MAXTEX];
unsigned int rgb[4];
MT_Point2 uv[4];
MT_Point2 uv2[4];
STR_String uvName;
STR_String uv2Name;
MT_Point2 uvs[4][MAXTEX];
void SetConversionRGB(unsigned int *rgb);
void GetConversionRGB(unsigned int *rgb);
void SetConversionUV(const STR_String& name, MT_Point2 *uv);
void GetConversionUV(MT_Point2 *uv);
void SetConversionUV2(const STR_String& name, MT_Point2 *uv);
void GetConversionUV2(MT_Point2 *uv);
void SetConversionUV(const MT_Point2 uv[4][MAXTEX]);
void GetConversionUV(MT_Point2 uv[4][MAXTEX]);
void SetSharedMaterial(bool v);
bool IsShared();

View File

@@ -144,7 +144,15 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap)
mNeedsDeleted = 1;
glGenTextures(1, (GLuint*)&mTexture);
#ifdef WITH_DDS
if (ibuf->ftype & DDS)
InitGLCompressedTex(ibuf, mipmap);
else
InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap);
#else
InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap);
#endif
// track created units
BL_TextureObject obj;
@@ -183,6 +191,64 @@ void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
void BL_Texture::InitGLCompressedTex(ImBuf* ibuf, bool mipmap)
{
#ifndef WITH_DDS
// Fall back to uncompressed if DDS isn't enabled
InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap);
return;
#else
GLint format=0;
int offset=0, i=0;
int blocksize, width, height;
int size;
GLint err;
if (ibuf->dds_data.fourcc == FOURCC_DXT1)
format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
else if (ibuf->dds_data.fourcc == FOURCC_DXT3)
format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
else if (ibuf->dds_data.fourcc == FOURCC_DXT5)
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
else
{
printf("Unable to find a suitable DXT compression, falling back to uncompressed\n");
InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap);
return;
}
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
height = ibuf->x;
width = ibuf->y;
blocksize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
for (int i=0; i<ibuf->dds_data.nummipmaps && (width||height); ++i)
{
if (width == 0)
width = 1;
if (height == 0)
height = 1;
size = ((width+3)/4)*((height+3)/4)*blocksize;
glCompressedTexImage2D(GL_TEXTURE_2D, i, format, width, height,
0, size, ibuf->dds_data.data + offset);
err = glGetError();
if (err != GL_NO_ERROR)
printf("OpenGL error: %s\nFormat: %x\n", gluErrorString(err), format);
offset += size;
width >>= 1;
height >>= 1;
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#endif
}
void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
{
@@ -681,4 +747,3 @@ void my_free_envmapdata(EnvMap *env)
} // extern C

View File

@@ -35,6 +35,7 @@ private:
void InitNonPow2Tex(unsigned int *p,int x,int y,bool mipmap );
void InitGLTex(unsigned int *p,int x,int y,bool mipmap );
void InitGLCompressedTex(struct ImBuf *p, bool mipmap);
public:
BL_Texture();
~BL_Texture( );

View File

@@ -221,6 +221,10 @@ set(SRC
add_definitions(-DGLEW_STATIC)
if(WITH_IMAGE_DDS)
add_definitions(-DWITH_DDS)
endif()
if(WITH_SDL)
list(APPEND INC_SYS
${SDL_INCLUDE_DIR}

View File

@@ -639,13 +639,6 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
for (int i=0; i<mMaterial->num_enabled; i++) {
int mode = mMaterial->mapping[i].mapping;
if (mode &USECUSTOMUV)
{
if (!mMaterial->mapping[i].uvCoName.IsEmpty())
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i);
continue;
}
if ( mode &(USEREFL|USEOBJ))
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i);
else if (mode &USEORCO)
@@ -653,7 +646,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
else if (mode &USENORM)
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i);
else if (mode &USEUV)
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i);
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV, i);
else if (mode &USETANG)
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i);
else

View File

@@ -80,6 +80,11 @@ struct KX_ObjectProperties
/////////////////////////
short m_col_group;
short m_col_mask;
/////////////////////////
int m_gamesoftFlag;
float m_soft_linStiff; /* linear stiffness 0..1 */
float m_soft_angStiff; /* angular stiffness 0..1 */

View File

@@ -400,12 +400,12 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
////////////////////
ci.m_collisionFilterGroup =
(isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) :
(isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) :
short(CcdConstructionInfo::StaticFilter);
ci.m_collisionFilterGroup = objprop->m_col_group;
ci.m_collisionFilterMask =
(isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) :
(isbulletdyna) ? short(CcdConstructionInfo::AllFilter) :
short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
ci.m_collisionFilterMask = objprop->m_col_mask;
ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so

View File

@@ -2972,7 +2972,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
m_testPropName = propName;
else
m_testPropName.SetLength(0);
KX_RayCast::Callback<KX_GameObject> callback(this,spc);
KX_RayCast::Callback<KX_GameObject> callback(this,spc, NULL, false, true);
KX_RayCast::RayTest(pe, fromPoint, toPoint, callback);
if (m_pHitObject)

View File

@@ -46,6 +46,32 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "GPU_material.h"
#include "MEM_guardedalloc.h"
extern "C"
{
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_library.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BLI_listbase.h"
}
typedef struct PoolLight {
Object* blenderlight;
bool lock;
} PoolLight;
static Scene* m_blenderlight_scene = NULL;
static int m_blenderlight_count = 0;
static std::vector<PoolLight*> m_blenderlight_points = vector<PoolLight*>();
static std::vector<PoolLight*> m_blenderlight_spots = vector<PoolLight*>();
static std::vector<PoolLight*> m_blenderlight_suns = vector<PoolLight*>();
static std::vector<PoolLight*> m_blenderlight_hemis = vector<PoolLight*>();
static std::vector<PoolLight*> m_blenderlight_areas = vector<PoolLight*>();
KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
class RAS_IRenderTools* rendertools,
@@ -59,13 +85,16 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
m_lightobj.m_light = this;
m_rendertools->AddLight(&m_lightobj);
m_glsl = glsl;
m_poollight = NULL;
m_blenderscene = ((KX_Scene*)sgReplicationInfo)->GetBlenderScene();
m_dynamic = false;
};
KX_LightObject::~KX_LightObject()
{
GPULamp *lamp;
Object* obj;
if ((lamp = GetGPULamp())) {
float obmat[4][4] = {{0}};
@@ -73,6 +102,9 @@ KX_LightObject::~KX_LightObject()
}
m_rendertools->RemoveLight(&m_lightobj);
if (m_dynamic && m_poollight)
checkin_blenderlight();
}
@@ -86,9 +118,17 @@ CValue* KX_LightObject::GetReplica()
replica->m_lightobj.m_light = replica;
m_rendertools->AddLight(&replica->m_lightobj);
replica->MakeDynamic();
return replica;
}
void KX_LightObject::MakeDynamic()
{
m_dynamic = true;
checkout_blenderlight();
}
bool KX_LightObject::ApplyLight(KX_Scene *kxscene, int oblayer, int slot)
{
KX_Scene* lightscene = (KX_Scene*)m_lightobj.m_scene;
@@ -181,8 +221,11 @@ bool KX_LightObject::ApplyLight(KX_Scene *kxscene, int oblayer, int slot)
GPULamp *KX_LightObject::GetGPULamp()
{
if (m_glsl)
return GPU_lamp_from_blender(m_blenderscene, GetBlenderObject(), GetBlenderGroupObject());
if (m_glsl && GetBlenderObject())
{
Scene *scene = (m_dynamic) ? m_blenderlight_scene : m_blenderscene;
return GPU_lamp_from_blender(scene, GetBlenderObject(), GetBlenderGroupObject());
}
else
return NULL;
}
@@ -192,6 +235,12 @@ void KX_LightObject::Update()
GPULamp *lamp;
if ((lamp = GetGPULamp()) != NULL && GetSGNode()) {
// If the light is inactive, we can reuse it's blender light for active lights
if (m_lightobj.m_layer != m_blenderscene->layact) {
forfeit_blenderlight();
return;
}
float obmat[4][4];
// lights don't get their openGL matrix updated, do it now
if (GetSGNode()->IsDirty())
@@ -205,6 +254,8 @@ void KX_LightObject::Update()
GPU_lamp_update(lamp, m_lightobj.m_layer, 0, obmat);
GPU_lamp_update_colors(lamp, m_lightobj.m_red, m_lightobj.m_green,
m_lightobj.m_blue, m_lightobj.m_energy);
GPU_lamp_update_distance(lamp, m_lightobj.m_distance, m_lightobj.m_att1, m_lightobj.m_att2);
GPU_lamp_update_spot(lamp, m_lightobj.m_spotsize, m_lightobj.m_spotblend);
}
}
@@ -267,6 +318,149 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
GPU_lamp_shadow_buffer_unbind(lamp);
}
void init_subpool(Scene *scene, std::vector<PoolLight*> *subpool, int count, short type)
{
Lamp *la;
subpool->resize(count);
for (int i = 0; i < count; ++i)
{
subpool->at(i) = new PoolLight();
subpool->at(i)->blenderlight = add_object(m_blenderlight_scene, OB_LAMP);
//Give the lights a unique name so the converter can avoid them
strcpy(subpool->at(i)->blenderlight->id.name, "__pool__");
la = (Lamp*)subpool->at(i)->blenderlight->data;
la->type = type;
la->energy = 0;
}
}
void KX_LightObject::InitBlenderLightPool(Scene *scene, int point_count, int spot_count, int sun_count, int hemi_count, int area_count)
{
//If the light pool is already built, there is no need to rebuild it,
//we don't want libload trying to reinitialize the light pool
if (m_blenderlight_count != 0)
return;
m_blenderlight_scene = scene;
m_blenderlight_count = point_count + spot_count + sun_count + hemi_count + area_count;
//Don't bother finishing setup if there are no lights in the pools
//Also if no Dynamic lights are allocated, sometimes libload will get passed the count
//check and screw things up
if (m_blenderlight_count == 0)
return;
init_subpool(scene, &m_blenderlight_points, point_count, LA_LOCAL);
init_subpool(scene, &m_blenderlight_spots, spot_count, LA_SPOT);
init_subpool(scene, &m_blenderlight_suns, sun_count, LA_SUN);
init_subpool(scene, &m_blenderlight_hemis, hemi_count, LA_HEMI);
init_subpool(scene, &m_blenderlight_areas, area_count, LA_AREA);
GPU_materials_free();
}
std::vector<PoolLight*>* get_subpool(short type)
{
if (type == RAS_LightObject::LIGHT_NORMAL)
return &m_blenderlight_points;
if (type == RAS_LightObject::LIGHT_SPOT)
return &m_blenderlight_spots;
if (type == RAS_LightObject::LIGHT_SUN)
return &m_blenderlight_suns;
if (type == RAS_LightObject::LIGHT_HEMI)
return &m_blenderlight_hemis;
if (type == RAS_LightObject::LIGHT_AREA)
return &m_blenderlight_areas;
}
void KX_LightObject::checkout_blenderlight()
{
std::vector<PoolLight*> *subpool = get_subpool(m_lightobj.m_type);
if (subpool->size() == 0)
{
SetBlenderObject(NULL);
return; //Sorry, out of lights :(
}
PoolLight* light = subpool->back();
subpool->pop_back();
m_poollight = light;
SetBlenderObject(light->blenderlight);
}
void KX_LightObject::checkin_blenderlight()
{
PoolLight* light = m_poollight;
std::vector<PoolLight*> *subpool = get_subpool(m_lightobj.m_type);
subpool->push_back(light);
m_poollight = NULL;
}
void KX_LightObject::forfeit_blenderlight()
{
std::vector<PoolLight*> *subpool = get_subpool(m_lightobj.m_type);
Object *obj = GetBlenderObject();
PoolLight* light = new PoolLight();
light->blenderlight = obj;
light->lock = true;
SetBlenderObject(NULL);
subpool->push_back(light);
m_blenderlight_count++;
}
void KX_LightObject::FreeBlenderLightPool()
{
Base *base;
std::vector<PoolLight*> *subpool;
PoolLight *light;
unsigned int i = 0;
int total = m_blenderlight_points.size() + m_blenderlight_spots.size() + m_blenderlight_suns.size() + m_blenderlight_hemis.size() + m_blenderlight_areas.size();
if (total != m_blenderlight_count)
{
printf("Light pool still has lights checked out. Or extra lights have been checked in\n");
m_blenderlight_count = total;
}
for (int i = 0; i < m_blenderlight_count; ++i)
{
if (m_blenderlight_points.size() > 0)
subpool = &m_blenderlight_points;
else if (m_blenderlight_spots.size() > 0)
subpool = &m_blenderlight_spots;
else if (m_blenderlight_suns.size() > 0)
subpool = &m_blenderlight_suns;
else if (m_blenderlight_hemis.size() > 0)
subpool = &m_blenderlight_hemis;
else if (m_blenderlight_areas.size() > 0)
subpool = &m_blenderlight_areas;
light = subpool->back();
if (light->lock)
{
subpool->pop_back();
continue;
}
base = object_in_scene(light->blenderlight, m_blenderlight_scene);
BLI_remlink(&m_blenderlight_scene->base, base);
GPU_lamp_free(base->object);
free_libblock_us(&G.main->object, base->object);
if (m_blenderlight_scene->basact == base) m_blenderlight_scene->basact = NULL;
MEM_freeN(base);
subpool->pop_back();
}
m_blenderlight_count = 0;
GPU_materials_free();
}
#ifdef WITH_PYTHON
/* ------------------------------------------------------------------------- */
/* Python Integration Hooks */

View File

@@ -34,9 +34,11 @@
#include "RAS_LightObject.h"
#include "KX_GameObject.h"
#include "DNA_lamp_types.h"
struct GPULamp;
struct Scene;
struct PoolLight;
class KX_Camera;
class RAS_IRasterizer;
class RAS_IRenderTools;
@@ -47,15 +49,22 @@ class KX_LightObject : public KX_GameObject
Py_Header
protected:
RAS_LightObject m_lightobj;
PoolLight* m_poollight;
class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj
bool m_glsl;
Scene* m_blenderscene;
bool m_dynamic;
void checkout_blenderlight();
void checkin_blenderlight();
void forfeit_blenderlight();
public:
KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, bool glsl);
virtual ~KX_LightObject();
virtual CValue* GetReplica();
RAS_LightObject* GetLightData() { return &m_lightobj;}
void MakeDynamic();
/* OpenGL Light */
bool ApplyLight(KX_Scene *kxscene, int oblayer, int slot);
@@ -67,6 +76,10 @@ public:
void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans);
void UnbindShadowBuffer(class RAS_IRasterizer *ras);
void Update();
/* Light Pool */
static void InitBlenderLightPool(Scene *scene, int point_count, int spot_count, int sun_count, int hemi_count, int area_count);
static void FreeBlenderLightPool();
void UpdateScene(class KX_Scene *kxscene) {m_lightobj.m_scene = (void*)kxscene;}

View File

@@ -1821,9 +1821,12 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
}
#endif // USE_BULLET
}
/* If the object is a light, update it's scene */
/* If the object is a light, update it's scene and make it dynamic*/
if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
{
((KX_LightObject*)gameobj)->UpdateScene(to);
((KX_LightObject*)gameobj)->MakeDynamic();
}
/* Add the object to the scene's logic manager */
to->GetLogicManager()->RegisterGameObjectName(gameobj->GetName(), gameobj);

View File

@@ -146,25 +146,25 @@ PyObject* KX_VertexProxy::pyattr_get_a(void *self_v, const KX_PYATTRIBUTE_DEF *a
PyObject* KX_VertexProxy::pyattr_get_u(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
return PyFloat_FromDouble(self->m_vertex->getUV1()[0]);
return PyFloat_FromDouble(self->m_vertex->getUV(0)[0]);
}
PyObject* KX_VertexProxy::pyattr_get_v(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
return PyFloat_FromDouble(self->m_vertex->getUV1()[1]);
return PyFloat_FromDouble(self->m_vertex->getUV(0)[1]);
}
PyObject* KX_VertexProxy::pyattr_get_u2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
return PyFloat_FromDouble(self->m_vertex->getUV2()[0]);
return PyFloat_FromDouble(self->m_vertex->getUV(1)[0]);
}
PyObject* KX_VertexProxy::pyattr_get_v2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
return PyFloat_FromDouble(self->m_vertex->getUV2()[1]);
return PyFloat_FromDouble(self->m_vertex->getUV(1)[1]);
}
PyObject* KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -176,7 +176,7 @@ PyObject* KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF
PyObject* KX_VertexProxy::pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
return PyObjectFrom(MT_Point2(self->m_vertex->getUV1()));
return PyObjectFrom(MT_Point2(self->m_vertex->getUV(0)));
}
PyObject* KX_VertexProxy::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -245,9 +245,9 @@ int KX_VertexProxy::pyattr_set_u(void *self_v, const struct KX_PYATTRIBUTE_DEF *
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
MT_Point2 uv = self->m_vertex->getUV1();
MT_Point2 uv = self->m_vertex->getUV(0);
uv[0] = val;
self->m_vertex->SetUV(uv);
self->m_vertex->SetUV(0, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -260,9 +260,9 @@ int KX_VertexProxy::pyattr_set_v(void *self_v, const struct KX_PYATTRIBUTE_DEF *
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
MT_Point2 uv = self->m_vertex->getUV1();
MT_Point2 uv = self->m_vertex->getUV(0);
uv[1] = val;
self->m_vertex->SetUV(uv);
self->m_vertex->SetUV(0, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -275,9 +275,9 @@ int KX_VertexProxy::pyattr_set_u2(void *self_v, const struct KX_PYATTRIBUTE_DEF
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
MT_Point2 uv = self->m_vertex->getUV2();
MT_Point2 uv = self->m_vertex->getUV(1);
uv[0] = val;
self->m_vertex->SetUV2(uv);
self->m_vertex->SetUV(1, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -290,9 +290,9 @@ int KX_VertexProxy::pyattr_set_v2(void *self_v, const struct KX_PYATTRIBUTE_DEF
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
MT_Point2 uv = self->m_vertex->getUV2();
MT_Point2 uv = self->m_vertex->getUV(1);
uv[1] = val;
self->m_vertex->SetUV2(uv);
self->m_vertex->SetUV(1, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -391,7 +391,7 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
MT_Point2 vec;
if (PyVecTo(value, vec))
{
self->m_vertex->SetUV(vec);
self->m_vertex->SetUV(0, vec);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -523,7 +523,7 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject* value)
PyObject* KX_VertexProxy::PyGetUV()
{
return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
return PyObjectFrom(MT_Vector2(m_vertex->getUV(0)));
}
PyObject* KX_VertexProxy::PySetUV(PyObject* value)
@@ -532,31 +532,23 @@ PyObject* KX_VertexProxy::PySetUV(PyObject* value)
if (!PyVecTo(value, vec))
return NULL;
m_vertex->SetUV(vec);
m_vertex->SetUV(0, vec);
m_mesh->SetMeshModified(true);
Py_RETURN_NONE;
}
PyObject* KX_VertexProxy::PyGetUV2()
{
return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
return PyObjectFrom(MT_Vector2(m_vertex->getUV(1)));
}
PyObject* KX_VertexProxy::PySetUV2(PyObject* args)
PyObject* KX_VertexProxy::PySetUV2(PyObject* value)
{
MT_Point2 vec;
unsigned int unit= RAS_TexVert::SECOND_UV;
PyObject* list= NULL;
if (!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit))
if (!PyVecTo(value, vec))
return NULL;
if (!PyVecTo(list, vec))
return NULL;
m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
m_vertex->SetUnit(unit);
m_vertex->SetUV2(vec);
m_vertex->SetUV(1, vec);
m_mesh->SetMeshModified(true);
Py_RETURN_NONE;
}

View File

@@ -221,7 +221,8 @@ struct CcdConstructionInfo
KinematicFilter = 4,
DebrisFilter = 8,
SensorFilter = 16,
AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorFilter,
UserFilter = 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12 | 1<<13 | 1<<14 | 1<<15,
AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorFilter | UserFilter,
};

View File

@@ -1095,6 +1095,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
// don't collision with sensor object
rayCallback.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter;
rayCallback.m_collisionFilterGroup = CcdConstructionInfo::AllFilter;
//, ,filterCallback.m_faceNormal);
m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback);

View File

@@ -52,6 +52,7 @@ using namespace std;
class RAS_ICanvas;
class RAS_IPolyMaterial;
class RAS_MeshSlot;
typedef vector<unsigned short> KX_IndexArray;
typedef vector<RAS_TexVert> KX_VertexArray;
@@ -129,7 +130,7 @@ public:
RAS_TEXCO_GEN, //< GPU will generate texture coordinates
RAS_TEXCO_ORCO, //< Vertex coordinates (object space)
RAS_TEXCO_GLOB, //< Vertex coordinates (world space)
RAS_TEXCO_UV1, //< UV coordinates
RAS_TEXCO_UV, //< UV coordinates
RAS_TEXCO_OBJECT, //< Use another object's position as coordinates
RAS_TEXCO_LAVECTOR, //< Light vector as coordinates
RAS_TEXCO_VIEW, //< View vector as coordinates
@@ -137,7 +138,6 @@ public:
RAS_TEXCO_WINDOW, //< Window coordinates
RAS_TEXCO_NORM, //< Normal coordinates
RAS_TEXTANGENT, //<
RAS_TEXCO_UV2, //<
RAS_TEXCO_VCOL, //< Vertex Color
RAS_TEXCO_DISABLE //< Disable this texture unit (cached)
};

View File

@@ -39,7 +39,9 @@ struct RAS_LightObject
enum LightType{
LIGHT_SPOT,
LIGHT_SUN,
LIGHT_NORMAL
LIGHT_NORMAL,
LIGHT_HEMI,
LIGHT_AREA
};
bool m_modified;
int m_layer;

View File

@@ -47,6 +47,7 @@
#include "RAS_MeshObject.h"
#include "RAS_Deformer.h" // __NLA
/* mesh slot */
RAS_MeshSlot::RAS_MeshSlot() : SG_QList()
@@ -605,7 +606,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
if (ms.m_pDeformer)
{
ms.m_pDeformer->Apply(m_material);
if (ms.m_pDeformer->Apply(m_material));
ms.m_mesh->SetMeshModified(true);
// KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_)
}
@@ -648,9 +650,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
else
rasty->IndexPrimitives(ms);
if (rasty->QueryLists())
if (ms.m_DisplayList)
ms.m_mesh->SetMeshModified(false);
ms.m_mesh->SetMeshModified(false);
rendertools->PopMatrix();
}

View File

@@ -324,15 +324,14 @@ void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i,
const MT_Point3& xyz,
const MT_Point2& uv,
const MT_Point2& uv2,
const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
bool flat,
int origindex)
{
RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex);
RAS_TexVert texvert(xyz, uvs, tangent, rgba, normal, flat, origindex);
RAS_MeshMaterial *mmat;
RAS_DisplayArray *darray;
RAS_MeshSlot *slot;

View File

@@ -116,8 +116,7 @@ public:
virtual RAS_Polygon* AddPolygon(RAS_MaterialBucket *bucket, int numverts);
virtual void AddVertex(RAS_Polygon *poly, int i,
const MT_Point3& xyz,
const MT_Point2& uv,
const MT_Point2& uv2,
const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgbacolor,
const MT_Vector3& normal,

View File

@@ -46,12 +46,17 @@ set(SRC
RAS_GLExtensionManager.cpp
RAS_ListRasterizer.cpp
RAS_OpenGLRasterizer.cpp
RAS_VAOpenGLRasterizer.cpp
RAS_StorageIM.cpp
RAS_StorageVA.cpp
RAS_StorageVBO.cpp
RAS_GLExtensionManager.h
RAS_IStorage.h
RAS_ListRasterizer.h
RAS_OpenGLRasterizer.h
RAS_VAOpenGLRasterizer.h
RAS_StorageIM.h
RAS_StorageVA.h
RAS_StorageVBO.h
)
add_definitions(-DGLEW_STATIC)

View File

@@ -0,0 +1,62 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __KX_STORAGE
#define __KX_STORAGE
#include "RAS_MaterialBucket.h"
enum RAS_STORAGE_TYPE {
RAS_AUTO_STORAGE,
RAS_IMMEDIATE,
RAS_VA,
RAS_VBO
};
class RAS_IStorage
{
public:
virtual ~RAS_IStorage() {};
virtual bool Init()=0;
virtual void Exit()=0;
virtual void IndexPrimitives(RAS_MeshSlot& ms)=0;
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms)=0;
virtual void SetDrawingMode(int drawingmode)=0;
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_IStorage"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif //__KX_STORAGE

View File

@@ -106,9 +106,8 @@ bool RAS_ListSlot::End()
RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock)
: RAS_VAOpenGLRasterizer(canvas, lock),
mUseVertexArrays(useVertexArrays),
RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock, int storage)
: RAS_OpenGLRasterizer(canvas, storage),
mATI(false)
{
if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc."))
@@ -238,11 +237,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
return;
}
}
// derived mesh cannot use vertex array
if (mUseVertexArrays && !ms.m_pDerivedMesh)
RAS_VAOpenGLRasterizer::IndexPrimitives(ms);
else
RAS_OpenGLRasterizer::IndexPrimitives(ms);
RAS_OpenGLRasterizer::IndexPrimitives(ms);
if (ms.m_bDisplayList) {
localSlot->EndList();
@@ -267,13 +263,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
}
}
// workaround: note how we do not use vertex arrays for making display
// lists, since glVertexAttribPointerARB doesn't seem to work correct
// in display lists on ATI? either a bug in the driver or in Blender ..
if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh)
RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms);
else
RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
if (ms.m_bDisplayList) {
localSlot->EndList();
@@ -283,29 +273,17 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
bool RAS_ListRasterizer::Init(void)
{
if (mUseVertexArrays) {
return RAS_VAOpenGLRasterizer::Init();
} else {
return RAS_OpenGLRasterizer::Init();
}
return RAS_OpenGLRasterizer::Init();
}
void RAS_ListRasterizer::SetDrawingMode(int drawingmode)
{
if (mUseVertexArrays) {
RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode);
} else {
RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
}
RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
}
void RAS_ListRasterizer::Exit()
{
if (mUseVertexArrays) {
RAS_VAOpenGLRasterizer::Exit();
} else {
RAS_OpenGLRasterizer::Exit();
}
RAS_OpenGLRasterizer::Exit();
}
// eof

View File

@@ -7,7 +7,7 @@
#define __RAS_LISTRASTERIZER_H__
#include "RAS_MaterialBucket.h"
#include "RAS_VAOpenGLRasterizer.h"
#include "RAS_OpenGLRasterizer.h"
#include <vector>
#include <map>
@@ -49,7 +49,7 @@ typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
typedef std::vector<RAS_ListSlot*> RAS_ListSlots; // indexed by material slot number
typedef std::map<DerivedMesh*, RAS_ListSlots*> RAS_DerivedMeshLists;
class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
class RAS_ListRasterizer : public RAS_OpenGLRasterizer
{
bool mUseVertexArrays;
bool mATI;
@@ -61,7 +61,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
public:
void RemoveListSlot(RAS_ListSlot* list);
RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false);
RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock=false, int storage=RAS_AUTO_STORAGE);
virtual ~RAS_ListRasterizer();
virtual void IndexPrimitives(class RAS_MeshSlot& ms);

View File

@@ -43,6 +43,10 @@
#include "MT_CmMatrix4x4.h"
#include "RAS_IRenderTools.h" // rendering text
#include "RAS_StorageIM.h"
#include "RAS_StorageVA.h"
#include "RAS_StorageVBO.h"
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
@@ -71,7 +75,7 @@ static GLuint right_eye_vinterlace_mask[32];
*/
static GLuint hinterlace_mask[33];
RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
:RAS_IRasterizer(canvas),
m_2DCanvas(canvas),
m_fogenabled(false),
@@ -90,7 +94,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_attrib_num(0),
//m_last_alphablend(GPU_BLEND_SOLID),
m_last_frontface(true),
m_materialCachingInfo(0)
m_materialCachingInfo(0),
m_storage_type(storage)
{
m_viewmatrix.setIdentity();
m_viewinvmatrix.setIdentity();
@@ -104,6 +109,24 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
hinterlace_mask[32] = 0;
m_prevafvalue = GPU_get_anisotropic();
if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/)
{
m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
m_storage_type = RAS_VBO;
}
else if (m_storage_type == RAS_VA || m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1)
{
m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
m_storage_type = RAS_VA;
}
else
{
m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
m_storage_type = RAS_IMMEDIATE;
}
}
@@ -112,10 +135,12 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
{
// Restore the previous AF value
GPU_set_anisotropic(m_prevafvalue);
delete m_storage;
}
bool RAS_OpenGLRasterizer::Init()
{
bool storage_init;
GPU_state_init();
@@ -143,7 +168,9 @@ bool RAS_OpenGLRasterizer::Init()
glShadeModel(GL_SMOOTH);
return true;
storage_init = m_storage->Init();
return true && storage_init;
}
@@ -264,6 +291,8 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
void RAS_OpenGLRasterizer::Exit()
{
m_storage->Exit();
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0);
@@ -286,7 +315,7 @@ void RAS_OpenGLRasterizer::Exit()
bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
{
m_time = time;
m_drawingmode = drawingmode;
SetDrawingMode(drawingmode);
// Blender camera routine destroys the settings
if (m_drawingmode < KX_SOLID)
@@ -325,6 +354,8 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
if (m_drawingmode == KX_WIREFRAME)
glDisable(GL_CULL_FACE);
m_storage->SetDrawingMode(drawingmode);
}
int RAS_OpenGLRasterizer::GetDrawingMode()
@@ -664,7 +695,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
glattrib = -1;
if (GLEW_ARB_vertex_program)
for (unit=0; unit<m_attrib_num; unit++)
if (m_attrib[unit] == RAS_TEXCO_UV1)
if (m_attrib[unit] == RAS_TEXCO_UV)
glattrib = unit;
rendertools->RenderText(polymat->GetDrawingMode(), polymat,
@@ -706,256 +737,20 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
m_attrib[unit] = coords;
}
void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
{
int unit;
if (GLEW_ARB_multitexture) {
for (unit=0; unit<m_texco_num; unit++) {
if (tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
continue;
}
switch(m_texco[unit]) {
case RAS_TEXCO_ORCO:
case RAS_TEXCO_GLOB:
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
break;
case RAS_TEXCO_UV1:
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
break;
case RAS_TEXCO_NORM:
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
break;
case RAS_TEXTANGENT:
glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
break;
case RAS_TEXCO_UV2:
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
break;
default:
break;
}
}
}
if (GLEW_ARB_vertex_program) {
for (unit=0; unit<m_attrib_num; unit++) {
switch(m_attrib[unit]) {
case RAS_TEXCO_ORCO:
case RAS_TEXCO_GLOB:
glVertexAttrib3fvARB(unit, tv.getXYZ());
break;
case RAS_TEXCO_UV1:
glVertexAttrib2fvARB(unit, tv.getUV1());
break;
case RAS_TEXCO_NORM:
glVertexAttrib3fvARB(unit, tv.getNormal());
break;
case RAS_TEXTANGENT:
glVertexAttrib4fvARB(unit, tv.getTangent());
break;
case RAS_TEXCO_UV2:
glVertexAttrib2fvARB(unit, tv.getUV2());
break;
case RAS_TEXCO_VCOL:
glVertexAttrib4ubvARB(unit, tv.getRGBA());
break;
default:
break;
}
}
}
}
void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
{
IndexPrimitivesInternal(ms, false);
if (ms.m_pDerivedMesh)
m_failsafe_storage->IndexPrimitives(ms);
else
m_storage->IndexPrimitives(ms);
}
void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
{
IndexPrimitivesInternal(ms, true);
}
static bool current_wireframe;
static RAS_MaterialBucket *current_bucket;
static RAS_IPolyMaterial *current_polymat;
static RAS_MeshSlot *current_ms;
static RAS_MeshObject *current_mesh;
static int current_blmat_nr;
static GPUVertexAttribs current_gpu_attribs;
static Image *current_image;
static int CheckMaterialDM(int matnr, void *attribs)
{
// only draw the current material
if (matnr != current_blmat_nr)
return 0;
GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
if (gattribs)
memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
return 1;
}
/*
static int CheckTexfaceDM(void *mcol, int index)
{
// index is the original face index, retrieve the polygon
RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
current_mesh->GetPolygon(index) : NULL;
if (polygon && polygon->GetMaterial() == current_bucket) {
// must handle color.
if (current_wireframe)
return 2;
if (current_ms->m_bObjectColor) {
MT_Vector4& rgba = current_ms->m_RGBAcolor;
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
// don't use mcol
return 2;
}
if (!mcol) {
// we have to set the color from the material
unsigned char rgba[4];
current_polymat->GetMaterialRGBAColor(rgba);
glColor4ubv((const GLubyte *)rgba);
return 2;
}
return 1;
}
return 0;
}
*/
static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
{
// index is the original face index, retrieve the polygon
if (matnr == current_blmat_nr &&
(tface == NULL || tface->tpage == current_image)) {
// must handle color.
if (current_wireframe)
return DM_DRAW_OPTION_NO_MCOL;
if (current_ms->m_bObjectColor) {
MT_Vector4& rgba = current_ms->m_RGBAcolor;
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
// don't use mcol
return DM_DRAW_OPTION_NO_MCOL;
}
if (!has_mcol) {
// we have to set the color from the material
unsigned char rgba[4];
current_polymat->GetMaterialRGBAColor(rgba);
glColor4ubv((const GLubyte *)rgba);
return DM_DRAW_OPTION_NO_MCOL;
}
return DM_DRAW_OPTION_NORMAL;
}
return DM_DRAW_OPTION_SKIP;
}
void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
{
bool obcolor = ms.m_bObjectColor;
bool wireframe = m_drawingmode <= KX_WIREFRAME;
MT_Vector4& rgba = ms.m_RGBAcolor;
RAS_MeshSlot::iterator it;
if (ms.m_pDerivedMesh) {
// mesh data is in derived mesh,
current_bucket = ms.m_bucket;
current_polymat = current_bucket->GetPolyMaterial();
current_ms = &ms;
current_mesh = ms.m_mesh;
current_wireframe = wireframe;
// MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
// handle two-side
if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
this->SetCullFace(true);
else
this->SetCullFace(false);
if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
// GetMaterialIndex return the original mface material index,
// increment by 1 to match what derived mesh is doing
current_blmat_nr = current_polymat->GetMaterialIndex()+1;
// For GLSL we need to retrieve the GPU material attribute
Material* blmat = current_polymat->GetBlenderMaterial();
Scene* blscene = current_polymat->GetBlenderScene();
if (!wireframe && blscene && blmat)
GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
else
memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
// DM draw can mess up blending mode, restore at the end
int current_blend_mode = GPU_get_material_alpha_blend();
ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
GPU_set_material_alpha_blend(current_blend_mode);
} else {
//ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
current_blmat_nr = current_polymat->GetMaterialIndex();
current_image = current_polymat->GetBlenderImage();
ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
}
return;
}
// iterate over display arrays, each containing an index + vertex array
for (ms.begin(it); !ms.end(it); ms.next(it)) {
RAS_TexVert *vertex;
size_t i, j, numvert;
numvert = it.array->m_type;
if (it.array->m_type == RAS_DisplayArray::LINE) {
// line drawing
glBegin(GL_LINES);
for (i=0; i<it.totindex; i+=2)
{
vertex = &it.vertex[it.index[i]];
glVertex3fv(vertex->getXYZ());
vertex = &it.vertex[it.index[i+1]];
glVertex3fv(vertex->getXYZ());
}
glEnd();
}
else {
// triangle and quad drawing
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
glBegin(GL_TRIANGLES);
else
glBegin(GL_QUADS);
for (i=0; i<it.totindex; i+=numvert)
{
if (obcolor)
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
for (j=0; j<numvert; j++) {
vertex = &it.vertex[it.index[i+j]];
if (!wireframe) {
if (!obcolor)
glColor4ubv((const GLubyte *)(vertex->getRGBA()));
glNormal3fv(vertex->getNormal());
if (multi)
TexCoord(*vertex);
else
glTexCoord2fv(vertex->getUV1());
}
glVertex3fv(vertex->getXYZ());
}
}
glEnd();
}
}
if (ms.m_pDerivedMesh)
m_failsafe_storage->IndexPrimitivesMulti(ms);
else
m_storage->IndexPrimitivesMulti(ms);
}
void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)

View File

@@ -41,6 +41,7 @@
using namespace std;
#include "RAS_IRasterizer.h"
#include "RAS_IStorage.h"
#include "RAS_MaterialBucket.h"
#include "RAS_ICanvas.h"
@@ -83,7 +84,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
float m_ambr;
float m_ambg;
float m_ambb;
double m_time;
MT_Matrix4x4 m_viewmatrix;
MT_Matrix4x4 m_viewinvmatrix;
@@ -115,9 +115,15 @@ protected:
/** Stores the caching information for the last material activated. */
RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
/** Making use of a Strategy desing pattern for storage behavior.
Examples of concrete strategies: Vertex Arrays, VBOs, Immediate Mode*/
int m_storage_type;
RAS_IStorage* m_storage;
RAS_IStorage* m_failsafe_storage; //So derived mesh can use immediate mode
public:
double GetTime();
RAS_OpenGLRasterizer(RAS_ICanvas* canv);
RAS_OpenGLRasterizer(RAS_ICanvas* canv, int storage=RAS_AUTO_STORAGE);
virtual ~RAS_OpenGLRasterizer();
/*enum DrawType
@@ -166,8 +172,6 @@ public:
class RAS_IPolyMaterial* polymat,
class RAS_IRenderTools* rendertools);
void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat);
virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat);
virtual void SetViewMatrix(

View File

@@ -0,0 +1,307 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "RAS_StorageIM.h"
#include "GL/glew.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
#include "DNA_meshdata_types.h"
#include "BKE_DerivedMesh.h"
RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
m_texco_num(texco_num),
m_texco(texco),
m_attrib_num(attrib_num),
m_attrib(attrib)
{
}
RAS_StorageIM::~RAS_StorageIM()
{
}
bool RAS_StorageIM::Init()
{
return true;
}
void RAS_StorageIM::Exit()
{
}
void RAS_StorageIM::IndexPrimitives(RAS_MeshSlot& ms)
{
IndexPrimitivesInternal(ms, false);
}
void RAS_StorageIM::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
{
IndexPrimitivesInternal(ms, true);
}
void RAS_StorageIM::TexCoord(const RAS_TexVert &tv)
{
int unit;
if (GLEW_ARB_multitexture) {
for (unit = 0; unit < *m_texco_num; unit++) {
switch(m_texco[unit]) {
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getXYZ());
break;
case RAS_IRasterizer::RAS_TEXCO_UV:
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, tv.getUV(unit));
break;
case RAS_IRasterizer::RAS_TEXCO_NORM:
glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getNormal());
break;
case RAS_IRasterizer::RAS_TEXTANGENT:
glMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, tv.getTangent());
break;
default:
break;
}
}
}
if (GLEW_ARB_vertex_program) {
int uv = 0;
for (unit = 0; unit < *m_attrib_num; unit++) {
switch(m_attrib[unit]) {
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
glVertexAttrib3fvARB(unit, tv.getXYZ());
break;
case RAS_IRasterizer::RAS_TEXCO_UV:
glVertexAttrib2fvARB(unit, tv.getUV(uv++));
break;
case RAS_IRasterizer::RAS_TEXCO_NORM:
glVertexAttrib3fvARB(unit, tv.getNormal());
break;
case RAS_IRasterizer::RAS_TEXTANGENT:
glVertexAttrib4fvARB(unit, tv.getTangent());
break;
case RAS_IRasterizer::RAS_TEXCO_VCOL:
glVertexAttrib4ubvARB(unit, tv.getRGBA());
break;
default:
break;
}
}
}
}
void RAS_StorageIM::SetCullFace(bool enable)
{
if (enable)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
}
static bool current_wireframe;
static RAS_MaterialBucket *current_bucket;
static RAS_IPolyMaterial *current_polymat;
static RAS_MeshSlot *current_ms;
static RAS_MeshObject *current_mesh;
static int current_blmat_nr;
static GPUVertexAttribs current_gpu_attribs;
static Image *current_image;
static int CheckMaterialDM(int matnr, void *attribs)
{
// only draw the current material
if (matnr != current_blmat_nr)
return 0;
GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
if (gattribs)
memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
return 1;
}
/*
static int CheckTexfaceDM(void *mcol, int index)
{
// index is the original face index, retrieve the polygon
RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
current_mesh->GetPolygon(index) : NULL;
if (polygon && polygon->GetMaterial() == current_bucket) {
// must handle color.
if (current_wireframe)
return 2;
if (current_ms->m_bObjectColor) {
MT_Vector4& rgba = current_ms->m_RGBAcolor;
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
// don't use mcol
return 2;
}
if (!mcol) {
// we have to set the color from the material
unsigned char rgba[4];
current_polymat->GetMaterialRGBAColor(rgba);
glColor4ubv((const GLubyte *)rgba);
return 2;
}
return 1;
}
return 0;
}
*/
static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
{
// index is the original face index, retrieve the polygon
if (matnr == current_blmat_nr &&
(tface == NULL || tface->tpage == current_image)) {
// must handle color.
if (current_wireframe)
return DM_DRAW_OPTION_NO_MCOL;
if (current_ms->m_bObjectColor) {
MT_Vector4& rgba = current_ms->m_RGBAcolor;
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
// don't use mcol
return DM_DRAW_OPTION_NO_MCOL;
}
if (!has_mcol) {
// we have to set the color from the material
unsigned char rgba[4];
current_polymat->GetMaterialRGBAColor(rgba);
glColor4ubv((const GLubyte *)rgba);
return DM_DRAW_OPTION_NO_MCOL;
}
return DM_DRAW_OPTION_NORMAL;
}
return DM_DRAW_OPTION_SKIP;
}
void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
{
bool obcolor = ms.m_bObjectColor;
bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
MT_Vector4& rgba = ms.m_RGBAcolor;
RAS_MeshSlot::iterator it;
if (ms.m_pDerivedMesh) {
// mesh data is in derived mesh,
current_bucket = ms.m_bucket;
current_polymat = current_bucket->GetPolyMaterial();
current_ms = &ms;
current_mesh = ms.m_mesh;
current_wireframe = wireframe;
// MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
// handle two-side
if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
this->SetCullFace(true);
else
this->SetCullFace(false);
if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
// GetMaterialIndex return the original mface material index,
// increment by 1 to match what derived mesh is doing
current_blmat_nr = current_polymat->GetMaterialIndex()+1;
// For GLSL we need to retrieve the GPU material attribute
Material* blmat = current_polymat->GetBlenderMaterial();
Scene* blscene = current_polymat->GetBlenderScene();
if (!wireframe && blscene && blmat)
GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
else
memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
// DM draw can mess up blending mode, restore at the end
int current_blend_mode = GPU_get_material_alpha_blend();
ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
GPU_set_material_alpha_blend(current_blend_mode);
} else {
//ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
current_blmat_nr = current_polymat->GetMaterialIndex();
current_image = current_polymat->GetBlenderImage();
ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
}
return;
}
// iterate over display arrays, each containing an index + vertex array
for (ms.begin(it); !ms.end(it); ms.next(it)) {
RAS_TexVert *vertex;
size_t i, j, numvert;
numvert = it.array->m_type;
if (it.array->m_type == RAS_DisplayArray::LINE) {
// line drawing
glBegin(GL_LINES);
for (i = 0; i < it.totindex; i += 2)
{
vertex = &it.vertex[it.index[i]];
glVertex3fv(vertex->getXYZ());
vertex = &it.vertex[it.index[i+1]];
glVertex3fv(vertex->getXYZ());
}
glEnd();
}
else {
// triangle and quad drawing
if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
glBegin(GL_TRIANGLES);
else
glBegin(GL_QUADS);
for (i = 0; i < it.totindex; i += numvert)
{
if (obcolor)
glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
for (j = 0; j < numvert; j++) {
vertex = &it.vertex[it.index[i+j]];
if (!wireframe) {
if (!obcolor)
glColor4ubv((const GLubyte *)(vertex->getRGBA()));
glNormal3fv(vertex->getNormal());
if (multi)
TexCoord(*vertex);
else
glTexCoord2fv(vertex->getUV(0));
}
glVertex3fv(vertex->getXYZ());
}
}
glEnd();
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __KX_IMMEDIATEMODESTORAGE
#define __KX_IMMEDIATEMODESTORAGE
#include "RAS_IStorage.h"
#include "RAS_IRasterizer.h"
class RAS_StorageIM : public RAS_IStorage
{
public:
RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
virtual ~RAS_StorageIM();
virtual bool Init();
virtual void Exit();
virtual void IndexPrimitives(RAS_MeshSlot& ms);
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
protected:
int m_drawingmode;
int* m_texco_num;
int* m_attrib_num;
RAS_IRasterizer::TexCoGen* m_texco;
RAS_IRasterizer::TexCoGen* m_attrib;
void TexCoord(const RAS_TexVert &tv);
void SetCullFace(bool enable);
void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageIM"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif //__KX_IMMEDIATEMODESTORAGE

View File

@@ -25,97 +25,51 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
* \ingroup bgerastogl
*/
#include "RAS_VAOpenGLRasterizer.h"
#include <stdlib.h>
#include "RAS_StorageVA.h"
#include "GL/glew.h"
#include "GPU_extensions.h"
#include "STR_String.h"
#include "RAS_TexVert.h"
#include "MT_CmMatrix4x4.h"
#include "RAS_IRenderTools.h" // rendering text
RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock)
: RAS_OpenGLRasterizer(canvas),
m_Lock(lock && GLEW_EXT_compiled_vertex_array),
RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
m_texco_num(texco_num),
m_texco(texco),
m_attrib_num(attrib_num),
m_attrib(attrib),
m_last_texco_num(0),
m_last_attrib_num(0)
{
}
RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
RAS_StorageVA::~RAS_StorageVA()
{
}
bool RAS_VAOpenGLRasterizer::Init(void)
bool RAS_StorageVA::Init()
{
bool result = RAS_OpenGLRasterizer::Init();
if (result)
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return result;
return true;
}
void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
{
m_drawingmode = drawingmode;
switch (m_drawingmode)
{
case KX_BOUNDINGBOX:
case KX_WIREFRAME:
//glDisableClientState(GL_COLOR_ARRAY);
//glDisable(GL_CULL_FACE);
break;
case KX_SOLID:
//glDisableClientState(GL_COLOR_ARRAY);
break;
case KX_TEXTURED:
case KX_SHADED:
case KX_SHADOW:
//glEnableClientState(GL_COLOR_ARRAY);
default:
break;
}
}
void RAS_VAOpenGLRasterizer::Exit()
void RAS_StorageVA::Exit()
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
RAS_OpenGLRasterizer::Exit();
}
void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
{
static const GLsizei stride = sizeof(RAS_TexVert);
bool wireframe = m_drawingmode <= KX_WIREFRAME;
bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
RAS_MeshSlot::iterator it;
GLenum drawmode;
if (ms.m_pDerivedMesh) {
// cannot be handled here, pass to RAS_OpenGLRasterizer
RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false);
return;
}
if (!wireframe)
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -151,7 +105,7 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
if (!wireframe) {
glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1());
glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
if (glIsEnabled(GL_COLOR_ARRAY))
glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
}
@@ -166,19 +120,13 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
}
}
void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
{
static const GLsizei stride = sizeof(RAS_TexVert);
bool wireframe = m_drawingmode <= KX_WIREFRAME;
bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
RAS_MeshSlot::iterator it;
GLenum drawmode;
if (ms.m_pDerivedMesh) {
// cannot be handled here, pass to RAS_OpenGLRasterizer
RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true);
return;
}
if (!wireframe)
EnableTextures(true);
@@ -229,7 +177,7 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
}
}
void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv)
{
/* note: this function must closely match EnableTextures to enable/disable
* the right arrays, otherwise coordinate and attribute pointers from other
@@ -238,34 +186,26 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
if (GLEW_ARB_multitexture)
{
for (unit=0; unit<m_texco_num; unit++)
for (unit = 0; unit < *m_texco_num; unit++)
{
glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
if (tv->getFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2());
continue;
}
switch(m_texco[unit])
switch (m_texco[unit])
{
case RAS_TEXCO_ORCO:
case RAS_TEXCO_GLOB:
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
break;
case RAS_TEXCO_UV1:
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1());
break;
case RAS_TEXCO_NORM:
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
break;
case RAS_TEXTANGENT:
glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
break;
case RAS_TEXCO_UV2:
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2());
break;
default:
break;
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
break;
case RAS_IRasterizer::RAS_TEXCO_UV:
glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit));
break;
case RAS_IRasterizer::RAS_TEXCO_NORM:
glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
break;
case RAS_IRasterizer::RAS_TEXTANGENT:
glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
break;
default:
break;
}
}
@@ -273,51 +213,49 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
}
if (GLEW_ARB_vertex_program) {
for (unit=0; unit<m_attrib_num; unit++) {
switch(m_attrib[unit]) {
case RAS_TEXCO_ORCO:
case RAS_TEXCO_GLOB:
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
break;
case RAS_TEXCO_UV1:
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1());
break;
case RAS_TEXCO_NORM:
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
break;
case RAS_TEXTANGENT:
glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
break;
case RAS_TEXCO_UV2:
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2());
break;
case RAS_TEXCO_VCOL:
glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
break;
default:
break;
int uv = 0;
for (unit = 0; unit < *m_attrib_num; unit++) {
switch (m_attrib[unit]) {
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
break;
case RAS_IRasterizer::RAS_TEXCO_UV:
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++));
break;
case RAS_IRasterizer::RAS_TEXCO_NORM:
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
break;
case RAS_IRasterizer::RAS_TEXTANGENT:
glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
break;
case RAS_IRasterizer::RAS_TEXCO_VCOL:
glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
break;
default:
break;
}
}
}
}
void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
void RAS_StorageVA::EnableTextures(bool enable)
{
TexCoGen *texco, *attrib;
RAS_IRasterizer::TexCoGen *texco, *attrib;
int unit, texco_num, attrib_num;
/* we cache last texcoords and attribs to ensure we disable the ones that
* were actually last set */
if (enable) {
texco = m_texco;
texco_num = m_texco_num;
texco_num = *m_texco_num;
attrib = m_attrib;
attrib_num = m_attrib_num;
attrib_num = *m_attrib_num;
memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num);
m_last_texco_num = m_texco_num;
memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num);
m_last_attrib_num = m_attrib_num;
memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num));
m_last_texco_num = *m_texco_num;
memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num));
m_last_attrib_num = *m_attrib_num;
}
else {
texco = m_last_texco;
@@ -327,23 +265,22 @@ void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
}
if (GLEW_ARB_multitexture) {
for (unit=0; unit<texco_num; unit++) {
glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
for (unit = 0; unit < texco_num; unit++) {
glClientActiveTextureARB(GL_TEXTURE0_ARB + unit);
switch(texco[unit])
switch (texco[unit])
{
case RAS_TEXCO_ORCO:
case RAS_TEXCO_GLOB:
case RAS_TEXCO_UV1:
case RAS_TEXCO_NORM:
case RAS_TEXTANGENT:
case RAS_TEXCO_UV2:
if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
break;
default:
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
break;
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
case RAS_IRasterizer::RAS_TEXCO_UV:
case RAS_IRasterizer::RAS_TEXCO_NORM:
case RAS_IRasterizer::RAS_TEXTANGENT:
if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
break;
default:
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
break;
}
}
@@ -357,21 +294,20 @@ void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
}
if (GLEW_ARB_vertex_program) {
for (unit=0; unit<attrib_num; unit++) {
switch(attrib[unit]) {
case RAS_TEXCO_ORCO:
case RAS_TEXCO_GLOB:
case RAS_TEXCO_UV1:
case RAS_TEXCO_NORM:
case RAS_TEXTANGENT:
case RAS_TEXCO_UV2:
case RAS_TEXCO_VCOL:
if (enable) glEnableVertexAttribArrayARB(unit);
else glDisableVertexAttribArrayARB(unit);
break;
default:
glDisableVertexAttribArrayARB(unit);
break;
for (unit = 0; unit < attrib_num; unit++) {
switch (attrib[unit]) {
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
case RAS_IRasterizer::RAS_TEXCO_UV:
case RAS_IRasterizer::RAS_TEXCO_NORM:
case RAS_IRasterizer::RAS_TEXTANGENT:
case RAS_IRasterizer::RAS_TEXCO_VCOL:
if (enable) glEnableVertexAttribArrayARB(unit);
else glDisableVertexAttribArrayARB(unit);
break;
default:
glDisableVertexAttribArrayARB(unit);
break;
}
}
}

View File

@@ -25,49 +25,53 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file RAS_VAOpenGLRasterizer.h
* \ingroup bgerastogl
*/
#ifndef __KX_VERTEXARRAYSTORAGE
#define __KX_VERTEXARRAYSTORAGE
#ifndef __RAS_VAOPENGLRASTERIZER_H__
#define __RAS_VAOPENGLRASTERIZER_H__
#include "RAS_IStorage.h"
#include "RAS_IRasterizer.h"
#include "RAS_OpenGLRasterizer.h"
class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer
class RAS_StorageVA : public RAS_IStorage
{
void TexCoordPtr(const RAS_TexVert *tv);
bool m_Lock;
TexCoGen m_last_texco[RAS_MAX_TEXCO];
TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
int m_last_texco_num;
int m_last_attrib_num;
public:
RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false);
virtual ~RAS_VAOpenGLRasterizer();
RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
virtual ~RAS_StorageVA();
virtual bool Init();
virtual void Exit();
virtual void SetDrawingMode(int drawingmode);
virtual void IndexPrimitives(class RAS_MeshSlot& ms);
virtual void IndexPrimitives(RAS_MeshSlot& ms);
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
private:
virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
protected:
int m_drawingmode;
int* m_texco_num;
int* m_attrib_num;
int m_last_texco_num;
int m_last_attrib_num;
RAS_IRasterizer::TexCoGen* m_texco;
RAS_IRasterizer::TexCoGen* m_attrib;
RAS_IRasterizer::TexCoGen m_last_texco[RAS_MAX_TEXCO];
RAS_IRasterizer::TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
virtual void EnableTextures(bool enable);
//virtual bool QueryArrays(){return true;}
//virtual bool QueryLists(){return m_Lock;}
virtual void TexCoordPtr(const RAS_TexVert *tv);
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_VAOpenGLRasterizer"); }
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif //__RAS_VAOPENGLRASTERIZER_H__
#endif //__KX_VERTEXARRAYSTORAGE

View File

@@ -0,0 +1,272 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "RAS_StorageVBO.h"
#include "RAS_MeshObject.h"
#include "GL/glew.h"
VBO::VBO(RAS_DisplayArray *data, unsigned int indices)
{
this->data = data;
this->size = data->m_vertex.size();
this->indices = indices;
this->stride = 28*sizeof(GLfloat);
// Determine drawmode
if (data->m_type == data->QUAD)
this->mode = GL_QUADS;
else if (data->m_type == data->TRIANGLE)
this->mode = GL_TRIANGLES;
else
this->mode = GL_LINE;
// Generate Buffers
glGenBuffersARB(1, &this->ibo);
glGenBuffersARB(1, &this->vbo_id);
// Allocate some space to gather data into before uploading to GPU
this->vbo = new GLfloat[this->stride*this->size];
// Fill the buffers with initial data
UpdateIndices();
UpdateData();
// Establish offsets
this->vertex_offset = 0;
this->normal_offset = (void*)(3*sizeof(GLfloat));
this->tangent_offset = (void*)(6*sizeof(GLfloat));
this->color_offset = (void*)(10*sizeof(GLfloat));
this->uv_offset = (void*)(11*sizeof(GLfloat));
this->dummy_offset = (void*)(27*sizeof(GLfloat));
}
VBO::~VBO()
{
glDeleteBuffersARB(1, &this->ibo);
glDeleteBuffersARB(1, &this->vbo_id);
delete this->vbo;
}
void VBO::UpdateData()
{
unsigned int i, j, k;
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
// Lets the video card know we are done with the old VBO
glBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, NULL, GL_DYNAMIC_DRAW_ARB);
// Gather data
for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat))
{
memcpy(&this->vbo[j], data->m_vertex[i].getXYZ(), sizeof(float)*3);
memcpy(&this->vbo[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3);
memcpy(&this->vbo[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4);
memcpy(&this->vbo[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4);
for (k = 0; k < RAS_TexVert::MAX_UNIT; k++)
memcpy(&this->vbo[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2);
}
// Upload Data to GPU
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->size*this->stride, this->vbo, GL_DYNAMIC_DRAW_ARB);
}
void VBO::UpdateIndices()
{
int space = data->m_index.size() * sizeof(GLushort);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
// Lets the video card know we are done with the old VBO
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, NULL, GL_DYNAMIC_DRAW_ARB);
// Upload Data to VBO
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, space, &data->m_index[0], GL_DYNAMIC_DRAW_ARB);
}
void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi)
{
int unit;
// Bind buffers
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
// Vertexes
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
// Normals
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, this->stride, this->normal_offset);
// Colors
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset);
if (multi)
{
for (unit = 0; unit < texco_num; ++unit)
{
glClientActiveTexture(GL_TEXTURE0_ARB + unit);
switch (texco[unit])
{
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
break;
case RAS_IRasterizer::RAS_TEXCO_UV:
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit)));
break;
case RAS_IRasterizer::RAS_TEXCO_NORM:
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset);
break;
case RAS_IRasterizer::RAS_TEXTANGENT:
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset);
break;
default:
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(1, GL_SHORT, this->stride, this->dummy_offset);
break;
}
}
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
else //TexFace
{
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset);
}
if (GLEW_ARB_vertex_program)
{
int uv = 0;
for (unit = 0; unit < attrib_num; ++unit)
{
switch (attrib[unit])
{
case RAS_IRasterizer::RAS_TEXCO_ORCO:
case RAS_IRasterizer::RAS_TEXCO_GLOB:
glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset);
glEnableVertexAttribArrayARB(unit);
break;
case RAS_IRasterizer::RAS_TEXCO_UV:
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv));
uv += sizeof(GLfloat)*2;
glEnableVertexAttribArrayARB(unit);
break;
case RAS_IRasterizer::RAS_TEXCO_NORM:
glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset);
glEnableVertexAttribArrayARB(unit);
break;
case RAS_IRasterizer::RAS_TEXTANGENT:
glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset);
glEnableVertexAttribArrayARB(unit);
break;
default:
break;
}
}
}
glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (GLEW_ARB_vertex_program)
{
for (int i = 0; i < attrib_num; ++i)
glDisableVertexAttribArrayARB(i);
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib):
m_texco_num(texco_num),
m_texco(texco),
m_attrib_num(attrib_num),
m_attrib(attrib)
{
}
RAS_StorageVBO::~RAS_StorageVBO()
{
}
bool RAS_StorageVBO::Init()
{
return true;
}
void RAS_StorageVBO::Exit()
{
m_vbo_lookup.clear();
}
void RAS_StorageVBO::IndexPrimitives(RAS_MeshSlot& ms)
{
IndexPrimitivesInternal(ms, false);
}
void RAS_StorageVBO::IndexPrimitivesMulti(RAS_MeshSlot& ms)
{
IndexPrimitivesInternal(ms, true);
}
void RAS_StorageVBO::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
{
RAS_MeshSlot::iterator it;
VBO *vbo;
for (ms.begin(it); !ms.end(it); ms.next(it))
{
vbo = m_vbo_lookup[it.array];
if (vbo == 0)
m_vbo_lookup[it.array] = vbo = new VBO(it.array, it.totindex);
// Update the vbo
if (ms.m_mesh->MeshModified())
{
vbo->UpdateData();
}
vbo->Draw(*m_texco_num, m_texco, *m_attrib_num, m_attrib, multi);
}
}

View File

@@ -0,0 +1,102 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __KX_VERTEXBUFFEROBJECTSTORAGE
#define __KX_VERTEXBUFFEROBJECTSTORAGE
#include <map>
#include "GL/glew.h"
#include "RAS_IStorage.h"
#include "RAS_IRasterizer.h"
#include "RAS_OpenGLRasterizer.h"
class VBO
{
public:
VBO(RAS_DisplayArray *data, unsigned int indices);
~VBO();
void Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi);
void UpdateData();
void UpdateIndices();
private:
RAS_DisplayArray* data;
GLuint size;
GLuint stride;
GLuint indices;
GLenum mode;
GLuint ibo;
GLuint vbo_id;
GLfloat* vbo;
void* vertex_offset;
void* normal_offset;
void* color_offset;
void* tangent_offset;
void* uv_offset;
void* dummy_offset;
};
class RAS_StorageVBO : public RAS_IStorage
{
public:
RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
virtual ~RAS_StorageVBO();
virtual bool Init();
virtual void Exit();
virtual void IndexPrimitives(RAS_MeshSlot& ms);
virtual void IndexPrimitivesMulti(RAS_MeshSlot& ms);
virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
protected:
int m_drawingmode;
int* m_texco_num;
int* m_attrib_num;
RAS_IRasterizer::TexCoGen* m_texco;
RAS_IRasterizer::TexCoGen* m_attrib;
std::map<RAS_DisplayArray*, class VBO*> m_vbo_lookup;
virtual void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif //__KX_VERTEXBUFFEROBJECTSTORAGE

View File

@@ -34,8 +34,7 @@
#include "MT_Matrix4x4.h"
RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
const MT_Point2& uv,
const MT_Point2& uv2,
const MT_Point2 uvs[MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
@@ -43,8 +42,6 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
const unsigned int origindex)
{
xyz.getValue(m_localxyz);
uv.getValue(m_uv1);
uv2.getValue(m_uv2);
SetRGBA(rgba);
SetNormal(normal);
tangent.getValue(m_tangent);
@@ -52,6 +49,11 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
m_origindex = origindex;
m_unit = 2;
m_softBodyIndex = -1;
for (int i = 0; i < MAX_UNIT; ++i)
{
uvs[i].getValue(m_uvs[i]);
}
}
const MT_Point3& RAS_TexVert::xyz()
@@ -80,14 +82,9 @@ void RAS_TexVert::SetXYZ(const float *xyz)
m_localxyz[0]= xyz[0]; m_localxyz[1]= xyz[1]; m_localxyz[2]= xyz[2];
}
void RAS_TexVert::SetUV(const MT_Point2& uv)
void RAS_TexVert::SetUV(int index, const MT_Point2& uv)
{
uv.getValue(m_uv1);
}
void RAS_TexVert::SetUV2(const MT_Point2& uv)
{
uv.getValue(m_uv2);
uv.getValue(m_uvs[index]);
}
@@ -121,14 +118,17 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
// compare two vertices, and return TRUE if both are almost identical (they can be shared)
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
{
bool uv_match = true;
for (int i=0; i<MAX_UNIT; i++)
uv_match = uv_match && MT_fuzzyEqual(MT_Vector2(m_uvs[i]), MT_Vector2(other->m_uvs[i]));
return (
/* m_flag == other->m_flag && */
/* at the moment the face only stores the smooth/flat setting so don't bother comparing it */
m_rgba == other->m_rgba &&
MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) &&
MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) &&
MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) &&
MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* &&
uv_match /* &&
MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/);
/* don't bother comparing m_localxyz since we know there from the same vert */
}

View File

@@ -48,23 +48,21 @@ class RAS_TexVert
{
float m_localxyz[3]; // 3*4 = 12
float m_uv1[2]; // 2*4 = 8
float m_uv2[2]; // 2*4 = 8
float m_uvs[8][2]; // 8*2*4=64 //8 = MAX_UNIT
unsigned int m_rgba; // 4
float m_tangent[4]; // 4*4 = 16
float m_normal[3]; // 3*4 = 12
float m_tangent[4]; // 4*4 = 16
float m_normal[3]; // 3*4 = 12
short m_flag; // 2
short m_softBodyIndex; //2
unsigned int m_unit; // 4
unsigned int m_origindex; // 4
//---------
// 56+6+8+2=72
// 32 bytes total size, fits nice = 56 = not fit nice.
// 120
// 32 bytes total size, fits nice = 120 = not fit nice.
public:
enum {
FLAT = 1,
SECOND_UV = 2,
MAX_UNIT = 8
};
@@ -74,8 +72,7 @@ public:
RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0)
{}
RAS_TexVert(const MT_Point3& xyz,
const MT_Point2& uv,
const MT_Point2& uv2,
const MT_Point2 uvs[MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
@@ -83,12 +80,8 @@ public:
const unsigned int origindex);
~RAS_TexVert() {};
const float* getUV1 () const {
return m_uv1;
};
const float* getUV2 () const {
return m_uv2;
const float* getUV (int unit) const {
return m_uvs[unit];
};
const float* getXYZ() const {
@@ -123,8 +116,7 @@ public:
void SetXYZ(const MT_Point3& xyz);
void SetXYZ(const float *xyz);
void SetUV(const MT_Point2& uv);
void SetUV2(const MT_Point2& uv);
void SetUV(int index, const MT_Point2& uv);
void SetRGBA(const unsigned int rgba);
void SetNormal(const MT_Vector3& normal);

View File

@@ -52,9 +52,9 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Ve
MT_Scalar d = -p[0].xyz().dot(normal);
MT_Matrix3x3 mat3( p[0].getUV1()[0],p[0].getUV1()[1], 1,
p[1].getUV1()[0],p[1].getUV1()[1], 1,
p[2].getUV1()[0],p[2].getUV1()[1], 1);
MT_Matrix3x3 mat3( p[0].getUV(0)[0],p[0].getUV(0)[1], 1,
p[1].getUV(0)[0],p[1].getUV(0)[1], 1,
p[2].getUV(0)[0],p[2].getUV(0)[1], 1);
MT_Matrix3x3 mat3inv = mat3.inverse();