The glOrtho command produces an "Oblique" projection that you see in the bottom row. No matter how far away vertexes are in the z direction, they will not ...
Home
Public
Questions
Tags
Users
Companies
Collectives
ExploreCollectives
Teams
StackOverflowforTeams
–Startcollaboratingandsharingorganizationalknowledge.
CreateafreeTeam
WhyTeams?
Teams
CreatefreeTeam
Collectives™onStackOverflow
Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost.
LearnmoreaboutCollectives
Teams
Q&Aforwork
Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch.
LearnmoreaboutTeams
HowtouseglOrtho()inOpenGL?
AskQuestion
Asked
12years,6monthsago
Modified
1year,9monthsago
Viewed
123ktimes
103
50
Ican'tunderstandtheusageofglOrtho.Cansomeoneexplainwhatitisusedfor?
Isitusedtosettherangeofxyandzcoordinateslimit?
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
Itmeansthatthex,yandzrangeisfrom-1to1?
c++copengl
Share
Follow
editedMar11,2018at10:26
CiroSantilliOurBigBook.com
316k8989goldbadges11251125silverbadges911911bronzebadges
askedApr3,2010at13:50
ufkufk
29.5k6161goldbadges224224silverbadges371371bronzebadges
1
1
Thisvideohelpedmealot.
– ViniciusArruda
Sep14,2017at13:53
Addacomment
|
3Answers
3
Sortedby:
Resettodefault
Highestscore(default)
Trending(recentvotescountmore)
Datemodified(newestfirst)
Datecreated(oldestfirst)
164
Havealookatthispicture:GraphicalProjections
TheglOrthocommandproducesan"Oblique"projectionthatyouseeinthebottomrow.Nomatterhowfarawayvertexesareinthezdirection,theywillnotrecedeintothedistance.
IuseglOrthoeverytimeIneedtodo2DgraphicsinOpenGL(suchashealthbars,menusetc)
usingthefollowingcodeeverytimethewindowisresized:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f,windowWidth,windowHeight,0.0f,0.0f,1.0f);
ThiswillremaptheOpenGLcoordinatesintotheequivalentpixelvalues(Xgoingfrom0towindowWidthandYgoingfrom0towindowHeight).NotethatI'veflippedtheYvaluesbecauseOpenGLcoordinatesstartfromthebottomleftcornerofthewindow.Sobyflipping,Igetamoreconventional(0,0)startingatthetopleftcornerofthewindowrather.
NotethattheZvaluesareclippedfrom0to1.SobecarefulwhenyouspecifyaZvalueforyourvertex'sposition,itwillbeclippedifitfallsoutsidethatrange.Otherwiseifit'sinsidethatrange,itwillappeartohavenoeffectonthepositionexceptforZtests.
Share
Follow
editedAug13,2019at8:33
answeredApr8,2010at19:12
MikepoteMikepote
5,77522goldbadges3232silverbadges3636bronzebadges
6
2
Note:(onAndroid)evenifthemodelhasonlynegativezvalues,itseemstobenecessarytohaveapositivevalueforthefinal(far)parameter.Ididasimpletriangletest(withcullingdisabled),withverticesatz=-2.ThetrianglewasinvisibleifIusedglOrtho(..,0.0f,-4.0f);,..-1.0f,-3.0f),or..-3.0f,-1.0f).Tobevisible,thefarparameterhadtobePOSITIVE2orgreater;itdidn'tseemtomatterwhatthenearparameterwas.Anyoftheseworked:..0.0f,2.0f),..-1.0f,2.0f),..-3.0f,2.0f),or..0.0f,1000.0f.
– ToolmakerSteve
Sep9,2014at21:11
15
It'sridiculoustheamountofbadtutorialsonOpenGlthereare.
– basickarl
Nov9,2014at17:56
1
@Kari,Hopethislinkcouldhelp.>learnopengl.com/#!In-Practice/2D-Game/Rendering-Sprites
– huahsin68
Feb5,2016at2:01
Canyouexplainthezrange?
– mgouin
May30,2017at15:47
2
@mgouinThezrangespecifieswhereyourZ-nearplaneandyourZ-farplaneare.Whenyoudrawyourgeometry,it'sZvaluesmustbeinsidethetwoZplanes.IftheyfalloutsidetheZplanes,yourgeometrywontberendered.Alsoyourrendereronlyhasacertainresolutionfordepth.Ifyouhaveyourfarplanesetto1000unitsawayandyoutrydrawatinymodelwithlittlefaces0.1unitsawayfromeachother,OpenGLwontbeablegiveyouthedepthresolutionyouneedandyou'llgetZ-fighting(flickering)betweenthefaces.
– Mikepote
May30,2017at17:06
|
Show1morecomment
60
Minimalrunnableexample
glOrtho:2Dgames,objectscloseandfarappearthesamesize:
glFrustrum:morereal-lifelike3D,identicalobjectsfurtherawayappearsmaller:
main.c
#include
#include
#include
#include
staticintortho=0;
staticvoiddisplay(void){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
if(ortho){
}else{
/*Thisonlyrotatesandtranslatestheworldaroundtolooklikethecameramoved.*/
gluLookAt(0.0,0.0,-3.0,0.0,0.0,0.0,0.0,1.0,0.0);
}
glColor3f(1.0f,1.0f,1.0f);
glutWireCube(2);
glFlush();
}
staticvoidreshape(intw,inth){
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(ortho){
glOrtho(-2.0,2.0,-2.0,2.0,-1.5,1.5);
}else{
glFrustum(-1.0,1.0,-1.0,1.0,1.5,20.0);
}
glMatrixMode(GL_MODELVIEW);
}
intmain(intargc,char**argv){
glutInit(&argc,argv);
if(argc>1){
ortho=1;
}
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow(argv[0]);
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
returnEXIT_SUCCESS;
}
GitHubupstream.
Compile:
gcc-ggdb3-O0-omain-std=c99-Wall-Wextra-pedanticmain.c-lGL-lGLU-lglut
RunwithglOrtho:
./main1
RunwithglFrustrum:
./main
TestedonUbuntu18.10.
Schema
Ortho:cameraisaplane,visiblevolumearectangle:
Frustrum:cameraisapoint,visiblevolumeasliceofapyramid:
Imagesource.
Parameters
Wearealwayslookingfrom+zto-zwith+yupwards:
glOrtho(left,right,bottom,top,near,far)
left:minimumxwesee
right:maximumxwesee
bottom:minimumywesee
top:maximumywesee
-near:minimumzwesee.Yes,thisis-1timesnear.Soanegativeinputmeanspositivez.
-far:maximumzwesee.Alsonegative.
Schema:
Imagesource.
Howitworksunderthehood
Intheend,OpenGLalways"uses":
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
IfweuseneitherglOrthonorglFrustrum,thatiswhatweget.
glOrthoandglFrustrumarejustlineartransformations(AKAmatrixmultiplication)suchthat:
glOrtho:takesagiven3Drectangleintothedefaultcube
glFrustrum:takesagivenpyramidsectionintothedefaultcube
Thistransformationisthenappliedtoallvertexes.ThisiswhatImeanin2D:
Imagesource.
Thefinalstepaftertransformationissimple:
removeanypointsoutsideofthecube(culling):justensurethatx,yandzarein[-1,+1]
ignorethezcomponentandtakeonlyxandy,whichnowcanbeputintoa2Dscreen
WithglOrtho,zisignored,soyoumightaswellalwaysuse0.
Onereasonyoumightwanttousez!=0istomakespriteshidethebackgroundwiththedepthbuffer.
Deprecation
glOrthoisdeprecatedasofOpenGL4.5:thecompatibilityprofile12.1."FIXED-FUNCTIONVERTEXTRANSFORMATIONS"isinred.
Sodon'tuseitforproduction.Inanycase,understandingitisagoodwaytogetsomeOpenGLinsight.
ModernOpenGL4programscalculatethetransformationmatrix(whichissmall)ontheCPU,andthengivethematrixandallpointstobetransformedtoOpenGL,whichcandothethousandsofmatrixmultiplicationsfordifferentpointsreallyfastinparallel.
Manuallywrittenvertexshadersthendothemultiplicationexplicitly,usuallywiththeconvenientvectordatatypesoftheOpenGLShadingLanguage.
Sinceyouwritetheshaderexplicitly,thisallowsyoutotweakthealgorithmtoyourneeds.SuchflexibilityisamajorfeatureofmoremodernGPUs,whichunliketheoldonesthatdidafixedalgorithmwithsomeinputparameters,cannowdoarbitrarycomputations.Seealso:https://stackoverflow.com/a/36211337/895245
WithanexplicitGLfloattransform[]itwouldlooksomethinglikethis:
glfw_transform.c
#include
#include
#include
#defineGLEW_STATIC
#include
#include
staticconstGLuintWIDTH=800;
staticconstGLuintHEIGHT=600;
/*ourColorispassedontothefragmentshader.*/
staticconstGLchar*vertex_shader_source=
"#version330core\n"
"layout(location=0)invec3position;\n"
"layout(location=1)invec3color;\n"
"outvec3ourColor;\n"
"uniformmat4transform;\n"
"voidmain(){\n"
"gl_Position=transform*vec4(position,1.0f);\n"
"ourColor=color;\n"
"}\n";
staticconstGLchar*fragment_shader_source=
"#version330core\n"
"invec3ourColor;\n"
"outvec4color;\n"
"voidmain(){\n"
"color=vec4(ourColor,1.0f);\n"
"}\n";
staticGLfloatvertices[]={
/*PositionsColors*/
0.5f,-0.5f,0.0f,1.0f,0.0f,0.0f,
-0.5f,-0.5f,0.0f,0.0f,1.0f,0.0f,
0.0f,0.5f,0.0f,0.0f,0.0f,1.0f
};
/*Buildandcompileshaderprogram,returnitsID.*/
GLuintcommon_get_shader_program(
constchar*vertex_shader_source,
constchar*fragment_shader_source
){
GLchar*log=NULL;
GLintlog_length,success;
GLuintfragment_shader,program,vertex_shader;
/*Vertexshader*/
vertex_shader=glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader,1,&vertex_shader_source,NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,&success);
glGetShaderiv(vertex_shader,GL_INFO_LOG_LENGTH,&log_length);
log=malloc(log_length);
if(log_length>0){
glGetShaderInfoLog(vertex_shader,log_length,NULL,log);
printf("vertexshaderlog:\n\n%s\n",log);
}
if(!success){
printf("vertexshadercompileerror\n");
exit(EXIT_FAILURE);
}
/*Fragmentshader*/
fragment_shader=glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader,1,&fragment_shader_source,NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader,GL_COMPILE_STATUS,&success);
glGetShaderiv(fragment_shader,GL_INFO_LOG_LENGTH,&log_length);
if(log_length>0){
log=realloc(log,log_length);
glGetShaderInfoLog(fragment_shader,log_length,NULL,log);
printf("fragmentshaderlog:\n\n%s\n",log);
}
if(!success){
printf("fragmentshadercompileerror\n");
exit(EXIT_FAILURE);
}
/*Linkshaders*/
program=glCreateProgram();
glAttachShader(program,vertex_shader);
glAttachShader(program,fragment_shader);
glLinkProgram(program);
glGetProgramiv(program,GL_LINK_STATUS,&success);
glGetProgramiv(program,GL_INFO_LOG_LENGTH,&log_length);
if(log_length>0){
log=realloc(log,log_length);
glGetProgramInfoLog(program,log_length,NULL,log);
printf("shaderlinklog:\n\n%s\n",log);
}
if(!success){
printf("shaderlinkerror");
exit(EXIT_FAILURE);
}
/*Cleanup.*/
free(log);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
returnprogram;
}
intmain(void){
GLintshader_program;
GLinttransform_location;
GLuintvbo;
GLuintvao;
GLFWwindow*window;
doubletime;
glfwInit();
window=glfwCreateWindow(WIDTH,HEIGHT,__FILE__,NULL,NULL);
glfwMakeContextCurrent(window);
glewExperimental=GL_TRUE;
glewInit();
glClearColor(0.0f,0.0f,0.0f,1.0f);
glViewport(0,0,WIDTH,HEIGHT);
shader_program=common_get_shader_program(vertex_shader_source,fragment_shader_source);
glGenVertexArrays(1,&vao);
glGenBuffers(1,&vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
/*Positionattribute*/
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,6*sizeof(GLfloat),(GLvoid*)0);
glEnableVertexAttribArray(0);
/*Colorattribute*/
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,6*sizeof(GLfloat),(GLvoid*)(3*sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
transform_location=glGetUniformLocation(shader_program,"transform");
/*THISisjustadummytransform.*/
GLfloattransform[]={
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f,
};
time=glfwGetTime();
transform[0]=2.0f*sin(time);
transform[5]=2.0f*cos(time);
glUniformMatrix4fv(transform_location,1,GL_FALSE,transform);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES,0,3);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1,&vao);
glDeleteBuffers(1,&vbo);
glfwTerminate();
returnEXIT_SUCCESS;
}
GitHubupstream.
Compileandrun:
gcc-ggdb3-O0-oglfw_transform.out-std=c99-Wall-Wextra-pedanticglfw_transform.c-lGL-lGLU-lglut-lGLEW-lglfw-lm
./glfw_transform.out
Output:
ThematrixforglOrthoisreallysimple,composedonlyofscalingandtranslation:
scalex,0,0,translatex,
0,scaley,0,translatey,
0,0,scalez,translatez,
0,0,0,1
asmentionedintheOpenGL2docs.
TheglFrustummatrixisnottoohardtocalculatebyhandeither,butstartsgettingannoying.NotehowfrustumcannotbemadeupwithonlyscalingandtranslationslikeglOrtho,moreinfoat:https://gamedev.stackexchange.com/a/118848/25171
TheGLMOpenGLC++mathlibraryisapopularchoiceforcalculatingsuchmatrices.http://glm.g-truc.net/0.9.2/api/a00245.htmldocumentsbothanorthoandfrustumoperations.
Share
Follow
editedDec9,2020at20:50
answeredMar16,2016at21:06
CiroSantilliOurBigBook.comCiroSantilliOurBigBook.com
316k8989goldbadges11251125silverbadges911911bronzebadges
3
1
"whatshouldbeusedinstead?"-constructyourownmatricesandassignthemdirectly.
– Kromster
Mar23,2016at13:05
I'mhavinghardtimetryingtocompileyourlastcodeexample(transformingtriangle),I'veclonedtherepositorybutIjustgettheerrorcommon.h:19:23:error:‘TIME_UTC’undeclared(firstuseinthisfunction)timespec_get(&ts,TIME_UTC);
– user2188550
Dec9,2020at19:11
1
@IvanzinhoIcouldn'treproduceonUbuntu20.04,presumablyhappeningbecausethatisinC11whichyourGCCdoesnotyetimplement.ButnowIminimizedtheexampleonthisanswerwithoutcommon.hasIshouldhavedonebeforesoitshouldwork:-)
– CiroSantilliOurBigBook.com
Dec9,2020at20:52
Addacomment
|
4
glOrthodescribesatransformationthatproducesaparallelprojection.Thecurrentmatrix(seeglMatrixMode)ismultipliedbythismatrixandtheresultreplacesthecurrentmatrix,asifglMultMatrixwerecalledwiththefollowingmatrixasitsargument:
OpenGLdocumentation(mybold)
Thenumbersdefinethelocationsoftheclippingplanes(left,right,bottom,top,nearandfar).
The"normal"projectionisaperspectiveprojectionthatprovidestheillusionofdepth.Wikipediadefinesaparallelprojectionas:
Parallelprojectionshavelinesofprojectionthatareparallelbothinrealityandintheprojectionplane.
Parallelprojectioncorrespondstoaperspectiveprojectionwithahypotheticalviewpoint—e.g.,onewherethecameraliesaninfinitedistanceawayfromtheobjectandhasaninfinitefocallength,or"zoom".
Share
Follow
editedJun20,2020at9:12
CommunityBot
111silverbadge
answeredApr3,2010at14:03
ChrisF♦ChrisF
132k3030goldbadges252252silverbadges323323bronzebadges
2
hithanksfortheinfo.icouldn'tquiteunderstandthedifferencebetweenparallelandperspectiveprojection.igoogledabitandfoundtheanswerinwiki.answers.com/Q/…
– ufk
Apr3,2010at15:08
6
Unfortunatelytheinformationyougotfromanswers.comisprettyworthless.Anisometricview,forexample,isvery3-D,yetitisaparallelprojectionwithoutperspective.Seehere,andtherearealsolinkstomanyotherexamplesofprojections:en.wikipedia.org/wiki/Isometric_projection
– BenVoigt
Apr4,2010at6:41
Addacomment
|
YourAnswer
ThanksforcontributingananswertoStackOverflow!Pleasebesuretoanswerthequestion.Providedetailsandshareyourresearch!Butavoid…Askingforhelp,clarification,orrespondingtootheranswers.Makingstatementsbasedonopinion;backthemupwithreferencesorpersonalexperience.Tolearnmore,seeourtipsonwritinggreatanswers.
Draftsaved
Draftdiscarded
Signuporlogin
SignupusingGoogle
SignupusingFacebook
SignupusingEmailandPassword
Submit
Postasaguest
Name
Email
Required,butnevershown
PostYourAnswer
Discard
Byclicking“PostYourAnswer”,youagreetoourtermsofservice,privacypolicyandcookiepolicy
Nottheansweryou'relookingfor?Browseotherquestionstaggedc++copengloraskyourownquestion.
TheOverflowBlog
StackOverflowtrends:Weekdayvsweekendsiteactivity
Fordevelopers,flowstatestartswithyourfingertips
FeaturedonMeta
RecentColorContrastChangesandAccessibilityUpdates
Revieweroverboard!Orarequesttoimprovetheonboardingguidancefornew...
ShouldIexplainotherpeople'scode-onlyanswers?
CollectivesUpdate:RecognizedMembers,Articles,andGitLab
Linked
30
WhatareshadersinOpenGLandwhatdoweneedthemfor?
9
OpenGL(ES)--What'sthedifferencebetweenfrustumandortho?
7
OpenGLESnotworkingasdesired
1
TransformationsfrompixelstoNDC
2
I'mhavingaproblemwithmovementinopengl3D
0
Finding/RemappingboundsofOpenGLEScoordinateplane
1
OpenGLDisplayError-Incorrectdisplay
0
movingcamerausingglOrtho
1
Howtostopstretchinginopengl
-1
openGLresolutionsettings,screenbehavingunexplainably
Seemorelinkedquestions
Related
3005
HowdoIset,clear,andtoggleasinglebit?
4230
TheDefinitiveC++BookGuideandList
3246
ImproveINSERT-per-secondperformanceofSQLite
1574
WhydoweneedvirtualfunctionsinC++?
1590
Cyclesinfamilytreesoftware
2134
C++11introducedastandardizedmemorymodel.Whatdoesitmean?AndhowisitgoingtoaffectC++programming?
968
WhyshouldC++programmersminimizeuseof'new'?
2293
Whatdoesthe??!??!operatordoinC?
1843
ImageProcessing:AlgorithmImprovementfor'Coca-ColaCan'Recognition
1837
WhyshouldIuseapointerratherthantheobjectitself?
HotNetworkQuestions
Whatarethethreeorfourholesonthebackofa3.5inchfloppydiskindicatingandusedfor?
FindTheRealSolutionsofaCubic
HowtosetupWindows1122H2withalocalaccount?
7or8speedcassette?
WhyismyDC-DCbuckconverterconsuming8mAofcurrentwithnoloadconnected?
Howtoindicatetotheuserthattheyhaven'tcompletedaprerequisite?
HowtotypeŬ(Uwithbreve)?
Ispassword-unmaskingworththepotentialsecuritydownside?
WhydoesScarecrowinTheWizardOfOzgetthePythagoreanTheoremwrong?
CouldwelocateSpringfieldusingthecharacters'accents?
MSSQLServerDBTransactionLogGrowthRate
Isthereanymonsterwithstatblockchangesduringanencounter?
Willitgiveanegativeimpressionifaprofessormentionsthathedeclinedagiftcardfrommeinhisreferenceletter?
Iftheserieshasalimitof0,CanIconcludethatitisalsothesum?
Discoveringgroupingsofdescriptivetagsfrommedia
Doesthehumanvoicequalifyasnoise?
Islightflickeringonlyoncameraisbad?
Howtotellwhenit'stimetogiveupontires?
It'sJustRocketScience
Isthereafasterwaytosolvethefollowingproblem?
HowdoIunlockaMathematicaNotebook?
InEarlyModernEnglish,arethereexamplesofthe"a-+gerund"progressiveconstructionwherethegerundbeginswithavowel?
ArcanePropulsionArmor—canitgivethewearerlimbstheyneverhad?
Whydonet.bridge.bridge-nf-call-{arp,ip,ip6}tablesdefaultto1?
morehotquestions
Questionfeed
SubscribetoRSS
Questionfeed
TosubscribetothisRSSfeed,copyandpastethisURLintoyourRSSreader.
default
Yourprivacy
Byclicking“Acceptallcookies”,youagreeStackExchangecanstorecookiesonyourdeviceanddiscloseinformationinaccordancewithourCookiePolicy.
Acceptallcookies
Customizesettings