Я могу отображать три текстуры одинаково на элементе управления OpenGL, используя приведенный ниже код.Элемент управления OpenGL находится в нижней части экрана (высота равна половине высоты экрана, а ширина равна ширине экрана).Но, похоже, в OpenGL Control отсутствует соотношение сторон изображений.Большая часть моего кода вставлена здесь.Подскажите, пожалуйста, в чем причина проблемы?
this.glControl1.BackColor = System.Drawing.Color.Blue;
this.glControl1.Location = new System.Drawing.Point(13, 412);
this.glControl1.Margin = new System.Windows.Forms.Padding(0);
this.glControl1.Name = "glControl1";
this.glControl1.Size = new System.Drawing.Size(469, 285);
this.glControl1.TabIndex = 8;
this.glControl1.VSync = false;
float[] vertices = {
// Left bottom triangle
-1f, -1f, 0f,
1f, -1f, 0f,
1f, 1f, 0f,
// Right top triangle
1f, 1f, 0f,
-1f, 1f, 0f,
-1f, -1f, 0f
};
int texSizeLoc;
int texSize1Loc;
int texSize2Loc;
public PlaywithTripleCam()
{
InitializeComponent();
this.SizeChanged += new EventHandler(PlaywithTripleCam_SizeChanged);
//ScreenWidth = Screen.PrimaryScreen.Bounds.Width;
//ScreenHeight = Screen.PrimaryScreen.Bounds.Height;
ScreenWidth = this.Width;
ScreenHeight = this.Height;
screenaspectratio =(float) ScreenWidth /(float) ScreenHeight;
//code for showing camera device list in three combo box
}
private void TripleCam_SizeChanged(object sender, EventArgs e)
{
glControl1.Width = this.Width;
glControl1.Height = this.Height / 2;
}
private void PlayButton_Click(object sender, EventArgs e)
{
StartPlaying();
GL.ClearColor(Color.MidnightBlue);
GL.Enable(EnableCap.DepthTest);
TexUtil.InitTexturing();
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
GL.DepthFunc(DepthFunction.Lequal);
GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse);
GL.Enable(EnableCap.ColorMaterial);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // render per default onto screen, not some FBO
glControl1.Resize += new EventHandler(glControl1_Resize);
glControl1.Paint += new PaintEventHandler(glControl1_Paint);
Application.Idle += Application_Idle;
// Ensure that the viewport and projection matrix are set correctly.
glControl1_Resize(glControl1, EventArgs.Empty);
}
private void Application_Idle(object sender, EventArgs e)
{
while (glControl1.IsIdle)
{
Render();
}
}
public void Render()
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); // use the visible framebuffer
if (videoFrame != null)
lock (videoFrame)
{
if (videoTexture != -1)
GL.DeleteTextures(1, ref videoTexture);
videoTexture = LoadTexture(videoFrame);
videoFrame.Dispose();
videoFrame = null;
}
GC.Collect();
if (videoFrame2 != null)
lock (videoFrame2)
{
if (videoTexture2 != -1)
GL.DeleteTextures(1, ref videoTexture2);
videoTexture2 = LoadTexture(videoFrame2);
videoFrame2.Dispose();
videoFrame2 = null;
}
GC.Collect();
if (videoFrame3!= null)
lock (videoFrame3)
{
if (videoTexture3 != -1)
GL.DeleteTextures(1, ref videoTexture3);
videoTexture3 = LoadTexture(videoFrame3);
videoFrame3.Dispose();
videoFrame3 = null;
}
GC.Collect();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
DrawImage(videoTexture, videoTexture2, videoTexture3);
}
private void CreateShaders()
{
/***********Vert Shader********************/
vertShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertShader, @"attribute vec3 a_position;
varying vec2 vTexCoordIn;
void main() {
vTexCoordIn=( a_position.xy+1)/2;
gl_Position = vec4(a_position,1);
}");
GL.CompileShader(vertShader);
/***********Frag Shader ****************/
fragShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragShader, @"
uniform sampler2D sTexture;
uniform sampler2D sTexture1;
uniform sampler2D sTexture2;
uniform vec2 sTexSize;
uniform vec2 sTexSize1;
uniform vec2 sTexSize2;
varying vec2 vTexCoordIn;
void main ()
{
vec2 vTexCoord=vec2(vTexCoordIn.x,vTexCoordIn.y);
if ( vTexCoord.x < 1.0/3.0 )
{
vec2 uv = vec2(vTexCoord.x * 3.0, vTexCoord.y);
uv.y *= sTexSize.x / sTexSize.y;
if (uv.y > 1.0)
discard;
gl_FragColor = texture2D(sTexture, uv);
}
else if ( vTexCoord.x >= 1.0/3.0 && vTexCoord.x < 2.0/3.0 )
{
vec2 uv = vec2(1.0-(vTexCoord.x * 3.0 - 1.0), vTexCoord.y);
uv.y *= sTexSize1.x / sTexSize1.y;
if (uv.y > 1.0)
discard;
gl_FragColor = texture2D(sTexture1, uv);
}
else if ( vTexCoord.x >= 2.0/3.0 )
{
vec2 uv = vec2(vTexCoord.x * 3.0 - 2.0, vTexCoord.y);
uv.y *= sTexSize2.x / sTexSize2.y;
if (uv.y > 1.0)
discard;
gl_FragColor = texture2D(sTexture2, uv);
}}");
GL.CompileShader(fragShader);
}
public void DrawImage(int image, int image1,int image2)
{
GL.Viewport(new Rectangle(0, 0, this.Width, this.Height / 2));
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
GL.LoadIdentity();
GL.MatrixMode(MatrixMode.Modelview);
GL.PushMatrix();
GL.LoadIdentity();
GL.Disable(EnableCap.Lighting);
GL.Enable(EnableCap.Texture2D);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, image);
GL.Uniform1(positionLocation1, 0);
GL.ActiveTexture(TextureUnit.Texture1);
GL.BindTexture(TextureTarget.Texture2D, image1);
GL.Uniform1(positionLocation2, 1);
GL.ActiveTexture(TextureUnit.Texture2);
GL.BindTexture(TextureTarget.Texture2D, image2);
GL.Uniform1(positionLocation3, 2);
if(videoFrame !=null )
{
float texW = videoFrame.Width;
float texH = videoFrame.Height;
GL.Uniform2(texSizeLoc, texW, texH);
}
if (videoFrame2 != null)
{
float tex1W = videoFrame2.Width;
float tex1H = videoFrame2.Height;
GL.Uniform2(texSize1Loc, tex1W, tex1H);
}
if (videoFrame3 != null)
{
float tex2W = videoFrame3.Width;
float tex2H = videoFrame3.Height;
GL.Uniform2(texSize2Loc, tex2W, tex2H);
}
GL.Begin(PrimitiveType.Quads);
GL.TexCoord2(0, 1);
GL.Vertex3(0, 0, 0);
GL.TexCoord2(0, 0);
GL.Vertex3(1920, 0, 0);
GL.TexCoord2(1, 1);
GL.Vertex3(1920, 1080, 0);
GL.TexCoord2(1, 0);
GL.Vertex3(0, 1080, 0);
GL.End();
RunShaders();
GL.Disable(EnableCap.Texture2D);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Modelview);
ErrorCode ec = GL.GetError();
if (ec != 0)
System.Console.WriteLine(ec.ToString());
Console.Read();
glControl1.SwapBuffers();
}
private void RunShaders()
{
GL.UseProgram(program);
GL.DrawArrays(PrimitiveType.Triangles, 0, vertices.Length / 3);
ErrorCode ec = GL.GetError();
if (ec != 0)
System.Console.WriteLine(ec.ToString());
Console.Read();
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
Render();
}
private void glControl1_Resize(object sender, EventArgs e)
{
Init();
}
private void Init()
{
CreateShaders();
CreateProgram();
InitBuffers();
}
private void CreateProgram()
{
program = GL.CreateProgram();
GL.AttachShader(program, vertShader);
GL.AttachShader(program, fragShader);
GL.LinkProgram(program);
}
private void InitBuffers()
{
buffer = GL.GenBuffer();
positionLocation = GL.GetAttribLocation(program, "a_position");
positionLocation1 = GL.GetUniformLocation(program, "sTexture");
positionLocation2 = GL.GetUniformLocation(program, "sTexture1");
positionLocation3 = GL.GetUniformLocation(program, "sTexture2");
texSizeLoc = GL.GetUniformLocation(program, "sTexSize");
texSize1Loc = GL.GetUniformLocation(program, "sTexSize1");
texSize2Loc = GL.GetUniformLocation(program, "sTexSize2");
GL.EnableVertexAttribArray(positionLocation);
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 0, 0);
}
public int LoadTexture(Bitmap bitmap)
{
int tex = -1;
if (bitmap != null)
{
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
GL.GenTextures(1, out tex);
GL.BindTexture(TextureTarget.Texture2D, tex);
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
bitmap.UnlockBits(data);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
}
return tex;
}