2018 bis heute | 2017 2016 2015 2014 | 2013 | 2012 | 2011 2010 2009 | 2008 | 2007

(ältere Archiveinträge vor 2007 nicht dargestellt, aber in der Suche enthalten)

Mailingliste - Einträge 2012


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [QF-Test] Creating QFTest for visual components based on openGL (JOGL)


  • Subject: Re: [QF-Test] Creating QFTest for visual components based on openGL (JOGL)
  • From: Ivan Boelle <ivan.boelle@?.com>
  • Date: Thu, 16 Aug 2012 17:59:25 +0200

Hello,

We are using OpenGL too, there is (at least) 2 way of dealing with that:

- Use a procedure to take the screenshot.
In that procedure you can setup a script like this:

comp = rc.getComponent("$(COMP)", timeout=-1, hidden=False)
iw = ImageWrapper(rc)
loc = comp.getLocationOnScreen()
size = comp.getSize()
print "\t\tScreenshoting: "+comp.getClass().getSimpleName()+" ("+str(loc.x)+","+ str(loc.y)+","+ str(size.width)+","+ str(size.height)+")"
image = iw.grabScreenshot(loc.x, loc.y, size.width, size.height)
iw.savePng("$(targetFile)", image)

And then compare png images.

- Add a custom check, with that when you will try to record a check on a GLComponent you will have a special option to make a "hard screenshot":
Below is our script that add this "option".
It might be more complicated than whet you need, feel free to remove parts :)
(I'm using QFTest 3.3, there might be some changes to do to be compatible with more recent versions)

Here are some discussions on this:
http://www.qfs.de/archive/qftest-list/2011/msg00035.html

Also, you will probably need to use a "special" algorithm for image comparison.
Indeed GL rendering is not always "consistent" from one run to another.

from de.qfs.apps.qftest.extensions.checks import CheckerRegistry, Checker, DefaultCheckType, CheckDataType, CheckerHelper
from de.qfs.apps.qftest.shared.extensions.image import ImageRep, BaseImageHandler, ImageComparator
from de.qfs.apps.qftest.shared.data.check import ImageCheckData
from de.qfs.lib.util import Pair
from imagewrapper import ImageWrapper
from javax.swing import SwingUtilities
from java.awt import Point
from java.awt.event import MouseEvent
from java.awt import Toolkit
from java.lang import System

import re
import time
import jarray
import os
import traceback
import sys

# Default checktype id
DEFAULT_ID = "GL_image"

glImageCheckType = DefaultCheckType(
    DEFAULT_ID,               # Identifier
    CheckDataType.IMAGE,            # Data type
    "GL Screenshot"       # Text for menu
)

# Components which should use this Custom checker
targetcomps = [
 "javax.media.opengl.GLCanvas", # JOGL component
 ]

# This custom checker provides 2 functionnalities:
# - Hard screenshot
#    As we have some OpenGL rendering, the classic screenshot (using Java2D) would be empty
#    This checker does a "screenshot" at the location of the targeted component.
#    This suppose the component is visible AND on top of ANY othe window
#
# - Mouse location handling
#    As we have a software cursor drawn in some Canvas we need it to be correctly positionned when screenshoting
#
#    Recording:
#    This checker retrieve the system cursor location when the "Screenshot" MenuItem is pressed
#    Then it simulates a cursor move to this location and update display
#    And finally it stores the x,y coordinates in the checktype parameters
#    => ID;x=#;y=#
#
#    Replaying:
#    This checker retrieve the x,y litterals in the checktype parameters and simulate the mouse move to this coordinates
#
class GLImageChecker(Checker):

    def getSupportedCheckTypes(self, com, item):
         return jarray.array([glImageCheckType], DefaultCheckType)

    def getCheckData(self, com, item, checkType):
        id = checkType.getIdentifier()
        print "Going to check : "+id

        size = com.getSize()

        if id == DEFAULT_ID:
            # parameters are no longer passed through but made available via the following method:
            params = CheckerHelper.instance().getCheckParameters()
            # params is now a Map<String,String>
            f = SwingUtilities.getWindowAncestor(com)
            f.setAlwaysOnTop(true)

            if params and params.containsKey("x") and params.containsKey("y"):
                print "\tCheck mode"
                # Replay mode (x and y are already set)
                x = int(params["x"])
                y = int(params["y"])

                f.setLocation(0, 0)

                doMouseMove(x, y, com)
                time.sleep(1)
            else:
                print "\tRecord mode"
                # Record mode (get and store custom x and y)

                # Determine current system cursor position relative to the component
                p = com.getMousePosition()
                x = p.x
                y = p.y

                # As the current system cursor location can be != of software cursor location, simulate mouse move
                doMouseMove(x, y, com)

                # Append the cursor information to the checktype id, separated with ';'
                id = "%s;x=%d;y=%d" % (glImageCheckType.getIdentifier(), x, y)

            # Grab the screenshot
            iw = ImageWrapper(rc)
            loc = com.getLocationOnScreen()
            image = iw.grabScreenshot(loc.x, loc.y, size.width, size.height)

            f.setAlwaysOnTop(false)
            return ImageCheckData(id, image, -1, -1, -1, -1, -1, -1, False)

    def getCheckDataAndItem(self, com, item, checkType):
        data = "" item, checkType)
        if data is None:
            return None
        return Pair(data, item)


# Relative x,y values to component f
# Simulate mouse move using MouseEvent on EventQueue and force rendering update
def doMouseMove(x, y, comp):
    # Move cursor to stored x,y using EventQueue.dispatch as we are on AWT
    q = Toolkit.getDefaultToolkit().getSystemEventQueue()
    evt = MouseEvent(comp,MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, x, y, 0, false)
    q.dispatchEvent(evt)
    # Force rendering update
    doPaint(SwingUtilities.getWindowAncestor(comp))

def doPaint(f):
    f.getRootPane().paintImmediately(f.getRootPane().getBounds())

def unregister():
    try:
        print "Cleaning"
        i = 1
        for s in targetcomps:
            resolvers.removeResolver("myCheckImage_"+str(i))
            CheckerRegistry.instance().unregisterChecker(s, glImageChecker)
            i += 1
        print "Clean done"
    except:
        pass

def register():
    global glImageChecker
    unregister()
    glImageChecker = GLImageChecker()
    print "Registering"
    i = 1
    for s in targetcomps:
        resolvers.addImageComparison("myCheckImage_"+str(i), compareImages, s)
        CheckerRegistry.instance().registerChecker(s,glImageChecker)
        i += 1
    print "Register done"

register()



---
Ivan Boelle

INT, Interactive Network Technologies






On Thu, Aug 16, 2012 at 3:30 PM, Unguryan, Vitaliy <VUnguryan@?.com> wrote:

Hello everyone!

 

Our application uses component GLCanvas (javax.media.opengl.awt) and it is not possible to make a screenshot of this component using standard procedure.
Could you please consult me on how to implement custom screenshot maker, if possible step by step or  example.
 

Best regards,

  

Vitaliy Unguryan
Java Developer

Anaconda Workbench

LUXOFT UKRAINE
Member of the IBS Group

 



This e-mail and any attachment(s) are intended only for the recipient(s) named above and others who have been specifically authorized to receive them. They may contain confidential information. If you are not the intended recipient, please do not read this email or its attachment(s). Furthermore, you are hereby notified that any dissemination, distribution or copying of this e-mail and any attachment(s) is strictly prohibited. If you have received this e-mail in error, please immediately notify the sender by replying to this e-mail and then delete this e-mail and any attachment(s) or copies thereof from your system. Thank you.

_______________________________________________
qftest-list mailing list
qftest-list@?.de
http://www.qfs.de/mailman/listinfo/qftest-list