PDA

View Full Version : I need some help with 2D drawing libraries



jonharkulsykkel
17-10-2010, 10:12 AM
ok so i making a game in delphi and every frame it needs to render about 1200 16x16 images, then 1200 alpha blended pics then a dude. i was first using delphix which works fine, but the alpha blending is ultra slow. so i tried opengl, which didnt draw the 2D images correctly, they became all blury, tried for 5 hours to get it to work and disabeld billinear interpolation and stuff but that just made the image blocky and ugly. i also tried andorra, but that turned out to work slower than delphix (?? ? ?? ?? ? ?)
:(:(:(:(
anyone have an idea of wat library i shud use? or how to get opengl to draw 2D stuff correctly? or make andorra go faster
or delphix

thx

Andru
17-10-2010, 06:43 PM
or how to get opengl to draw 2D stuff correctly?
Can I see your code? There are many reasons why you can get this... I can enumerate next:
- textures created with mipmap
- wrong texture coordinates
- position of sprites are with float values

About Andorra - maybe you used it in wrong way... or maybe Andorra's sprite engine too slow for so much sprites :)

jonharkulsykkel
17-10-2010, 06:49 PM
here its:


procedure TForm1.FormCreate(Sender: TObject);
begin
DC := GetDC(Handle);
if not InitOpenGL then Application.Terminate;
RC := CreateRenderingContext(DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
ActivateRenderingContext(DC, RC);

//load textures
LoadTexture('img\char.tga', tex, false);
Timer1.Enabled := true;
end;

procedure DrawQuad(pX, pY, pZ, pWidth, pHeight:single);
begin
glBegin(GL_QUADS);
glTexCoord2f(0,1); glVertex3f(pX, pY, -pZ);
glTexCoord2f(1,1); glVertex3f(pX+pWidth, pY, -pZ);
glTexCoord2f(1,0); glVertex3f(pX+pWidth, pY+pHeight, -pZ);
glTexCoord2f(0,0); glVertex3f(pX, pY+pHeight, -pZ);
glEnd;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
DeactivateRenderingContext;
DestroyRenderingContext(RC);
ReleaseDC(Handle, DC);
end;

procedure TForm1.Render;
begin
//clear
//glClearColor(0.6, 0.7, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);


glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, ClientWidth, ClientHeight);
glOrtho(0, ClientWidth, ClientHeight, 0, -1, 1);
glDisable(GL_DEPTH_TEST);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0, 0, 0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

//sdfffdsgfhhf
DrawQuad(x, 0, 0, 320, 32);

SwapBuffers(DC);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Render;
end;

phibermon
17-10-2010, 07:06 PM
glTranslatef(0.375, 0.375, 0.0);

That is the most important line of code for 2D opengl. disable mipmapping/filtering on textures. All coordinates as integers.

pixel perfect 2D. perfect for fonts and sprites :)

jonharkulsykkel
17-10-2010, 07:09 PM
glTranslatef(0.375, 0.375, 0.0);

That is the most important line of code for 2D opengl. disable mipmapping/filtering on textures. All coordinates as integers.

pixel perfect 2D. perfect for fonts and sprites :)

i tried that too :( even with a fdsfgfgdfgload of diffrent numbers
didnt make any diffrence

Andru
17-10-2010, 07:28 PM
glTranslatef(0.375, 0.375, 0.0);
I remember "problems" only with Direct3D, when I use some offset for texture coordinates, but in OpenGL there is no problems with it. Here two screenshots:
http://img221.imageshack.us/img221/5103/normal.th.png (http://img221.imageshack.us/i/normal.png/) http://img151.imageshack.us/img151/2065/gltranslatef.th.png (http://img151.imageshack.us/i/gltranslatef.png/)

First one without glTranslatef, another one - with it.

phibermon
17-10-2010, 07:32 PM
oh it's only if you want a texture in orthographic mode to be pixel perfect. have a look at my screenshots for JUI and look at the fonts.

jonharkulsykkel
17-10-2010, 07:34 PM
but both are megablurry :0
thx for replyeis btw

Andru
17-10-2010, 07:44 PM
jonharkulsykkel
Can you show code inside LoadTexture? Because render code seems ok. And what size of your texture? If it 320x32, maybe problem that your videocard doesn't support NPOT textures correctly.

Andru
17-10-2010, 07:46 PM
oh it's only if you want a texture in orthographic mode to be pixel perfect.
Those screenshots made in demo, that use glOrho :)

phibermon
17-10-2010, 07:50 PM
unit jui_screen;

{$mode objfpc}{$H+}
{$i jui.inc}


interface

uses
sysutils, SDL,

SDL_Video,

u_gl,

JUI_const, JUI_log;

type TVideoMode = record
H : integer;
V : integer;
Bits : integer;
Fullscreen : Boolean;
end;

const
//Constant Video Mode Records, Treeitem.Data pointer asigned to these records
Mode640_16 : TVideoMode = (H:640; V:480; Bits:24; FullScreen:false;);
Mode640_16_FULL : TVideoMode = (H:640; V:480; Bits:24; FullScreen:true;);
Mode640_32 : TVideoMode = (H:640; V:480; Bits:32; FullScreen:false;);
Mode640_32_FULL : TVideoMode = (H:640; V:480; Bits:32; FullScreen:true;);

Mode800_16 : TVideoMode = (H:800; V:600; Bits:24; FullScreen:false;);
Mode800_16_FULL : TVideoMode = (H:800; V:600; Bits:24; FullScreen:true;);
Mode800_32 : TVideoMode = (H:800; V:600; Bits:32; FullScreen:false;);
Mode800_32_FULL : TVideoMode = (H:800; V:600; Bits:32; FullScreen:true;);

Mode1024_16 : TVideoMode = (H:1024; V:768; Bits:24; FullScreen:false;);
Mode1024_16_FULL : TVideoMode = (H:1024; V:768; Bits:24; FullScreen:true;);
Mode1024_32 : TVideoMode = (H:1024; V:768; Bits:32; FullScreen:false;);
Mode1024_32_FULL : TVideoMode = (H:1024; V:768; Bits:32; FullScreen:true;);
Mode1280_32_FULL : TvideoMode = (H:1280; V:1024; Bits:32; Fullscreen:true;);




type TJUIScreen = class

public
Width : integer;
Height : integer;

ProjectionMatrixGL : TGLMatrixd4;
ViewPortGL : TGLVectori4;

constructor create(WinTitle : shortstring; Xres,Yres,BPP : word;FullScreen : Boolean);
destructor destroy;override;


procedure SetOrthographic;
procedure SetOrthographicFlipY;
procedure SetOrthographic(x,y,awidth,aheight:integer);
procedure SetVideomode(Vmode:TVideoMode);

private
Screen : PSDL_Surface;
B_FullScreen : boolean;
error : boolean;
WindowTitle : string; //must be shortstring or string with $H-
WindowBPP : word;

procedure SetWindowTitle(Title:string);
procedure SetupGL; //sets up 2d ortho mode

published
{ Published declarations }
property Caption: string read WindowTitle write SetWindowTitle;

end;

implementation

constructor TJUIScreen.create(WinTitle : shortstring; Xres,Yres,BPP : word;FullScreen : Boolean);
var
I : integer;
NumDrivers : integer;
DriverName : PChar;
begin
NumDrivers := SDL_GetNumVideoDrivers;
for I := 0 to NumDrivers-1 do
begin
DriverName := SDL_GetVideoDriver(I);
JUILOG(self.classname,'SDL Video Driver : '+DriverName);
end;


JUIlog(self.classname,'Creating SDL Window...');
error := false;
Width := Xres;
Height := Yres;
WindowBPP := BPP;


if FullScreen then
screen := SDL_SetVideoMode(Width, Height, WindowBPP, SDL_OPENGL or SDL_ANYFORMAT or SDL_FULLSCREEN) //create the surface
else
screen := SDL_SetVideoMode(Width, Height, WindowBPP, SDL_OPENGL or SDL_ANYFORMAT {or SDL_NOFRAME or SDL_VIDEORESIZE}); //create the surface

if not assigned(screen) then
begin
JUIlog(self.classname,'Couldn''t create a surface: '+SDL_GetError());
error := true;
exit;
end;

SetWindowTitle(WinTitle);


JUIlogdone;


initopengl;
ReadImplementationProperties;
ReadExtensions;


if not error then SetupGL;

end;

destructor TJUIScreen.destroy;
begin
inherited;
end;

procedure TJUIScreen.SetOrthographic;
begin
glViewport( 0, 0, Width, Height );
//glGetIntegerv(GL_VIEWPORT, @viewportGL); //CALLING THIS IS *SLOW*!
glMatrixMode( GL_PROJECTION );
glLoadIdentity;
glOrtho( 1, Width+1, Height+1, 1, -1.0, 1.0 );
glmatrixmode(GL_TEXTURE);
glloadidentity();
glmatrixmode(GL_MODELVIEW);
glloadidentity();
glTranslatef(0.375, 0.375, 0.0);
end;


procedure TJUIScreen.SetOrthographicFlipY;
begin
glViewport( 0, 0, Width, Height );
//glGetIntegerv(GL_VIEWPORT, @viewportGL); //CALLING THIS IS *SLOW*!

glMatrixMode( GL_PROJECTION );

glLoadIdentity;
glOrtho( 1, Width+1, 1, Height+1, -1.0, 1.0 );

glmatrixmode(GL_TEXTURE);
glloadidentity();

glmatrixmode(GL_MODELVIEW);

glloadidentity();
glTranslatef(0.375, 0.375, 0.0);
end;

procedure TJUIScreen.SetOrthographic(x,y,awidth,aheight:inte ger);
begin
glViewport( x, -y+Height-aheight, awidth, aheight ); // we flip our y coord upside down to match everything else
//glGetIntegerv(GL_VIEWPORT, @viewportGL); //CALLING THIS IS *SLOW*!
glMatrixMode( GL_PROJECTION );
glLoadIdentity;
glOrtho( 1, awidth+1, aheight+1, 1, -1.0, 1.0 );

glmatrixmode(GL_TEXTURE);
glloadidentity();
glmatrixmode(GL_MODELVIEW);
glloadidentity();
glTranslatef(0.375, 0.375, 0.0);

end;




procedure TJUIScreen.SetVideomode(Vmode:TVideoMode); // NOTE THIS DESTROYS AND RECREATES OUR OPENGL CONTEXT, ALL TEXTURES MUST BE RELOADED INCLUDING FONTS
begin

Width := vmode.H;
Height := vmode.V;
WindowBPP := vmode.Bits;
B_Fullscreen := vmode.Fullscreen;

//if we toggle fullscreen we MUST restore the original width and height
if B_Fullscreen then
begin
screen := SDL_SetVideoMode(Width, Height, WindowBPP, SDL_OPENGL or SDL_ANYFORMAT or SDL_FULLSCREEN); //create the surface
JUIlog(classname,'Setting FullScreen Mode - X:'+inttostr(Width) + ' Y:' + inttostr(Height)+' Depth:'+inttostr(WindowBPP));
end else
begin
screen := SDL_SetVideoMode(Width, Height, WindowBPP, SDL_OPENGL or SDL_ANYFORMAT); //create the surface
JUIlog(classname,'Setting windowmode Mode - X:'+inttostr(Width) + ' Y:' + inttostr(Height)+' Depth:'+inttostr(WindowBPP));
end;

SetWindowTitle(WindowTitle);
SetupGL; //this must be called because our window is destroyed and re-created, the context along with it
end;

procedure TJUIScreen.SetWindowTitle(Title:string);
begin
WindowTitle := Title;
SDL_WM_SetCaption(pchar(WindowTitle),pchar(WindowT itle)); //set the window title
end;

procedure TJUIScreen.SetupGL; //this section contains all OpenGL init stuff
var
GlobalAmbient: array[0..3] of glFloat = (0.1, 0.1, 0.1, 1); // Global Ambient

begin
JUIlog(classname,'Setting up OpenGL...');

glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glClearColor(0.0, 0.0, 0.0, 1.0);
glClearDepth(1.0);

glEnable(GL_DEPTH_TEST); // Enable Depth Buffer
glDepthFunc(GL_LEQUAL);

glenable(GL_CULL_FACE);
glCullFace(GL_BACK);

glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading


JUIlogdone;
end;


end.



Please forgive the messy commenting, this unit is what I use for JUI. it will give you pixel perfect 2D Orthographic mode in OpenGL. load your texture when you load them as seen here :



function TJUITextureMan.LoadTGA(FileName : string;TextureID : integer):glint;
var
// Create storage space for the texture
NewTextureID : GLint;
texture : TTGAImage;
x : integer;
done : boolean;
begin
done := false;
if fileexists(filename) then
begin
//this ensures existing textures dont get reloaded
for x := 0 to Available do
if lowercase(Textures[x].filename) = lowercase(Filename) then
begin
done := true;
result := Textures[x].ID;
end;

if not done or reloadingtextures then
begin
texture := TTGAImage.create;
texture.LoadFromFile(FileName);

NewTextureID := GetNewTextureID(filename,TextureID);

glBindTexture(GL_TEXTURE_2D, NewTextureID);

// Generate The Texture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_NEAREST); // ( NEW )
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_NEAREST); // ( NEW )

texture.BGRtoRGB;

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );


gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA,texture.header.imgspec.width,
texture.header.imgspec.height, GL_RGBA, GL_UNSIGNED_BYTE,
texture.Data);

Result := NewTextureID;
texture.free;
end;
end else result := -1;
end;


All I can say is that it works perfectly for me.

ensure that whatever QUAD your mapping your texture to is the same size as the texture itself plus both +1 to the width and +1 to the height.

with the glTranslatef(0.375, 0.375, 0.0); you ensure that texture pixels are perfectly centered.

if you are getting distortion in the texture, it's probably because you're mapping it to a quad and have not added the pixel. I'm not sure why, I never bothered to find out, but it's somthing to do with the OpenGL rasterizer.

anyway, it's 0.375 because that value works for both ATI and Nvidia implementations, I've tested it extensivley, trust me :)

Andru
17-10-2010, 08:09 PM
phibermon
Too strange solution for me. I have never heard about it and never get problems with mine standard render code... :) Something like that(with half-pixel offset) I use only in mine Direct3D render.

User137
18-10-2010, 09:16 AM
glTranslatef(0.375, 0.375, 0.0);

That is the most important line of code for 2D opengl. disable mipmapping/filtering on textures. All coordinates as integers.

pixel perfect 2D. perfect for fonts and sprites :)
That shouldn't be the case... There was time when different graphics cards drew with a little different coordinates but i think modern cards know better to do it from 0,0.

If you draw a quad that fills the screen the coordinates are:
0,0-Width,Height
Do you see why it's not Width-1, Height-1? The same reason that if you want to draw a quad that fills 1 pixel only.
To show a pixel at 5,5 use quad coordinates 5,5 - 6,6. (Or use GL_POINTS at 5.5, 5.5)

But if you want to draw a GL_LINE on right edge:
(width-0.5, 0.5) - (width-0.5, height-0.5)
Because center of pixel is 0.5, 0.5.
A sprite for example wants to utilize the whole pixel so it starts from 0,0.

phibermon
18-10-2010, 09:07 PM
I got it from the OpenGL red-book... And I quote :

"An optimum compromise that allows all primitives to be specified at integer positions, while still ensuring predictable rasterization, is to translate x and y by 0.375, as shown in the following code fragment. Such a translation keeps polygon and pixel image edges safely away from the centers of pixels, while moving line vertices close enough to the pixel centers."

But if you want to add 0.5, on the CPU, to both components of every coordinate you send, to the GPU, be my guest :)

I'm no longer using immediate mode, will post if I find any problems getting unfiltered, pixel aligned fonts working under GL3 Core. (I may go down the vector font route if I can't figure out an elegant way to render bitmap fonts using shaders)

jonharkulsykkel
22-10-2010, 05:37 AM
but waht is this JUI thing? ;0

chronozphere
22-10-2010, 09:54 AM
It's the GUI library he's working on:

http://www.pascalgamedevelopment.com/showthread.php?6041-JUI-Another-GUI

Keep in mind that we won't give you copy-pastable sollutions to your problems. The code snippet phibermon provided is from his own library and shows the way he fixed the issue. You have to study it for yourself and then try improve your own code. :)

Ñuño Martínez
22-10-2010, 10:49 AM
ok so i making a game in delphi and every frame it needs to render about 1200 16x16 images, then 1200 alpha blended pics then a dude.
I think the problem isn't the library. You have 2401 blitting each frame, that's "too much". I'm sure you can do the same drawing less pictures.

WILL
22-10-2010, 12:21 PM
Maybe if you tell us what all these images are for we may be able to help a bit better I think. I'm guessing it's a tiled engine? That may account for the "1200 16x16 images" in which case I must ask what your game's screen resolution with 16x16 sized sprites. :) So what are the 1200 alpha blended images?

It almost seems like you are trying to swallow a whale without knowing how to... well... "fish" *ahem* pardon the expression. So lets start with what type of game it is and what gameplay features are you trying to put into it?

chronozphere
22-10-2010, 01:13 PM
I'd go down the OpenGL path if I were you. :)

So, can you provide use with a screenshot of your app. We would like to see what you are trying to do and how blurry the output actually is. :)

dazappa
23-10-2010, 01:13 AM
What function specifically are you using in andorra? (do you mean additive blending?)


for i := 0 to 2400 do
begin
gui[1].DrawAdd(AdDraw,AdRect(0,0,16,16),1,250);
end;

I can do the above with an average of 300 FPS. I think it may be your computer or drivers, unless you consider 300 fps too slow...

jonharkulsykkel
23-10-2010, 10:21 AM
heres the code i tested with andorra


//cam stuff
cx := camx div 16;
cy := camy div 16;
cxl := cx+blockw;
cyl := cy+blockh;

//update grass
updGrass := updGrass+1;
if updGrass > 60*2 then begin
updGrass := 0;
updateGrass(false);
end;

//draw blocks
for y := cy to cyl do begin
for x := cx to cxl do begin
if not(blocks[x,y,0] = 0) then begin
images.Items[1].Draw(dxdraw, (x*16)-camx, (y*16)-camy, blocks[x,y,0]-1);

blockRect.Left := (x*16)-camx;
blockRect.Top := (y*16)-camy;
blockRect.Right := blockRect.Left+16;
blockRect.Bottom := blockRect.Top+16;
images.Items[5].DrawAlpha(dxdraw, blockRect, 0, blocks[x,y,1]);
end;
end;
end;
its a tile based game yes, and it draws first all the tiles, then bllack boxes with various alpha levels to create shadows
i got a solution to some of my problems, i kinda cached all the blocks in an array with 15 diffrent light values instead of drawing alpha blended images over them. but i still need to alpha blend the sky, becus the dude will be walking there and i want him to be dark and also there will be water so i definatly need it
and here screenshot of my game (this is done in delphix) ;)
http://zworqy.com/up/files/mc2ddfsdf.png

chronozphere
23-10-2010, 02:28 PM
so i tried opengl, which didnt draw the 2D images correctly, they became all blury


The screenshot you posted looks good. What is the blurryness your talking about? :)

I don't really know delphix well. There might be a simple option you have to set to make it alot faster. Also, you should use the latest version of UnDelphiX (http://www.micrel.cz/Dx/), not the old DelphiX by hiroyuki hori which is not hardware accellerated and therefore horribly slow.

jonharkulsykkel
23-10-2010, 05:21 PM
blurriness is when i try to draw with opengl, on this screen i used latest verison of undelphix

WILL
23-10-2010, 07:03 PM
its a tile based game yes, and it draws first all the tiles, then bllack boxes with various alpha levels to create shadows
i got a solution to some of my problems, i kinda cached all the blocks in an array with 15 diffrent light values instead of drawing alpha blended images over them. but i still need to alpha blend the sky, becus the dude will be walking there and i want him to be dark and also there will be water so i definatly need it
and here screenshot of my game (this is done in delphix) ;)
http://zworqy.com/up/files/mc2ddfsdf.png

Thanks for providing this for us, this helps us a whole lot when knowing what kind of advice we can give. Scrolling platform game it is then. ;)

First thing I can say is that I know why your rendering (this term applies for 2D as well as 3D really) is so slow. It seems you are trying to alpha blend every single 16x16 square pixel of your entire screen. This is a really really slow and painful thing to do to your game. :) I think if you optimize this a little bit you'll be happier with the speed and performance of your game's code.

A good tip: The less "drawing" you do for the basic stuff in your game, ie. level tiles, character display, and so on, the more stuff you can draw to enhance your game as you polish it up. Less is more in this case.

First thing you need to do is eliminate the drawing of the biggest portion of your tiles. Usually you'd want to make your sky a single color or image (like a gradient or a long background that you can scroll gradually as you progress through the game's level) Since you have a single color for your sky I'll just assume that you can use a single color which would be faster anyways.

So in your game loop where you perform all your graphics functions you will want to do the following:



// --- graphics control start ---

ClearScreen; // beginning the next frame by clearing out the old
// <-- here is where you want to use the same color as your sky so to save
// a lot of time just color it the sky color instead of clearing to black first.

// draw your tiles, but none of your sky tiles! (NO Alpha)

// Now Draw only your tiles that need alpha.

// draw your hero character

//draw your enemies

//draw your pickups

// draw the rest...

// --- graphics control end ---


by doing this alone, you've saved a whole lot of unnecessary processing that will help you later on.

Now you mentioned something that flagged my attention. You said that you were drawing your tiles using alpha. I have to ask you aren't drawing ALL your tiles with alpha are you? Because thats not good for your game's speed either. You should try to restrict that you draw with alpha as much as you can. So I'd either separate what tiles you need to alpha blend (that actually SHOW as blended) and those you don't and only draw with alpha what you need. Just defaulting to draw everything with alpha is such a waste of processing power and keep your game running slow as ever.

One last thing you mentioned that I am curious about, you said something about making your character look darker using alpha blending for the sky? I would recommend if you aren't using some kind of effect on your character, fog or shadow effect, to just modify your character sprite. However if you insist you need to change the character's appearance during game time, just do it to your character not the whole screen. It's so wasteful to alpha draw up near the top left corner where nothing is being effected by it where all you need is to change your character's pixels only.

Also one last thing to keep in mind, the more pixels you manipulate per graphics function the more processing it takes and the slower your game overall. Also the more drawing functions you use, the more processing is required and the slower your game is. This also goes for effects. If you use alpha, rotate and scaling in a single draw function, it will be much slower than if you just draw without alpha, rotate or scaling.

Try to restrict as much unnecessary drawing functions as possible and ONLY use effects if they make a difference and this will allow you MORE speed in your games. This will help a lot.

Try this approach to your game, modify it accordingly and you should be able to achieve the same effect and get more performance out of your game. And please, let us know how it goes. :)

AthenaOfDelphi
23-10-2010, 07:11 PM
I'll just throw into the mix... if you need to use alpha blending, I would step away from UnDelphiX... I tried it for our competition entry way back in 2006 (IIRC). With no alpha, UnDelphiX was acceptable (note... I only said acceptable). With alpha, it practically ground to a halt.

I wrote a proof of concept piece to test out OpenGL and alpha blending... on the same hardware it was significantly faster (UnDelphiX managed single figure frame rates, whilst OpenGL managed triple digit frame rates).

jonharkulsykkel
28-10-2010, 08:16 AM
i have optimsized it to the max, and it doesnt alpha blend anything right now, but i will need to later :U it woud be nice if anywone cuold post a simpel opengl aplication that works without bluring the images, ive tryed everything in this thred and nothing works(