Я пытаюсь взять пример 3D вращающейся обезьяны Киви и применить к нему текстуру.
Кажется, что метод графического контекста Киви "BindTexture()
метод должен сделать свое дело, но это, похоже, не имеет никакого эффекта. Я изменил пример, включив в него метод "BindTexture ()" в методе init (). Я также изменил код включения шейдера в текстуре.
Кажется, что я ' Нам удалось передать координаты текстуры в шейдер просто отлично, потому что когда я рендеринг использую только координаты текстуры в качестве значений цвета (используя строку комментария рядом с концом кода шейдера), я получаю разноцветный объект. Однако, когда я размещаю эту текстуру координаты внутри вызова texture2D (), объект отображается без текстуры вообще.
Согласно BindTexture docs:
Инструкция BindTexture будет свяжите текстуру и включите GL_TEXTURE_2D для последующего рисования.
Так что, похоже, это должно быть довольно просто, но я явно скучаю по чему-то Хин.
Я новичок в Kivy и OpenGL. Одна из вещей, с которой я действительно борюсь, это как передать значения во входные переменные в шейдерном коде GL. Например, в моем коде шейдера переменная "texture0" используется для рассматриваемой текстуры - однако я не уверен, как это будет отображаться в моей текстуре. На основании некоторых примеров, которые я видел, например, мультитекстура Киви , кажется, что «BindTexture ()» должен позаботиться об этом, но мне немного неловко, что все это похоже на черных магов c мне прямо сейчас.
main.py:
from kivy.clock import Clock
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.graphics import RenderContext, Color, Rectangle, BindTexture
class Renderer(Widget):
def __init__(self, **kwargs):
self.canvas = RenderContext(compute_normal_mat=True)
# self.canvas.shader.source = resource_find('default.glsl')
self.canvas.shader.source = resource_find('simple.glsl')
self.scene = ObjFile(resource_find("monkey.obj"))
BindTexture(source='mtexture2.png')
super(Renderer, self).__init__(**kwargs)
with self.canvas:
self.cb = Callback(self.setup_gl_context)
PushMatrix()
self.setup_scene()
PopMatrix()
self.cb = Callback(self.reset_gl_context)
BindTexture(source='mtexture2.png')
self.canvas['texture0'] = 0
Clock.schedule_interval(self.update_glsl, 1 / 60.)
def setup_gl_context(self, *args):
glEnable(GL_DEPTH_TEST)
def reset_gl_context(self, *args):
glDisable(GL_DEPTH_TEST)
def update_glsl(self, delta):
asp = self.width / float(self.height)
proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1)
# Color(1,0,0)
self.canvas['projection_mat'] = proj
self.canvas['diffuse_light'] = (1.0, 0.0, 0.8)
self.canvas['ambient_light'] = (0.1, 0.1, 0.1)
self.rot.angle += delta * 100
def setup_scene(self):
Color(1, 1, 1)
PushMatrix()
Translate(0, -2.5, -8)
self.rot = Rotate(1, 0, 1, 0)
UpdateNormalMatrix()
for m in list(self.scene.objects.values()):
self.mesh = Mesh(
vertices=m.vertices,
indices=m.indices,
fmt=m.vertex_format,
mode='triangles',
)
PopMatrix()
class RendererApp(App):
def build(self):
return Renderer()
if __name__ == "__main__":
RendererApp().run()
Код шейдера "simple.glsl":
/* simple.glsl
simple diffuse lighting based on laberts cosine law; see e.g.:
http://en.wikipedia.org/wiki/Lambertian_reflectance
http://en.wikipedia.org/wiki/Lambert%27s_cosine_law
*/
---VERTEX SHADER-------------------------------------------------------
#ifdef GL_ES
precision highp float;
#endif
/* Vertex attributes/inputs, defined in MeshData Object */
attribute vec3 v_pos;
attribute vec3 v_normal;
attribute vec2 v_tc0;
/* Outputs to the fragment shader */
varying vec2 tex_coord0;
varying vec4 normal_vec;
varying vec4 vertex_pos;
uniform mat4 modelview_mat;
uniform mat4 projection_mat;
void main (void) {
//compute vertex position in eye_space and normalize normal vector
vec4 pos = modelview_mat * vec4(v_pos,1.0);
vertex_pos = pos;
normal_vec = vec4(v_normal,0.0);
gl_Position = projection_mat * pos;
tex_coord0 = v_tc0;
}
---FRAGMENT SHADER-----------------------------------------------------
#ifdef GL_ES
precision highp float;
#endif
/* Outputs from Vertex Shader */
varying vec4 normal_vec;
varying vec4 vertex_pos;
varying vec2 tex_coord0;
uniform sampler2D texture0;
uniform mat4 normal_mat;
void main (void){
//correct normal, and compute light vector (assume light at the eye)
vec4 v_normal = normalize( normal_mat * normal_vec ) ;
vec4 v_light = normalize( vec4(0,0,0,1) - vertex_pos );
//reflectance based on lamberts law of cosine
float theta = clamp(dot(v_normal, v_light), 0.0, 1.0);
//gl_FragColor = vec4(theta, theta, theta, 1.0)*vec4(tex_coord0, 1, 1);
gl_FragColor = vec4(theta, theta, theta, 1.0)*texture2D(texture0, tex_coord0);
}