Compare commits
4 Commits
temp-node-
...
ge_2df_tex
Author | SHA1 | Date | |
---|---|---|---|
4ef064d4c2 | |||
9bf3c96376 | |||
9847537979 | |||
e4ea5e5810 |
@@ -641,7 +641,7 @@ int GPU_verify_image(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO unneeded when float images are correctly treated as linear always */
|
/* TODO unneeded when float images are correctly treated as linear always */
|
||||||
if (!is_data) {
|
if (!is_data && !(ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
|
||||||
do_color_management = true;
|
do_color_management = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -122,6 +122,23 @@ static BlendFileData *load_game_data(const char *filename)
|
|||||||
return bfd;
|
return bfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void BL_KetsjiRender(KX_KetsjiEngine *ketsjiengine, ARegion *ar, Scene *scene, int draw_letterbox)
|
||||||
|
{
|
||||||
|
if (draw_letterbox) {
|
||||||
|
// Clear screen to border color
|
||||||
|
// We do this here since we set the canvas to be within the frames. This means the engine
|
||||||
|
// itself is unaware of the extra space, so we clear the whole region for it.
|
||||||
|
glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f);
|
||||||
|
glViewport(ar->winrct.xmin, ar->winrct.ymin,
|
||||||
|
BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// render the frame
|
||||||
|
ketsjiengine->Render();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int BL_KetsjiNextFrame(KX_KetsjiEngine *ketsjiengine, bContext *C, wmWindow *win, Scene *scene, ARegion *ar,
|
static int BL_KetsjiNextFrame(KX_KetsjiEngine *ketsjiengine, bContext *C, wmWindow *win, Scene *scene, ARegion *ar,
|
||||||
KX_BlenderKeyboardDevice* keyboarddevice, KX_BlenderMouseDevice* mousedevice, int draw_letterbox)
|
KX_BlenderKeyboardDevice* keyboarddevice, KX_BlenderMouseDevice* mousedevice, int draw_letterbox)
|
||||||
{
|
{
|
||||||
@@ -134,18 +151,7 @@ static int BL_KetsjiNextFrame(KX_KetsjiEngine *ketsjiengine, bContext *C, wmWind
|
|||||||
bool render = ketsjiengine->NextFrame();
|
bool render = ketsjiengine->NextFrame();
|
||||||
|
|
||||||
if (render) {
|
if (render) {
|
||||||
if (draw_letterbox) {
|
BL_KetsjiRender(ketsjiengine, ar, scene, draw_letterbox);
|
||||||
// Clear screen to border color
|
|
||||||
// We do this here since we set the canvas to be within the frames. This means the engine
|
|
||||||
// itself is unaware of the extra space, so we clear the whole region for it.
|
|
||||||
glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f);
|
|
||||||
glViewport(ar->winrct.xmin, ar->winrct.ymin,
|
|
||||||
BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// render the frame
|
|
||||||
ketsjiengine->Render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wm_window_process_events_nosleep();
|
wm_window_process_events_nosleep();
|
||||||
@@ -211,6 +217,13 @@ static int BL_KetsjiPyNextFrame(void *state0)
|
|||||||
state->mousedevice,
|
state->mousedevice,
|
||||||
state->draw_letterbox);
|
state->draw_letterbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void BL_KetsjiPyRender(void *state0)
|
||||||
|
{
|
||||||
|
BL_KetsjiNextFrameState *state = (BL_KetsjiNextFrameState *) state0;
|
||||||
|
BL_KetsjiRender(state->ketsjiengine, state->ar, state->scene, state->draw_letterbox);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -526,6 +539,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
|
|||||||
char *python_main = NULL;
|
char *python_main = NULL;
|
||||||
pynextframestate.state = NULL;
|
pynextframestate.state = NULL;
|
||||||
pynextframestate.func = NULL;
|
pynextframestate.func = NULL;
|
||||||
|
pynextframestate.render = NULL;
|
||||||
python_main = KX_GetPythonMain(scene);
|
python_main = KX_GetPythonMain(scene);
|
||||||
|
|
||||||
// the mainloop
|
// the mainloop
|
||||||
@@ -548,6 +562,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
|
|||||||
|
|
||||||
pynextframestate.state = &ketsjinextframestate;
|
pynextframestate.state = &ketsjinextframestate;
|
||||||
pynextframestate.func = &BL_KetsjiPyNextFrame;
|
pynextframestate.func = &BL_KetsjiPyNextFrame;
|
||||||
|
pynextframestate.render = &BL_KetsjiPyRender;
|
||||||
printf("Yielding control to Python script '%s'...\n", python_main);
|
printf("Yielding control to Python script '%s'...\n", python_main);
|
||||||
PyRun_SimpleString(python_code);
|
PyRun_SimpleString(python_code);
|
||||||
printf("Exit Python script '%s'\n", python_main);
|
printf("Exit Python script '%s'\n", python_main);
|
||||||
|
@@ -210,8 +210,8 @@ SetViewPort(
|
|||||||
* the width,height is calculated including both pixels
|
* the width,height is calculated including both pixels
|
||||||
* therefore: max - min + 1
|
* therefore: max - min + 1
|
||||||
*/
|
*/
|
||||||
int vp_width = (x2 - x1) + 1;
|
int vp_width = (x2 - x1);
|
||||||
int vp_height = (y2 - y1) + 1;
|
int vp_height = (y2 - y1);
|
||||||
int minx = m_frame_rect.GetLeft();
|
int minx = m_frame_rect.GetLeft();
|
||||||
int miny = m_frame_rect.GetBottom();
|
int miny = m_frame_rect.GetBottom();
|
||||||
|
|
||||||
|
@@ -69,6 +69,7 @@
|
|||||||
#include "KX_SCA_DynamicActuator.h"
|
#include "KX_SCA_DynamicActuator.h"
|
||||||
#include "KX_SteeringActuator.h"
|
#include "KX_SteeringActuator.h"
|
||||||
#include "KX_MouseActuator.h"
|
#include "KX_MouseActuator.h"
|
||||||
|
#include "KX_BlenderMaterial.h"
|
||||||
|
|
||||||
#include "KX_Scene.h"
|
#include "KX_Scene.h"
|
||||||
#include "KX_KetsjiEngine.h"
|
#include "KX_KetsjiEngine.h"
|
||||||
@@ -911,6 +912,7 @@ void BL_ConvertActuators(const char* maggiename,
|
|||||||
{
|
{
|
||||||
bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
|
bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
|
||||||
SCA_2DFilterActuator *tmp = NULL;
|
SCA_2DFilterActuator *tmp = NULL;
|
||||||
|
BL_Material *mat = NULL;
|
||||||
|
|
||||||
RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode;
|
RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode;
|
||||||
switch (_2dfilter->type) {
|
switch (_2dfilter->type) {
|
||||||
@@ -949,6 +951,16 @@ void BL_ConvertActuators(const char* maggiename,
|
|||||||
break;
|
break;
|
||||||
case ACT_2DFILTER_CUSTOMFILTER:
|
case ACT_2DFILTER_CUSTOMFILTER:
|
||||||
filtermode = RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER;
|
filtermode = RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER;
|
||||||
|
if (gameobj->GetMeshCount() > 0) {
|
||||||
|
unsigned int matid = 0;
|
||||||
|
RAS_MeshMaterial *meshMat = gameobj->GetMesh(0)->GetMeshMaterial(matid);
|
||||||
|
if (meshMat != NULL && meshMat->m_bucket != NULL) {
|
||||||
|
RAS_IPolyMaterial *polymat = meshMat->m_bucket->GetPolyMaterial();
|
||||||
|
if (polymat->GetFlag() & RAS_BLENDERGLSL) {
|
||||||
|
mat = ((KX_BlenderMaterial *)polymat)->GetBLMaterial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACT_2DFILTER_NOFILTER:
|
case ACT_2DFILTER_NOFILTER:
|
||||||
filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
|
filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
|
||||||
@@ -964,7 +976,7 @@ void BL_ConvertActuators(const char* maggiename,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag,
|
tmp = new SCA_2DFilterActuator(gameobj, mat, filtermode, _2dfilter->flag,
|
||||||
_2dfilter->float_arg, _2dfilter->int_arg,
|
_2dfilter->float_arg, _2dfilter->int_arg,
|
||||||
ketsjiEngine->GetRasterizer(), scene);
|
ketsjiEngine->GetRasterizer(), scene);
|
||||||
|
|
||||||
|
@@ -40,6 +40,7 @@ SCA_2DFilterActuator::~SCA_2DFilterActuator()
|
|||||||
|
|
||||||
SCA_2DFilterActuator::SCA_2DFilterActuator(
|
SCA_2DFilterActuator::SCA_2DFilterActuator(
|
||||||
SCA_IObject *gameobj,
|
SCA_IObject *gameobj,
|
||||||
|
BL_Material *mat,
|
||||||
RAS_2DFilterManager::RAS_2DFILTER_MODE type,
|
RAS_2DFilterManager::RAS_2DFILTER_MODE type,
|
||||||
short flag,
|
short flag,
|
||||||
float float_arg,
|
float float_arg,
|
||||||
@@ -55,9 +56,11 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
|
|||||||
m_scene(scene)
|
m_scene(scene)
|
||||||
{
|
{
|
||||||
m_gameobj = NULL;
|
m_gameobj = NULL;
|
||||||
|
m_mat = NULL;
|
||||||
if (gameobj) {
|
if (gameobj) {
|
||||||
m_propNames = gameobj->GetPropertyNames();
|
m_propNames = gameobj->GetPropertyNames();
|
||||||
m_gameobj = gameobj;
|
m_gameobj = gameobj;
|
||||||
|
m_mat = mat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +93,7 @@ bool SCA_2DFilterActuator::Update()
|
|||||||
}
|
}
|
||||||
else if (m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
|
else if (m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
|
||||||
{
|
{
|
||||||
m_scene->Update2DFilter(m_propNames, m_gameobj, m_type, m_int_arg, m_shaderText);
|
m_scene->Update2DFilter(m_propNames, m_gameobj, m_mat, m_type, m_int_arg, m_shaderText);
|
||||||
}
|
}
|
||||||
// once the filter is in place, no need to update it again => disable the actuator
|
// once the filter is in place, no need to update it again => disable the actuator
|
||||||
return false;
|
return false;
|
||||||
|
@@ -35,6 +35,8 @@
|
|||||||
#include "SCA_IActuator.h"
|
#include "SCA_IActuator.h"
|
||||||
#include "SCA_IScene.h"
|
#include "SCA_IScene.h"
|
||||||
|
|
||||||
|
class BL_Material;
|
||||||
|
|
||||||
class SCA_2DFilterActuator : public SCA_IActuator
|
class SCA_2DFilterActuator : public SCA_IActuator
|
||||||
{
|
{
|
||||||
Py_Header
|
Py_Header
|
||||||
@@ -48,11 +50,13 @@ private:
|
|||||||
STR_String m_shaderText;
|
STR_String m_shaderText;
|
||||||
RAS_IRasterizer* m_rasterizer;
|
RAS_IRasterizer* m_rasterizer;
|
||||||
SCA_IScene* m_scene;
|
SCA_IScene* m_scene;
|
||||||
|
BL_Material* m_mat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SCA_2DFilterActuator(
|
SCA_2DFilterActuator(
|
||||||
class SCA_IObject* gameobj,
|
class SCA_IObject* gameobj,
|
||||||
|
BL_Material *mat,
|
||||||
RAS_2DFilterManager::RAS_2DFILTER_MODE type,
|
RAS_2DFilterManager::RAS_2DFILTER_MODE type,
|
||||||
short flag,
|
short flag,
|
||||||
float float_arg,
|
float float_arg,
|
||||||
|
@@ -74,7 +74,8 @@ public:
|
|||||||
void RemoveDebugProperty(class CValue *gameobj, const STR_String &name);
|
void RemoveDebugProperty(class CValue *gameobj, const STR_String &name);
|
||||||
void RemoveObjectDebugProperties(class CValue* gameobj);
|
void RemoveObjectDebugProperties(class CValue* gameobj);
|
||||||
|
|
||||||
virtual void Update2DFilter(std::vector<STR_String>& propNames, void* gameObj,
|
virtual void Update2DFilter(std::vector<STR_String>& propNames, void* gameObj,
|
||||||
|
void *mat,
|
||||||
RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode,
|
RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode,
|
||||||
int pass, STR_String& text) {}
|
int pass, STR_String& text) {}
|
||||||
|
|
||||||
|
@@ -97,11 +97,11 @@ void GPC_Canvas::SetViewPort(int x1, int y1, int x2, int y2)
|
|||||||
|
|
||||||
m_viewport[0] = x1;
|
m_viewport[0] = x1;
|
||||||
m_viewport[1] = y1;
|
m_viewport[1] = y1;
|
||||||
m_viewport[2] = x2-x1 + 1;
|
m_viewport[2] = x2-x1;
|
||||||
m_viewport[3] = y2-y1 + 1;
|
m_viewport[3] = y2-y1;
|
||||||
|
|
||||||
glViewport(x1,y1,x2-x1 + 1,y2-y1 + 1);
|
glViewport(x1,y1,x2-x1,y2-y1);
|
||||||
glScissor(x1,y1,x2-x1 + 1,y2-y1 + 1);
|
glScissor(x1,y1,x2-x1,y2-y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPC_Canvas::UpdateViewPort(int x1, int y1, int x2, int y2)
|
void GPC_Canvas::UpdateViewPort(int x1, int y1, int x2, int y2)
|
||||||
|
@@ -848,6 +848,12 @@ void GPG_Application::EngineNextFrame()
|
|||||||
m_exitString = m_ketsjiengine->GetExitString();
|
m_exitString = m_ketsjiengine->GetExitString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPG_Application::EngineRender()
|
||||||
|
{
|
||||||
|
// render the frame
|
||||||
|
m_ketsjiengine->Render();
|
||||||
|
}
|
||||||
|
|
||||||
void GPG_Application::exitEngine()
|
void GPG_Application::exitEngine()
|
||||||
{
|
{
|
||||||
// We only want to kill the engine if it has been initialized
|
// We only want to kill the engine if it has been initialized
|
||||||
|
@@ -93,6 +93,7 @@ public:
|
|||||||
bool StartGameEngine(int stereoMode);
|
bool StartGameEngine(int stereoMode);
|
||||||
void StopGameEngine();
|
void StopGameEngine();
|
||||||
void EngineNextFrame();
|
void EngineNextFrame();
|
||||||
|
void EngineRender();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool handleWheel(GHOST_IEvent* event);
|
bool handleWheel(GHOST_IEvent* event);
|
||||||
|
@@ -385,6 +385,11 @@ static bool GPG_NextFrame(GHOST_ISystem* system, GPG_Application *app, int &exit
|
|||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GPG_Render(GPG_Application *app)
|
||||||
|
{
|
||||||
|
app->EngineRender();
|
||||||
|
}
|
||||||
|
|
||||||
struct GPG_NextFrameState {
|
struct GPG_NextFrameState {
|
||||||
GHOST_ISystem* system;
|
GHOST_ISystem* system;
|
||||||
GPG_Application *app;
|
GPG_Application *app;
|
||||||
@@ -405,6 +410,12 @@ static int GPG_PyNextFrame(void *state0)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GPG_PyRender(void *state0)
|
||||||
|
{
|
||||||
|
GPG_NextFrameState *state = (GPG_NextFrameState *) state0;
|
||||||
|
GPG_Render(state->app);
|
||||||
|
}
|
||||||
|
|
||||||
int main(
|
int main(
|
||||||
int argc,
|
int argc,
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -562,6 +573,7 @@ int main(
|
|||||||
U.anisotropic_filter = 2;
|
U.anisotropic_filter = 2;
|
||||||
// enable fast mipmap generation
|
// enable fast mipmap generation
|
||||||
U.use_gpu_mipmap = 1;
|
U.use_gpu_mipmap = 1;
|
||||||
|
U.use_16bit_textures = 1;
|
||||||
|
|
||||||
BKE_sound_init_once();
|
BKE_sound_init_once();
|
||||||
|
|
||||||
@@ -1123,6 +1135,7 @@ int main(
|
|||||||
char *python_main = NULL;
|
char *python_main = NULL;
|
||||||
pynextframestate.state = NULL;
|
pynextframestate.state = NULL;
|
||||||
pynextframestate.func = NULL;
|
pynextframestate.func = NULL;
|
||||||
|
pynextframestate.render = NULL;
|
||||||
#ifdef WITH_PYTHON
|
#ifdef WITH_PYTHON
|
||||||
python_main = KX_GetPythonMain(scene);
|
python_main = KX_GetPythonMain(scene);
|
||||||
#endif // WITH_PYTHON
|
#endif // WITH_PYTHON
|
||||||
@@ -1140,6 +1153,7 @@ int main(
|
|||||||
gpg_nextframestate.gs = &gs;
|
gpg_nextframestate.gs = &gs;
|
||||||
pynextframestate.state = &gpg_nextframestate;
|
pynextframestate.state = &gpg_nextframestate;
|
||||||
pynextframestate.func = &GPG_PyNextFrame;
|
pynextframestate.func = &GPG_PyNextFrame;
|
||||||
|
pynextframestate.render = &GPG_PyRender;
|
||||||
|
|
||||||
printf("Yielding control to Python script '%s'...\n", python_main);
|
printf("Yielding control to Python script '%s'...\n", python_main);
|
||||||
PyRun_SimpleString(python_code);
|
PyRun_SimpleString(python_code);
|
||||||
|
@@ -2018,7 +2018,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i)
|
|||||||
if (!cam)
|
if (!cam)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_canvas->SetViewPort(0,0,m_buffersize-1,m_buffersize-1);
|
m_canvas->SetViewPort(0,0,m_buffersize,m_buffersize);
|
||||||
|
|
||||||
// m_rasterizer->SetAmbient();
|
// m_rasterizer->SetAmbient();
|
||||||
m_rasterizer->DisplayFog();
|
m_rasterizer->DisplayFog();
|
||||||
|
@@ -52,6 +52,7 @@
|
|||||||
#include "RAS_IRasterizer.h"
|
#include "RAS_IRasterizer.h"
|
||||||
#include "RAS_ICanvas.h"
|
#include "RAS_ICanvas.h"
|
||||||
#include "RAS_ILightObject.h"
|
#include "RAS_ILightObject.h"
|
||||||
|
#include "RAS_IOffScreen.h"
|
||||||
#include "MT_Vector3.h"
|
#include "MT_Vector3.h"
|
||||||
#include "MT_Transform.h"
|
#include "MT_Transform.h"
|
||||||
#include "SCA_IInputDevice.h"
|
#include "SCA_IInputDevice.h"
|
||||||
@@ -109,6 +110,7 @@ double KX_KetsjiEngine::m_average_framerate = 0.0;
|
|||||||
bool KX_KetsjiEngine::m_restrict_anim_fps = false;
|
bool KX_KetsjiEngine::m_restrict_anim_fps = false;
|
||||||
short KX_KetsjiEngine::m_exitkey = 130; // ESC Key
|
short KX_KetsjiEngine::m_exitkey = 130; // ESC Key
|
||||||
bool KX_KetsjiEngine::m_doRender = true;
|
bool KX_KetsjiEngine::m_doRender = true;
|
||||||
|
bool KX_KetsjiEngine::m_doOffScreen = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor of the Ketsji Engine
|
* Constructor of the Ketsji Engine
|
||||||
@@ -116,6 +118,7 @@ bool KX_KetsjiEngine::m_doRender = true;
|
|||||||
KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
|
KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
|
||||||
: m_canvas(NULL),
|
: m_canvas(NULL),
|
||||||
m_rasterizer(NULL),
|
m_rasterizer(NULL),
|
||||||
|
m_offScreenRender(NULL),
|
||||||
m_kxsystem(system),
|
m_kxsystem(system),
|
||||||
m_sceneconverter(NULL),
|
m_sceneconverter(NULL),
|
||||||
m_networkdevice(NULL),
|
m_networkdevice(NULL),
|
||||||
@@ -778,6 +781,16 @@ bool KX_KetsjiEngine::NextFrame()
|
|||||||
return doRender && m_doRender;
|
return doRender && m_doRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KX_KetsjiEngine::BindOffScreen(bool bind)
|
||||||
|
{
|
||||||
|
if (m_doOffScreen && m_offScreenRender)
|
||||||
|
{
|
||||||
|
if (bind)
|
||||||
|
m_offScreenRender->Bind(RAS_IOffScreen::RAS_OFS_BIND_READ);
|
||||||
|
else
|
||||||
|
m_offScreenRender->Unbind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void KX_KetsjiEngine::Render()
|
void KX_KetsjiEngine::Render()
|
||||||
@@ -797,9 +810,12 @@ void KX_KetsjiEngine::Render()
|
|||||||
if (m_hideCursor)
|
if (m_hideCursor)
|
||||||
m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
|
m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
|
||||||
|
|
||||||
|
m_canvas->BeginDraw();
|
||||||
|
// redirect render if requested
|
||||||
|
if (m_doOffScreen && m_offScreenRender)
|
||||||
|
m_offScreenRender->Bind(RAS_IOffScreen::RAS_OFS_BIND_RENDER);
|
||||||
// clear the entire game screen with the border color
|
// clear the entire game screen with the border color
|
||||||
// only once per frame
|
// only once per frame
|
||||||
m_canvas->BeginDraw();
|
|
||||||
if (m_rasterizer->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
|
if (m_rasterizer->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
|
||||||
m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
|
m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
|
||||||
if (m_overrideFrameColor)
|
if (m_overrideFrameColor)
|
||||||
@@ -845,7 +861,10 @@ void KX_KetsjiEngine::Render()
|
|||||||
//scene->UpdateMeshTransformations();
|
//scene->UpdateMeshTransformations();
|
||||||
|
|
||||||
// shadow buffers
|
// shadow buffers
|
||||||
RenderShadowBuffers(scene);
|
if (RenderShadowBuffers(scene) && m_doOffScreen && m_offScreenRender)
|
||||||
|
// shadow render restore the frame buffer, must restore it if we have a customer render buffer
|
||||||
|
m_offScreenRender->Bind(RAS_IOffScreen::RAS_OFS_BIND_RENDER);
|
||||||
|
|
||||||
|
|
||||||
// Avoid drawing the scene with the active camera twice when its viewport is enabled
|
// Avoid drawing the scene with the active camera twice when its viewport is enabled
|
||||||
if (cam && !cam->GetViewport())
|
if (cam && !cam->GetViewport())
|
||||||
@@ -929,6 +948,8 @@ void KX_KetsjiEngine::Render()
|
|||||||
PostRenderScene(scene);
|
PostRenderScene(scene);
|
||||||
}
|
}
|
||||||
} // if (m_rasterizer->Stereo())
|
} // if (m_rasterizer->Stereo())
|
||||||
|
if (m_doOffScreen && m_offScreenRender)
|
||||||
|
m_offScreenRender->Unbind();
|
||||||
|
|
||||||
EndFrame();
|
EndFrame();
|
||||||
}
|
}
|
||||||
@@ -1085,10 +1106,11 @@ void KX_KetsjiEngine::UpdateAnimations(KX_Scene *scene)
|
|||||||
scene->UpdateAnimations(m_frameTime);
|
scene->UpdateAnimations(m_frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
|
bool KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
|
||||||
{
|
{
|
||||||
CListValue *lightlist = scene->GetLightList();
|
CListValue *lightlist = scene->GetLightList();
|
||||||
int i, drawmode;
|
int i, drawmode;
|
||||||
|
bool hasShadow = false;
|
||||||
|
|
||||||
m_rasterizer->SetAuxilaryClientInfo(scene);
|
m_rasterizer->SetAuxilaryClientInfo(scene);
|
||||||
|
|
||||||
@@ -1135,10 +1157,12 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
|
|||||||
raslight->UnbindShadowBuffer();
|
raslight->UnbindShadowBuffer();
|
||||||
m_rasterizer->SetDrawingMode(drawmode);
|
m_rasterizer->SetDrawingMode(drawmode);
|
||||||
cam->Release();
|
cam->Release();
|
||||||
|
hasShadow = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* remember that we have a valid shadow buffer for that scene */
|
/* remember that we have a valid shadow buffer for that scene */
|
||||||
scene->SetShadowDone(true);
|
scene->SetShadowDone(true);
|
||||||
|
return hasShadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update graphics
|
// update graphics
|
||||||
@@ -1335,6 +1359,11 @@ void KX_KetsjiEngine::StopEngine()
|
|||||||
}
|
}
|
||||||
m_scenes.clear();
|
m_scenes.clear();
|
||||||
|
|
||||||
|
if (m_offScreenRender)
|
||||||
|
{
|
||||||
|
delete m_offScreenRender;
|
||||||
|
m_offScreenRender = NULL;
|
||||||
|
}
|
||||||
// cleanup all the stuff
|
// cleanup all the stuff
|
||||||
m_rasterizer->Exit();
|
m_rasterizer->Exit();
|
||||||
}
|
}
|
||||||
@@ -1941,6 +1970,17 @@ bool KX_KetsjiEngine::GetRender()
|
|||||||
return m_doRender;
|
return m_doRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KX_KetsjiEngine::SetOffScreen(bool offScreen)
|
||||||
|
{
|
||||||
|
m_doOffScreen = offScreen;
|
||||||
|
if (offScreen && !m_offScreenRender)
|
||||||
|
{
|
||||||
|
// offscreen render requested, create the offscreen render buffer
|
||||||
|
m_offScreenRender = m_rasterizer->CreateOffScreen(m_canvas->GetWidth(), m_canvas->GetHeight(), 0, RAS_IOffScreen::RAS_OFS_RENDER_BUFFER, RAS_IOffScreen::RAS_OFS_COLOR_FLOAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void KX_KetsjiEngine::SetShowFramerate(bool frameRate)
|
void KX_KetsjiEngine::SetShowFramerate(bool frameRate)
|
||||||
{
|
{
|
||||||
m_show_framerate = frameRate;
|
m_show_framerate = frameRate;
|
||||||
|
@@ -74,6 +74,7 @@ class KX_KetsjiEngine
|
|||||||
private:
|
private:
|
||||||
class RAS_ICanvas* m_canvas; // 2D Canvas (2D Rendering Device Context)
|
class RAS_ICanvas* m_canvas; // 2D Canvas (2D Rendering Device Context)
|
||||||
class RAS_IRasterizer* m_rasterizer; // 3D Rasterizer (3D Rendering)
|
class RAS_IRasterizer* m_rasterizer; // 3D Rasterizer (3D Rendering)
|
||||||
|
class RAS_IOffScreen* m_offScreenRender; // render in render buffer instead of frame buffer
|
||||||
class KX_ISystem* m_kxsystem;
|
class KX_ISystem* m_kxsystem;
|
||||||
class KX_ISceneConverter* m_sceneconverter;
|
class KX_ISceneConverter* m_sceneconverter;
|
||||||
class NG_NetworkDeviceInterface* m_networkdevice;
|
class NG_NetworkDeviceInterface* m_networkdevice;
|
||||||
@@ -130,6 +131,7 @@ private:
|
|||||||
static short m_exitkey; /* Key used to exit the BGE */
|
static short m_exitkey; /* Key used to exit the BGE */
|
||||||
|
|
||||||
static bool m_doRender; /* whether or not the scene should be rendered after the logic frame */
|
static bool m_doRender; /* whether or not the scene should be rendered after the logic frame */
|
||||||
|
static bool m_doOffScreen; /* whether normal render should be sent to an offscreen render buffer or to the frame buffer */
|
||||||
|
|
||||||
int m_exitcode;
|
int m_exitcode;
|
||||||
STR_String m_exitstring;
|
STR_String m_exitstring;
|
||||||
@@ -252,7 +254,8 @@ public:
|
|||||||
///returns true if an update happened to indicate -> Render
|
///returns true if an update happened to indicate -> Render
|
||||||
bool NextFrame();
|
bool NextFrame();
|
||||||
void Render();
|
void Render();
|
||||||
void RenderShadowBuffers(KX_Scene *scene);
|
bool RenderShadowBuffers(KX_Scene *scene);
|
||||||
|
void BindOffScreen(bool bind);
|
||||||
|
|
||||||
void StartEngine(bool clearIpo);
|
void StartEngine(bool clearIpo);
|
||||||
void StopEngine();
|
void StopEngine();
|
||||||
@@ -413,6 +416,11 @@ public:
|
|||||||
* Get the current render flag value
|
* Get the current render flag value
|
||||||
*/
|
*/
|
||||||
static bool GetRender();
|
static bool GetRender();
|
||||||
|
/**
|
||||||
|
* Activate or deactivates the offscreen render of the scene after the logic frame
|
||||||
|
* \param offScreen true (render to offScreen) or false (render to frame buffer)
|
||||||
|
*/
|
||||||
|
void SetOffScreen(bool offScreen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \Sets the display for frame rate on or off.
|
* \Sets the display for frame rate on or off.
|
||||||
|
@@ -484,6 +484,14 @@ static PyObject *gPyGetRender(PyObject *)
|
|||||||
return PyBool_FromLong(KX_KetsjiEngine::GetRender());
|
return PyBool_FromLong(KX_KetsjiEngine::GetRender());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *gPySetOffScreen(PyObject *, PyObject *args)
|
||||||
|
{
|
||||||
|
int offScreen;
|
||||||
|
if (!PyArg_ParseTuple(args, "i:setOffScreen", &offScreen))
|
||||||
|
return NULL;
|
||||||
|
gp_KetsjiEngine->SetOffScreen(offScreen);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *gPySetMaxLogicFrame(PyObject *, PyObject *args)
|
static PyObject *gPySetMaxLogicFrame(PyObject *, PyObject *args)
|
||||||
{
|
{
|
||||||
@@ -897,6 +905,15 @@ static PyObject *gPyNextFrame(PyObject *)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *gPyRender(PyObject *)
|
||||||
|
{
|
||||||
|
if (pynextframestate.render == NULL) Py_RETURN_NONE;
|
||||||
|
if (pynextframestate.state == NULL) Py_RETURN_NONE; //should never happen; raise exception instead?
|
||||||
|
|
||||||
|
pynextframestate.render(pynextframestate.state);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct PyMethodDef game_methods[] = {
|
static struct PyMethodDef game_methods[] = {
|
||||||
{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (const char *)gPyExpandPath_doc},
|
{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (const char *)gPyExpandPath_doc},
|
||||||
@@ -927,6 +944,7 @@ static struct PyMethodDef game_methods[] = {
|
|||||||
{"setExitKey", (PyCFunction) gPySetExitKey, METH_VARARGS, (const char *)"Sets the key used to exit the game engine"},
|
{"setExitKey", (PyCFunction) gPySetExitKey, METH_VARARGS, (const char *)"Sets the key used to exit the game engine"},
|
||||||
{"setRender", (PyCFunction) gPySetRender, METH_VARARGS, (const char *)"Set the global render flag"},
|
{"setRender", (PyCFunction) gPySetRender, METH_VARARGS, (const char *)"Set the global render flag"},
|
||||||
{"getRender", (PyCFunction) gPyGetRender, METH_NOARGS, (const char *)"get the global render flag value"},
|
{"getRender", (PyCFunction) gPyGetRender, METH_NOARGS, (const char *)"get the global render flag value"},
|
||||||
|
{"setOffScreen", (PyCFunction) gPySetOffScreen, METH_VARARGS, (const char *)"Set the global offscreen flag"},
|
||||||
{"getUseExternalClock", (PyCFunction) gPyGetUseExternalClock, METH_NOARGS, (const char *)"Get if we use the time provided by an external clock"},
|
{"getUseExternalClock", (PyCFunction) gPyGetUseExternalClock, METH_NOARGS, (const char *)"Get if we use the time provided by an external clock"},
|
||||||
{"setUseExternalClock", (PyCFunction) gPySetUseExternalClock, METH_VARARGS, (const char *)"Set if we use the time provided by an external clock"},
|
{"setUseExternalClock", (PyCFunction) gPySetUseExternalClock, METH_VARARGS, (const char *)"Set if we use the time provided by an external clock"},
|
||||||
{"getClockTime", (PyCFunction) gPyGetClockTime, METH_NOARGS, (const char *)"Get the last BGE render time. "
|
{"getClockTime", (PyCFunction) gPyGetClockTime, METH_NOARGS, (const char *)"Get the last BGE render time. "
|
||||||
@@ -944,6 +962,7 @@ static struct PyMethodDef game_methods[] = {
|
|||||||
{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
|
{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
|
||||||
{"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine statistics"},
|
{"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine statistics"},
|
||||||
{"NextFrame", (PyCFunction)gPyNextFrame, METH_NOARGS, (const char *)"Render next frame (if Python has control)"},
|
{"NextFrame", (PyCFunction)gPyNextFrame, METH_NOARGS, (const char *)"Render next frame (if Python has control)"},
|
||||||
|
{"Render", (PyCFunction)gPyRender, METH_NOARGS, (const char *)"Do only render (skip logic), if Python has control"},
|
||||||
{"getProfileInfo", (PyCFunction)gPyGetProfileInfo, METH_NOARGS, gPyGetProfileInfo_doc},
|
{"getProfileInfo", (PyCFunction)gPyGetProfileInfo, METH_NOARGS, gPyGetProfileInfo_doc},
|
||||||
/* library functions */
|
/* library functions */
|
||||||
{"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS|METH_KEYWORDS, (const char *)""},
|
{"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS|METH_KEYWORDS, (const char *)""},
|
||||||
@@ -1520,12 +1539,13 @@ static PyGetSetDef RASOffScreen_getseters[] = {
|
|||||||
|
|
||||||
static int PyRASOffScreen__tp_init(PyRASOffScreen *self, PyObject *args, PyObject *kwargs)
|
static int PyRASOffScreen__tp_init(PyRASOffScreen *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
int width, height, samples, target;
|
int width, height, samples, target, bits;
|
||||||
const char *keywords[] = {"width", "height", "samples", "target", NULL};
|
const char *keywords[] = {"width", "height", "samples", "target", "bits", NULL};
|
||||||
|
|
||||||
samples = 0;
|
samples = 0;
|
||||||
target = RAS_IOffScreen::RAS_OFS_RENDER_BUFFER;
|
target = RAS_IOffScreen::RAS_OFS_RENDER_BUFFER;
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii:RASOffscreen", (char **)keywords, &width, &height, &samples, &target)) {
|
bits = RAS_IOffScreen::RAS_OFS_COLOR_8BITS;
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|iii:RASOffscreen", (char **)keywords, &width, &height, &samples, &target, &bits)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1549,12 +1569,17 @@ static int PyRASOffScreen__tp_init(PyRASOffScreen *self, PyObject *args, PyObjec
|
|||||||
PyErr_SetString(PyExc_ValueError, "invalid 'target' given, can only be RAS_OFS_RENDER_BUFFER or RAS_OFS_RENDER_TEXTURE");
|
PyErr_SetString(PyExc_ValueError, "invalid 'target' given, can only be RAS_OFS_RENDER_BUFFER or RAS_OFS_RENDER_TEXTURE");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (bits != RAS_IOffScreen::RAS_OFS_COLOR_8BITS && bits != RAS_IOffScreen::RAS_OFS_COLOR_FLOAT)
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_ValueError, "invalid 'bits' given, can only be RAS_OFS_COLOR_8BITS or RAS_OFS_COLOR_FLOAT");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (!gp_Rasterizer)
|
if (!gp_Rasterizer)
|
||||||
{
|
{
|
||||||
PyErr_SetString(PyExc_SystemError, "no rasterizer");
|
PyErr_SetString(PyExc_SystemError, "no rasterizer");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
self->ofs = gp_Rasterizer->CreateOffScreen(width, height, samples, target);
|
self->ofs = gp_Rasterizer->CreateOffScreen(width, height, samples, target, bits);
|
||||||
if (!self->ofs) {
|
if (!self->ofs) {
|
||||||
PyErr_SetString(PyExc_SystemError, "creation failed");
|
PyErr_SetString(PyExc_SystemError, "creation failed");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1619,9 +1644,10 @@ static PyObject *gPyOffScreenCreate(PyObject *UNUSED(self), PyObject *args)
|
|||||||
int height;
|
int height;
|
||||||
int samples;
|
int samples;
|
||||||
int target;
|
int target;
|
||||||
|
int bits
|
||||||
|
|
||||||
samples = 0;
|
samples = 0;
|
||||||
if (!PyArg_ParseTuple(args, "ii|ii:offScreenCreate", &width, &height, &samples, &target))
|
if (!PyArg_ParseTuple(args, "ii|iii:offScreenCreate", &width, &height, &samples, &target, &bits))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return PyObject_CallObject((PyObject *) &PyRASOffScreen_Type, args);
|
return PyObject_CallObject((PyObject *) &PyRASOffScreen_Type, args);
|
||||||
|
@@ -78,12 +78,15 @@ KX_Scene *KX_GetActiveScene();
|
|||||||
KX_KetsjiEngine *KX_GetActiveEngine();
|
KX_KetsjiEngine *KX_GetActiveEngine();
|
||||||
|
|
||||||
typedef int (*PyNextFrameFunc)(void *);
|
typedef int (*PyNextFrameFunc)(void *);
|
||||||
|
typedef void (*PyRenderFunc)(void *);
|
||||||
|
|
||||||
struct PyNextFrameState {
|
struct PyNextFrameState {
|
||||||
/** can be either a GPG_NextFrameState or a BL_KetsjiNextFrameState */
|
/** can be either a GPG_NextFrameState or a BL_KetsjiNextFrameState */
|
||||||
void *state;
|
void *state;
|
||||||
/** can be either GPG_PyNextFrame or BL_KetsjiPyNextFrame */
|
/** can be either GPG_PyNextFrame or BL_KetsjiPyNextFrame */
|
||||||
PyNextFrameFunc func;
|
PyNextFrameFunc func;
|
||||||
|
/** can be either GPG_PyRender or BL_KetsjiPyRender */
|
||||||
|
PyRenderFunc render;
|
||||||
};
|
};
|
||||||
extern struct PyNextFrameState pynextframestate;
|
extern struct PyNextFrameState pynextframestate;
|
||||||
|
|
||||||
|
@@ -2152,9 +2152,9 @@ bool KX_Scene::MergeScene(KX_Scene *other)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KX_Scene::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
|
void KX_Scene::Update2DFilter(vector<STR_String>& propNames, void* gameObj, void *mat, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
|
||||||
{
|
{
|
||||||
m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
|
m_filtermanager.EnableFilter(propNames, gameObj, mat, filtermode, pass, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KX_Scene::Render2DFilters(RAS_ICanvas* canvas)
|
void KX_Scene::Render2DFilters(RAS_ICanvas* canvas)
|
||||||
|
@@ -82,6 +82,7 @@ class RAS_MaterialBucket;
|
|||||||
class RAS_IPolyMaterial;
|
class RAS_IPolyMaterial;
|
||||||
class RAS_IRasterizer;
|
class RAS_IRasterizer;
|
||||||
class RAS_IRenderTools;
|
class RAS_IRenderTools;
|
||||||
|
class RAS_MeshObject;
|
||||||
class SCA_JoystickManager;
|
class SCA_JoystickManager;
|
||||||
class btCollisionShape;
|
class btCollisionShape;
|
||||||
class KX_BlenderSceneConverter;
|
class KX_BlenderSceneConverter;
|
||||||
@@ -607,7 +608,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 2D Filters
|
* 2D Filters
|
||||||
*/
|
*/
|
||||||
void Update2DFilter(std::vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
|
void Update2DFilter(std::vector<STR_String>& propNames, void* gameObj, void *mat, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
|
||||||
void Render2DFilters(RAS_ICanvas* canvas);
|
void Render2DFilters(RAS_ICanvas* canvas);
|
||||||
|
|
||||||
KX_ObstacleSimulation* GetObstacleSimulation() { return m_obstacleSimulation; }
|
KX_ObstacleSimulation* GetObstacleSimulation() { return m_obstacleSimulation; }
|
||||||
|
@@ -41,14 +41,27 @@
|
|||||||
#include "RAS_ICanvas.h"
|
#include "RAS_ICanvas.h"
|
||||||
#include "RAS_Rect.h"
|
#include "RAS_Rect.h"
|
||||||
#include "RAS_2DFilterManager.h"
|
#include "RAS_2DFilterManager.h"
|
||||||
|
#include "RAS_MaterialBucket.h"
|
||||||
|
#include "BL_Material.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "DNA_image_types.h"
|
||||||
|
#include "DNA_meshdata_types.h"
|
||||||
#include "glew-mx.h"
|
#include "glew-mx.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "EXP_Value.h"
|
#include "EXP_Value.h"
|
||||||
|
|
||||||
|
#define MAX_OBJ_TEXTURE 5
|
||||||
|
static const char *objTextureName[MAX_OBJ_TEXTURE] = {
|
||||||
|
"bgl_ObjectTexture0",
|
||||||
|
"bgl_ObjectTexture1",
|
||||||
|
"bgl_ObjectTexture2",
|
||||||
|
"bgl_ObjectTexture3",
|
||||||
|
"bgl_ObjectTexture4"
|
||||||
|
};
|
||||||
|
|
||||||
RAS_2DFilterManager::RAS_2DFilterManager():
|
RAS_2DFilterManager::RAS_2DFilterManager():
|
||||||
texturewidth(-1), textureheight(-1),
|
texturewidth(-1), textureheight(-1),
|
||||||
/* numberoffilters(0), */ /* UNUSED */ need_tex_update(true)
|
/* numberoffilters(0), */ /* UNUSED */ need_tex_update(true)
|
||||||
@@ -67,6 +80,7 @@ texturewidth(-1), textureheight(-1),
|
|||||||
m_enabled[passindex] = 0;
|
m_enabled[passindex] = 0;
|
||||||
texflag[passindex] = 0;
|
texflag[passindex] = 0;
|
||||||
m_gameObjects[passindex] = NULL;
|
m_gameObjects[passindex] = NULL;
|
||||||
|
m_blmat[passindex] = NULL;
|
||||||
}
|
}
|
||||||
texname[0] = texname[1] = texname[2] = -1;
|
texname[0] = texname[1] = texname[2] = -1;
|
||||||
errorprinted= false;
|
errorprinted= false;
|
||||||
@@ -217,6 +231,19 @@ void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propN
|
|||||||
if (glGetUniformLocationARB(m_filters[passindex], propNames[i]) != -1)
|
if (glGetUniformLocationARB(m_filters[passindex], propNames[i]) != -1)
|
||||||
m_properties[passindex].push_back(propNames[i]);
|
m_properties[passindex].push_back(propNames[i]);
|
||||||
}
|
}
|
||||||
|
if (m_blmat[passindex])
|
||||||
|
{
|
||||||
|
BL_Material *mat = (BL_Material *)m_blmat[passindex];
|
||||||
|
m_textures[passindex].resize(MAX_OBJ_TEXTURE);
|
||||||
|
for (int i=0; i<MAX_OBJ_TEXTURE; i++)
|
||||||
|
{
|
||||||
|
m_textures[passindex][i] = NULL;
|
||||||
|
if (i < MAXTEX && glGetUniformLocationARB(m_filters[passindex], objTextureName[i]) != -1)
|
||||||
|
{
|
||||||
|
m_textures[passindex][i] = mat->img[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAS_2DFilterManager::StartShaderProgram(int passindex)
|
void RAS_2DFilterManager::StartShaderProgram(int passindex)
|
||||||
@@ -224,35 +251,35 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
|
|||||||
GLint uniformLoc;
|
GLint uniformLoc;
|
||||||
glUseProgramObjectARB(m_filters[passindex]);
|
glUseProgramObjectARB(m_filters[passindex]);
|
||||||
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTexture");
|
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTexture");
|
||||||
glActiveTextureARB(GL_TEXTURE0);
|
glActiveTextureARB(GL_TEXTURE5);
|
||||||
glBindTexture(GL_TEXTURE_2D, texname[0]);
|
glBindTexture(GL_TEXTURE_2D, texname[0]);
|
||||||
|
|
||||||
if (uniformLoc != -1)
|
if (uniformLoc != -1)
|
||||||
{
|
{
|
||||||
glUniform1iARB(uniformLoc, 0);
|
glUniform1iARB(uniformLoc, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send depth texture to glsl program if it needs */
|
/* send depth texture to glsl program if it needs */
|
||||||
if (texflag[passindex] & 0x1) {
|
if (texflag[passindex] & 0x1) {
|
||||||
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture");
|
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture");
|
||||||
glActiveTextureARB(GL_TEXTURE1);
|
glActiveTextureARB(GL_TEXTURE6);
|
||||||
glBindTexture(GL_TEXTURE_2D, texname[1]);
|
glBindTexture(GL_TEXTURE_2D, texname[1]);
|
||||||
|
|
||||||
if (uniformLoc != -1)
|
if (uniformLoc != -1)
|
||||||
{
|
{
|
||||||
glUniform1iARB(uniformLoc, 1);
|
glUniform1iARB(uniformLoc, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send luminance texture to glsl program if it needs */
|
/* send luminance texture to glsl program if it needs */
|
||||||
if (texflag[passindex] & 0x2) {
|
if (texflag[passindex] & 0x2) {
|
||||||
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
|
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
|
||||||
glActiveTextureARB(GL_TEXTURE2);
|
glActiveTextureARB(GL_TEXTURE7);
|
||||||
glBindTexture(GL_TEXTURE_2D, texname[2]);
|
glBindTexture(GL_TEXTURE_2D, texname[2]);
|
||||||
|
|
||||||
if (uniformLoc != -1)
|
if (uniformLoc != -1)
|
||||||
{
|
{
|
||||||
glUniform1iARB(uniformLoc, 2);
|
glUniform1iARB(uniformLoc, 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,6 +323,23 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int objTextures = m_textures[passindex].size();
|
||||||
|
for (i=0; i<objTextures; i++)
|
||||||
|
{
|
||||||
|
Image *img;
|
||||||
|
unsigned int bindcode;
|
||||||
|
if ((img = m_textures[passindex][i]) != NULL && (bindcode = img->bindcode[TEXTARGET_TEXTURE_2D]) != 0)
|
||||||
|
{
|
||||||
|
uniformLoc = glGetUniformLocationARB(m_filters[passindex], objTextureName[i]);
|
||||||
|
glActiveTextureARB(GL_TEXTURE0+i);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, bindcode);
|
||||||
|
|
||||||
|
if (uniformLoc != -1)
|
||||||
|
{
|
||||||
|
glUniform1iARB(uniformLoc, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAS_2DFilterManager::EndShaderProgram()
|
void RAS_2DFilterManager::EndShaderProgram()
|
||||||
@@ -315,6 +359,7 @@ void RAS_2DFilterManager::FreeTextures()
|
|||||||
|
|
||||||
void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
|
void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
|
||||||
{
|
{
|
||||||
|
GLenum error;
|
||||||
FreeTextures();
|
FreeTextures();
|
||||||
|
|
||||||
glGenTextures(1, (GLuint*)&texname[0]);
|
glGenTextures(1, (GLuint*)&texname[0]);
|
||||||
@@ -354,8 +399,8 @@ void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
|
|||||||
void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
|
void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
|
||||||
{
|
{
|
||||||
/* RAS_Rect canvas_rect = canvas->GetWindowArea(); */ /* UNUSED */
|
/* RAS_Rect canvas_rect = canvas->GetWindowArea(); */ /* UNUSED */
|
||||||
texturewidth = canvas->GetWidth()+1;
|
texturewidth = canvas->GetWidth();
|
||||||
textureheight = canvas->GetHeight()+1;
|
textureheight = canvas->GetHeight();
|
||||||
GLint i,j;
|
GLint i,j;
|
||||||
|
|
||||||
if (!GL_ARB_texture_non_power_of_two)
|
if (!GL_ARB_texture_non_power_of_two)
|
||||||
@@ -443,13 +488,13 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (need_depth) {
|
if (need_depth) {
|
||||||
glActiveTextureARB(GL_TEXTURE1);
|
glActiveTextureARB(GL_TEXTURE6);
|
||||||
glBindTexture(GL_TEXTURE_2D, texname[1]);
|
glBindTexture(GL_TEXTURE_2D, texname[1]);
|
||||||
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], viewport[2], viewport[3], 0);
|
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], viewport[2], viewport[3], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_luminance) {
|
if (need_luminance) {
|
||||||
glActiveTextureARB(GL_TEXTURE2);
|
glActiveTextureARB(GL_TEXTURE7);
|
||||||
glBindTexture(GL_TEXTURE_2D, texname[2]);
|
glBindTexture(GL_TEXTURE_2D, texname[2]);
|
||||||
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1], viewport[2], viewport[3], 0);
|
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1], viewport[2], viewport[3], 0);
|
||||||
}
|
}
|
||||||
@@ -463,8 +508,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
|
|||||||
|
|
||||||
glScissor(scissor_rect.GetLeft() + viewport[0],
|
glScissor(scissor_rect.GetLeft() + viewport[0],
|
||||||
scissor_rect.GetBottom() + viewport[1],
|
scissor_rect.GetBottom() + viewport[1],
|
||||||
scissor_rect.GetWidth() + 1,
|
scissor_rect.GetWidth(),
|
||||||
scissor_rect.GetHeight() + 1);
|
scissor_rect.GetHeight());
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
// in case the previous material was wire
|
// in case the previous material was wire
|
||||||
@@ -488,9 +533,9 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
|
|||||||
{
|
{
|
||||||
StartShaderProgram(passindex);
|
StartShaderProgram(passindex);
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0);
|
glActiveTextureARB(GL_TEXTURE5);
|
||||||
glBindTexture(GL_TEXTURE_2D, texname[0]);
|
glBindTexture(GL_TEXTURE_2D, texname[0]);
|
||||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], viewport[2], viewport[3], 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport[0], viewport[1], viewport[2], viewport[3], 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
@@ -502,6 +547,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
|
|||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
glActiveTextureARB(GL_TEXTURE0);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
EndShaderProgram();
|
EndShaderProgram();
|
||||||
@@ -510,7 +556,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text)
|
void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, void *mat, RAS_2DFILTER_MODE mode, int pass, STR_String& text)
|
||||||
{
|
{
|
||||||
if (!isshadersupported)
|
if (!isshadersupported)
|
||||||
return;
|
return;
|
||||||
@@ -536,7 +582,9 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game
|
|||||||
m_enabled[pass] = 0;
|
m_enabled[pass] = 0;
|
||||||
m_filters[pass] = 0;
|
m_filters[pass] = 0;
|
||||||
m_gameObjects[pass] = NULL;
|
m_gameObjects[pass] = NULL;
|
||||||
|
m_blmat[pass] = NULL;
|
||||||
m_properties[pass].clear();
|
m_properties[pass].clear();
|
||||||
|
m_textures[pass].clear();
|
||||||
texflag[pass] = 0;
|
texflag[pass] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -547,6 +595,7 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game
|
|||||||
glDeleteObjectARB(m_filters[pass]);
|
glDeleteObjectARB(m_filters[pass]);
|
||||||
m_filters[pass] = CreateShaderProgram(text.Ptr());
|
m_filters[pass] = CreateShaderProgram(text.Ptr());
|
||||||
m_gameObjects[pass] = gameObj;
|
m_gameObjects[pass] = gameObj;
|
||||||
|
m_blmat[pass] = mat;
|
||||||
AnalyseShader(pass, propNames);
|
AnalyseShader(pass, propNames);
|
||||||
m_enabled[pass] = 1;
|
m_enabled[pass] = 1;
|
||||||
return;
|
return;
|
||||||
@@ -557,6 +606,7 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game
|
|||||||
glDeleteObjectARB(m_filters[pass]);
|
glDeleteObjectARB(m_filters[pass]);
|
||||||
m_filters[pass] = CreateShaderProgram(mode);
|
m_filters[pass] = CreateShaderProgram(mode);
|
||||||
m_gameObjects[pass] = NULL;
|
m_gameObjects[pass] = NULL;
|
||||||
|
m_blmat[pass] = NULL;
|
||||||
AnalyseShader(pass, propNames);
|
AnalyseShader(pass, propNames);
|
||||||
m_enabled[pass] = 1;
|
m_enabled[pass] = 1;
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
class RAS_ICanvas;
|
class RAS_ICanvas;
|
||||||
|
struct Image;
|
||||||
|
|
||||||
class RAS_2DFilterManager
|
class RAS_2DFilterManager
|
||||||
{
|
{
|
||||||
@@ -78,6 +79,10 @@ private:
|
|||||||
// stores object properties to send to shaders in each pass
|
// stores object properties to send to shaders in each pass
|
||||||
std::vector<STR_String> m_properties[MAX_RENDER_PASS];
|
std::vector<STR_String> m_properties[MAX_RENDER_PASS];
|
||||||
void* m_gameObjects[MAX_RENDER_PASS];
|
void* m_gameObjects[MAX_RENDER_PASS];
|
||||||
|
void *m_blmat[MAX_RENDER_PASS];
|
||||||
|
// stores the additional textures that should be mapped during render pass to GL_TEXTURE3..7
|
||||||
|
std::vector<struct Image *> m_textures[MAX_RENDER_PASS];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum RAS_2DFILTER_MODE {
|
enum RAS_2DFILTER_MODE {
|
||||||
RAS_2DFILTER_ENABLED = -2,
|
RAS_2DFILTER_ENABLED = -2,
|
||||||
@@ -104,7 +109,7 @@ public:
|
|||||||
|
|
||||||
void RenderFilters(RAS_ICanvas* canvas);
|
void RenderFilters(RAS_ICanvas* canvas);
|
||||||
|
|
||||||
void EnableFilter(std::vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text);
|
void EnableFilter(std::vector<STR_String>& propNames, void* gameObj, void *mat, RAS_2DFILTER_MODE mode, int pass, STR_String& text);
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_CXX_GUARDEDALLOC
|
#ifdef WITH_CXX_GUARDEDALLOC
|
||||||
|
@@ -51,6 +51,10 @@ public:
|
|||||||
RAS_OFS_RENDER_BUFFER = 0, // use render buffer as render target
|
RAS_OFS_RENDER_BUFFER = 0, // use render buffer as render target
|
||||||
RAS_OFS_RENDER_TEXTURE, // use texture as render target
|
RAS_OFS_RENDER_TEXTURE, // use texture as render target
|
||||||
};
|
};
|
||||||
|
enum RAS_OFS_COLOR_BITS {
|
||||||
|
RAS_OFS_COLOR_8BITS = 0, // color buffer will be 8bits unsigned per color
|
||||||
|
RAS_OFS_COLOR_FLOAT, // color buffer will be 32bits float per color (if OpenGL supports it)
|
||||||
|
};
|
||||||
|
|
||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
@@ -59,7 +63,7 @@ public:
|
|||||||
|
|
||||||
virtual ~RAS_IOffScreen() {}
|
virtual ~RAS_IOffScreen() {}
|
||||||
|
|
||||||
virtual bool Create(int width, int height, int samples, RAS_OFS_RENDER_TARGET target) = 0;
|
virtual bool Create(int width, int height, int samples, RAS_OFS_RENDER_TARGET target, RAS_OFS_COLOR_BITS bits) = 0;
|
||||||
virtual void Destroy() = 0;
|
virtual void Destroy() = 0;
|
||||||
virtual void Bind(RAS_OFS_BIND_MODE mode) = 0;
|
virtual void Bind(RAS_OFS_BIND_MODE mode) = 0;
|
||||||
virtual void Blit() = 0;
|
virtual void Blit() = 0;
|
||||||
|
@@ -263,7 +263,7 @@ public:
|
|||||||
* Create an offscreen render buffer that can be used as target for render.
|
* Create an offscreen render buffer that can be used as target for render.
|
||||||
* For the time being, it is only used in VideoTexture for custom render.
|
* For the time being, it is only used in VideoTexture for custom render.
|
||||||
*/
|
*/
|
||||||
virtual RAS_IOffScreen *CreateOffScreen(int width, int height, int samples, int target) = 0;
|
virtual RAS_IOffScreen *CreateOffScreen(int width, int height, int samples, int target, int bits) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a sync object
|
* Create a sync object
|
||||||
|
@@ -47,7 +47,7 @@ RAS_OpenGLOffScreen::~RAS_OpenGLOffScreen()
|
|||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, RAS_OFS_RENDER_TARGET target)
|
bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, RAS_OFS_RENDER_TARGET target, RAS_OFS_COLOR_BITS bits)
|
||||||
{
|
{
|
||||||
GLenum status;
|
GLenum status;
|
||||||
GLuint glo[2], fbo;
|
GLuint glo[2], fbo;
|
||||||
@@ -111,7 +111,10 @@ bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, RAS_OFS_REN
|
|||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_depthtx);
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_depthtx);
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_DEPTH_COMPONENT, width, height, true);
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_DEPTH_COMPONENT, width, height, true);
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_colortx);
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_colortx);
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, width, height, true);
|
if (bits == RAS_OFS_COLOR_FLOAT && GLEW_ARB_texture_float)
|
||||||
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, width, height, true);
|
||||||
|
else
|
||||||
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA32F, width, height, true);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@@ -123,7 +126,10 @@ bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, RAS_OFS_REN
|
|||||||
glBindTexture(GL_TEXTURE_2D, m_depthtx);
|
glBindTexture(GL_TEXTURE_2D, m_depthtx);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_colortx);
|
glBindTexture(GL_TEXTURE_2D, m_colortx);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
if (bits == RAS_OFS_COLOR_FLOAT && GLEW_ARB_texture_float)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||||
@@ -141,7 +147,10 @@ bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, RAS_OFS_REN
|
|||||||
glBindRenderbufferEXT(GL_RENDERBUFFER, m_depthrb);
|
glBindRenderbufferEXT(GL_RENDERBUFFER, m_depthrb);
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT, width, height);
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT, width, height);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER, m_colorrb);
|
glBindRenderbufferEXT(GL_RENDERBUFFER, m_colorrb);
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);
|
if (bits == RAS_OFS_COLOR_FLOAT && GLEW_ARB_texture_float)
|
||||||
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_RGBA32F, width, height);
|
||||||
|
else
|
||||||
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
|
glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||||
@@ -180,7 +189,10 @@ bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, RAS_OFS_REN
|
|||||||
// m_color is the texture where the final render goes, the blit texture in this case
|
// m_color is the texture where the final render goes, the blit texture in this case
|
||||||
m_color = m_blittex = blit_tex;
|
m_color = m_blittex = blit_tex;
|
||||||
glBindTexture(GL_TEXTURE_2D, m_blittex);
|
glBindTexture(GL_TEXTURE_2D, m_blittex);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
if (bits == RAS_OFS_COLOR_FLOAT && GLEW_ARB_texture_float)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@@ -198,7 +210,10 @@ bool RAS_OpenGLOffScreen::Create(int width, int height, int samples, RAS_OFS_REN
|
|||||||
}
|
}
|
||||||
m_blitrbo = blit_tex;
|
m_blitrbo = blit_tex;
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER, m_blitrbo);
|
glBindRenderbufferEXT(GL_RENDERBUFFER, m_blitrbo);
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 0, GL_RGBA8, width, height);
|
if (bits == RAS_OFS_COLOR_FLOAT && GLEW_ARB_texture_float)
|
||||||
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 0, GL_RGBA32F, width, height);
|
||||||
|
else
|
||||||
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 0, GL_RGBA8, width, height);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
|
glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_blitfbo);
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_blitfbo);
|
||||||
glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER, m_blitrbo);
|
glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER, m_blitrbo);
|
||||||
|
@@ -53,7 +53,7 @@ public:
|
|||||||
RAS_OpenGLOffScreen(RAS_ICanvas *canvas);
|
RAS_OpenGLOffScreen(RAS_ICanvas *canvas);
|
||||||
~RAS_OpenGLOffScreen();
|
~RAS_OpenGLOffScreen();
|
||||||
|
|
||||||
bool Create(int width, int height, int samples, RAS_OFS_RENDER_TARGET target);
|
bool Create(int width, int height, int samples, RAS_OFS_RENDER_TARGET target, RAS_OFS_COLOR_BITS bits);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
void Bind(RAS_OFS_BIND_MODE mode);
|
void Bind(RAS_OFS_BIND_MODE mode);
|
||||||
void Blit();
|
void Blit();
|
||||||
|
@@ -601,13 +601,13 @@ float RAS_OpenGLRasterizer::GetFocalLength()
|
|||||||
return m_focallength;
|
return m_focallength;
|
||||||
}
|
}
|
||||||
|
|
||||||
RAS_IOffScreen *RAS_OpenGLRasterizer::CreateOffScreen(int width, int height, int samples, int target)
|
RAS_IOffScreen *RAS_OpenGLRasterizer::CreateOffScreen(int width, int height, int samples, int target, int bits)
|
||||||
{
|
{
|
||||||
RAS_IOffScreen *ofs;
|
RAS_IOffScreen *ofs;
|
||||||
|
|
||||||
ofs = new RAS_OpenGLOffScreen(m_2DCanvas);
|
ofs = new RAS_OpenGLOffScreen(m_2DCanvas);
|
||||||
|
|
||||||
if (!ofs->Create(width, height, samples, (RAS_IOffScreen::RAS_OFS_RENDER_TARGET)target)) {
|
if (!ofs->Create(width, height, samples, (RAS_IOffScreen::RAS_OFS_RENDER_TARGET)target, (RAS_IOffScreen::RAS_OFS_COLOR_BITS)bits)) {
|
||||||
delete ofs;
|
delete ofs;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@@ -181,7 +181,7 @@ public:
|
|||||||
virtual float GetEyeSeparation();
|
virtual float GetEyeSeparation();
|
||||||
virtual void SetFocalLength(const float focallength);
|
virtual void SetFocalLength(const float focallength);
|
||||||
virtual float GetFocalLength();
|
virtual float GetFocalLength();
|
||||||
virtual RAS_IOffScreen *CreateOffScreen(int width, int height, int samples, int target);
|
virtual RAS_IOffScreen *CreateOffScreen(int width, int height, int samples, int target, int bits);
|
||||||
virtual RAS_ISync *CreateSync(int type);
|
virtual RAS_ISync *CreateSync(int type);
|
||||||
virtual void SwapBuffers();
|
virtual void SwapBuffers();
|
||||||
|
|
||||||
|
@@ -118,6 +118,26 @@ unsigned int * ImageBase::getImage (unsigned int texId, double ts)
|
|||||||
return m_avail ? m_image : NULL;
|
return m_avail ? m_image : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ImageBase::getPixelSize(unsigned int format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case GL_RGBA:
|
||||||
|
case GL_BGRA:
|
||||||
|
case GL_DEPTH_COMPONENT32F:
|
||||||
|
return 4;
|
||||||
|
case GL_RGBA32F:
|
||||||
|
return 4*4;
|
||||||
|
case GL_RGB32F:
|
||||||
|
return 3*4;
|
||||||
|
case GL_RG32F:
|
||||||
|
return 2*4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool ImageBase::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
|
bool ImageBase::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
|
||||||
{
|
{
|
||||||
unsigned int *d, *s, v, len;
|
unsigned int *d, *s, v, len;
|
||||||
@@ -564,6 +584,14 @@ PyObject *Image_refresh (PyImage *self, PyObject *args)
|
|||||||
format = GL_RGBA;
|
format = GL_RGBA;
|
||||||
else if (!strcmp(mode, "BGRA"))
|
else if (!strcmp(mode, "BGRA"))
|
||||||
format = GL_BGRA;
|
format = GL_BGRA;
|
||||||
|
else if (!strcmp(mode, "DEPTH"))
|
||||||
|
format = GL_DEPTH_COMPONENT32F;
|
||||||
|
else if (!strcmp(mode, "RGBA32F"))
|
||||||
|
format = GL_RGBA32F;
|
||||||
|
else if (!strcmp(mode, "RGB32F"))
|
||||||
|
format = GL_RGB32F;
|
||||||
|
else if (!strcmp(mode, "RG32F"))
|
||||||
|
format = GL_RG32F;
|
||||||
else
|
else
|
||||||
THRWEXCP(InvalidImageMode,S_OK);
|
THRWEXCP(InvalidImageMode,S_OK);
|
||||||
|
|
||||||
|
@@ -70,8 +70,9 @@ public:
|
|||||||
/// get image size
|
/// get image size
|
||||||
short * getSize(void) { return m_size; }
|
short * getSize(void) { return m_size; }
|
||||||
/// get image buffer size
|
/// get image buffer size
|
||||||
unsigned long getBuffSize(void)
|
unsigned long getBuffSize()
|
||||||
{ return m_size[0] * m_size[1] * sizeof(unsigned int); }
|
{ return m_size[0] * m_size[1] * sizeof(unsigned int); }
|
||||||
|
unsigned int getPixelSize(unsigned int format);
|
||||||
/// refresh image - invalidate its current content
|
/// refresh image - invalidate its current content
|
||||||
virtual void refresh(void);
|
virtual void refresh(void);
|
||||||
|
|
||||||
|
@@ -134,7 +134,7 @@ void ImageRender::setBackgroundFromScene (KX_Scene *scene)
|
|||||||
|
|
||||||
|
|
||||||
// capture image from viewport
|
// capture image from viewport
|
||||||
void ImageRender::calcViewport (unsigned int texId, double ts, unsigned int format)
|
void ImageRender::calcImage (unsigned int texId, double ts)
|
||||||
{
|
{
|
||||||
// render the scene from the camera
|
// render the scene from the camera
|
||||||
if (!m_done) {
|
if (!m_done) {
|
||||||
@@ -148,12 +148,34 @@ void ImageRender::calcViewport (unsigned int texId, double ts, unsigned int form
|
|||||||
// wait until all render operations are completed
|
// wait until all render operations are completed
|
||||||
WaitSync();
|
WaitSync();
|
||||||
// get image from viewport (or FBO)
|
// get image from viewport (or FBO)
|
||||||
ImageViewport::calcViewport(texId, ts, format);
|
calcViewport(texId, ts);
|
||||||
if (m_offscreen) {
|
if (m_offscreen) {
|
||||||
m_offscreen->ofs->Unbind();
|
m_offscreen->ofs->Unbind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ImageRender::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
// render the scene from the camera
|
||||||
|
if (!m_done) {
|
||||||
|
if (!Render()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_offscreen) {
|
||||||
|
m_offscreen->ofs->Bind(RAS_IOffScreen::RAS_OFS_BIND_READ);
|
||||||
|
}
|
||||||
|
// wait until all render operations are completed
|
||||||
|
WaitSync();
|
||||||
|
// get image from viewport (or FBO)
|
||||||
|
ret = loadRender(buffer, size, format);
|
||||||
|
if (m_offscreen) {
|
||||||
|
m_offscreen->ofs->Unbind();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool ImageRender::Render()
|
bool ImageRender::Render()
|
||||||
{
|
{
|
||||||
RAS_FrameFrustum frustum;
|
RAS_FrameFrustum frustum;
|
||||||
@@ -246,7 +268,7 @@ bool ImageRender::Render()
|
|||||||
m_canvas->UpdateViewPort(0, 0, m_offscreen->ofs->GetWidth(), m_offscreen->ofs->GetHeight());
|
m_canvas->UpdateViewPort(0, 0, m_offscreen->ofs->GetWidth(), m_offscreen->ofs->GetHeight());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1);
|
m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0], m_position[1]+m_capSize[1]);
|
||||||
}
|
}
|
||||||
m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]);
|
m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]);
|
||||||
m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
|
m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
|
||||||
|
@@ -73,6 +73,8 @@ public:
|
|||||||
void Unbind();
|
void Unbind();
|
||||||
/// wait for render to complete
|
/// wait for render to complete
|
||||||
void WaitSync();
|
void WaitSync();
|
||||||
|
/// load render buffer directly into user image
|
||||||
|
virtual bool loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// true if ready to render
|
/// true if ready to render
|
||||||
@@ -111,10 +113,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
/// render 3d scene to image
|
/// render 3d scene to image
|
||||||
virtual void calcImage (unsigned int texId, double ts) { calcViewport(texId, ts, GL_RGBA); }
|
virtual void calcImage (unsigned int texId, double ts);
|
||||||
|
|
||||||
/// render 3d scene to image
|
|
||||||
virtual void calcViewport (unsigned int texId, double ts, unsigned int format);
|
|
||||||
|
|
||||||
void setBackgroundFromScene(KX_Scene *scene);
|
void setBackgroundFromScene(KX_Scene *scene);
|
||||||
void SetWorldSettings(KX_WorldInfo* wi);
|
void SetWorldSettings(KX_WorldInfo* wi);
|
||||||
|
@@ -132,9 +132,15 @@ void ImageViewport::setPosition (GLint pos[2])
|
|||||||
m_upLeft[idx] = m_position[idx] + m_viewport[idx];
|
m_upLeft[idx] = m_position[idx] + m_viewport[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageViewport::calcImage (unsigned int texId, double ts)
|
||||||
|
{
|
||||||
|
KX_GetActiveEngine()->BindOffScreen(true);
|
||||||
|
calcViewport(texId, ts);
|
||||||
|
KX_GetActiveEngine()->BindOffScreen(false);
|
||||||
|
}
|
||||||
|
|
||||||
// capture image from viewport
|
// capture image from viewport
|
||||||
void ImageViewport::calcViewport (unsigned int texId, double ts, unsigned int format)
|
void ImageViewport::calcViewport (unsigned int texId, double ts)
|
||||||
{
|
{
|
||||||
// if scale was changed
|
// if scale was changed
|
||||||
if (m_scaleChange)
|
if (m_scaleChange)
|
||||||
@@ -192,12 +198,12 @@ void ImageViewport::calcViewport (unsigned int texId, double ts, unsigned int fo
|
|||||||
!m_flip &&
|
!m_flip &&
|
||||||
!m_pyfilter)
|
!m_pyfilter)
|
||||||
{
|
{
|
||||||
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], format,
|
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA,
|
||||||
GL_UNSIGNED_BYTE, m_image);
|
GL_UNSIGNED_BYTE, m_image);
|
||||||
m_avail = true;
|
m_avail = true;
|
||||||
}
|
}
|
||||||
else if (!m_pyfilter) {
|
else if (!m_pyfilter) {
|
||||||
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], format,
|
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA,
|
||||||
GL_UNSIGNED_BYTE, m_viewportImage);
|
GL_UNSIGNED_BYTE, m_viewportImage);
|
||||||
FilterRGBA32 filt;
|
FilterRGBA32 filt;
|
||||||
filterImage(filt, m_viewportImage, m_capSize);
|
filterImage(filt, m_viewportImage, m_capSize);
|
||||||
@@ -207,10 +213,6 @@ void ImageViewport::calcViewport (unsigned int texId, double ts, unsigned int fo
|
|||||||
GL_UNSIGNED_BYTE, m_viewportImage);
|
GL_UNSIGNED_BYTE, m_viewportImage);
|
||||||
FilterRGBA32 filt;
|
FilterRGBA32 filt;
|
||||||
filterImage(filt, m_viewportImage, m_capSize);
|
filterImage(filt, m_viewportImage, m_capSize);
|
||||||
if (format == GL_BGRA) {
|
|
||||||
// in place byte swapping
|
|
||||||
swapImageBR();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -219,10 +221,6 @@ void ImageViewport::calcViewport (unsigned int texId, double ts, unsigned int fo
|
|||||||
// filter loaded data
|
// filter loaded data
|
||||||
FilterRGB24 filt;
|
FilterRGB24 filt;
|
||||||
filterImage(filt, m_viewportImage, m_capSize);
|
filterImage(filt, m_viewportImage, m_capSize);
|
||||||
if (format == GL_BGRA) {
|
|
||||||
// in place byte swapping
|
|
||||||
swapImageBR();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,35 +229,55 @@ void ImageViewport::calcViewport (unsigned int texId, double ts, unsigned int fo
|
|||||||
|
|
||||||
bool ImageViewport::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
|
bool ImageViewport::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
|
||||||
{
|
{
|
||||||
unsigned int *tmp_image;
|
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
// if scale was changed
|
KX_GetActiveEngine()->BindOffScreen(true);
|
||||||
if (m_scaleChange) {
|
ret = loadRender(buffer, size, format);
|
||||||
// reset image
|
KX_GetActiveEngine()->BindOffScreen(false);
|
||||||
init(m_capSize[0], m_capSize[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// size must be identical
|
|
||||||
if (size < getBuffSize())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_avail) {
|
|
||||||
// just copy
|
|
||||||
return ImageBase::loadImage(buffer, size, format, ts);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tmp_image = m_image;
|
|
||||||
m_image = buffer;
|
|
||||||
calcViewport(0, ts, format);
|
|
||||||
ret = m_avail;
|
|
||||||
m_image = tmp_image;
|
|
||||||
// since the image was not loaded to our buffer, it's not valid
|
|
||||||
m_avail = false;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ImageViewport::loadRender(unsigned int *buffer, unsigned int size, unsigned int format)
|
||||||
|
{
|
||||||
|
unsigned int renderSize;
|
||||||
|
|
||||||
|
renderSize = getPixelSize(format)*m_capSize[0]*m_capSize[1];
|
||||||
|
if (renderSize == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// size must be identical
|
||||||
|
if (size < renderSize)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case GL_DEPTH_COMPONENT32F:
|
||||||
|
// Use read pixels with the depth buffer
|
||||||
|
// See warning above about m_viewportImage.
|
||||||
|
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
|
||||||
|
GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
|
||||||
|
break;
|
||||||
|
case GL_RGBA:
|
||||||
|
case GL_BGRA:
|
||||||
|
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
|
||||||
|
format, GL_UNSIGNED_BYTE, buffer);
|
||||||
|
break;
|
||||||
|
case GL_RGBA32F:
|
||||||
|
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
|
||||||
|
GL_RGBA, GL_FLOAT, buffer);
|
||||||
|
break;
|
||||||
|
case GL_RGB32F:
|
||||||
|
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
|
||||||
|
GL_RGB, GL_FLOAT, buffer);
|
||||||
|
break;
|
||||||
|
case GL_RG32F:
|
||||||
|
glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1],
|
||||||
|
GL_RG, GL_FLOAT, buffer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// cast Image pointer to ImageViewport
|
// cast Image pointer to ImageViewport
|
||||||
inline ImageViewport * getImageViewport (PyImage *self)
|
inline ImageViewport * getImageViewport (PyImage *self)
|
||||||
|
@@ -93,10 +93,13 @@ protected:
|
|||||||
bool m_texInit;
|
bool m_texInit;
|
||||||
|
|
||||||
/// capture image from viewport
|
/// capture image from viewport
|
||||||
virtual void calcImage (unsigned int texId, double ts) { calcViewport(texId, ts, GL_RGBA); }
|
virtual void calcImage (unsigned int texId, double ts);
|
||||||
|
|
||||||
/// capture image from viewport
|
/// capture image from viewport
|
||||||
virtual void calcViewport (unsigned int texId, double ts, unsigned int format);
|
virtual void calcViewport (unsigned int texId, double ts);
|
||||||
|
|
||||||
|
/// read render buffer to user buffer
|
||||||
|
virtual bool loadRender(unsigned int *buffer, unsigned int size, unsigned int format);
|
||||||
|
|
||||||
/// get viewport size
|
/// get viewport size
|
||||||
GLint * getViewportSize (void) { return m_viewport + 2; }
|
GLint * getViewportSize (void) { return m_viewport + 2; }
|
||||||
|
Reference in New Issue
Block a user