oakes / play-clj

A Clojure game library
The Unlicense
939 stars 73 forks source link

Improving graphical fidelity via a texture filter #38

Closed Misophistful closed 10 years ago

Misophistful commented 10 years ago

My sprites suffer a fairly significant drop in quality when I rotate them. I found a StackExchange question with a promising looking answer to this problem: set the texture filter settings to TextureFilter.linear.

What would be the best way to achieve that in play-clj?

oakes commented 10 years ago

Either method they describe would require using interop at the moment. Are you currently using an asset manager?

Misophistful commented 10 years ago

I'm not currently using an asset manager, but loading each texture with texture. However, switching to an asset manager is on my todo list, so if it will help with this problem too then I can bump it up in priority.

Misophistful commented 10 years ago

I've been looking at the example projects to try to figure out how asset-manager works, and I haven't been able to wrap my head around it.

It looks like you are just defining one, calling set-asset-manager!, and then not referring to it again. I was expecting to see use of :load and :get to manage the assets, but didn't find any. Am I misunderstanding what an asset-manager is for, and how it works?

oakes commented 10 years ago

Yes, using an asset manager really only requires (set-asset-manager! (asset-manager)). The loading/getting is done automatically in each function that loads an asset. You don't actually need to use it in order to set the filter, but it has other advantages like automatically preventing you from loading the same texture twice.

As for the filter, I think you can do this on an individual texture like this:

(.setFilter (texture! t :get-texture) Texture$TextureFilter/Linear)
Misophistful commented 10 years ago

It's great that asset-manager handles everything automatically. I've added one to my project.

Does it matter where I do .setFilter? I tried doing it before returning the texture, but got a cryptic exception:

(ns elemental.entities.puck
  (:require [elemental.settings :refer :all]
            [play-clj.core :refer :all]
            [play-clj.g2d :refer :all]
            [play-clj.math :refer :all])
  (:import [com.badlogic.gdx.graphics Texture$TextureFilter]))

(defn create-puck [player]
  (let [puck-texture (texture (str "player-" player ".png"))]
    (.setFilter (texture! puck-texture :get-texture) Texture$TextureFilter/Linear)
    puck-texture))
"\tat elemental.entities.puck$create_puck.invoke(/Users/jamtru/Projects/clojure/elemental/desktop/src-common/elemental/entities/puck.clj:12)"
"\tat elemental.entities.piece$create_piece.invoke(piece.clj:32)"
"\tat clojure.core$map$fn__4245.invoke(core.clj:2557)"
"\tat clojure.lang.LazySeq.sval(LazySeq.java:40)"
"\tat clojure.lang.LazySeq.seq(LazySeq.java:49)"
"\tat clojure.lang.RT.seq(RT.java:484)"
"\tat clojure.core$seq.invoke(core.clj:133)"
"\tat clojure.core$concat$cat__3957$fn__3958.invoke(core.clj:694)"
"\tat clojure.lang.LazySeq.sval(LazySeq.java:40)"
"\tat clojure.lang.LazySeq.seq(LazySeq.java:56)"
"\tat clojure.lang.ChunkedCons.chunkedNext(ChunkedCons.java:59)"
"\tat clojure.lang.ChunkedCons.next(ChunkedCons.java:43)"
"\tat clojure.lang.RT.next(RT.java:598)"
"\tat clojure.core$next.invoke(core.clj:64)"
"\tat clojure.core$some.invoke(core.clj:2515)"
"\tat elemental.pieces$piece_with_id.invoke(pieces.clj:21)"
"\tat elemental.replays$replay_event.invoke(replays.clj:10)"
"\tat clojure.core.protocols$fn__6086.invoke(protocols.clj:143)"
"\tat clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)"
"\tat clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)"
"\tat clojure.core.protocols$fn__6078.invoke(protocols.clj:54)"
"\tat clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)"
"\tat clojure.core$reduce.invoke(core.clj:6289)"
"\tat elemental.replays$replay_to_turn.invoke(replays.clj:25)"
"\tat elemental.core$eval6544$fn__6564.invoke(/Users/jamtru/Projects/clojure/elemental/desktop/src-common/elemental/core.clj:30)"
"\tat clojure.lang.Var.invoke(Var.java:383)"
"\tat play_clj.core$defscreen_STAR_$execute_fn_BANG___884$fn__887.invoke(core.clj:73)"
"\tat clojure.lang.AFn.applyToHelper(AFn.java:152)"
"\tat clojure.lang.AFn.applyTo(AFn.java:144)"
"\tat clojure.lang.AFunction$1.doInvoke(AFunction.java:29)"
"\tat clojure.lang.RestFn.invoke(RestFn.java:397)"
"\tat elemental.utilities.exceptions$fn__1655.invoke(exceptions.clj:18)"
"\tat play_clj.core$defscreen_STAR_$execute_fn_BANG___884.doInvoke(core.clj:75)"
"\tat clojure.lang.RestFn.invoke(RestFn.java:410)"
"\tat play_clj.core$defscreen_STAR_$fn__905.invoke(core.clj:97)"
"\tat clojure.lang.AFn.applyToHelper(AFn.java:152)"
"\tat clojure.lang.AFn.applyTo(AFn.java:144)"
"\tat clojure.core$apply.invoke(core.clj:624)"
"\tat play_clj.core$set_screen_BANG_$run_fn_BANG___928.doInvoke(core.clj:452)"
"\tat clojure.lang.RestFn.invoke(RestFn.java:410)"
"\tat play_clj.core$set_screen_BANG_$reify__936.show(core.clj:457)"
"\tat com.badlogic.gdx.Game.setScreen(Game.java:61)"
"\tat play_clj.core.proxy$com.badlogic.gdx.Game$ff19274a.setScreen(Unknown Source)"
"\tat play_clj.core$set_screen_BANG_.doInvoke(core.clj:453)"
"\tat clojure.lang.RestFn.invoke(RestFn.java:423)"
"\tat elemental.core$eval6544$fn__6580$fn__6581.invoke(/Users/jamtru/Projects/clojure/elemental/desktop/src-common/elemental/core.clj:46)"
"\tat clojure.lang.AFn.run(AFn.java:22)"
"\tat com.badlogic.gdx.backends.lwjgl.LwjglApplication.executeRunnables(LwjglApplication.java:237)"
"\tat com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:192)"
"\tat com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)"
oakes commented 10 years ago

Strange error message, but one mistake I made is that setFilter has two arguments, not one. So try this out:

(.setFilter (texture! puck-texture :get-texture) Texture$TextureFilter/Linear Texture$TextureFilter/Linear)
Misophistful commented 10 years ago

The extra argument fixed the error, and the linear filter makes the rotated texture look superb - thanks!