Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compositing a webview with an opengl context #337

Open
ghost opened this issue May 14, 2018 · 8 comments
Open

Compositing a webview with an opengl context #337

ghost opened this issue May 14, 2018 · 8 comments
Labels
support This issue was posted by user to ask for help

Comments

@ghost
Copy link

ghost commented May 14, 2018

I am have a webview in one window and a 3d opengl view in another window.

But I would like to composite them into the same window OR dock one window to the other.

Wondering if SDL can help or if I should keep trying with glfw.
I have not used SDL

@veeableful veeableful added the support This issue was posted by user to ask for help label May 15, 2018
@veeableful
Copy link
Contributor

Hi @gedw99, I believe it isn't possible to do that if you're not using SDL for creating the windows. If you created the windows using SDL, you could use window.GetSurface() to get the pixels of the windows and blit one of the surfaces to another.

@ghost
Copy link
Author

ghost commented May 15, 2018

Thank you the the thorough answer.
Any examples of this that you know of. Its a bit specialised.
Boy i wish i used SDL :)

@ghost
Copy link
Author

ghost commented May 15, 2018

i see now that what i need to do is edit each of the programs i want to composite into SDL and give them a SDL "Veneer" on top so that the Main SDL windows can plug into them.
Correct ?

Here are the two systems i want to combine

webview is a webview :)
engine is a generic 3D engine. Its using opengl
flutter-sdl is a wrapper of Google's flutter designed to work with SDL.

what about this ?
http://lazyfoo.net/tutorials/SDL/09_the_viewport/index.php
Its using SDL_RenderSetViewport.

@ghost
Copy link
Author

ghost commented May 15, 2018

this looks like the way to get it working !!!
https://github.com/golang-ui/nuklear/blob/master/cmd/nk-example-sdl2/main.go

that gets me a opengl context with a SDL window managing it.

@malashin
Copy link
Collaborator

malashin commented May 15, 2018

I'm not familiar with how webview works.

But you can either create separate windows in SDL, or do rendering inside one window.

I couldn't get separate windows to follow each other as you drag them around since window movement event occurs only after the window was moved. If that's ok you can just use event to move the other window to the side of new windows position.

Pressing 1 or 2 selects Renderer or OpenGL.
Pressing R, G, B changes it's background color.
Q exits.

package main

import (
	"runtime"

	"github.com/go-gl/gl/v2.1/gl"
	"github.com/veandco/go-sdl2/sdl"
)

var winWidth int32 = 320
var winHeight int32 = 480

func main() {
	runtime.LockOSThread()

	err := sdl.Init(sdl.INIT_EVERYTHING)
	if err != nil {
		panic(err)
	}
	defer sdl.Quit()

	window1, err := sdl.CreateWindow("Renderer Window", sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, winWidth, winHeight, 0)
	if err != nil {
		panic(err)
	}
	defer window1.Destroy()

	renderer, err := sdl.CreateRenderer(window1, -1, 0)
	if err != nil {
		panic(err)
	}
	defer renderer.Destroy()

	window2, err := sdl.CreateWindow("GL Window", sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, winWidth, winHeight, sdl.WINDOW_OPENGL)
	if err != nil {
		panic(err)
	}
	defer window2.Destroy()

	x, y := window1.GetPosition()
	w, _ := window1.GetSize()
	window2.SetPosition(x+w, y)

	context, err := window2.GLCreateContext()
	if err != nil {
		panic(err)
	}
	defer sdl.GLDeleteContext(context)

	err = gl.Init()
	if err != nil {
		panic(err)
	}

	w1ID, err := window1.GetID()
	if err != nil {
		panic(err)
	}
	w2ID, err := window2.GetID()
	if err != nil {
		panic(err)
	}

	isGL := false
	running := true
	for running {
		draw := false
		for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch t := event.(type) {
			case *sdl.WindowEvent:
				switch t.Event {
				case sdl.WINDOWEVENT_CLOSE:
					running = false
				case sdl.WINDOWEVENT_MOVED:
					switch t.WindowID {
					case w1ID:
						window2.SetPosition(t.Data1+w, t.Data2)
					case w2ID:
						window1.SetPosition(t.Data1-w, t.Data2)
					}
				}
			case *sdl.KeyboardEvent:
				if t.Type == sdl.KEYDOWN {
					switch t.Keysym.Sym {
					case sdl.K_q:
						running = false
						break
					case sdl.K_1:
						isGL = false
					case sdl.K_2:
						isGL = true
					}
					if isGL {
						switch t.Keysym.Sym {
						case sdl.K_r:
							gl.ClearColor(1, 0, 0, 1)
							draw = true
						case sdl.K_g:
							gl.ClearColor(0, 1, 0, 1)
							draw = true
						case sdl.K_b:
							gl.ClearColor(0, 0, 1, 1)
							draw = true
						}
						if draw {
							gl.Clear(gl.COLOR_BUFFER_BIT)
							window2.GLSwap()
						}
					}
					if !isGL {
						switch t.Keysym.Sym {
						case sdl.K_r:
							renderer.SetDrawColor(255, 0, 0, 255)
							draw = true
						case sdl.K_g:
							renderer.SetDrawColor(0, 255, 0, 255)
							draw = true
						case sdl.K_b:
							renderer.SetDrawColor(0, 0, 255, 255)
							draw = true
						}
						if draw {
							renderer.Clear()
							renderer.Present()
						}
					}
				}
			case *sdl.QuitEvent:
				running = false
			}
		}
	}
}

The other option is to render into one window and manage where each item is rendered by yourself.

This example will create SDL window with OpenGL rendering context that you can use with OpenGL and sdl.Renderer at the same time.

Pressing R, G, B changes background color, Q exits.

package main

import (
	"runtime"

	"github.com/go-gl/gl/v2.1/gl"
	"github.com/veandco/go-sdl2/sdl"
)

var winWidth int32 = 320
var winHeight int32 = 240
var angle float32
var x float32 = 50.0
var y float32 = 50.0

func main() {
	runtime.LockOSThread()

	err := sdl.Init(sdl.INIT_EVERYTHING)
	if err != nil {
		panic(err)
	}
	defer sdl.Quit()

	window, err := sdl.CreateWindow("Renderer/GL Window", sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, winWidth, winHeight, sdl.WINDOW_OPENGL)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()

	context, err := window.GLCreateContext()
	if err != nil {
		panic(err)
	}
	defer sdl.GLDeleteContext(context)

	err = gl.Init()
	if err != nil {
		panic(err)
	}

	glIdx := -1
	nrd, err := sdl.GetNumRenderDrivers()
	if err != nil {
		panic(err)
	}
	rndInfo := sdl.RendererInfo{}
	for i := 0; i < nrd; i++ {
		_, err := sdl.GetRenderDriverInfo(i, &rndInfo)
		if err != nil {
			panic(err)
		}
		if rndInfo.Name == "opengl" {
			glIdx = i
			break
		}
	}

	renderer, err := sdl.CreateRenderer(window, glIdx, 0)
	if err != nil {
		panic(err)
	}
	defer renderer.Destroy()

	sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
	gl.MatrixMode(gl.MODELVIEW)
	gl.LoadIdentity()

	
	running := true
	for running {
		draw := false
		for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch t := event.(type) {
			case *sdl.KeyboardEvent:
				if t.Type == sdl.KEYDOWN {
					switch t.Keysym.Sym {
					case sdl.K_q:
						running = false
						break
					case sdl.K_r:
						renderer.SetDrawColor(255, 0, 0, 255)
						draw = true
					case sdl.K_g:
						renderer.SetDrawColor(0, 255, 0, 255)
						draw = true
					case sdl.K_b:
						renderer.SetDrawColor(0, 0, 255, 255)
						draw = true
					}
					if draw {
						renderer.Clear()
						renderer.Present()
					}
				}
			case *sdl.QuitEvent:
				running = false
			}
		}
		gl.Clear(gl.COLOR_BUFFER_BIT)
		gl.PushMatrix()
		gl.Translatef(float32(winWidth)/2, float32(winHeight)/2, 0)
		gl.Rotatef(angle, 0.0, 0.0, 1.0)
		gl.Begin(gl.QUADS)
		gl.Color3f(1.0, 0.0, 0.0)
		gl.Vertex2f(x, y)
		gl.Color3f(0.0, 1.0, 0.0)
		gl.Vertex2f(-x, y)
		gl.Color3f(0.0, 0.0, 1.0)
		gl.Vertex2f(-x, -y)
		gl.Color3f(1.0, 1.0, 1.0)
		gl.Vertex2f(x, -y)
		gl.End()
		gl.PopMatrix()
		renderer.Present()
		sdl.Delay(16)
		angle++
	}
}

@ghost
Copy link
Author

ghost commented May 15, 2018

@malashin thank you soooo much for the sample of docking windows. that is as good as it gets.
will give this a whirl now and see how it goes !

@ghost
Copy link

ghost commented Sep 7, 2018

any progress @gedw99???

@dock-lab
Copy link

Hey @malashin

your example with the docking windows is exactly what I was looking for thanks a lot.

In the first window I create a WebView using :
https://github.com/zserge/webview

This also works so far, except for a few slight delays when moving a window. The other window will follow after a short time.

I just wonder if it is possible to put these two into one main(parent) window?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support This issue was posted by user to ask for help
Projects
None yet
Development

No branches or pull requests

3 participants