Skip to content

Instantly share code, notes, and snippets.

@earl
Created October 25, 2010 21:33
Show Gist options
  • Save earl/9d6d0330b88d6d5419b1 to your computer and use it in GitHub Desktop.
Save earl/9d6d0330b88d6d5419b1 to your computer and use it in GitHub Desktop.
Differences between RT A109 Host Kit for Win32 and Maxim Olivier-Adlhoch's "Custom Gob Rendering" Host Kit
diff -urw r3-host-kit-a109/src/agg/agg_compo.cpp r3-cgr/r3-host-kit-a109/src/agg/agg_compo.cpp
--- r3-host-kit-a109/src/agg/agg_compo.cpp 2010-10-22 18:21:18.000000000 +0200
+++ r3-cgr/r3-host-kit-a109/src/agg/agg_compo.cpp 2010-10-24 23:51:50.000000000 +0200
@@ -2,12 +2,23 @@
//include "agg_effects.h"
#include "agg_truetype_text.h"
+#include "ht-linked-list.h" // [CGR]
+#include "cgr-ext.h" //[CGR]
+
+
+
+extern "C" void RL_Print(char *fmt, ...);//output just for testing [CGR]
//extern "C" void Reb_Print(char *fmt, ...);//output just for testing
extern "C" void Blit_Rect(REBGOB *gob, REBPAR d, REBPAR dsize, REBYTE *src, REBPAR s, REBPAR ssize);
extern "C" void* Rich_Text;
//extern "C" void* Effects;
extern "C" void *RL_Series(REBSER *ser, REBINT what);
+//[CGR] start
+extern "C" GOBD *GetCustomGobData(REBGOB *gob);
+extern "C" REBGOB *GetGobWindow(REBGOB *gob);
+extern "C" void HT_Print(char *fmt, ...);
+//[CGR] end
namespace agg
{
compositor::compositor(REBGOB* rootGob, REBGOB* winGob) :
@@ -465,6 +476,7 @@
REBINT tx = sx;
REBINT ty = sy;
+ REBINT gob_type; // [CGR] this is temporarily used to allow SAFE custom gobs detection & rendering.
rect clip;
if (GOB_PARENT(gob) && (GOB_PARENT(gob) != m_rootGob)){
@@ -524,11 +536,15 @@
prim_pixfmt_type pixf(m_rbuf_win);
m_rb_win(pixf);
*/
+
+ // offset window buffer pointer to current gob offset?
m_rbuf_win.attach(m_buf + (ox * 4) + (oy * m_stride), sx, sy, m_stride);
int abs_ox = ox;
int abs_oy = oy;
+
+ // adjust offset so we are at the start of the current clip region?
if (ox < clip.x1) {
ox = -ox + clip.x1;
} else {
@@ -540,6 +556,7 @@
oy = 0;
}
+ // set the clip region to the actual visible portion of a gob?
m_rb_win.clip_box(ox,oy,sx,sy);
//try to store final area for later blitting
@@ -555,8 +572,143 @@
}
if (!m_opaque){
+ //---------
+ //[CGR] start
+ // here we try to detect if the gob being rendered is managed by a CGR
+ // this is a little bit sub-optimal, but at least its 100% safe
+ GOBD *gobd;
+
+ // this *will* slow down rendering, but is temporarily required to allow
+ // integrated and safe use of custom gob renderers
+ gob_type = GOB_TYPE(gob);
+
+ // we make a fast check to filter out any content gob
+ // this prevents us from having to iterate over the custom gob list for all gobs.
+ // gobs are only none, when their data has never been set (to a color, block, text, etc)
+ if (IS_GOB_NONE(gob)){
+
+ // then check if the gob is in our custom gob list
+ gobd = GOBD_GET(gob);
+ if (gobd){
+ gob_type = GOBT_CUSTOM;
+ }
+ }
+ //[CGR] end
+
+ switch (gob_type) {
+
+ //[CGR] start
+ case GOBT_CUSTOM: {
+ // Note that most of the code below has been temporarily disabled,
+ // since the current Test CGR doesn't support compositor mode yet.
+ // this WILL be re-instated when I have time to polish up the API a bit.
+
+ //u32 success = 0;
+ REBYTE* tmp_buf;
+
+
+
+ REBINT result;
+
+ //HT_Print("compositing CUSTOM gob\n");
+
+ // allocate a new buffer & agg base_renderer for our custom gob renderer if it doesn't have one
+ // current system is STUPID... we render the whole area and then clip it to visible area.
+ //
+ // ultimately, renderer will receive both the buffer, size info and visible area.
+ // either it renders only visible portion, or we clip after its rendered everything.
+ // its return result will indicate what its returning
+ //
+ // this is because some renderers can adapt their view (like opengl cameras) to
+ // account for the smaller visible area and render only that region directly.
+ //
+ // also it may be that some renderers render directly to the HW and we only need to
+ // tell it to render, not actually needing to blit anything afterwards.
+ //if (!gobd->renderer->agg_rdr){
+ // eventually we will verify previous size and compare it with new one.
+ // we might need to re-allocate a new, bigger buffer.
+// ren_buf aggrdr;
+// tmp_buf = new REBYTE [sx * sy * 4];
+//
+// aggrdr.attach(tmp_buf,gobw,gobh,gobw * 4);
+// agg_graphics::pixfmt pixf_img(m_rbuf_img);
+// gobd->renderer->agg_rdr
+ //}
+
+
+// agg_graphics::ren_base rb;
+// ren_buf* renbuf;
+// ren_buf rbuf_tmp;
+// agg_graphics::pixfmt pixf_tmp(rbuf_tmp);
+// agg_graphics::ren_base rb_tmp(pixf_tmp);
+
+ // generate temporary buffer
+
+ //agg_graphics::ren_base rb;
+// ren_buf* renbuf;
+ ren_buf rbuf_tmp;
+ REBGOB *win_gob = GET_GOB_WINDOW(gob);
+
+ //HT_Print("agg_compo/process()-> offset: %d,%d size: %d,%d\n", abs_ox, abs_oy, sx, sy);
+ tmp_buf = new REBYTE [sx * sy * 4];
+ memset(tmp_buf, 255, sx * sy * 4);
+ rbuf_tmp.attach(tmp_buf,sx,sy,sx * 4);
+
+ agg_graphics::pixfmt pixf_tmp(rbuf_tmp);
+ agg_graphics::ren_base rb(pixf_tmp);
+
+
+ //rb = rb_tmp;
+ rb.clip_box(ox,oy,30,30);
+ //renbuf = &rbuf_tmp;
+
+ //---------------
+ // render image
+ // might not actually put graphics in tmp_buf since it may
+ // be rendering in container mode.
+ result = gobd->renderer->on_render( gobd, win_gob, tmp_buf, abs_ox, abs_oy, sx, sy );
+
+ if (!result){
+ //HT_Print("RENDERING SUCCESS\n");
+ }else{
+ //HT_Print("RENDERING FAILURE\n");
+ }
+
+
+// void* graphics = new agg_graphics(renbuf, tx, ty, ox, oy);
+//
+// REBSER *args = 0;
+//
+// REBINT result = Draw_Gob(graphics, (REBSER *)GOB_CONTENT(gob), args);
+//
+// if (result < 0) goto do_cleanup;
+//
+// result = ((agg_graphics*)graphics)->agg_render(rb);
+
+// do_cleanup:
+ //delete (agg_graphics*)graphics;
+
+
+ // blend result back in window
+ if (tmp_buf){
+
+ //blend with main buffer
+ m_rb_win.blend_from(pixf_tmp,0,0,0,255 - GOB_ALPHA(gob));
+
+ //deallocate temporary buffer
+ delete tmp_buf;
+ }
+
+
+ if (result < 0) return result;
+
+
+
+
+ }
+ break;
+ //[CGR] end
- switch (GOB_TYPE(gob)) {
case GOBT_COLOR:
{
//draw background color
@@ -616,7 +768,7 @@
break;
case GOBT_DRAW:
{
-// Reb_Print("GOB DRAW");
+ //RL_Print("GOB DRAW");
agg_graphics::ren_base rb;
REBYTE* tmp_buf = 0;
diff -urw r3-host-kit-a109/src/include/reb-ext.h r3-cgr/r3-host-kit-a109/src/include/reb-ext.h
--- r3-host-kit-a109/src/include/reb-ext.h 2010-10-22 18:21:20.000000000 +0200
+++ r3-cgr/r3-host-kit-a109/src/include/reb-ext.h 2010-10-24 02:32:32.000000000 +0200
@@ -69,6 +69,16 @@
REBCNT index; // 0-based index of current command in block
} REBCEC;
+
+//*************
+//- RXICAL
+//*************
+// declares the command! calling function interface
+//
+// cmd: is the command number (usually resolved via an enum)
+// *args: a pointer to an argument frame (an array of values passed to the command)
+// *ctx: a pointer to an extension's environment
+//*************
typedef int (*RXICAL)(int cmd, RXIFRM *args, REBCEC *ctx);
// Access macros (indirect access via RXIFRM pointer):
diff -urw r3-host-kit-a109/src/include/reb-lib.h r3-cgr/r3-host-kit-a109/src/include/reb-lib.h
--- r3-host-kit-a109/src/include/reb-lib.h 2010-10-22 18:21:20.000000000 +0200
+++ r3-cgr/r3-host-kit-a109/src/include/reb-lib.h 2010-10-23 23:14:26.000000000 +0200
@@ -65,7 +65,8 @@
// Extension entry point functions:
#ifdef TO_WIN32
#ifdef __cplusplus
-#define extern "C" RXIEXT __declspec(dllexport)
+//#define extern "C" RXIEXT __declspec(dllexport) // A109 release error!
+#define RXIEXT extern "C" __declspec(dllexport)
#else
#define RXIEXT __declspec(dllexport)
#endif
diff -urw r3-host-kit-a109/src/os/host-main.c r3-cgr/r3-host-kit-a109/src/os/host-main.c
--- r3-host-kit-a109/src/os/host-main.c 2010-10-22 18:21:18.000000000 +0200
+++ r3-cgr/r3-host-kit-a109/src/os/host-main.c 2010-10-24 02:36:32.000000000 +0200
@@ -137,6 +137,8 @@
#ifndef REB_CORE
Init_Windows();
+
+ // setup view extensions
Init_Graphics();
#endif
diff -urw r3-host-kit-a109/src/os/win32/host-graphics.c r3-cgr/r3-host-kit-a109/src/os/win32/host-graphics.c
--- r3-host-kit-a109/src/os/win32/host-graphics.c 2010-10-22 18:21:18.000000000 +0200
+++ r3-cgr/r3-host-kit-a109/src/os/win32/host-graphics.c 2010-10-24 23:51:50.000000000 +0200
@@ -39,11 +39,20 @@
#include "host-ext-shape.h"
#include "host-ext-text.h"
+
+#include "ht-linked-list.h" // [CGR]
+#include "cgr-ext.h" // [CGR]
+#include "host-ext-cgr.h" // [CGR]
+
+
+
+
//***** Externs *****
extern REBINT Show_Gob(REBGOB *gob);
extern HCURSOR Cursor;
static REBOOL Custom_Cursor = FALSE;
+extern RXIEXT int RXD_cgr(int cmd, RXIFRM *frm, void *data); //[CGR]
static u32* draw_ext_words;
static u32* shape_ext_words;
@@ -1219,14 +1228,41 @@
**
*/ void Init_Graphics(void)
/*
-** Initialize special variables of the graphics subsystem.
+** Initialize special variables and embedded extensions of the graphics subsystem.
**
***********************************************************************/
{
+ // add the graphics extension to Rebol's list of extensions (provide source and command! callback).
+ // this extension mainly handles high-level user-run commands such as:
+ // 'SHOW, 'DRAW, 'OFFSET-TO-CARET, etc.
RL = (RL_LIB *)RL_Extend((REBYTE *)(&RX_graphics[0]), &RXD_Graphics);
+
+ // the draw extension handles the graphic elements & properties used within a draw dialect block
+ // box, polygon, pen, fill-pen, line-width, etc
RL_Extend((REBYTE *)(&RX_draw[0]), &RXD_Draw);
+
+ // the shape extension manages the 'SHAPE draw command on its own, since its a
+ // complex subsystem which has its own dialect, and works much like the old logo
+ // and turtle graphics. where appropriate, some draw and shape command use similar interfaces
RL_Extend((REBYTE *)(&RX_shape[0]), &RXD_Shape);
+
+ // the Text extension deals with the rich text dialect, it supports unicode fonts,
+ // color and style attributes like bold, italics, paragraphs and more.
RL_Extend((REBYTE *)(&RX_text[0]), &RXD_Text);
+
+ // [CGR]
+ // cgr is an extension which allows external rendering engines to draw directly
+ // into view. when possible these draw directly within the gob they are assigned to
+ // and can potentially even be drawn over by child gobs, when the engine allows such a setup.
+ //
+ // some external renderers such as video players will not allow things to be rendered over them
+ // without some loss of speed... but in any case, just having the sizing follow the gob is
+ // sufficiently usefull.
+
+ RL_Extend((REBYTE *)(&RX_cgr[0]), &RXD_cgr);
+
+
+
}
#ifdef OLD__FUNCS_NEED_CONVERSION
diff -urw r3-host-kit-a109/src/os/win32/host-window.c r3-cgr/r3-host-kit-a109/src/os/win32/host-window.c
--- r3-host-kit-a109/src/os/win32/host-window.c 2010-10-22 18:21:18.000000000 +0200
+++ r3-cgr/r3-host-kit-a109/src/os/win32/host-window.c 2010-10-24 02:41:02.000000000 +0200
@@ -131,7 +131,7 @@
return -1;
}
-static HWND Find_Window(REBGOB *gob) {
+const HWND Find_Window(REBGOB *gob) {
int n;
for (n = 0; n < MAX_WINDOWS; n++) {
if (Gob_Windows[n].gob == gob) return Gob_Windows[n].win;
@@ -182,7 +182,8 @@
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
+ //wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; // [CGR]
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
@@ -318,7 +319,8 @@
WS_EX_WINDOWEDGE,
Window_Class_Name,
title,
- options,
+ //options,
+ options | WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, // [CGR]
x, y, w, h,
parent,
NULL, App_Instance, NULL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment