/// <summary> /// Texture loading /// </summary> public void loadShaderMaps(shader_p surface, shader_gl shader) { if (shader.sky == true) { q3bsp.skybox_env = skybox.loadFromShader(surface, shader); } for (int i = 0; i < shader.stages.Count; ++i) { stage_gl stage = shader.stages[i]; stage.shaderName = shader.name; if (stage.map != null) { loadTexture(shader, surface, stage); } if (stage.shaderSrc != null && stage.program == null) { Console.WriteLine("Compiling " + shader.name); //fetch_update("Compiling " + shader.name); stage.program = compileShaderProgram(stage.shaderSrc.vertex.source_code, stage.shaderSrc.fragment.source_code); } } }
public void loadTexture(shader_gl shader, shader_p surface, stage_gl stage) { int i; if (shader.sky) { Console.WriteLine("[skybox] {0}", shader.name); } if (stage.map == null) { stage.texture = white; return; } else if (stage.map.Contains("$lightmap")) { stage.texture = (surface.geomType != 3 ? q3bsp.lightmap : white); return; } else if (stage.map.Contains("$whiteimage")) { stage.texture = white; return; } stage.texture = defaultTexture; if (stage.map == "anim") { stage.animTexture = new List <int>(); for (i = 0; i < stage.animMaps.Count; ++i) { if (i > stage.animTexture.Count - 1) { stage.animTexture.Add(defaultTexture); } string url = Config.q3bsp_base_folder + "/" + stage.animMaps[i]; loadTextureUrl(stage, url, (int texture) => { stage.animTexture.Insert(i, texture); }); } stage.animFrame = 0; } else { if (shader.sky == false) { string url = Config.q3bsp_base_folder + "/" + stage.map; loadTextureUrl(stage, url, (int texture) => { stage.texture = texture; }); } } }
public shader_gl buildDefault(shader_p surface) { stage_gl diffuseStage = new stage_gl(); diffuseStage.map = (surface != null ? surface.shaderName + ".jpg" : null); diffuseStage.isLightmap = false; diffuseStage.blendSrc = (int)BlendingFactorSrc.One; diffuseStage.blendDest = (int)BlendingFactorDest.Zero; diffuseStage.depthFunc = DepthFunction.Lequal; diffuseStage.depthWrite = true; shader_gl glShader = new shader_gl(); glShader.cull = CullFaceMode.Front; glShader.blend = false; glShader.sort = 3; glShader.stages = (new stage_gl[] { diffuseStage }).ToList(); glShader.sky = false; if (surface != null) { loadTexture(glShader, surface, diffuseStage); } else { diffuseStage.texture = defaultTexture; } return(glShader); }
public static skybox loadFromShader(shader_p surface, shader_gl shader) { skybox sky = new skybox(); var context = new OpenTK.Graphics.GraphicsContext(AlethaApplication.GraphicsMode, AlethaApplication.NativeWindowContext.WindowInfo); context.MakeCurrent(AlethaApplication.NativeWindowContext.WindowInfo); // determine type of skybox: number of textures to load //sky.type = skybox_type.one_tex; buildSkyboxbuffers(); loadSkyTexture(shader, surface, (int texture) => { //.skymap = texture; }, (int texture) => { sky.skymap = texture; //GL.GenerateMipmap(GenerateMipmapTarget.TextureCubeMap); }); return(sky); }
public static void loadSkyTexture(shader_gl shader, shader_p surface, OnTextueLoad onTextureLoading, OnTextueLoad onTextureLoadComplete) { bool has_skyparams = shader.sky_env_map != null; if (has_skyparams) { // hard code in six or one texture mode for now String url = Config.q3bsp_base_folder + "/" + shader.sky_env_map.@params; String back_url = url + "_bk.jpg"; String down_url = url + "_dn.jpg"; String front_url = url + "_ft.jpg"; String left_url = url + "_lf.jpg"; String right_url = url + "_rt.jpg"; String up_url = url + "_up.jpg"; cubemap_texture_six.load(back_url, down_url, front_url, left_url, right_url, up_url, (int texture) => { onTextureLoading(texture); }, (int texture) => { onTextureLoadComplete(texture); }); //TODO: support for single texture mode using something like this. need to find test map. // cubemap_texture_one.load(back_url, gl, // (GLTexture texture) // { // onTextureLoading(texture); // }, // (GLTexture texture) // { // onTextureLoadComplete(texture); // }); //cubemap_texture_one.load(q3bsp_base_folder + '/' + stage.map, gl, null, onTextureLoadComplete); } else { //UNTESTED condition } }
public ShaderCompiler() { white = -1; defaultShader = null; defaultTexture = -1; texMat = Matrix4.Identity; // mat4.create() defaultProgram = null; //defaultShader = buildDefault(null); //defaultProgram = compileShaderProgram(Config.q3bsp_default_vertex, Config.q3bsp_default_fragment); }
/// <summary> /// Shader building /// </summary> public shader_gl build(shader_t shader, shader_p surface) { if (shader == null) { return(null); } shader_gl glShader = new shader_gl(); glShader.cull = translateCull(shader.cull); glShader.sort = shader.sort; glShader.sky = shader.sky; glShader.blend = shader.blend; glShader.name = shader.name; glShader.sky_env_map = shader.sky_env_map; glShader.stages = new List <stage_gl>(); for (int j = 0; j < shader.stages.Count; ++j) { stage_t t = shader.stages[j]; stage_gl s = new stage_gl(); //s.animFrame = t.animFrame; s.animFreq = t.animFreq; s.animMaps = t.animMaps; //s.animTexture = t.animTexture; s.texture = -1; s.blendSrc = translateBlendSrc(t.blendSrc); s.blendDest = translateBlendDest(t.blendDest); s.depthFunc = translateDepthFunc(t.depthFunc); s.map = t.map; s.tcMods = t.tcMods; s.depthWrite = t.depthWrite; s.isLightmap = t.isLightmap; s.shaderSrc = t.shaderSrc; s.clamp = t.clamp; s.tcGen = t.tcGen; s.rgbGen = t.rgbGen; s.rgbWaveform = t.rgbWaveform; s.alphaGen = t.alphaGen; s.alphaFunc = t.alphaFunc; s.alphaWaveform = t.alphaWaveform; s.hasBlendFunc = t.hasBlendFunc; s.depthWriteOverride = t.depthWriteOverride; s.blend = t.blend; s.opaque = t.opaque; glShader.stages.Add(s); } return(glShader); }
/// <summary> /// Render state setup /// </summary> public bool setShader(shader_gl shader) { if (shader == null) { GL.Enable(EnableCap.CullFace); GL.CullFace(CullFaceMode.Back); } else if (shader.cull.HasValue && shader.sky == false) { GL.Enable(EnableCap.CullFace); GL.CullFace(shader.cull.Value); } else { GL.Disable(EnableCap.CullFace); } return(true); }
public static void buildShaders(List <shader_t> shaders) { q3bsp.shaders = new Dictionary <string, shader_gl>(); for (var i = 0; i < shaders.Count; ++i) { shader_t shader = shaders[i]; if (shader == null) { continue; } shader_gl glShader = q3bsp.glshading.build(shader, null); String shader_name = shader.name; q3bsp.shaders[shader_name] = glShader; } }
public shader_prog_t setShaderStage_EffectDEBUG(shader_gl shader, stage_gl shaderStage, float time) { shader_prog_t program; stage_gl stage = shaderStage; if (stage == null) { stage = defaultShader.stages[0]; } if (stage.animFreq.HasValue && stage.animFreq != 0) { // Texture animation seems like a natural place for setInterval, but that approach has proved error prone. // It can easily get out of sync with other effects (like rgbGen pulses and whatnot) which can give a // jittery or flat out wrong appearance. Doing it this way ensures all effects are synced. float ff = time * (float)stage.animFreq.Value; //var animFrame = ff.floor() % stage.animTexture.length; stage.texture = stage.animTexture[stage.animFrame]; // stage.animTexture.animFrame; } GL.BlendFunc((BlendingFactorSrc)stage.blendSrc, (BlendingFactorDest)stage.blendDest); if (stage.depthWrite == true && shader.sky == false) { GL.DepthMask(true); } else { GL.DepthMask(false); } GL.DepthFunc(stage.depthFunc); program = stage.program; int prog = program != null ? program.program : -1; if (prog == -1) { if (shader.model == true) { program = modelProgram; prog = program.program; } else { program = defaultProgram; prog = program.program; } } //program = defaultProgram; //prog = program.program; GL.UseProgram(prog); if (shader.sky == true) { //q3bsp.skybox_env.bindSkyTexture(stage, program, time); //var a = 3; } else { int texture = stage.texture; if (texture == -1) { texture = defaultTexture; } //texture = defaultTexture; GL.ActiveTexture(TextureUnit.Texture0); if (program.uniform.ContainsKey("texture")) { GL.Uniform1(program.uniform["texture"], 0); } GL.BindTexture(TextureTarget.Texture2D, texture); } if (program.uniform.ContainsKey("lightmap")) { GL.ActiveTexture(TextureUnit.Texture1); GL.Uniform1(program.uniform["lightmap"], 1); GL.BindTexture(TextureTarget.Texture2D, q3bsp.lightmap); } if (program.uniform.ContainsKey("time")) { GL.Uniform1(program.uniform["time"], time); } return(program); }
public void init() { white = createSolidTexture(new Vector4(255, 255, 255, 0)); //white = createSolidTexture(gl, [0,0,0,255]); defaultProgram = compileShaderProgram(Config.q3bsp_default_vertex, Config.q3bsp_default_fragment); modelProgram = compileShaderProgram(Config.q3bsp_default_vertex, Config.q3bsp_model_fragment); // Load default texture texture.fetch_texture(Config.q3bsp_no_shader_default_texture_url, (int defau) => { defaultTexture = defau; }, (int defau, Bitmap image) => { bool isPowerOf2 = false; BitmapData pixelData; Rectangle boundingbox; boundingbox = new Rectangle(0, 0, image.Width, image.Height); pixelData = image.LockBits(boundingbox, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.BindTexture(TextureTarget.Texture2D, defau); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte, pixelData.Scan0); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (isPowerOf2 ? (int)TextureMinFilter.LinearMipmapNearest : (int)TextureMinFilter.Linear)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); if (isPowerOf2) { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } image.UnlockBits(pixelData); }); texture.fetch_texture(Config.q3bsp_no_shader_default_texture_url2, (int defau) => { defaultTextureRed = defau; }, (int defau, Bitmap image) => { bool isPowerOf2 = false; BitmapData pixelData; Rectangle boundingbox; boundingbox = new Rectangle(0, 0, image.Width, image.Height); pixelData = image.LockBits(boundingbox, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.BindTexture(TextureTarget.Texture2D, defau); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte, pixelData.Scan0); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (isPowerOf2 ? (int)TextureMinFilter.LinearMipmapNearest : (int)TextureMinFilter.Linear)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); if (isPowerOf2) { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } }); // Load default stage defaultShader = buildDefault(null); }
public void Render(float time, Viewport leftViewport, Matrix4 leftViewMat, Matrix4 leftProjMat) { //q3bsp.skybox_env.bindSkyTexture(gl, stage, program, time); // Loop through all shaders, drawing all surfaces associated with them if (q3bsp.surfaces.Count > 0) { shader_gl shader = skyShader == null ? q3bsp.glshading.defaultShader : skyShader; // If we have a skybox, render it first if (shader != null && skyboxIndexBuffer != -1 && skyboxBuffer != -1) { //bindSkySingleTexture(time); // SkyBox Buffers GL.BindBuffer(BufferTarget.ElementArrayBuffer, skyboxIndexBuffer); GL.BindBuffer(BufferTarget.ArrayBuffer, skyboxBuffer); // Render Skybox if (q3bsp.glshading.setShader(shader)) { stage_gl stage; shader_prog_t shaderProgram; for (int j = 0; j < shader.stages.Count; ++j) { stage = shader.stages[j]; shaderProgram = q3bsp.glshading.setShaderStage(shader, stage, time); if (shaderProgram == null) { continue; } skybox.bindSkyAttribs(shaderProgram); // Draw Sky geometry skybox.bindSkyMatrix(shaderProgram, leftViewMat, leftProjMat); q3bsp.setViewport(leftViewport); //GL.DrawElements(RenderingContext.TRIANGLES, skyboxIndexCount, RenderingContext.UNSIGNED_SHORT, 0); GL.DrawElements(BeginMode.Triangles, skyboxIndexCount, DrawElementsType.UnsignedShort, 0); } if (shader.stages.Count == 0) { // NO SHADER for sky so use default shader if possible shaderProgram = q3bsp.glshading.defaultProgram; GL.UseProgram(shaderProgram.program); //bindSkyTexture(null, shaderProgram, time); if (shaderProgram.uniform.ContainsKey("texture")) { GL.Uniform1(shaderProgram.uniform["texture"], 0); } bindSkySingleTexture(time); skybox.bindSkyAttribs(shaderProgram); skybox.bindSkyMatrix(shaderProgram, leftViewMat, leftProjMat); //q3bsp.setViewport(leftViewport); GL.Disable(EnableCap.DepthTest); //bindSkySingleTexture(time); GL.DrawElements(BeginMode.Triangles, skyboxIndexCount, DrawElementsType.UnsignedShort, 0); GL.Enable(EnableCap.DepthTest); } } } } }