Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
190ed585
Commit
190ed585
authored
Jul 30, 2013
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Code refactoring.
parent
790a1f85
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
886 additions
and
1089 deletions
+886
-1089
cairo_compositor.cpp
common/gal/cairo/cairo_compositor.cpp
+4
-1
cairo_gal.cpp
common/gal/cairo/cairo_gal.cpp
+271
-303
graphics_abstraction_layer.cpp
common/gal/graphics_abstraction_layer.cpp
+29
-2
gpu_manager.cpp
common/gal/opengl/gpu_manager.cpp
+1
-1
opengl_compositor.cpp
common/gal/opengl/opengl_compositor.cpp
+3
-1
opengl_gal.cpp
common/gal/opengl/opengl_gal.cpp
+429
-542
shader.cpp
common/gal/opengl/shader.cpp
+9
-8
vertex_manager.cpp
common/gal/opengl/vertex_manager.cpp
+7
-4
wx_view_controls.cpp
common/view/wx_view_controls.cpp
+0
-1
cairo_compositor.h
include/gal/cairo/cairo_compositor.h
+8
-10
cairo_gal.h
include/gal/cairo/cairo_gal.h
+29
-72
graphics_abstraction_layer.h
include/gal/graphics_abstraction_layer.h
+6
-4
cached_container.h
include/gal/opengl/cached_container.h
+6
-6
opengl_compositor.h
include/gal/opengl/opengl_compositor.h
+0
-2
opengl_gal.h
include/gal/opengl/opengl_gal.h
+81
-128
vertex_common.h
include/gal/opengl/vertex_common.h
+3
-4
No files found.
common/gal/cairo/cairo_compositor.cpp
View file @
190ed585
...
...
@@ -34,7 +34,7 @@
using
namespace
KiGfx
;
CAIRO_COMPOSITOR
::
CAIRO_COMPOSITOR
(
cairo_t
**
aMainContext
)
:
m_current
(
0
),
m_currentContext
(
aMainContext
),
m_mainContext
(
*
aMainContext
)
m_current
(
0
),
m_currentContext
(
aMainContext
),
m_mainContext
(
*
aMainContext
)
{
// Obtain the transformation matrix used in the main context
cairo_get_matrix
(
m_mainContext
,
&
m_matrix
);
...
...
@@ -69,6 +69,7 @@ unsigned int CAIRO_COMPOSITOR::GetBuffer()
{
// Pixel storage
BitmapPtr
bitmap
(
new
unsigned
int
[
m_bufferSize
]
);
memset
(
bitmap
.
get
(),
0x00
,
m_bufferSize
*
sizeof
(
int
)
);
// Create the Cairo surface
...
...
@@ -105,6 +106,7 @@ void CAIRO_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
m_current
=
aBufferHandle
-
1
;
*
m_currentContext
=
m_buffers
[
m_current
].
context
;
}
#ifdef __WXDEBUG__
else
wxLogDebug
(
wxT
(
"Tried to use a not existing buffer"
)
);
...
...
@@ -141,6 +143,7 @@ void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
// Restore the transformation matrix
cairo_set_matrix
(
m_mainContext
,
&
m_matrix
);
}
#ifdef __WXDEBUG__
else
wxLogDebug
(
wxT
(
"Tried to use a not existing buffer"
)
);
...
...
common/gal/cairo/cairo_gal.cpp
View file @
190ed585
...
...
@@ -87,117 +87,7 @@ CAIRO_GAL::~CAIRO_GAL()
}
void
CAIRO_GAL
::
onPaint
(
wxPaintEvent
&
aEvent
)
{
PostPaint
();
}
void
CAIRO_GAL
::
ResizeScreen
(
int
aWidth
,
int
aHeight
)
{
screenSize
=
VECTOR2D
(
aWidth
,
aHeight
);
// Recreate the bitmaps
deleteBitmaps
();
allocateBitmaps
();
SetSize
(
wxSize
(
aWidth
,
aHeight
)
);
}
void
CAIRO_GAL
::
skipMouseEvent
(
wxMouseEvent
&
aEvent
)
{
// Post the mouse event to the event listener registered in constructor, if any
if
(
mouseListener
)
wxPostEvent
(
mouseListener
,
aEvent
);
}
void
CAIRO_GAL
::
initSurface
()
{
wxASSERT
(
!
isInitialized
);
// Create the Cairo surface
surface
=
cairo_image_surface_create_for_data
(
(
unsigned
char
*
)
bitmapBuffer
,
GAL_FORMAT
,
screenSize
.
x
,
screenSize
.
y
,
stride
);
context
=
cairo_create
(
surface
);
#ifdef __WXDEBUG__
cairo_status_t
status
=
cairo_status
(
context
);
wxASSERT_MSG
(
status
==
CAIRO_STATUS_SUCCESS
,
"Cairo context creation error"
);
#endif
/* __WXDEBUG__ */
currentContext
=
context
;
cairo_set_antialias
(
context
,
CAIRO_ANTIALIAS_SUBPIXEL
);
// Clear the screen
ClearScreen
();
// Compute the world <-> screen transformations
ComputeWorldScreenMatrix
();
cairo_matrix_init
(
&
cairoWorldScreenMatrix
,
worldScreenMatrix
.
m_data
[
0
][
0
],
worldScreenMatrix
.
m_data
[
1
][
0
],
worldScreenMatrix
.
m_data
[
0
][
1
],
worldScreenMatrix
.
m_data
[
1
][
1
],
worldScreenMatrix
.
m_data
[
0
][
2
],
worldScreenMatrix
.
m_data
[
1
][
2
]
);
cairo_set_matrix
(
context
,
&
cairoWorldScreenMatrix
);
isSetAttributes
=
false
;
// Start drawing with a new path
cairo_new_path
(
context
);
isElementAdded
=
true
;
cairo_set_line_join
(
context
,
CAIRO_LINE_JOIN_ROUND
);
cairo_set_line_cap
(
context
,
CAIRO_LINE_CAP_ROUND
);
lineWidth
=
0
;
isDeleteSavedPixels
=
true
;
isInitialized
=
true
;
}
void
CAIRO_GAL
::
deinitSurface
()
{
if
(
!
isInitialized
)
return
;
// Destroy Cairo objects
cairo_destroy
(
context
);
cairo_surface_destroy
(
surface
);
isInitialized
=
false
;
}
void
CAIRO_GAL
::
setCompositor
()
{
// Recreate the compositor with the new Cairo context
compositor
.
reset
(
new
CAIRO_COMPOSITOR
(
&
currentContext
)
);
compositor
->
Resize
(
screenSize
.
x
,
screenSize
.
y
);
// Prepare buffers
mainBuffer
=
compositor
->
GetBuffer
();
overlayBuffer
=
compositor
->
GetBuffer
();
}
unsigned
int
CAIRO_GAL
::
getNewGroupNumber
()
{
wxASSERT_MSG
(
groups
.
size
()
<
std
::
numeric_limits
<
unsigned
int
>::
max
(),
wxT
(
"There are no free slots to store a group"
)
);
while
(
groups
.
find
(
groupCounter
)
!=
groups
.
end
()
)
{
groupCounter
++
;
}
return
groupCounter
++
;
}
void
CAIRO_GAL
::
BeginDrawing
()
throw
(
int
)
void
CAIRO_GAL
::
BeginDrawing
()
{
initSurface
();
setCompositor
();
...
...
@@ -245,65 +135,6 @@ void CAIRO_GAL::EndDrawing()
}
void
CAIRO_GAL
::
SaveScreen
()
{
// Copy the current bitmap to the backup buffer
int
offset
=
0
;
for
(
int
j
=
0
;
j
<
screenSize
.
y
;
j
++
)
{
for
(
int
i
=
0
;
i
<
stride
;
i
++
)
{
bitmapBufferBackup
[
offset
+
i
]
=
bitmapBuffer
[
offset
+
i
];
offset
+=
stride
;
}
}
}
void
CAIRO_GAL
::
RestoreScreen
()
{
int
offset
=
0
;
for
(
int
j
=
0
;
j
<
screenSize
.
y
;
j
++
)
{
for
(
int
i
=
0
;
i
<
stride
;
i
++
)
{
bitmapBuffer
[
offset
+
i
]
=
bitmapBufferBackup
[
offset
+
i
];
offset
+=
stride
;
}
}
}
void
CAIRO_GAL
::
SetTarget
(
RenderTarget
aTarget
)
{
// If the compositor is not set, that means that there is a recaching process going on
// and we do not need the compositor now
if
(
!
compositor
)
return
;
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
cairo_pop_group_to_source
(
currentContext
);
cairo_paint_with_alpha
(
currentContext
,
fillColor
.
a
);
switch
(
aTarget
)
{
default
:
case
TARGET_CACHED
:
case
TARGET_NONCACHED
:
compositor
->
SetBuffer
(
mainBuffer
);
break
;
case
TARGET_OVERLAY
:
compositor
->
SetBuffer
(
overlayBuffer
);
break
;
}
cairo_push_group
(
currentContext
);
}
void
CAIRO_GAL
::
DrawLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
{
cairo_move_to
(
currentContext
,
aStartPoint
.
x
,
aStartPoint
.
y
);
...
...
@@ -335,7 +166,7 @@ void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPo
cairo_translate
(
currentContext
,
aStartPoint
.
x
,
aStartPoint
.
y
);
cairo_rotate
(
currentContext
,
lineAngle
);
cairo_arc
(
currentContext
,
0.0
,
0.0
,
aWidth
/
2.0
,
M_PI
/
2.0
,
3.0
*
M_PI
/
2.0
);
cairo_arc
(
currentContext
,
0.0
,
0.0
,
aWidth
/
2.0
,
M_PI
/
2.0
,
3.0
*
M_PI
/
2.0
);
cairo_arc
(
currentContext
,
lineLength
,
0.0
,
aWidth
/
2.0
,
-
M_PI
/
2.0
,
M_PI
/
2.0
);
cairo_move_to
(
currentContext
,
0.0
,
aWidth
/
2.0
);
...
...
@@ -373,12 +204,30 @@ void CAIRO_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aS
}
void
CAIRO_GAL
::
DrawRectangle
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
{
// Calculate the diagonal points
VECTOR2D
diagonalPointA
(
aEndPoint
.
x
,
aStartPoint
.
y
);
VECTOR2D
diagonalPointB
(
aStartPoint
.
x
,
aEndPoint
.
y
);
// The path is composed from 4 segments
cairo_move_to
(
currentContext
,
aStartPoint
.
x
,
aStartPoint
.
y
);
cairo_line_to
(
currentContext
,
diagonalPointA
.
x
,
diagonalPointA
.
y
);
cairo_line_to
(
currentContext
,
aEndPoint
.
x
,
aEndPoint
.
y
);
cairo_line_to
(
currentContext
,
diagonalPointB
.
x
,
diagonalPointB
.
y
);
cairo_close_path
(
currentContext
);
isElementAdded
=
true
;
}
void
CAIRO_GAL
::
DrawPolyline
(
std
::
deque
<
VECTOR2D
>&
aPointList
)
{
// Iterate over the point list and draw the segments
std
::
deque
<
VECTOR2D
>::
const_iterator
it
=
aPointList
.
begin
();
cairo_move_to
(
currentContext
,
it
->
x
,
it
->
y
);
for
(
++
it
;
it
!=
aPointList
.
end
();
++
it
)
{
cairo_line_to
(
currentContext
,
it
->
x
,
it
->
y
);
...
...
@@ -394,6 +243,7 @@ void CAIRO_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
std
::
deque
<
VECTOR2D
>::
const_iterator
it
=
aPointList
.
begin
();
cairo_move_to
(
currentContext
,
it
->
x
,
it
->
y
);
for
(
++
it
;
it
!=
aPointList
.
end
();
++
it
)
{
cairo_line_to
(
currentContext
,
it
->
x
,
it
->
y
);
...
...
@@ -403,38 +253,53 @@ void CAIRO_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
}
void
CAIRO_GAL
::
DrawRectangle
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
void
CAIRO_GAL
::
DrawCurve
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aControlPointA
,
const
VECTOR2D
&
aControlPointB
,
const
VECTOR2D
&
aEndPoint
)
{
// Calculate the diagonal points
VECTOR2D
diagonalPointA
(
aEndPoint
.
x
,
aStartPoint
.
y
);
VECTOR2D
diagonalPointB
(
aStartPoint
.
x
,
aEndPoint
.
y
);
// The path is composed from 4 segments
cairo_move_to
(
currentContext
,
aStartPoint
.
x
,
aStartPoint
.
y
);
cairo_line_to
(
currentContext
,
diagonalPointA
.
x
,
diagonalPointA
.
y
);
cairo_curve_to
(
currentContext
,
aControlPointA
.
x
,
aControlPointA
.
y
,
aControlPointB
.
x
,
aControlPointB
.
y
,
aEndPoint
.
x
,
aEndPoint
.
y
);
cairo_line_to
(
currentContext
,
aEndPoint
.
x
,
aEndPoint
.
y
);
cairo_line_to
(
currentContext
,
diagonalPointB
.
x
,
diagonalPointB
.
y
);
cairo_close_path
(
currentContext
);
isElementAdded
=
true
;
}
void
CAIRO_GAL
::
DrawCurve
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aControlPointA
,
const
VECTOR2D
&
aControlPointB
,
const
VECTOR2D
&
aEndPoint
)
void
CAIRO_GAL
::
ResizeScreen
(
int
aWidth
,
int
aHeight
)
{
cairo_move_to
(
currentContext
,
aStartPoint
.
x
,
aStartPoint
.
y
);
cairo_curve_to
(
currentContext
,
aControlPointA
.
x
,
aControlPointA
.
y
,
aControlPointB
.
x
,
aControlPointB
.
y
,
aEndPoint
.
x
,
aEndPoint
.
y
);
cairo_line_to
(
currentContext
,
aEndPoint
.
x
,
aEndPoint
.
y
);
screenSize
=
VECTOR2D
(
aWidth
,
aHeight
);
isElementAdded
=
true
;
// Recreate the bitmaps
deleteBitmaps
();
allocateBitmaps
();
SetSize
(
wxSize
(
aWidth
,
aHeight
)
);
}
bool
CAIRO_GAL
::
Show
(
bool
aShow
)
{
bool
s
=
wxWindow
::
Show
(
aShow
);
if
(
aShow
)
wxWindow
::
Raise
();
return
s
;
}
void
CAIRO_GAL
::
Flush
()
{
storePath
();
}
void
CAIRO_GAL
::
SetBackgroundColor
(
const
COLOR4D
&
aColor
)
void
CAIRO_GAL
::
ClearScreen
(
)
{
backgroundColor
=
aColor
;
cairo_set_source_rgb
(
currentContext
,
backgroundColor
.
r
,
backgroundColor
.
g
,
backgroundColor
.
b
);
cairo_rectangle
(
currentContext
,
0.0
,
0.0
,
screenSize
.
x
,
screenSize
.
y
);
cairo_fill
(
currentContext
);
}
...
...
@@ -528,15 +393,6 @@ void CAIRO_GAL::SetLineWidth( double aLineWidth )
}
void
CAIRO_GAL
::
ClearScreen
()
{
cairo_set_source_rgb
(
currentContext
,
backgroundColor
.
r
,
backgroundColor
.
g
,
backgroundColor
.
b
);
cairo_rectangle
(
currentContext
,
0.0
,
0.0
,
screenSize
.
x
,
screenSize
.
y
);
cairo_fill
(
currentContext
);
}
void
CAIRO_GAL
::
SetLayerDepth
(
double
aLayerDepth
)
{
super
::
SetLayerDepth
(
aLayerDepth
);
...
...
@@ -686,39 +542,10 @@ void CAIRO_GAL::EndGroup()
}
void
CAIRO_GAL
::
ClearCache
(
)
void
CAIRO_GAL
::
DrawGroup
(
int
aGroupNumber
)
{
for
(
int
i
=
groups
.
size
()
-
1
;
i
>=
0
;
--
i
)
{
DeleteGroup
(
i
);
}
}
void
CAIRO_GAL
::
DeleteGroup
(
int
aGroupNumber
)
{
storePath
();
// Delete the Cairo paths
std
::
deque
<
GroupElement
>::
iterator
it
,
end
;
for
(
it
=
groups
[
aGroupNumber
].
begin
(),
end
=
groups
[
aGroupNumber
].
end
();
it
!=
end
;
++
it
)
{
if
(
it
->
command
==
CMD_FILL_PATH
||
it
->
command
==
CMD_STROKE_PATH
)
{
cairo_path_destroy
(
it
->
cairoPath
);
}
}
// Delete the group
groups
.
erase
(
aGroupNumber
);
}
void
CAIRO_GAL
::
DrawGroup
(
int
aGroupNumber
)
{
// This method implements a small Virtual Machine - all stored commands
// are executed; nested calling is also possible
// This method implements a small Virtual Machine - all stored commands
// are executed; nested calling is also possible
storePath
();
...
...
@@ -828,31 +655,147 @@ void CAIRO_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth )
}
void
CAIRO_GAL
::
Flush
(
)
void
CAIRO_GAL
::
DeleteGroup
(
int
aGroupNumber
)
{
storePath
();
// Delete the Cairo paths
std
::
deque
<
GroupElement
>::
iterator
it
,
end
;
for
(
it
=
groups
[
aGroupNumber
].
begin
(),
end
=
groups
[
aGroupNumber
].
end
();
it
!=
end
;
++
it
)
{
if
(
it
->
command
==
CMD_FILL_PATH
||
it
->
command
==
CMD_STROKE_PATH
)
{
cairo_path_destroy
(
it
->
cairoPath
);
}
}
// Delete the group
groups
.
erase
(
aGroupNumber
);
}
void
CAIRO_GAL
::
ClearCache
()
{
for
(
int
i
=
groups
.
size
()
-
1
;
i
>=
0
;
--
i
)
{
DeleteGroup
(
i
);
}
}
void
CAIRO_GAL
::
SaveScreen
()
{
// Copy the current bitmap to the backup buffer
int
offset
=
0
;
for
(
int
j
=
0
;
j
<
screenSize
.
y
;
j
++
)
{
for
(
int
i
=
0
;
i
<
stride
;
i
++
)
{
bitmapBufferBackup
[
offset
+
i
]
=
bitmapBuffer
[
offset
+
i
];
offset
+=
stride
;
}
}
}
void
CAIRO_GAL
::
RestoreScreen
()
{
int
offset
=
0
;
for
(
int
j
=
0
;
j
<
screenSize
.
y
;
j
++
)
{
for
(
int
i
=
0
;
i
<
stride
;
i
++
)
{
bitmapBuffer
[
offset
+
i
]
=
bitmapBufferBackup
[
offset
+
i
];
offset
+=
stride
;
}
}
}
void
CAIRO_GAL
::
SetTarget
(
RenderTarget
aTarget
)
{
// If the compositor is not set, that means that there is a recaching process going on
// and we do not need the compositor now
if
(
!
compositor
)
return
;
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
cairo_pop_group_to_source
(
currentContext
);
cairo_paint_with_alpha
(
currentContext
,
fillColor
.
a
);
switch
(
aTarget
)
{
default
:
case
TARGET_CACHED
:
case
TARGET_NONCACHED
:
compositor
->
SetBuffer
(
mainBuffer
);
break
;
case
TARGET_OVERLAY
:
compositor
->
SetBuffer
(
overlayBuffer
);
break
;
}
cairo_push_group
(
currentContext
);
}
VECTOR2D
CAIRO_GAL
::
ComputeCursorToWorld
(
const
VECTOR2D
&
aCursorPosition
)
{
MATRIX3x3D
inverseMatrix
=
worldScreenMatrix
.
Inverse
();
VECTOR2D
cursorPositionWorld
=
inverseMatrix
*
aCursorPosition
;
return
cursorPositionWorld
;
}
void
CAIRO_GAL
::
ComputeWorldScreenMatrix
(
)
void
CAIRO_GAL
::
DrawCursor
(
VECTOR2D
aCursorPosition
)
{
ComputeWorldScale
();
if
(
!
IsShownOnScreen
()
)
return
;
wxClientDC
clientDC
(
this
);
wxMemoryDC
cursorSave
(
*
cursorPixelsSaved
);
wxMemoryDC
cursorShape
(
*
cursorPixels
);
// Snap to grid
VECTOR2D
cursorPositionWorld
=
ComputeCursorToWorld
(
aCursorPosition
);
worldScreenMatrix
.
SetIdentity
();
cursorPositionWorld
.
x
=
round
(
cursorPositionWorld
.
x
/
gridSize
.
x
)
*
gridSize
.
x
;
cursorPositionWorld
.
y
=
round
(
cursorPositionWorld
.
y
/
gridSize
.
y
)
*
gridSize
.
y
;
aCursorPosition
=
worldScreenMatrix
*
cursorPositionWorld
;
aCursorPosition
=
aCursorPosition
-
VECTOR2D
(
cursorSize
/
2
,
cursorSize
/
2
);
if
(
!
isDeleteSavedPixels
)
{
clientDC
.
Blit
(
savedCursorPosition
.
x
,
savedCursorPosition
.
y
,
cursorSize
,
cursorSize
,
&
cursorSave
,
0
,
0
);
}
else
{
isDeleteSavedPixels
=
false
;
}
cursorSave
.
Blit
(
0
,
0
,
cursorSize
,
cursorSize
,
&
clientDC
,
aCursorPosition
.
x
,
aCursorPosition
.
y
);
MATRIX3x3D
translation
;
translation
.
SetIdentity
();
translation
.
SetTranslation
(
0.5
*
screenSize
);
clientDC
.
Blit
(
aCursorPosition
.
x
,
aCursorPosition
.
y
,
cursorSize
,
cursorSize
,
&
cursorShape
,
0
,
0
,
wxOR
);
MATRIX3x3D
scale
;
s
cale
.
SetIdentity
()
;
scale
.
SetScale
(
VECTOR2D
(
worldScale
,
worldScale
)
);
savedCursorPosition
.
x
=
(
wxCoord
)
aCursorPosition
.
x
;
s
avedCursorPosition
.
y
=
(
wxCoord
)
aCursorPosition
.
y
;
}
MATRIX3x3D
lookat
;
lookat
.
SetIdentity
();
lookat
.
SetTranslation
(
-
lookAtPoint
);
worldScreenMatrix
=
translation
*
scale
*
lookat
*
worldScreenMatrix
;
void
CAIRO_GAL
::
drawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
{
cairo_move_to
(
currentContext
,
aStartPoint
.
x
,
aStartPoint
.
y
);
cairo_line_to
(
currentContext
,
aEndPoint
.
x
,
aEndPoint
.
y
);
cairo_set_source_rgb
(
currentContext
,
gridColor
.
r
,
gridColor
.
g
,
gridColor
.
b
);
cairo_stroke
(
currentContext
);
}
...
...
@@ -872,7 +815,8 @@ void CAIRO_GAL::storePath()
if
(
isStrokeEnabled
)
{
cairo_set_source_rgb
(
currentContext
,
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
);
cairo_set_source_rgb
(
currentContext
,
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
);
cairo_stroke_preserve
(
currentContext
);
}
}
...
...
@@ -903,9 +847,18 @@ void CAIRO_GAL::storePath()
}
// ---------------
// Cursor handling
// ---------------
void
CAIRO_GAL
::
onPaint
(
wxPaintEvent
&
aEvent
)
{
PostPaint
();
}
void
CAIRO_GAL
::
skipMouseEvent
(
wxMouseEvent
&
aEvent
)
{
// Post the mouse event to the event listener registered in constructor, if any
if
(
mouseListener
)
wxPostEvent
(
mouseListener
,
aEvent
);
}
void
CAIRO_GAL
::
initCursor
(
int
aCursorSize
)
...
...
@@ -919,7 +872,7 @@ void CAIRO_GAL::initCursor( int aCursorSize )
cursorShape
.
SetBackground
(
*
wxTRANSPARENT_BRUSH
);
wxColour
color
(
cursorColor
.
r
*
cursorColor
.
a
*
255
,
cursorColor
.
g
*
cursorColor
.
a
*
255
,
cursorColor
.
b
*
cursorColor
.
a
*
255
,
255
);
wxPen
pen
=
wxPen
(
color
);
wxPen
pen
=
wxPen
(
color
);
cursorShape
.
SetPen
(
pen
);
cursorShape
.
Clear
();
...
...
@@ -928,88 +881,103 @@ void CAIRO_GAL::initCursor( int aCursorSize )
}
VECTOR2D
CAIRO_GAL
::
ComputeCursorToWorld
(
const
VECTOR2D
&
aCursorPosition
)
void
CAIRO_GAL
::
allocateBitmaps
(
)
{
MATRIX3x3D
inverseMatrix
=
worldScreenMatrix
.
Inverse
();
VECTOR2D
cursorPositionWorld
=
inverseMatrix
*
aCursorPosition
;
// Create buffer, use the system independent Cairo context backend
stride
=
cairo_format_stride_for_width
(
GAL_FORMAT
,
screenSize
.
x
);
bufferSize
=
stride
*
screenSize
.
y
;
return
cursorPositionWorld
;
bitmapBuffer
=
new
unsigned
int
[
bufferSize
];
bitmapBufferBackup
=
new
unsigned
int
[
bufferSize
];
wxOutput
=
new
unsigned
char
[
bufferSize
*
3
];
}
void
CAIRO_GAL
::
DrawCursor
(
VECTOR2D
aCursorPosition
)
void
CAIRO_GAL
::
deleteBitmaps
(
)
{
if
(
!
IsShownOnScreen
()
)
return
;
delete
[]
bitmapBuffer
;
delete
[]
bitmapBufferBackup
;
delete
[]
wxOutput
;
}
wxClientDC
clientDC
(
this
);
wxMemoryDC
cursorSave
(
*
cursorPixelsSaved
);
wxMemoryDC
cursorShape
(
*
cursorPixels
);
// Snap to grid
VECTOR2D
cursorPositionWorld
=
ComputeCursorToWorld
(
aCursorPosition
);
void
CAIRO_GAL
::
initSurface
()
{
wxASSERT
(
!
isInitialized
);
cursorPositionWorld
.
x
=
round
(
cursorPositionWorld
.
x
/
gridSize
.
x
)
*
gridSize
.
x
;
cursorPositionWorld
.
y
=
round
(
cursorPositionWorld
.
y
/
gridSize
.
y
)
*
gridSize
.
y
;
aCursorPosition
=
worldScreenMatrix
*
cursorPositionWorld
;
aCursorPosition
=
aCursorPosition
-
VECTOR2D
(
cursorSize
/
2
,
cursorSize
/
2
);
// Create the Cairo surface
surface
=
cairo_image_surface_create_for_data
(
(
unsigned
char
*
)
bitmapBuffer
,
GAL_FORMAT
,
screenSize
.
x
,
screenSize
.
y
,
stride
);
context
=
cairo_create
(
surface
);
#ifdef __WXDEBUG__
cairo_status_t
status
=
cairo_status
(
context
);
wxASSERT_MSG
(
status
==
CAIRO_STATUS_SUCCESS
,
"Cairo context creation error"
);
#endif
/* __WXDEBUG__ */
currentContext
=
context
;
if
(
!
isDeleteSavedPixels
)
{
clientDC
.
Blit
(
savedCursorPosition
.
x
,
savedCursorPosition
.
y
,
cursorSize
,
cursorSize
,
&
cursorSave
,
0
,
0
);
}
else
{
isDeleteSavedPixels
=
false
;
}
cairo_set_antialias
(
context
,
CAIRO_ANTIALIAS_SUBPIXEL
);
cursorSave
.
Blit
(
0
,
0
,
cursorSize
,
cursorSize
,
&
clientDC
,
aCursorPosition
.
x
,
aCursorPosition
.
y
);
// Clear the screen
ClearScreen
(
);
clientDC
.
Blit
(
aCursorPosition
.
x
,
aCursorPosition
.
y
,
cursorSize
,
cursorSize
,
&
cursorShape
,
0
,
0
,
wxOR
);
// Compute the world <-> screen transformations
ComputeWorldScreenMatrix
(
);
savedCursorPosition
.
x
=
(
wxCoord
)
aCursorPosition
.
x
;
savedCursorPosition
.
y
=
(
wxCoord
)
aCursorPosition
.
y
;
}
cairo_matrix_init
(
&
cairoWorldScreenMatrix
,
worldScreenMatrix
.
m_data
[
0
][
0
],
worldScreenMatrix
.
m_data
[
1
][
0
],
worldScreenMatrix
.
m_data
[
0
][
1
],
worldScreenMatrix
.
m_data
[
1
][
1
],
worldScreenMatrix
.
m_data
[
0
][
2
],
worldScreenMatrix
.
m_data
[
1
][
2
]
);
cairo_set_matrix
(
context
,
&
cairoWorldScreenMatrix
);
void
CAIRO_GAL
::
DrawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
{
cairo_move_to
(
currentContext
,
aStartPoint
.
x
,
aStartPoint
.
y
);
cairo_line_to
(
currentContext
,
aEndPoint
.
x
,
aEndPoint
.
y
);
cairo_set_source_rgb
(
currentContext
,
gridColor
.
r
,
gridColor
.
g
,
gridColor
.
b
);
cairo_stroke
(
currentContext
);
// Start drawing with a new path
cairo_new_path
(
context
);
isElementAdded
=
true
;
cairo_set_line_join
(
context
,
CAIRO_LINE_JOIN_ROUND
);
cairo_set_line_cap
(
context
,
CAIRO_LINE_CAP_ROUND
);
lineWidth
=
0
;
isDeleteSavedPixels
=
true
;
isInitialized
=
true
;
}
void
CAIRO_GAL
::
allocateBitmaps
()
void
CAIRO_GAL
::
deinitSurface
()
{
// Create buffer, use the system independent Cairo context backend
stride
=
cairo_format_stride_for_width
(
GAL_FORMAT
,
screenSize
.
x
);
bufferSize
=
stride
*
screenSize
.
y
;
if
(
!
isInitialized
)
return
;
bitmapBuffer
=
new
unsigned
int
[
bufferSize
];
bitmapBufferBackup
=
new
unsigned
int
[
bufferSize
];
wxOutput
=
new
unsigned
char
[
bufferSize
*
3
];
// Destroy Cairo objects
cairo_destroy
(
context
);
cairo_surface_destroy
(
surface
);
isInitialized
=
false
;
}
void
CAIRO_GAL
::
deleteBitmaps
()
void
CAIRO_GAL
::
setCompositor
()
{
delete
[]
bitmapBuffer
;
delete
[]
bitmapBufferBackup
;
delete
[]
wxOutput
;
// Recreate the compositor with the new Cairo context
compositor
.
reset
(
new
CAIRO_COMPOSITOR
(
&
currentContext
)
);
compositor
->
Resize
(
screenSize
.
x
,
screenSize
.
y
);
// Prepare buffers
mainBuffer
=
compositor
->
GetBuffer
();
overlayBuffer
=
compositor
->
GetBuffer
();
}
bool
CAIRO_GAL
::
Show
(
bool
aShow
)
unsigned
int
CAIRO_GAL
::
getNewGroupNumber
(
)
{
bool
s
=
wxWindow
::
Show
(
aShow
);
wxASSERT_MSG
(
groups
.
size
()
<
std
::
numeric_limits
<
unsigned
int
>::
max
(),
wxT
(
"There are no free slots to store a group"
)
);
if
(
aShow
)
wxWindow
::
Raise
();
while
(
groups
.
find
(
groupCounter
)
!=
groups
.
end
()
)
{
groupCounter
++
;
}
return
s
;
return
groupCounter
++
;
}
common/gal/graphics_abstraction_layer.cpp
View file @
190ed585
...
...
@@ -63,6 +63,33 @@ GAL::~GAL()
}
void
GAL
::
ComputeWorldScreenMatrix
()
{
ComputeWorldScale
();
worldScreenMatrix
.
SetIdentity
();
MATRIX3x3D
translation
;
translation
.
SetIdentity
();
translation
.
SetTranslation
(
0.5
*
screenSize
);
MATRIX3x3D
scale
;
scale
.
SetIdentity
();
scale
.
SetScale
(
VECTOR2D
(
worldScale
,
worldScale
)
);
MATRIX3x3D
flip
;
flip
.
SetIdentity
();
flip
.
SetScale
(
VECTOR2D
(
1.0
,
1.0
)
);
MATRIX3x3D
lookat
;
lookat
.
SetIdentity
();
lookat
.
SetTranslation
(
-
lookAtPoint
);
worldScreenMatrix
=
translation
*
flip
*
scale
*
lookat
*
worldScreenMatrix
;
}
void
GAL
::
DrawGrid
()
{
if
(
!
gridVisibility
)
...
...
@@ -136,7 +163,7 @@ void GAL::DrawGrid()
if
(
(
j
%
gridTick
==
0
&&
gridScreenSizeCoarse
>
gridDrawThreshold
)
||
gridScreenSizeDense
>
gridDrawThreshold
)
{
D
rawGridLine
(
VECTOR2D
(
gridStartX
*
gridSize
.
x
,
j
*
gridSize
.
y
),
d
rawGridLine
(
VECTOR2D
(
gridStartX
*
gridSize
.
x
,
j
*
gridSize
.
y
),
VECTOR2D
(
gridEndX
*
gridSize
.
x
,
j
*
gridSize
.
y
)
);
}
}
...
...
@@ -155,7 +182,7 @@ void GAL::DrawGrid()
if
(
(
i
%
gridTick
==
0
&&
gridScreenSizeCoarse
>
gridDrawThreshold
)
||
gridScreenSizeDense
>
gridDrawThreshold
)
{
D
rawGridLine
(
VECTOR2D
(
i
*
gridSize
.
x
,
gridStartY
*
gridSize
.
y
),
d
rawGridLine
(
VECTOR2D
(
i
*
gridSize
.
x
,
gridStartY
*
gridSize
.
y
),
VECTOR2D
(
i
*
gridSize
.
x
,
gridEndY
*
gridSize
.
y
)
);
}
}
...
...
common/gal/opengl/gpu_manager.cpp
View file @
190ed585
...
...
@@ -52,7 +52,7 @@ GPU_MANAGER* GPU_MANAGER::MakeManager( VERTEX_CONTAINER* aContainer )
GPU_MANAGER
::
GPU_MANAGER
(
VERTEX_CONTAINER
*
aContainer
)
:
m_isDrawing
(
false
),
m_container
(
aContainer
),
m_shader
(
NULL
)
m_isDrawing
(
false
),
m_container
(
aContainer
),
m_shader
(
NULL
)
{
}
...
...
common/gal/opengl/opengl_compositor.cpp
View file @
190ed585
...
...
@@ -104,7 +104,7 @@ unsigned int OPENGL_COMPOSITOR::GetBuffer()
wxASSERT
(
m_initialized
);
if
(
m_buffers
.
size
()
>=
m_maxBuffers
)
return
0
;
// Unfortunately we have no more free buffers left
return
0
;
// Unfortunately we have no more free buffers left
// GL_COLOR_ATTACHMENTn are consecutive integers
GLuint
attachmentPoint
=
GL_COLOR_ATTACHMENT0
+
usedBuffers
();
...
...
@@ -229,9 +229,11 @@ void OPENGL_COMPOSITOR::clean()
{
glDeleteTextures
(
1
,
&
it
->
textureTarget
);
}
m_buffers
.
clear
();
m_initialized
=
false
;
}
GLuint
OPENGL_COMPOSITOR
::
m_currentFbo
=
0
;
common/gal/opengl/opengl_gal.cpp
View file @
190ed585
...
...
@@ -36,7 +36,6 @@
#endif
/* __WXDEBUG__ */
#include <limits>
#include <boost/foreach.hpp>
#ifndef CALLBACK
#define CALLBACK
...
...
@@ -94,9 +93,6 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
tesselator
=
gluNewTess
();
InitTesselatorCallbacks
(
tesselator
);
gluTessProperty
(
tesselator
,
GLU_TESS_WINDING_RULE
,
GLU_TESS_WINDING_POSITIVE
);
// Compute the unit circle vertices and store them in a buffer for faster drawing
computeCircle
();
}
...
...
@@ -111,109 +107,6 @@ OPENGL_GAL::~OPENGL_GAL()
}
void
OPENGL_GAL
::
onPaint
(
wxPaintEvent
&
aEvent
)
{
PostPaint
();
}
void
OPENGL_GAL
::
ResizeScreen
(
int
aWidth
,
int
aHeight
)
{
screenSize
=
VECTOR2D
(
aWidth
,
aHeight
);
// Resize framebuffers
compositor
.
Resize
(
aWidth
,
aHeight
);
isFramebufferInitialized
=
false
;
wxGLCanvas
::
SetSize
(
aWidth
,
aHeight
);
}
void
OPENGL_GAL
::
skipMouseEvent
(
wxMouseEvent
&
aEvent
)
{
// Post the mouse event to the event listener registered in constructor, if any
if
(
mouseListener
)
wxPostEvent
(
mouseListener
,
aEvent
);
}
void
OPENGL_GAL
::
SaveScreen
()
{
wxASSERT_MSG
(
false
,
wxT
(
"Not implemented yet"
)
);
}
void
OPENGL_GAL
::
RestoreScreen
()
{
wxASSERT_MSG
(
false
,
wxT
(
"Not implemented yet"
)
);
}
void
OPENGL_GAL
::
SetTarget
(
RenderTarget
aTarget
)
{
switch
(
aTarget
)
{
default
:
case
TARGET_CACHED
:
currentManager
=
&
cachedManager
;
break
;
case
TARGET_NONCACHED
:
currentManager
=
&
nonCachedManager
;
break
;
case
TARGET_OVERLAY
:
currentManager
=
&
overlayManager
;
break
;
}
}
void
OPENGL_GAL
::
initGlew
()
{
// Initialize GLEW library
GLenum
err
=
glewInit
();
if
(
GLEW_OK
!=
err
)
{
wxLogError
(
wxString
::
FromUTF8
(
(
char
*
)
glewGetErrorString
(
err
)
)
);
exit
(
1
);
}
else
{
wxLogDebug
(
wxString
(
wxT
(
"Status: Using GLEW "
)
)
+
FROM_UTF8
(
(
char
*
)
glewGetString
(
GLEW_VERSION
)
)
);
}
// Check the OpenGL version (minimum 2.1 is required)
if
(
GLEW_VERSION_2_1
)
{
wxLogInfo
(
wxT
(
"OpenGL Version 2.1 supported."
)
);
}
else
{
wxLogError
(
wxT
(
"OpenGL Version 2.1 is not supported!"
)
);
exit
(
1
);
}
// Framebuffers have to be supported
if
(
!
GLEW_ARB_framebuffer_object
)
{
wxLogError
(
wxT
(
"Framebuffer objects are not supported!"
)
);
exit
(
1
);
}
// Vertex buffer have to be supported
if
(
!
GLEW_ARB_vertex_buffer_object
)
{
wxLogError
(
wxT
(
"Vertex buffer objects are not supported!"
)
);
exit
(
1
);
}
isGlewInitialized
=
true
;
}
void
OPENGL_GAL
::
BeginDrawing
()
{
SetCurrent
(
*
glContext
);
...
...
@@ -232,7 +125,8 @@ void OPENGL_GAL::BeginDrawing()
glViewport
(
0
,
0
,
(
GLsizei
)
screenSize
.
x
,
(
GLsizei
)
screenSize
.
y
);
// Create the screen transformation
glOrtho
(
0
,
(
GLint
)
screenSize
.
x
,
0
,
(
GLsizei
)
screenSize
.
y
,
-
depthRange
.
x
,
-
depthRange
.
y
);
glOrtho
(
0
,
(
GLint
)
screenSize
.
x
,
0
,
(
GLsizei
)
screenSize
.
y
,
-
depthRange
.
x
,
-
depthRange
.
y
);
// Prepare rendering target buffers
compositor
.
Initialize
();
...
...
@@ -301,7 +195,7 @@ void OPENGL_GAL::BeginDrawing()
compositor
.
ClearBuffer
();
compositor
.
SetBuffer
(
overlayBuffer
);
compositor
.
ClearBuffer
();
compositor
.
SetBuffer
(
0
);
// Unbind buffers
compositor
.
SetBuffer
(
0
);
// Unbind buffers
nonCachedManager
.
Clear
();
overlayManager
.
Clear
();
...
...
@@ -333,37 +227,16 @@ void OPENGL_GAL::EndDrawing()
}
inline
void
OPENGL_GAL
::
drawLineQuad
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
void
OPENGL_GAL
::
DrawLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
{
VECTOR2D
startEndVector
=
aEndPoint
-
aStartPoint
;
double
lineLength
=
startEndVector
.
EuclideanNorm
();
double
scale
=
0.5
*
lineWidth
/
lineLength
;
if
(
lineLength
<=
0.0
)
return
;
// The perpendicular vector also needs transformations
glm
::
vec4
vector
=
currentManager
->
GetTransformation
()
*
glm
::
vec4
(
-
startEndVector
.
y
*
scale
,
startEndVector
.
x
*
scale
,
0.0
,
0.0
);
// Line width is maintained by the vertex shader
currentManager
->
Shader
(
SHADER_LINE
,
vector
.
x
,
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aStartPoint
.
x
,
aStartPoint
.
y
,
layerDepth
);
// v0
currentManager
->
Shader
(
SHADER_LINE
,
-
vector
.
x
,
-
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aStartPoint
.
x
,
aStartPoint
.
y
,
layerDepth
);
// v1
currentManager
->
Shader
(
SHADER_LINE
,
-
vector
.
x
,
-
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aEndPoint
.
x
,
aEndPoint
.
y
,
layerDepth
);
// v3
currentManager
->
Shader
(
SHADER_LINE
,
vector
.
x
,
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aStartPoint
.
x
,
aStartPoint
.
y
,
layerDepth
);
// v0
const
VECTOR2D
startEndVector
=
aEndPoint
-
aStartPoint
;
double
lineAngle
=
startEndVector
.
Angle
();
currentManager
->
Shader
(
SHADER_LINE
,
-
vector
.
x
,
-
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aEndPoint
.
x
,
aEndPoint
.
y
,
layerDepth
);
// v3
drawLineQuad
(
aStartPoint
,
aEndPoint
);
currentManager
->
Shader
(
SHADER_LINE
,
vector
.
x
,
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aEndPoint
.
x
,
aEndPoint
.
y
,
layerDepth
);
// v2
// Line caps
drawFilledSemiCircle
(
aStartPoint
,
lineWidth
/
2
,
lineAngle
+
M_PI
/
2
);
drawFilledSemiCircle
(
aEndPoint
,
lineWidth
/
2
,
lineAngle
-
M_PI
/
2
);
}
...
...
@@ -414,53 +287,124 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
}
unsigned
int
OPENGL_GAL
::
getNewGroupNumber
(
)
void
OPENGL_GAL
::
DrawCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
)
{
wxASSERT_MSG
(
groups
.
size
()
<
std
::
numeric_limits
<
unsigned
int
>::
max
(),
wxT
(
"There are no free slots to store a group"
)
);
while
(
groups
.
find
(
groupCounter
)
!=
groups
.
end
()
)
if
(
isFillEnabled
)
{
groupCounter
++
;
currentManager
->
Color
(
fillColor
.
r
,
fillColor
.
g
,
fillColor
.
b
,
fillColor
.
a
);
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
* Parameters given to setShader are indices of the triangle's vertices
* (if you want to understand more, check the vertex shader source [shader.vert]).
* Shader uses this coordinates to determine if fragments are inside the circle or not.
* v2
* /\
* //\\
* v0 /_\/_\ v1
*/
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
1.0
);
currentManager
->
Vertex
(
aCenterPoint
.
x
-
aRadius
*
sqrt
(
3.0
f
),
// v0
aCenterPoint
.
y
-
aRadius
,
layerDepth
);
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
2.0
);
currentManager
->
Vertex
(
aCenterPoint
.
x
+
aRadius
*
sqrt
(
3.0
f
),
// v1
aCenterPoint
.
y
-
aRadius
,
layerDepth
);
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
3.0
);
currentManager
->
Vertex
(
aCenterPoint
.
x
,
aCenterPoint
.
y
+
aRadius
*
2.0
f
,
// v2
layerDepth
);
}
return
groupCounter
++
;
if
(
isStrokeEnabled
)
{
currentManager
->
Color
(
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
,
strokeColor
.
a
);
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
* Parameters given to setShader are indices of the triangle's vertices
* (if you want to understand more, check the vertex shader source [shader.vert]).
* and the line width. Shader uses this coordinates to determine if fragments are
* inside the circle or not.
* v2
* /\
* //\\
* v0 /_\/_\ v1
*/
double
outerRadius
=
aRadius
+
(
lineWidth
/
2
);
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
1.0
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
aCenterPoint
.
x
-
outerRadius
*
sqrt
(
3.0
f
),
// v0
aCenterPoint
.
y
-
outerRadius
,
layerDepth
);
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
2.0
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
aCenterPoint
.
x
+
outerRadius
*
sqrt
(
3.0
f
),
// v1
aCenterPoint
.
y
-
outerRadius
,
layerDepth
);
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
3.0
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
aCenterPoint
.
x
,
aCenterPoint
.
y
+
outerRadius
*
2.0
f
,
// v2
layerDepth
);
}
}
void
OPENGL_GAL
::
DrawLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
void
OPENGL_GAL
::
DrawArc
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aStartAngle
,
double
aEndAngle
)
{
const
VECTOR2D
startEndVector
=
aEndPoint
-
aStartPoint
;
double
lineAngle
=
startEndVector
.
Angle
()
;
if
(
aRadius
<=
0
)
return
;
drawLineQuad
(
aStartPoint
,
aEndPoint
);
// Swap the angles, if start angle is greater than end angle
SWAP
(
aStartAngle
,
>
,
aEndAngle
);
// Line caps
drawFilledSemiCircle
(
aStartPoint
,
lineWidth
/
2
,
lineAngle
+
M_PI
/
2
);
drawFilledSemiCircle
(
aEndPoint
,
lineWidth
/
2
,
lineAngle
-
M_PI
/
2
)
;
}
VECTOR2D
startPoint
(
cos
(
aStartAngle
),
sin
(
aStartAngle
)
);
VECTOR2D
endPoint
(
cos
(
aEndAngle
),
sin
(
aEndAngle
)
);
VECTOR2D
startEndPoint
=
startPoint
+
endPoint
;
VECTOR2D
middlePoint
=
0.5
*
startEndPoint
;
Save
();
currentManager
->
Translate
(
aCenterPoint
.
x
,
aCenterPoint
.
y
,
layerDepth
);
void
OPENGL_GAL
::
DrawPolyline
(
std
::
deque
<
VECTOR2D
>&
aPointList
)
{
std
::
deque
<
VECTOR2D
>::
const_iterator
it
=
aPointList
.
begin
();
if
(
isStrokeEnabled
)
{
double
alphaIncrement
=
2.0
*
M_PI
/
CIRCLE_POINTS
;
currentManager
->
Color
(
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
,
strokeColor
.
a
);
// Start from the second point
for
(
it
++
;
it
!=
aPointList
.
end
();
it
++
)
VECTOR2D
p
(
cos
(
aStartAngle
)
*
aRadius
,
sin
(
aStartAngle
)
*
aRadius
);
double
alpha
;
for
(
alpha
=
aStartAngle
+
alphaIncrement
;
alpha
<
aEndAngle
;
alpha
+=
alphaIncrement
)
{
VECTOR2D
p_next
(
cos
(
alpha
)
*
aRadius
,
sin
(
alpha
)
*
aRadius
);
DrawLine
(
p
,
p_next
);
p
=
p_next
;
}
// Draw the last missing part
if
(
alpha
!=
aEndAngle
)
{
VECTOR2D
p_last
(
cos
(
aEndAngle
)
*
aRadius
,
sin
(
aEndAngle
)
*
aRadius
);
DrawLine
(
p
,
p_last
);
}
}
if
(
isFillEnabled
)
{
const
VECTOR2D
startEndVector
=
(
*
it
-
*
(
it
-
1
)
);
double
lineAngle
=
startEndVector
.
Angle
();
double
alphaIncrement
=
2
*
M_PI
/
CIRCLE_POINTS
;
double
alpha
;
currentManager
->
Color
(
fillColor
.
r
,
fillColor
.
g
,
fillColor
.
b
,
fillColor
.
a
);
drawLineQuad
(
*
(
it
-
1
),
*
it
);
for
(
alpha
=
aStartAngle
;
(
alpha
+
alphaIncrement
)
<
aEndAngle
;
)
{
currentManager
->
Vertex
(
middlePoint
.
x
,
middlePoint
.
y
,
0.0
);
currentManager
->
Vertex
(
cos
(
alpha
),
sin
(
alpha
),
0.0
);
alpha
+=
alphaIncrement
;
currentManager
->
Vertex
(
cos
(
alpha
),
sin
(
alpha
),
0.0
);
}
// There is no need to draw line caps on both ends of polyline's segments
drawFilledSemiCircle
(
*
(
it
-
1
),
lineWidth
/
2
,
lineAngle
+
M_PI
/
2
);
currentManager
->
Vertex
(
middlePoint
.
x
,
middlePoint
.
y
,
0.0
);
currentManager
->
Vertex
(
cos
(
alpha
),
sin
(
alpha
),
0.0
);
currentManager
->
Vertex
(
endPoint
.
x
,
endPoint
.
y
,
0.0
);
}
// ..and now - draw the ending cap
const
VECTOR2D
startEndVector
=
(
*
(
it
-
1
)
-
*
(
it
-
2
)
);
double
lineAngle
=
startEndVector
.
Angle
();
drawFilledSemiCircle
(
*
(
it
-
1
),
lineWidth
/
2
,
lineAngle
-
M_PI
/
2
);
Restore
();
}
...
...
@@ -501,234 +445,29 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
}
void
OPENGL_GAL
::
Draw
Circle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
)
void
OPENGL_GAL
::
Draw
Polyline
(
std
::
deque
<
VECTOR2D
>&
aPointList
)
{
if
(
isFillEnabled
)
std
::
deque
<
VECTOR2D
>::
const_iterator
it
=
aPointList
.
begin
();
// Start from the second point
for
(
it
++
;
it
!=
aPointList
.
end
();
it
++
)
{
currentManager
->
Color
(
fillColor
.
r
,
fillColor
.
g
,
fillColor
.
b
,
fillColor
.
a
);
const
VECTOR2D
startEndVector
=
(
*
it
-
*
(
it
-
1
)
);
double
lineAngle
=
startEndVector
.
Angle
();
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
Parameters given to setShader are indices of the triangle's vertices
(if you want to understand more, check the vertex shader source [shader.vert]).
Shader uses this coordinates to determine if fragments are inside the circle or not.
v2
/\
//\\
v0 /_\/_\ v1
*/
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
1.0
);
currentManager
->
Vertex
(
aCenterPoint
.
x
-
aRadius
*
sqrt
(
3.0
f
),
// v0
aCenterPoint
.
y
-
aRadius
,
layerDepth
);
drawLineQuad
(
*
(
it
-
1
),
*
it
);
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
2.0
);
currentManager
->
Vertex
(
aCenterPoint
.
x
+
aRadius
*
sqrt
(
3.0
f
),
// v1
aCenterPoint
.
y
-
aRadius
,
layerDepth
);
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
3.0
);
currentManager
->
Vertex
(
aCenterPoint
.
x
,
aCenterPoint
.
y
+
aRadius
*
2.0
f
,
// v2
layerDepth
);
}
if
(
isStrokeEnabled
)
{
currentManager
->
Color
(
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
,
strokeColor
.
a
);
/* Draw a triangle that contains the circle, then shade it leaving only the circle.
Parameters given to setShader are indices of the triangle's vertices
(if you want to understand more, check the vertex shader source [shader.vert]).
and the line width. Shader uses this coordinates to determine if fragments are
inside the circle or not.
v2
/\
//\\
v0 /_\/_\ v1
*/
double
outerRadius
=
aRadius
+
(
lineWidth
/
2
);
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
1.0
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
aCenterPoint
.
x
-
outerRadius
*
sqrt
(
3.0
f
),
// v0
aCenterPoint
.
y
-
outerRadius
,
layerDepth
);
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
2.0
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
aCenterPoint
.
x
+
outerRadius
*
sqrt
(
3.0
f
),
// v1
aCenterPoint
.
y
-
outerRadius
,
layerDepth
);
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
3.0
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
aCenterPoint
.
x
,
aCenterPoint
.
y
+
outerRadius
*
2.0
f
,
// v2
layerDepth
);
}
}
void
OPENGL_GAL
::
drawSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
)
{
if
(
isFillEnabled
)
{
currentManager
->
Color
(
fillColor
.
r
,
fillColor
.
g
,
fillColor
.
b
,
fillColor
.
a
);
drawFilledSemiCircle
(
aCenterPoint
,
aRadius
,
aAngle
);
}
if
(
isStrokeEnabled
)
{
currentManager
->
Color
(
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
,
strokeColor
.
a
);
drawStrokedSemiCircle
(
aCenterPoint
,
aRadius
,
aAngle
);
}
}
void
OPENGL_GAL
::
drawFilledSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
)
{
Save
();
currentManager
->
Translate
(
aCenterPoint
.
x
,
aCenterPoint
.
y
,
0.0
f
);
currentManager
->
Rotate
(
aAngle
,
0.0
f
,
0.0
f
,
1.0
f
);
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
(if you want to understand more, check the vertex shader source [shader.vert]).
Shader uses this coordinates to determine if fragments are inside the semicircle or not.
v2
/\
/__\
v0 //__\\ v1
*/
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
4.0
f
);
currentManager
->
Vertex
(
-
aRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v0
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
5.0
f
);
currentManager
->
Vertex
(
aRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v1
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
6.0
f
);
currentManager
->
Vertex
(
0.0
f
,
aRadius
*
2.0
f
,
layerDepth
);
// v2
Restore
();
}
void
OPENGL_GAL
::
drawStrokedSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
)
{
double
outerRadius
=
aRadius
+
(
lineWidth
/
2
);
Save
();
currentManager
->
Translate
(
aCenterPoint
.
x
,
aCenterPoint
.
y
,
0.0
f
);
currentManager
->
Rotate
(
aAngle
,
0.0
f
,
0.0
f
,
1.0
f
);
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
(if you want to understand more, check the vertex shader source [shader.vert]), the
radius and the line width. Shader uses this coordinates to determine if fragments are
inside the semicircle or not.
v2
/\
/__\
v0 //__\\ v1
*/
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
4.0
f
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
-
outerRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v0
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
5.0
f
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
outerRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v1
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
6.0
f
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
0.0
f
,
outerRadius
*
2.0
f
,
layerDepth
);
// v2
Restore
();
}
// FIXME Optimize
void
OPENGL_GAL
::
DrawArc
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aStartAngle
,
double
aEndAngle
)
{
if
(
aRadius
<=
0
)
return
;
// Swap the angles, if start angle is greater than end angle
SWAP
(
aStartAngle
,
>
,
aEndAngle
);
VECTOR2D
startPoint
(
cos
(
aStartAngle
),
sin
(
aStartAngle
)
);
VECTOR2D
endPoint
(
cos
(
aEndAngle
),
sin
(
aEndAngle
)
);
VECTOR2D
startEndPoint
=
startPoint
+
endPoint
;
VECTOR2D
middlePoint
=
0.5
*
startEndPoint
;
Save
();
currentManager
->
Translate
(
aCenterPoint
.
x
,
aCenterPoint
.
y
,
layerDepth
);
if
(
isStrokeEnabled
)
{
double
alphaIncrement
=
2.0
*
M_PI
/
CIRCLE_POINTS
;
currentManager
->
Color
(
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
,
strokeColor
.
a
);
VECTOR2D
p
(
cos
(
aStartAngle
)
*
aRadius
,
sin
(
aStartAngle
)
*
aRadius
);
double
alpha
;
for
(
alpha
=
aStartAngle
+
alphaIncrement
;
alpha
<
aEndAngle
;
alpha
+=
alphaIncrement
)
{
VECTOR2D
p_next
(
cos
(
alpha
)
*
aRadius
,
sin
(
alpha
)
*
aRadius
);
DrawLine
(
p
,
p_next
);
p
=
p_next
;
}
// Draw the last missing part
if
(
alpha
!=
aEndAngle
)
{
VECTOR2D
p_last
(
cos
(
aEndAngle
)
*
aRadius
,
sin
(
aEndAngle
)
*
aRadius
);
DrawLine
(
p
,
p_last
);
}
}
if
(
isFillEnabled
)
{
double
alphaIncrement
=
2
*
M_PI
/
CIRCLE_POINTS
;
double
alpha
;
currentManager
->
Color
(
fillColor
.
r
,
fillColor
.
g
,
fillColor
.
b
,
fillColor
.
a
);
for
(
alpha
=
aStartAngle
;
(
alpha
+
alphaIncrement
)
<
aEndAngle
;
)
{
currentManager
->
Vertex
(
middlePoint
.
x
,
middlePoint
.
y
,
0.0
);
currentManager
->
Vertex
(
cos
(
alpha
),
sin
(
alpha
),
0.0
);
alpha
+=
alphaIncrement
;
currentManager
->
Vertex
(
cos
(
alpha
),
sin
(
alpha
),
0.0
);
}
currentManager
->
Vertex
(
middlePoint
.
x
,
middlePoint
.
y
,
0.0
);
currentManager
->
Vertex
(
cos
(
alpha
),
sin
(
alpha
),
0.0
);
currentManager
->
Vertex
(
endPoint
.
x
,
endPoint
.
y
,
0.0
);
// There is no need to draw line caps on both ends of polyline's segments
drawFilledSemiCircle
(
*
(
it
-
1
),
lineWidth
/
2
,
lineAngle
+
M_PI
/
2
);
}
Restore
();
// ..and now - draw the ending cap
const
VECTOR2D
startEndVector
=
(
*
(
it
-
1
)
-
*
(
it
-
2
)
);
double
lineAngle
=
startEndVector
.
Angle
();
drawFilledSemiCircle
(
*
(
it
-
1
),
lineWidth
/
2
,
lineAngle
-
M_PI
/
2
);
}
struct
OGLPOINT
{
OGLPOINT
()
:
x
(
0.0
),
y
(
0.0
),
z
(
0.0
)
{}
OGLPOINT
(
const
char
*
fastest
)
{
// do nothing for fastest speed, and keep inline
}
OGLPOINT
(
const
VECTOR2D
&
aPoint
)
:
x
(
aPoint
.
x
),
y
(
aPoint
.
y
),
z
(
0.0
)
{}
OGLPOINT
&
operator
=
(
const
VECTOR2D
&
aPoint
)
{
x
=
aPoint
.
x
;
y
=
aPoint
.
y
;
z
=
0.0
;
return
*
this
;
}
GLdouble
x
;
GLdouble
y
;
GLdouble
z
;
};
void
OPENGL_GAL
::
DrawPolygon
(
const
std
::
deque
<
VECTOR2D
>&
aPointList
)
{
// Any non convex polygon needs to be tesselated
...
...
@@ -808,34 +547,32 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro
}
void
OPENGL_GAL
::
SetStrokeColor
(
const
COLOR4D
&
aColor
)
void
OPENGL_GAL
::
ResizeScreen
(
int
aWidth
,
int
aHeight
)
{
isSetAttributes
=
true
;
strokeColor
=
aColor
;
screenSize
=
VECTOR2D
(
aWidth
,
aHeight
);
// This is the default drawing color
currentManager
->
Color
(
aColor
.
r
,
aColor
.
g
,
aColor
.
b
,
aColor
.
a
);
// Resize framebuffers
compositor
.
Resize
(
aWidth
,
aHeight
);
isFramebufferInitialized
=
false
;
wxGLCanvas
::
SetSize
(
aWidth
,
aHeight
);
}
void
OPENGL_GAL
::
SetFillColor
(
const
COLOR4D
&
aColor
)
bool
OPENGL_GAL
::
Show
(
bool
aShow
)
{
isSetAttributes
=
true
;
fillColor
=
aColor
;
}
bool
s
=
wxGLCanvas
::
Show
(
aShow
);
if
(
aShow
)
wxGLCanvas
::
Raise
();
void
OPENGL_GAL
::
SetBackgroundColor
(
const
COLOR4D
&
aColor
)
{
isSetAttributes
=
true
;
backgroundColor
=
aColor
;
return
s
;
}
void
OPENGL_GAL
::
SetLineWidth
(
double
aLineWidth
)
void
OPENGL_GAL
::
Flush
(
)
{
isSetAttributes
=
true
;
lineWidth
=
aLineWidth
;
glFlush
();
}
...
...
@@ -847,6 +584,15 @@ void OPENGL_GAL::ClearScreen()
}
void
OPENGL_GAL
::
SetStrokeColor
(
const
COLOR4D
&
aColor
)
{
strokeColor
=
aColor
;
// This is the default drawing color
currentManager
->
Color
(
aColor
.
r
,
aColor
.
g
,
aColor
.
b
,
aColor
.
a
);
}
void
OPENGL_GAL
::
Transform
(
MATRIX3x3D
aTransformation
)
{
GLdouble
matrixData
[
16
]
=
{
1
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
1
};
...
...
@@ -883,12 +629,6 @@ void OPENGL_GAL::Scale( const VECTOR2D& aScale )
}
void
OPENGL_GAL
::
Flush
()
{
glFlush
();
}
void
OPENGL_GAL
::
Save
()
{
currentManager
->
PushMatrix
();
...
...
@@ -919,19 +659,6 @@ void OPENGL_GAL::EndGroup()
}
void
OPENGL_GAL
::
ClearCache
()
{
groups
.
clear
();
cachedManager
.
Clear
();
}
void
OPENGL_GAL
::
DeleteGroup
(
int
aGroupNumber
)
{
groups
.
erase
(
aGroupNumber
);
}
void
OPENGL_GAL
::
DrawGroup
(
int
aGroupNumber
)
{
cachedManager
.
DrawItem
(
*
groups
[
aGroupNumber
]
);
...
...
@@ -950,140 +677,65 @@ void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth )
}
void
OPENGL_GAL
::
computeCircle
(
)
void
OPENGL_GAL
::
DeleteGroup
(
int
aGroupNumber
)
{
VERTEX
*
vertex
=
circleContainer
.
Allocate
(
CIRCLE_POINTS
);
groups
.
erase
(
aGroupNumber
);
}
// Compute the circle points for a given number of segments
for
(
int
i
=
0
;
i
<
CIRCLE_POINTS
;
++
i
)
{
vertex
->
x
=
0.0
f
;
vertex
->
y
=
0.0
f
;
vertex
->
z
=
0.0
f
;
vertex
++
;
vertex
->
x
=
cos
(
2.0
*
M_PI
/
CIRCLE_POINTS
*
i
);
vertex
->
y
=
sin
(
2.0
*
M_PI
/
CIRCLE_POINTS
*
i
);
vertex
->
z
=
0.0
f
;
vertex
++
;
vertex
->
x
=
cos
(
2.0
*
M_PI
/
CIRCLE_POINTS
*
(
i
+
1
)
);
vertex
->
y
=
sin
(
2.0
*
M_PI
/
CIRCLE_POINTS
*
(
i
+
1
)
);
vertex
->
z
=
0.0
f
;
vertex
++
;
}
void
OPENGL_GAL
::
ClearCache
()
{
groups
.
clear
();
cachedManager
.
Clear
();
}
void
OPENGL_GAL
::
ComputeWorldScreenMatrix
()
void
OPENGL_GAL
::
SaveScreen
()
{
ComputeWorldScale
();
wxASSERT_MSG
(
false
,
wxT
(
"Not implemented yet"
)
);
}
worldScreenMatrix
.
SetIdentity
();
MATRIX3x3D
translation
;
translation
.
SetIdentity
();
translation
.
SetTranslation
(
0.5
*
screenSize
);
void
OPENGL_GAL
::
RestoreScreen
()
{
wxASSERT_MSG
(
false
,
wxT
(
"Not implemented yet"
)
);
}
MATRIX3x3D
scale
;
scale
.
SetIdentity
();
scale
.
SetScale
(
VECTOR2D
(
worldScale
,
worldScale
)
);
MATRIX3x3D
flip
;
flip
.
SetIdentity
();
flip
.
SetScale
(
VECTOR2D
(
1.0
,
1.0
)
);
void
OPENGL_GAL
::
SetTarget
(
RenderTarget
aTarget
)
{
switch
(
aTarget
)
{
default
:
case
TARGET_CACHED
:
currentManager
=
&
cachedManager
;
break
;
MATRIX3x3D
lookat
;
lookat
.
SetIdentity
()
;
lookat
.
SetTranslation
(
-
lookAtPoint
)
;
case
TARGET_NONCACHED
:
currentManager
=
&
nonCachedManager
;
break
;
worldScreenMatrix
=
translation
*
flip
*
scale
*
lookat
*
worldScreenMatrix
;
case
TARGET_OVERLAY
:
currentManager
=
&
overlayManager
;
break
;
}
}
// -------------------------------------
// Callback functions for the tesselator
// -------------------------------------
VECTOR2D
OPENGL_GAL
::
ComputeCursorToWorld
(
const
VECTOR2D
&
aCursorPosition
)
{
VECTOR2D
cursorPosition
=
aCursorPosition
;
cursorPosition
.
y
=
screenSize
.
y
-
aCursorPosition
.
y
;
MATRIX3x3D
inverseMatrix
=
worldScreenMatrix
.
Inverse
();
VECTOR2D
cursorPositionWorld
=
inverseMatrix
*
cursorPosition
;
// Compare Redbook Chapter 11
void
CALLBACK
VertexCallback
(
GLvoid
*
aVertexPtr
,
void
*
aData
)
{
GLdouble
*
vertex
=
static_cast
<
GLdouble
*>
(
aVertexPtr
);
OPENGL_GAL
::
TessParams
*
param
=
static_cast
<
OPENGL_GAL
::
TessParams
*>
(
aData
);
VERTEX_MANAGER
*
vboManager
=
param
->
vboManager
;
if
(
vboManager
)
vboManager
->
Vertex
(
vertex
[
0
],
vertex
[
1
],
vertex
[
2
]
);
}
void
CALLBACK
CombineCallback
(
GLdouble
coords
[
3
],
GLdouble
*
vertex_data
[
4
],
GLfloat
weight
[
4
],
GLdouble
**
dataOut
,
void
*
aData
)
{
GLdouble
*
vertex
=
new
GLdouble
[
3
];
OPENGL_GAL
::
TessParams
*
param
=
static_cast
<
OPENGL_GAL
::
TessParams
*>
(
aData
);
// Save the pointer so we can delete it later
param
->
intersectPoints
.
push_back
(
vertex
);
memcpy
(
vertex
,
coords
,
3
*
sizeof
(
GLdouble
)
);
*
dataOut
=
vertex
;
}
void
CALLBACK
EdgeCallback
(
void
)
{
// This callback is needed to force GLU tesselator to use triangles only
}
void
CALLBACK
ErrorCallback
(
GLenum
aErrorCode
)
{
const
GLubyte
*
estring
;
estring
=
gluErrorString
(
aErrorCode
);
wxLogError
(
wxT
(
"Tessellation Error: %s"
),
(
char
*
)
estring
);
}
void
InitTesselatorCallbacks
(
GLUtesselator
*
aTesselator
)
{
gluTessCallback
(
aTesselator
,
GLU_TESS_VERTEX_DATA
,
(
void
(
CALLBACK
*
)()
)
VertexCallback
);
gluTessCallback
(
aTesselator
,
GLU_TESS_COMBINE_DATA
,
(
void
(
CALLBACK
*
)()
)
CombineCallback
);
gluTessCallback
(
aTesselator
,
GLU_TESS_EDGE_FLAG
,
(
void
(
CALLBACK
*
)()
)
EdgeCallback
);
gluTessCallback
(
aTesselator
,
GLU_TESS_ERROR_DATA
,
(
void
(
CALLBACK
*
)()
)
ErrorCallback
);
}
// ---------------
// Cursor handling
// ---------------
void
OPENGL_GAL
::
initCursor
(
int
aCursorSize
)
{
cursorSize
=
aCursorSize
;
}
VECTOR2D
OPENGL_GAL
::
ComputeCursorToWorld
(
const
VECTOR2D
&
aCursorPosition
)
{
VECTOR2D
cursorPosition
=
aCursorPosition
;
cursorPosition
.
y
=
screenSize
.
y
-
aCursorPosition
.
y
;
MATRIX3x3D
inverseMatrix
=
worldScreenMatrix
.
Inverse
();
VECTOR2D
cursorPositionWorld
=
inverseMatrix
*
cursorPosition
;
return
cursorPositionWorld
;
}
return
cursorPositionWorld
;
}
void
OPENGL_GAL
::
DrawCursor
(
VECTOR2D
aCursorPosition
)
{
wxLogWarning
(
wxT
(
"Not tested
"
)
);
wxLogWarning
(
wxT
(
"Not tested
"
)
);
SetCurrent
(
*
glContext
);
...
...
@@ -1096,8 +748,8 @@ void OPENGL_GAL::DrawCursor( VECTOR2D aCursorPosition )
aCursorPosition
=
worldScreenMatrix
*
cursorPositionWorld
;
// Switch to the main framebuffer and blit the scene
//glBindFramebuffer( GL_FRAMEBUFFER, 0 );
//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
//
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity
();
...
...
@@ -1140,7 +792,7 @@ void OPENGL_GAL::DrawCursor( VECTOR2D aCursorPosition )
}
void
OPENGL_GAL
::
D
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
void
OPENGL_GAL
::
d
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
{
compositor
.
SetBuffer
(
mainBuffer
);
...
...
@@ -1165,12 +817,247 @@ void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
}
bool
OPENGL_GAL
::
Show
(
bool
aShow
)
inline
void
OPENGL_GAL
::
drawLineQuad
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
{
bool
s
=
wxGLCanvas
::
Show
(
aShow
);
VECTOR2D
startEndVector
=
aEndPoint
-
aStartPoint
;
double
lineLength
=
startEndVector
.
EuclideanNorm
();
double
scale
=
0.5
*
lineWidth
/
lineLength
;
if
(
aShow
)
wxGLCanvas
::
Raise
()
;
if
(
lineLength
<=
0.0
)
return
;
return
s
;
// The perpendicular vector also needs transformations
glm
::
vec4
vector
=
currentManager
->
GetTransformation
()
*
glm
::
vec4
(
-
startEndVector
.
y
*
scale
,
startEndVector
.
x
*
scale
,
0.0
,
0.0
);
// Line width is maintained by the vertex shader
currentManager
->
Shader
(
SHADER_LINE
,
vector
.
x
,
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aStartPoint
.
x
,
aStartPoint
.
y
,
layerDepth
);
// v0
currentManager
->
Shader
(
SHADER_LINE
,
-
vector
.
x
,
-
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aStartPoint
.
x
,
aStartPoint
.
y
,
layerDepth
);
// v1
currentManager
->
Shader
(
SHADER_LINE
,
-
vector
.
x
,
-
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aEndPoint
.
x
,
aEndPoint
.
y
,
layerDepth
);
// v3
currentManager
->
Shader
(
SHADER_LINE
,
vector
.
x
,
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aStartPoint
.
x
,
aStartPoint
.
y
,
layerDepth
);
// v0
currentManager
->
Shader
(
SHADER_LINE
,
-
vector
.
x
,
-
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aEndPoint
.
x
,
aEndPoint
.
y
,
layerDepth
);
// v3
currentManager
->
Shader
(
SHADER_LINE
,
vector
.
x
,
vector
.
y
,
lineWidth
);
currentManager
->
Vertex
(
aEndPoint
.
x
,
aEndPoint
.
y
,
layerDepth
);
// v2
}
void
OPENGL_GAL
::
drawSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
)
{
if
(
isFillEnabled
)
{
currentManager
->
Color
(
fillColor
.
r
,
fillColor
.
g
,
fillColor
.
b
,
fillColor
.
a
);
drawFilledSemiCircle
(
aCenterPoint
,
aRadius
,
aAngle
);
}
if
(
isStrokeEnabled
)
{
currentManager
->
Color
(
strokeColor
.
r
,
strokeColor
.
g
,
strokeColor
.
b
,
strokeColor
.
a
);
drawStrokedSemiCircle
(
aCenterPoint
,
aRadius
,
aAngle
);
}
}
void
OPENGL_GAL
::
drawFilledSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
)
{
Save
();
currentManager
->
Translate
(
aCenterPoint
.
x
,
aCenterPoint
.
y
,
0.0
f
);
currentManager
->
Rotate
(
aAngle
,
0.0
f
,
0.0
f
,
1.0
f
);
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
* (if you want to understand more, check the vertex shader source [shader.vert]).
* Shader uses this coordinates to determine if fragments are inside the semicircle or not.
* v2
* /\
* /__\
* v0 //__\\ v1
*/
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
4.0
f
);
currentManager
->
Vertex
(
-
aRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v0
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
5.0
f
);
currentManager
->
Vertex
(
aRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v1
currentManager
->
Shader
(
SHADER_FILLED_CIRCLE
,
6.0
f
);
currentManager
->
Vertex
(
0.0
f
,
aRadius
*
2.0
f
,
layerDepth
);
// v2
Restore
();
}
void
OPENGL_GAL
::
drawStrokedSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
)
{
double
outerRadius
=
aRadius
+
(
lineWidth
/
2
);
Save
();
currentManager
->
Translate
(
aCenterPoint
.
x
,
aCenterPoint
.
y
,
0.0
f
);
currentManager
->
Rotate
(
aAngle
,
0.0
f
,
0.0
f
,
1.0
f
);
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
* (if you want to understand more, check the vertex shader source [shader.vert]), the
* radius and the line width. Shader uses this coordinates to determine if fragments are
* inside the semicircle or not.
* v2
* /\
* /__\
* v0 //__\\ v1
*/
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
4.0
f
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
-
outerRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v0
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
5.0
f
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
outerRadius
*
3.0
f
/
sqrt
(
3.0
f
),
0.0
f
,
layerDepth
);
// v1
currentManager
->
Shader
(
SHADER_STROKED_CIRCLE
,
6.0
f
,
aRadius
,
lineWidth
);
currentManager
->
Vertex
(
0.0
f
,
outerRadius
*
2.0
f
,
layerDepth
);
// v2
Restore
();
}
void
OPENGL_GAL
::
onPaint
(
wxPaintEvent
&
aEvent
)
{
PostPaint
();
}
void
OPENGL_GAL
::
skipMouseEvent
(
wxMouseEvent
&
aEvent
)
{
// Post the mouse event to the event listener registered in constructor, if any
if
(
mouseListener
)
wxPostEvent
(
mouseListener
,
aEvent
);
}
void
OPENGL_GAL
::
initGlew
()
{
// Initialize GLEW library
GLenum
err
=
glewInit
();
if
(
GLEW_OK
!=
err
)
{
wxLogError
(
wxString
::
FromUTF8
(
(
char
*
)
glewGetErrorString
(
err
)
)
);
exit
(
1
);
}
else
{
wxLogDebug
(
wxString
(
wxT
(
"Status: Using GLEW "
)
)
+
FROM_UTF8
(
(
char
*
)
glewGetString
(
GLEW_VERSION
)
)
);
}
// Check the OpenGL version (minimum 2.1 is required)
if
(
GLEW_VERSION_2_1
)
{
wxLogInfo
(
wxT
(
"OpenGL Version 2.1 supported."
)
);
}
else
{
wxLogError
(
wxT
(
"OpenGL Version 2.1 is not supported!"
)
);
exit
(
1
);
}
// Framebuffers have to be supported
if
(
!
GLEW_ARB_framebuffer_object
)
{
wxLogError
(
wxT
(
"Framebuffer objects are not supported!"
)
);
exit
(
1
);
}
// Vertex buffer have to be supported
if
(
!
GLEW_ARB_vertex_buffer_object
)
{
wxLogError
(
wxT
(
"Vertex buffer objects are not supported!"
)
);
exit
(
1
);
}
isGlewInitialized
=
true
;
}
void
OPENGL_GAL
::
initCursor
(
int
aCursorSize
)
{
cursorSize
=
aCursorSize
;
}
unsigned
int
OPENGL_GAL
::
getNewGroupNumber
()
{
wxASSERT_MSG
(
groups
.
size
()
<
std
::
numeric_limits
<
unsigned
int
>::
max
(),
wxT
(
"There are no free slots to store a group"
)
);
while
(
groups
.
find
(
groupCounter
)
!=
groups
.
end
()
)
{
groupCounter
++
;
}
return
groupCounter
++
;
}
// -------------------------------------
// Callback functions for the tesselator
// -------------------------------------
// Compare Redbook Chapter 11
void
CALLBACK
VertexCallback
(
GLvoid
*
aVertexPtr
,
void
*
aData
)
{
GLdouble
*
vertex
=
static_cast
<
GLdouble
*>
(
aVertexPtr
);
OPENGL_GAL
::
TessParams
*
param
=
static_cast
<
OPENGL_GAL
::
TessParams
*>
(
aData
);
VERTEX_MANAGER
*
vboManager
=
param
->
vboManager
;
if
(
vboManager
)
vboManager
->
Vertex
(
vertex
[
0
],
vertex
[
1
],
vertex
[
2
]
);
}
void
CALLBACK
CombineCallback
(
GLdouble
coords
[
3
],
GLdouble
*
vertex_data
[
4
],
GLfloat
weight
[
4
],
GLdouble
**
dataOut
,
void
*
aData
)
{
GLdouble
*
vertex
=
new
GLdouble
[
3
];
OPENGL_GAL
::
TessParams
*
param
=
static_cast
<
OPENGL_GAL
::
TessParams
*>
(
aData
);
// Save the pointer so we can delete it later
param
->
intersectPoints
.
push_back
(
vertex
);
memcpy
(
vertex
,
coords
,
3
*
sizeof
(
GLdouble
)
);
*
dataOut
=
vertex
;
}
void
CALLBACK
EdgeCallback
()
{
// This callback is needed to force GLU tesselator to use triangles only
}
void
CALLBACK
ErrorCallback
(
GLenum
aErrorCode
)
{
const
GLubyte
*
estring
;
estring
=
gluErrorString
(
aErrorCode
);
wxLogError
(
wxT
(
"Tessellation Error: %s"
),
(
char
*
)
estring
);
}
void
InitTesselatorCallbacks
(
GLUtesselator
*
aTesselator
)
{
gluTessCallback
(
aTesselator
,
GLU_TESS_VERTEX_DATA
,
(
void
(
CALLBACK
*
)()
)
VertexCallback
);
gluTessCallback
(
aTesselator
,
GLU_TESS_COMBINE_DATA
,
(
void
(
CALLBACK
*
)()
)
CombineCallback
);
gluTessCallback
(
aTesselator
,
GLU_TESS_EDGE_FLAG
,
(
void
(
CALLBACK
*
)()
)
EdgeCallback
);
gluTessCallback
(
aTesselator
,
GLU_TESS_ERROR_DATA
,
(
void
(
CALLBACK
*
)()
)
ErrorCallback
);
}
common/gal/opengl/shader.cpp
View file @
190ed585
...
...
@@ -37,12 +37,12 @@
using
namespace
KiGfx
;
SHADER
::
SHADER
()
:
isProgramCreated
(
false
),
isShaderLinked
(
false
),
active
(
false
),
maximumVertices
(
4
),
geomInputType
(
GL_LINES
),
geomOutputType
(
GL_LINES
)
isProgramCreated
(
false
),
isShaderLinked
(
false
),
active
(
false
),
maximumVertices
(
4
),
geomInputType
(
GL_LINES
),
geomOutputType
(
GL_LINES
)
{
}
...
...
@@ -97,7 +97,8 @@ bool SHADER::Link()
programInfo
(
programNumber
);
// Check the Link state
glGetObjectParameterivARB
(
programNumber
,
GL_OBJECT_LINK_STATUS_ARB
,
(
GLint
*
)
&
isShaderLinked
);
glGetObjectParameterivARB
(
programNumber
,
GL_OBJECT_LINK_STATUS_ARB
,
(
GLint
*
)
&
isShaderLinked
);
#ifdef __WXDEBUG__
if
(
!
isShaderLinked
)
...
...
@@ -253,6 +254,7 @@ bool SHADER::addSource( const std::string& aShaderSource, ShaderType aShaderType
glCompileShader
(
shaderNumber
);
GLint
status
;
glGetShaderiv
(
shaderNumber
,
GL_COMPILE_STATUS
,
&
status
);
if
(
status
!=
GL_TRUE
)
{
wxLogError
(
wxT
(
"Shader compilation error"
)
);
...
...
@@ -275,4 +277,3 @@ bool SHADER::addSource( const std::string& aShaderSource, ShaderType aShaderType
return
true
;
}
common/gal/opengl/vertex_manager.cpp
View file @
190ed585
...
...
@@ -37,7 +37,7 @@
using
namespace
KiGfx
;
VERTEX_MANAGER
::
VERTEX_MANAGER
(
bool
aCached
)
:
m_noTransform
(
true
),
m_transform
(
1.0
f
)
m_noTransform
(
true
),
m_transform
(
1.0
f
)
{
m_container
.
reset
(
VERTEX_CONTAINER
::
MakeContainer
(
aCached
)
);
m_gpu
.
reset
(
GPU_MANAGER
::
MakeManager
(
m_container
.
get
()
)
);
...
...
@@ -52,6 +52,7 @@ void VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ ) const
{
// Obtain the pointer to the vertex in the currently used container
VERTEX
*
newVertex
=
m_container
->
Allocate
(
1
);
if
(
newVertex
==
NULL
)
{
wxLogError
(
wxT
(
"Vertex allocation error"
)
);
...
...
@@ -66,6 +67,7 @@ void VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize ) co
{
// Obtain pointer to the vertex in currently used container
VERTEX
*
newVertex
=
m_container
->
Allocate
(
aSize
);
if
(
newVertex
==
NULL
)
{
wxLogError
(
wxT
(
"Vertex allocation error"
)
);
...
...
@@ -95,7 +97,7 @@ void VERTEX_MANAGER::FreeItem( VERTEX_ITEM& aItem ) const
void
VERTEX_MANAGER
::
ChangeItemColor
(
const
VERTEX_ITEM
&
aItem
,
const
COLOR4D
&
aColor
)
const
{
unsigned
int
size
=
aItem
.
GetSize
();
unsigned
int
size
=
aItem
.
GetSize
();
unsigned
int
offset
=
aItem
.
GetOffset
();
VERTEX
*
vertex
=
m_container
->
GetVertices
(
offset
);
...
...
@@ -114,7 +116,7 @@ void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& a
void
VERTEX_MANAGER
::
ChangeItemDepth
(
const
VERTEX_ITEM
&
aItem
,
GLfloat
aDepth
)
const
{
unsigned
int
size
=
aItem
.
GetSize
();
unsigned
int
size
=
aItem
.
GetSize
();
unsigned
int
offset
=
aItem
.
GetOffset
();
VERTEX
*
vertex
=
m_container
->
GetVertices
(
offset
);
...
...
@@ -131,7 +133,7 @@ void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth )
VERTEX
*
VERTEX_MANAGER
::
GetVertices
(
const
VERTEX_ITEM
&
aItem
)
const
{
if
(
aItem
.
GetSize
()
==
0
)
return
NULL
;
// The item is not stored in the container
return
NULL
;
// The item is not stored in the container
return
m_container
->
GetVertices
(
aItem
.
GetOffset
()
);
}
...
...
@@ -158,6 +160,7 @@ void VERTEX_MANAGER::BeginDrawing() const
void
VERTEX_MANAGER
::
DrawItem
(
const
VERTEX_ITEM
&
aItem
)
const
{
int
size
=
aItem
.
GetSize
();
if
(
size
>
0
)
{
int
offset
=
aItem
.
GetOffset
();
...
...
common/view/wx_view_controls.cpp
View file @
190ed585
...
...
@@ -85,7 +85,6 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& event )
else
scrollSpeed
=
scrollVec
.
y
;
VECTOR2D
t
=
m_view
->
GetScreenPixelSize
();
VECTOR2D
delta
(
event
.
ControlDown
()
?
-
scrollSpeed
:
0.0
,
event
.
ShiftDown
()
?
-
scrollSpeed
:
0.0
);
...
...
include/gal/cairo/cairo_compositor.h
View file @
190ed585
...
...
@@ -38,7 +38,6 @@
namespace
KiGfx
{
class
CAIRO_COMPOSITOR
:
public
COMPOSITOR
{
public
:
...
...
@@ -67,25 +66,25 @@ protected:
typedef
boost
::
shared_array
<
unsigned
int
>
BitmapPtr
;
typedef
struct
{
cairo_t
*
context
;
///< Main texture handle
cairo_surface_t
*
surface
;
///< Point to which an image from texture is attached
BitmapPtr
bitmap
;
///< Pixel storage
cairo_t
*
context
;
///< Main texture handle
cairo_surface_t
*
surface
;
///< Point to which an image from texture is attached
BitmapPtr
bitmap
;
///< Pixel storage
}
CAIRO_BUFFER
;
unsigned
int
m_current
;
///< Currently used buffer handle
unsigned
int
m_current
;
///< Currently used buffer handle
typedef
std
::
deque
<
CAIRO_BUFFER
>
CAIRO_BUFFERS
;
/// Pointer to the current context, so it can be changed
cairo_t
**
m_currentContext
;
cairo_t
**
m_currentContext
;
/// Rendering target used for compositing (the main display)
cairo_t
*
m_mainContext
;
cairo_t
*
m_mainContext
;
/// Transformation matrix
cairo_matrix_t
m_matrix
;
cairo_matrix_t
m_matrix
;
/// Stores information about initialized buffers
CAIRO_BUFFERS
m_buffers
;
CAIRO_BUFFERS
m_buffers
;
unsigned
int
m_stride
;
///< Stride to use given the desired format and width
unsigned
int
m_bufferSize
;
///< Amount of memory needed to store a buffer
...
...
@@ -102,7 +101,6 @@ protected:
return
m_buffers
.
size
();
}
};
}
// namespace KiGfx
#endif
/* COMPOSITOR_H_ */
include/gal/cairo/cairo_gal.h
View file @
190ed585
...
...
@@ -45,9 +45,6 @@
#endif
#endif
#define EXCEPTION_ZERO_CLIENT_RECTANGLE 0
#define EXCEPTION_ZERO_CONTEXT 1
/**
* @brief Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
*
...
...
@@ -92,7 +89,7 @@ public:
// ---------------
/// @copydoc GAL::BeginDrawing()
virtual
void
BeginDrawing
()
throw
(
int
)
;
virtual
void
BeginDrawing
();
/// @copydoc GAL::EndDrawing()
virtual
void
EndDrawing
();
...
...
@@ -103,19 +100,19 @@ public:
/// @copydoc GAL::DrawSegment()
virtual
void
DrawSegment
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
,
double
aWidth
);
/// @copydoc GAL::DrawPolyline()
virtual
void
DrawPolyline
(
std
::
deque
<
VECTOR2D
>&
aPointList
);
/// @copydoc GAL::DrawCircle()
virtual
void
DrawCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
);
/// @copydoc GAL::DrawArc()
virtual
void
DrawArc
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aStartAngle
,
double
aEndAngle
);
virtual
void
DrawArc
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aStartAngle
,
double
aEndAngle
);
/// @copydoc GAL::DrawRectangle()
virtual
void
DrawRectangle
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
/// @copydoc GAL::DrawPolyline()
virtual
void
DrawPolyline
(
std
::
deque
<
VECTOR2D
>&
aPointList
);
/// @copydoc GAL::DrawPolygon()
virtual
void
DrawPolygon
(
const
std
::
deque
<
VECTOR2D
>&
aPointList
);
...
...
@@ -149,24 +146,15 @@ public:
/// @copydoc GAL::SetIsStroke()
virtual
void
SetIsStroke
(
bool
aIsStrokeEnabled
);
/// @copydoc GAL::SetFillColor()
virtual
void
SetFillColor
(
const
COLOR4D
&
aColor
);
/// @copydoc GAL::SetStrokeColor()
virtual
void
SetStrokeColor
(
const
COLOR4D
&
aColor
);
/// @copydoc GAL::GetStrokeColor()
COLOR4D
GetStrokeColor
();
/// @copydoc GAL::SetBackgroundColor()
virtual
void
SetBackgroundColor
(
const
COLOR4D
&
aColor
);
/// @copydoc GAL::SetFillColor()
virtual
void
SetFillColor
(
const
COLOR4D
&
aColor
);
/// @copydoc GAL::SetLineWidth()
virtual
void
SetLineWidth
(
double
aLineWidth
);
/// @copydoc GAL::GetLineWidth()
double
GetLineWidth
();
/// @copydoc GAL::SetLayerDepth()
virtual
void
SetLayerDepth
(
double
aLayerDepth
);
...
...
@@ -221,33 +209,6 @@ public:
// Handling the world <-> screen transformation
// --------------------------------------------------------
/// @copydoc GAL::ComputeWorldScreenMatrix()
virtual
void
ComputeWorldScreenMatrix
();
/// @copydoc GAL::GetWorldScreenMatrix()
MATRIX3x3D
GetWorldScreenMatrix
();
/// @copydoc GAL::SetWorldScreenMatrix()
void
SetWorldScreenMatrix
(
MATRIX3x3D
aMatrix
);
/// @copydoc GAL::SetWorldUnitLength()
void
SetWorldUnitLength
(
double
aWorldUnitLength
);
/// @copydoc GAL::SetScreenDPI()
void
SetScreenDPI
(
double
aScreenDPI
);
/// @copydoc GAL::SetLookAtPoint()
void
SetLookAtPoint
(
const
VECTOR2D
&
aPoint
);
/// @copydoc GAL::GetLookAtPoint()
VECTOR2D
GetLookAtPoint
();
/// @copydoc GAL::SetZoomFactor()
void
SetZoomFactor
(
double
aZoomFactor
);
/// @copydoc GAL::GetZoomFactor()
double
GetZoomFactor
();
/// @copydoc GAL::SaveScreen()
virtual
void
SaveScreen
();
...
...
@@ -264,9 +225,6 @@ public:
/// @copydoc GAL::ComputeCursorToWorld()
virtual
VECTOR2D
ComputeCursorToWorld
(
const
VECTOR2D
&
aCursorPosition
);
/// @copydoc GAL::SetIsCursorEnabled()
void
SetIsCursorEnabled
(
bool
aIsCursorEnabled
);
/// @copydoc GAL::DrawCursor()
virtual
void
DrawCursor
(
VECTOR2D
aCursorPosition
);
...
...
@@ -295,7 +253,7 @@ public:
}
protected
:
virtual
void
D
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
virtual
void
d
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
private
:
/// Super class definition
...
...
@@ -303,30 +261,29 @@ private:
// Compositing variables
boost
::
shared_ptr
<
CAIRO_COMPOSITOR
>
compositor
;
///< Object for layers compositing
unsigned
int
mainBuffer
;
///< Handle to the main buffer
unsigned
int
overlayBuffer
;
///< Handle to the overlay buffer
unsigned
int
mainBuffer
;
///< Handle to the main buffer
unsigned
int
overlayBuffer
;
///< Handle to the overlay buffer
// Variables related to wxWidgets
wxWindow
*
parentWindow
;
///< Parent window
wxEvtHandler
*
mouseListener
;
///< Mouse listener
wxEvtHandler
*
paintListener
;
///< Paint listener
unsigned
int
bufferSize
;
///< Size of buffers cairoOutput, bitmapBuffers
unsigned
char
*
wxOutput
;
///< wxImage comaptible buffer
wxWindow
*
parentWindow
;
///< Parent window
wxEvtHandler
*
mouseListener
;
///< Mouse listener
wxEvtHandler
*
paintListener
;
///< Paint listener
unsigned
int
bufferSize
;
///< Size of buffers cairoOutput, bitmapBuffers
unsigned
char
*
wxOutput
;
///< wxImage comaptible buffer
// Cursor variables
std
::
deque
<
wxColour
>
savedCursorPixels
;
///< Saved pixels of the cursor
bool
isDeleteSavedPixels
;
///< True, if the saved pixels can be discarded
wxPoint
savedCursorPosition
;
///< The last cursor position
wxBitmap
*
cursorPixels
;
///< Cursor pixels
wxBitmap
*
cursorPixelsSaved
;
///< Saved cursor pixels
int
cursorSize
;
///< Cursor size
std
::
deque
<
wxColour
>
savedCursorPixels
;
///< Saved pixels of the cursor
bool
isDeleteSavedPixels
;
///< True, if the saved pixels can be discarded
wxPoint
savedCursorPosition
;
///< The last cursor position
wxBitmap
*
cursorPixels
;
///< Cursor pixels
wxBitmap
*
cursorPixelsSaved
;
///< Saved cursor pixels
int
cursorSize
;
///< Cursor size
/// Maximum number of arguments for one command
static
const
int
MAX_CAIRO_ARGUMENTS
=
6
;
/// Definitions for the command recorder
enum
GraphicsCommand
{
enum
GraphicsCommand
{
CMD_SET_FILL
,
///< Enable/disable filling
CMD_SET_STROKE
,
///< Enable/disable stroking
CMD_SET_FILLCOLOR
,
///< Set the fill color
...
...
@@ -392,18 +349,18 @@ private:
/// @copydoc GAL::initCursor()
virtual
void
initCursor
(
int
aCursorSize
);
/// Allocate the bitmaps for drawing
void
allocateBitmaps
();
/// Allocate the bitmaps for drawing
void
deleteBitmaps
();
/// Prepare Cairo surfaces for drawing
void
initSurface
();
/// Destroy Cairo surfaces when are not needed anymore
void
deinitSurface
();
/// Allocate the bitmaps for drawing
void
allocateBitmaps
();
/// Allocate the bitmaps for drawing
void
deleteBitmaps
();
/// Prepare the compositor
void
setCompositor
();
...
...
include/gal/graphics_abstraction_layer.h
View file @
190ed585
...
...
@@ -231,7 +231,10 @@ public:
*
* @param aColor is the color for background filling.
*/
virtual
void
SetBackgroundColor
(
const
COLOR4D
&
aColor
)
=
0
;
inline
virtual
void
SetBackgroundColor
(
const
COLOR4D
&
aColor
)
{
backgroundColor
=
aColor
;
}
/**
* @brief Set the line width.
...
...
@@ -417,7 +420,7 @@ public:
// --------------------------------------------------------
/// @brief Compute the world <-> screen transformation matrix
virtual
void
ComputeWorldScreenMatrix
()
=
0
;
virtual
void
ComputeWorldScreenMatrix
();
/**
* @brief Get the world <-> screen transformation matrix.
...
...
@@ -745,7 +748,6 @@ protected:
bool
isFillEnabled
;
///< Is filling of graphic objects enabled ?
bool
isStrokeEnabled
;
///< Are the outlines stroked ?
bool
isSetAttributes
;
///< True, if the attributes have been set
COLOR4D
backgroundColor
;
///< The background color
COLOR4D
fillColor
;
///< The fill color
...
...
@@ -784,7 +786,7 @@ protected:
* @param aStartPoint is the start point of the line.
* @param aEndPoint is the end point of the line.
*/
virtual
void
D
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
=
0
;
virtual
void
d
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
)
=
0
;
/**
* @brief Initialize the cursor.
...
...
include/gal/opengl/cached_container.h
View file @
190ed585
...
...
@@ -94,12 +94,12 @@ protected:
unsigned
int
m_itemSize
;
/**
* Function reallocate()
* resizes the chunk that stores the current item to the given size.
*
* @param aSize is the number of vertices to be stored.
* @return offset of the new chunk.
*/
* Function reallocate()
* resizes the chunk that stores the current item to the given size.
*
* @param aSize is the number of vertices to be stored.
* @return offset of the new chunk.
*/
virtual
unsigned
int
reallocate
(
unsigned
int
aSize
);
/**
...
...
include/gal/opengl/opengl_compositor.h
View file @
190ed585
...
...
@@ -37,7 +37,6 @@
namespace
KiGfx
{
class
OPENGL_COMPOSITOR
:
public
COMPOSITOR
{
public
:
...
...
@@ -94,7 +93,6 @@ protected:
return
m_buffers
.
size
();
}
};
}
// namespace KiGfx
#endif
/* COMPOSITOR_H_ */
include/gal/opengl/opengl_gal.h
View file @
190ed585
...
...
@@ -104,19 +104,19 @@ public:
/// @copydoc GAL::DrawSegment()
virtual
void
DrawSegment
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
,
double
aWidth
);
/// @copydoc GAL::DrawPolyline()
virtual
void
DrawPolyline
(
std
::
deque
<
VECTOR2D
>&
aPointList
);
/// @copydoc GAL::DrawCircle()
virtual
void
DrawCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
);
/// @copydoc GAL::DrawArc()
virtual
void
DrawArc
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aStartAngle
,
double
aEndAngle
);
virtual
void
DrawArc
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aStartAngle
,
double
aEndAngle
);
/// @copydoc GAL::DrawRectangle()
virtual
void
DrawRectangle
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
/// @copydoc GAL::DrawPolyline()
virtual
void
DrawPolyline
(
std
::
deque
<
VECTOR2D
>&
aPointList
);
/// @copydoc GAL::DrawPolygon()
virtual
void
DrawPolygon
(
const
std
::
deque
<
VECTOR2D
>&
aPointList
);
...
...
@@ -129,7 +129,7 @@ public:
// --------------
/// @brief Resizes the canvas.
virtual
void
ResizeScreen
(
int
aWidth
,
int
aHeight
);
virtual
void
ResizeScreen
(
int
aWidth
,
int
aHeight
);
/// @brief Shows/hides the GAL canvas
virtual
bool
Show
(
bool
aShow
);
...
...
@@ -144,42 +144,9 @@ public:
// Attribute setting
// -----------------
/// @copydoc GAL::SetIsFill()
virtual
void
SetIsFill
(
bool
aIsFillEnabled
)
{
isFillEnabled
=
aIsFillEnabled
;
}
/// @copydoc GAL::SetIsStroke()
virtual
void
SetIsStroke
(
bool
aIsStrokeEnabled
)
{
isStrokeEnabled
=
aIsStrokeEnabled
;
}
/// @copydoc GAL::SetFillColor()
virtual
void
SetFillColor
(
const
COLOR4D
&
aColor
);
/// @copydoc GAL::SetStrokeColor()
virtual
void
SetStrokeColor
(
const
COLOR4D
&
aColor
);
/// @copydoc GAL::GetStrokeColor()
COLOR4D
GetStrokeColor
();
/// @copydoc GAL::SetBackgroundColor()
virtual
void
SetBackgroundColor
(
const
COLOR4D
&
aColor
);
/// @copydoc GAL::SetLineWidth()
virtual
void
SetLineWidth
(
double
aLineWidth
);
/// @copydoc GAL::GetLineWidth()
double
GetLineWidth
();
/// @copydoc GAL::SetLayerDepth()
virtual
void
SetLayerDepth
(
double
aLayerDepth
)
{
super
::
SetLayerDepth
(
aLayerDepth
);
}
// --------------
// Transformation
// --------------
...
...
@@ -231,33 +198,6 @@ public:
// Handling the world <-> screen transformation
// --------------------------------------------------------
/// @copydoc GAL::ComputeWorldScreenMatrix()
virtual
void
ComputeWorldScreenMatrix
();
/// @copydoc GAL::GetWorldScreenMatrix()
MATRIX3x3D
GetWorldScreenMatrix
();
/// @copydoc GAL::SetWorldScreenMatrix()
void
SetWorldScreenMatrix
(
MATRIX3x3D
aMatrix
);
/// @copydoc GAL::SetWorldUnitLength()
void
SetWorldUnitLength
(
double
aWorldUnitLength
);
/// @copydoc GAL::SetScreenDPI()
void
SetScreenDPI
(
double
aScreenDPI
);
/// @copydoc GAL::SetLookAtPoint()
void
SetLookAtPoint
(
const
VECTOR2D
&
aPoint
);
/// @copydoc GAL::GetLookAtPoint()
VECTOR2D
GetLookAtPoint
();
/// @copydoc GAL::SetZoomFactor()
void
SetZoomFactor
(
double
aZoomFactor
);
/// @copydoc GAL::GetZoomFactor()
double
GetZoomFactor
();
/// @copydoc GAL::SaveScreen()
virtual
void
SaveScreen
();
...
...
@@ -274,9 +214,6 @@ public:
/// @copydoc GAL::ComputeCursorToWorld()
virtual
VECTOR2D
ComputeCursorToWorld
(
const
VECTOR2D
&
aCursorPosition
);
/// @copydoc GAL::SetIsCursorEnabled()
void
SetIsCursorEnabled
(
bool
aIsCursorEnabled
);
/// @copydoc GAL::DrawCursor()
virtual
void
DrawCursor
(
VECTOR2D
aCursorPosition
);
...
...
@@ -312,7 +249,7 @@ public:
}
TessParams
;
protected
:
virtual
void
D
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
virtual
void
d
rawGridLine
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
private
:
/// Super class definition
...
...
@@ -321,90 +258,114 @@ private:
static
const
int
CIRCLE_POINTS
=
64
;
///< The number of points for circle approximation
static
const
int
CURVE_POINTS
=
32
;
///< The number of points for curve approximation
wxClientDC
*
clientDC
;
///< Drawing context
wxGLContext
*
glContext
;
///< OpenGL context of wxWidgets
wxWindow
*
parentWindow
;
///< Parent window
wxEvtHandler
*
mouseListener
;
wxEvtHandler
*
paintListener
;
// Precomputed vertices for faster circle & semicircle drawing
NONCACHED_CONTAINER
circleContainer
;
///< Container for storing circle vertices
wxClientDC
*
clientDC
;
///< Drawing context
wxGLContext
*
glContext
;
///< OpenGL context of wxWidgets
wxWindow
*
parentWindow
;
///< Parent window
wxEvtHandler
*
mouseListener
;
wxEvtHandler
*
paintListener
;
// Vertex buffer objects related fields
typedef
std
::
map
<
unsigned
int
,
boost
::
shared_ptr
<
VERTEX_ITEM
>
>
GroupsMap
;
GroupsMap
groups
;
///< Stores informations about VBO objects (groups)
unsigned
int
groupCounter
;
///< Counter used for generating keys for groups
VERTEX_MANAGER
*
currentManager
;
///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs)
VERTEX_MANAGER
cachedManager
;
///< Container for storing cached VERTEX_ITEMs
VERTEX_MANAGER
nonCachedManager
;
///< Container for storing non-cached VERTEX_ITEMs
VERTEX_MANAGER
overlayManager
;
///< Container for storing overlaid VERTEX_ITEMs
GroupsMap
groups
;
///< Stores informations about VBO objects (groups)
unsigned
int
groupCounter
;
///< Counter used for generating keys for groups
VERTEX_MANAGER
*
currentManager
;
///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs)
VERTEX_MANAGER
cachedManager
;
///< Container for storing cached VERTEX_ITEMs
VERTEX_MANAGER
nonCachedManager
;
///< Container for storing non-cached VERTEX_ITEMs
VERTEX_MANAGER
overlayManager
;
///< Container for storing overlaid VERTEX_ITEMs
// Framebuffer & compositing
OPENGL_COMPOSITOR
compositor
;
///< Handles multiple rendering targets
unsigned
int
mainBuffer
;
///< Main rendering target
unsigned
int
overlayBuffer
;
///< Auxiliary rendering target (for menus etc.)
// Polygon tesselation
GLUtesselator
*
tesselator
;
///< Pointer to the tesselator
std
::
vector
<
GLdouble
*>
tessIntersects
;
///< Storage of intersecting points
OPENGL_COMPOSITOR
compositor
;
///< Handles multiple rendering targets
unsigned
int
mainBuffer
;
///< Main rendering target
unsigned
int
overlayBuffer
;
///< Auxiliary rendering target (for menus etc.)
// Shader
SHADER
shader
;
///< There is only one shader used for different objects
SHADER
shader
;
///< There is only one shader used for different objects
// Cursor
int
cursorSize
;
///< Size of the cursor in pixels
GLubyte
*
cursorShape
;
///< Cursor pixel storage
GLubyte
*
cursorSave
;
///< Saved cursor pixels
VECTOR2D
savedCursorPosition
;
///< Last saved cursor position
int
cursorSize
;
///< Size of the cursor in pixels
GLubyte
*
cursorShape
;
///< Cursor pixel storage
GLubyte
*
cursorSave
;
///< Saved cursor pixels
VECTOR2D
savedCursorPosition
;
///< Last saved cursor position
// Internal flags
bool
isGlewInitialized
;
///< Is GLEW initialized?
bool
isFramebufferInitialized
;
///< Are the framebuffers initialized?
bool
isShaderInitialized
;
///< Was the shader initialized?
bool
isGrouping
;
///< Was a group started?
bool
isGlewInitialized
;
///< Is GLEW initialized?
bool
isFramebufferInitialized
;
///< Are the framebuffers initialized?
bool
isShaderInitialized
;
///< Was the shader initialized?
bool
isGrouping
;
///< Was a group started?
// Polygon tesselation
GLUtesselator
*
tesselator
;
///< Pointer to the tesselator
std
::
vector
<
GLdouble
*>
tessIntersects
;
///< Storage of intersecting points
// Structure used for tesselation of polygons
struct
OGLPOINT
{
OGLPOINT
()
:
x
(
0
.
0
),
y
(
0
.
0
),
z
(
0
.
0
)
{}
OGLPOINT
(
const
char
*
fastest
)
{
// do nothing for fastest speed, and keep inline
}
OGLPOINT
(
const
VECTOR2D
&
aPoint
)
:
x
(
aPoint
.
x
),
y
(
aPoint
.
y
),
z
(
0
.
0
)
{}
OGLPOINT
&
operator
=
(
const
VECTOR2D
&
aPoint
)
{
x
=
aPoint
.
x
;
y
=
aPoint
.
y
;
z
=
0
.
0
;
return
*
this
;
}
GLdouble
x
;
GLdouble
y
;
GLdouble
z
;
};
/**
* @brief Draw a semi circle. Depending on settings (isStrokeEnabled & isFilledEnabled) it runs
* @brief Draw a quad for the line.
*
* @param aStartPoint is the start point of the line.
* @param aEndPoint is the end point of the line.
*/
inline
void
drawLineQuad
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
/**
* @brief Draw a semicircle. Depending on settings (isStrokeEnabled & isFilledEnabled) it runs
* the proper function (drawStrokedSemiCircle or drawFilledSemiCircle).
*
* @param aCenterPoint is the center point.
* @param aRadius is the radius of the semi
-
circle.
* @param aAngle is the angle of the semi
-
circle.
* @param aRadius is the radius of the semicircle.
* @param aAngle is the angle of the semicircle.
*
*/
void
drawSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
);
/**
* @brief Draw a filled semi
circle.
* @brief Draw a filled semicircle.
*
* @param aCenterPoint is the center point.
* @param aRadius is the radius of the semi
-
circle.
* @param aAngle is the angle of the semi
-
circle.
* @param aRadius is the radius of the semicircle.
* @param aAngle is the angle of the semicircle.
*
*/
void
drawFilledSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
);
/**
* @brief Draw a stroked semi
circle.
* @brief Draw a stroked semicircle.
*
* @param aCenterPoint is the center point.
* @param aRadius is the radius of the semi
-
circle.
* @param aAngle is the angle of the semi
-
circle.
* @param aRadius is the radius of the semicircle.
* @param aAngle is the angle of the semicircle.
*
*/
void
drawStrokedSemiCircle
(
const
VECTOR2D
&
aCenterPoint
,
double
aRadius
,
double
aAngle
);
/// Compute the points of the unit circle and store them in VBO.
void
computeCircle
();
// Event handling
/**
* @brief This is the window creation event handler.
*
* @param aEvent is the window creation event.
*/
void
onCreate
(
wxWindowCreateEvent
&
aEvent
);
/**
* @brief This is the OnPaint event handler.
*
...
...
@@ -419,20 +380,12 @@ private:
*/
void
skipMouseEvent
(
wxMouseEvent
&
aEvent
);
/// Initialize GLEW
.
/// Initialize GLEW
void
initGlew
();
/// @copydoc GAL::initCursor()
virtual
void
initCursor
(
int
aCursorSize
);
/**
* @brief Draw a quad for the line.
*
* @param aStartPoint is the start point of the line.
* @param aEndPoint is the end point of the line.
*/
inline
void
drawLineQuad
(
const
VECTOR2D
&
aStartPoint
,
const
VECTOR2D
&
aEndPoint
);
/**
* @brief Returns a valid key that can be used as a new group number.
*
...
...
include/gal/opengl/vertex_common.h
View file @
190ed585
...
...
@@ -35,9 +35,8 @@
namespace
KiGfx
{
// Possible types of shaders
enum
SHADER_TYPE
{
SHADER_NONE
=
0
,
enum
SHADER_TYPE
{
SHADER_NONE
=
0
,
SHADER_LINE
,
SHADER_FILLED_CIRCLE
,
SHADER_STROKED_CIRCLE
,
...
...
@@ -60,7 +59,7 @@ const unsigned int CoordStride = CoordSize / sizeof(GLfloat);
// Offset of color data from the beginning of each vertex data
const
unsigned
int
ColorOffset
=
offsetof
(
VERTEX
,
r
);
const
unsigned
int
ColorSize
=
sizeof
(
VERTEX
().
r
)
+
sizeof
(
VERTEX
().
g
)
+
sizeof
(
VERTEX
().
b
)
+
sizeof
(
VERTEX
().
a
);
sizeof
(
VERTEX
().
b
)
+
sizeof
(
VERTEX
().
a
);
const
unsigned
int
ColorStride
=
ColorSize
/
sizeof
(
GLubyte
);
// Shader attributes
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment