mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
graphicsdriver/opengl: Enable to bind multiple textures (in theory)
This commit is contained in:
parent
733c463e26
commit
7f2092f964
@ -198,6 +198,13 @@ func (c *context) framebufferPixels(f *framebuffer, width, height int) ([]byte,
|
||||
return pixels, nil
|
||||
}
|
||||
|
||||
func (c *context) activeTexture(idx int) {
|
||||
_ = c.t.Call(func() error {
|
||||
gl.ActiveTexture(gl.TEXTURE0 + uint32(idx))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (c *context) bindTextureImpl(t textureNative) {
|
||||
_ = c.t.Call(func() error {
|
||||
gl.BindTexture(gl.TEXTURE_2D, uint32(t))
|
||||
|
@ -112,6 +112,8 @@ var (
|
||||
unsignedByte js.Value
|
||||
unsignedShort js.Value
|
||||
|
||||
texture0 int
|
||||
|
||||
isWebGL2Available bool
|
||||
)
|
||||
|
||||
@ -154,6 +156,7 @@ func init() {
|
||||
nearest = contextPrototype.Get("NEAREST")
|
||||
noError = contextPrototype.Get("NO_ERROR")
|
||||
rgba = contextPrototype.Get("RGBA")
|
||||
texture0 = contextPrototype.Get("TEXTURE0").Int()
|
||||
texture2d = contextPrototype.Get("TEXTURE_2D")
|
||||
textureMagFilter = contextPrototype.Get("TEXTURE_MAG_FILTER")
|
||||
textureMinFilter = contextPrototype.Get("TEXTURE_MIN_FILTER")
|
||||
@ -279,6 +282,12 @@ func (c *context) framebufferPixels(f *framebuffer, width, height int) ([]byte,
|
||||
return jsutil.Uint8ArrayToSlice(p), nil
|
||||
}
|
||||
|
||||
func (c *context) activeTexture(idx int) {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
gl.Call("activeTexture", texture0+idx)
|
||||
}
|
||||
|
||||
func (c *context) bindTextureImpl(t textureNative) {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
|
@ -156,6 +156,11 @@ func (c *context) framebufferPixels(f *framebuffer, width, height int) ([]byte,
|
||||
return pixels, nil
|
||||
}
|
||||
|
||||
func (c *context) activeTexture(idx int) {
|
||||
gl := c.gl
|
||||
gl.ActiveTexture(mgl.Enum(mgl.TEXTURE0 + idx))
|
||||
}
|
||||
|
||||
func (c *context) bindTextureImpl(t textureNative) {
|
||||
gl := c.gl
|
||||
gl.BindTexture(mgl.TEXTURE_2D, mgl.Texture(t))
|
||||
|
@ -49,6 +49,7 @@ const (
|
||||
NO_ERROR = 0
|
||||
READ_WRITE = 0x88BA
|
||||
RGBA = 0x1908
|
||||
TEXTURE0 = 0x84C0
|
||||
TEXTURE_2D = 0x0DE1
|
||||
TEXTURE_MAG_FILTER = 0x2800
|
||||
TEXTURE_MIN_FILTER = 0x2801
|
||||
|
@ -95,7 +95,8 @@ package gl
|
||||
// typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
|
||||
// typedef unsigned short GLhalfNV;
|
||||
// typedef GLintptr GLvdpauSurfaceNV;
|
||||
// typedef void (APIENTRY *GLVULKANPROCNV)(void);
|
||||
//
|
||||
// typedef void (APIENTRYP GPACTIVETEXTURE)(GLenum texture);
|
||||
// typedef void (APIENTRYP GPATTACHSHADER)(GLuint program, GLuint shader);
|
||||
// typedef void (APIENTRYP GPBINDATTRIBLOCATION)(GLuint program, GLuint index, const GLchar * name);
|
||||
// typedef void (APIENTRYP GPBINDBUFFER)(GLenum target, GLuint buffer);
|
||||
@ -159,6 +160,9 @@ package gl
|
||||
// typedef void (APIENTRYP GPVERTEXATTRIBPOINTER)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const uintptr_t pointer);
|
||||
// typedef void (APIENTRYP GPVIEWPORT)(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
//
|
||||
// static void glowActiveTexture(GPACTIVETEXTURE fnptr, GLenum texture) {
|
||||
// (*fnptr)(texture);
|
||||
// }
|
||||
// static void glowAttachShader(GPATTACHSHADER fnptr, GLuint program, GLuint shader) {
|
||||
// (*fnptr)(program, shader);
|
||||
// }
|
||||
@ -353,6 +357,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
gpActiveTexture C.GPACTIVETEXTURE
|
||||
gpAttachShader C.GPATTACHSHADER
|
||||
gpBindAttribLocation C.GPBINDATTRIBLOCATION
|
||||
gpBindBuffer C.GPBINDBUFFER
|
||||
@ -424,6 +429,10 @@ func boolToInt(b bool) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func ActiveTexture(texture uint32) {
|
||||
C.glowActiveTexture(gpActiveTexture, (C.GLenum)(texture))
|
||||
}
|
||||
|
||||
func AttachShader(program uint32, shader uint32) {
|
||||
C.glowAttachShader(gpAttachShader, (C.GLuint)(program), (C.GLuint)(shader))
|
||||
}
|
||||
@ -675,6 +684,10 @@ func Viewport(x int32, y int32, width int32, height int32) {
|
||||
// InitWithProcAddrFunc intializes the package using the specified OpenGL
|
||||
// function pointer loading function. For more cases Init should be used
|
||||
func InitWithProcAddrFunc(getProcAddr func(name string) unsafe.Pointer) error {
|
||||
gpActiveTexture = (C.GPACTIVETEXTURE)(getProcAddr("glActiveTexture"))
|
||||
if gpActiveTexture == nil {
|
||||
return errors.New("glActiveTexture")
|
||||
}
|
||||
gpAttachShader = (C.GPATTACHSHADER)(getProcAddr("glAttachShader"))
|
||||
if gpAttachShader == nil {
|
||||
return errors.New("glAttachShader")
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
gpActiveTexture uintptr
|
||||
gpAttachShader uintptr
|
||||
gpBindAttribLocation uintptr
|
||||
gpBindBuffer uintptr
|
||||
@ -81,6 +82,10 @@ func boolToUintptr(b bool) uintptr {
|
||||
return 0
|
||||
}
|
||||
|
||||
func ActiveTexture(texture uint32) {
|
||||
syscall.Syscall(gpActiveTexture, 1, uintptr(texture), 0, 0)
|
||||
}
|
||||
|
||||
func AttachShader(program uint32, shader uint32) {
|
||||
syscall.Syscall(gpAttachShader, 2, uintptr(program), uintptr(shader), 0)
|
||||
}
|
||||
@ -332,6 +337,10 @@ func Viewport(x int32, y int32, width int32, height int32) {
|
||||
// InitWithProcAddrFunc intializes the package using the specified OpenGL
|
||||
// function pointer loading function. For more cases Init should be used
|
||||
func InitWithProcAddrFunc(getProcAddr func(name string) uintptr) error {
|
||||
gpActiveTexture = getProcAddr("glActiveTexture")
|
||||
if gpActiveTexture == 0 {
|
||||
return errors.New("glActiveTexture")
|
||||
}
|
||||
gpAttachShader = getProcAddr("glAttachShader")
|
||||
if gpAttachShader == 0 {
|
||||
return errors.New("glAttachShader")
|
||||
|
@ -160,7 +160,7 @@ func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode
|
||||
uniforms["scale"] = scale
|
||||
}
|
||||
|
||||
uniforms["texture"] = source.textureNative
|
||||
uniforms["texture/0"] = source.textureNative
|
||||
|
||||
if err := g.useProgram(program, uniforms); err != nil {
|
||||
return err
|
||||
|
@ -16,6 +16,8 @@ package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/driver"
|
||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||
@ -132,8 +134,9 @@ type openGLState struct {
|
||||
// programs is OpenGL's program for rendering a texture.
|
||||
programs map[programKey]program
|
||||
|
||||
lastProgram program
|
||||
lastUniforms map[string]interface{}
|
||||
lastProgram program
|
||||
lastUniforms map[string]interface{}
|
||||
lastActiveTexture int
|
||||
|
||||
source *Image
|
||||
destination *Image
|
||||
@ -251,6 +254,8 @@ func (g *Graphics) useProgram(program program, uniforms map[string]interface{})
|
||||
|
||||
g.state.lastProgram = program
|
||||
g.state.lastUniforms = map[string]interface{}{}
|
||||
g.state.lastActiveTexture = 0
|
||||
g.context.activeTexture(0)
|
||||
}
|
||||
|
||||
for key, u := range uniforms {
|
||||
@ -271,10 +276,19 @@ func (g *Graphics) useProgram(program program, uniforms map[string]interface{})
|
||||
g.state.lastUniforms[key] = u
|
||||
case textureNative:
|
||||
// Apparently, a texture must be bound every time. The cache is not used here.
|
||||
// TODO: Use another value than 0 when binding multiple textures.
|
||||
g.context.uniformInt(program, key, 0)
|
||||
// We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture
|
||||
// See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml
|
||||
tokens := strings.SplitN(key, "/", 2)
|
||||
if len(tokens) != 2 {
|
||||
return fmt.Errorf("opengl: a uniform variable name for textures must be '[name]/[index]' but %s", key)
|
||||
}
|
||||
idx, err := strconv.Atoi(tokens[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("opengl: a uniform variable name for textures must be '[name]/[index]' but %s", key)
|
||||
}
|
||||
g.context.uniformInt(program, tokens[0], idx)
|
||||
if g.state.lastActiveTexture != idx {
|
||||
g.context.activeTexture(idx)
|
||||
g.state.lastActiveTexture = idx
|
||||
}
|
||||
g.context.bindTexture(u)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user