I am trying to draw a kite:
...using glBegin(GL_QUADS)
:
// g++ main.cpp -lopengl32 -lgdi32 -municode
#include <windows.h>
#include <GL/gl.h>
#include <cstdlib> //system
#include <cstdio> //printf, puts
void RenderQuad(HDC DeviceContext){
GLdouble A[] = {0, -1};
GLdouble B[] = {-1, 1};
GLdouble C[] = {1, 1};
GLdouble O[] = {0, 0};
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
//Render kite
glBegin(GL_QUADS);
glVertex2dv(A);
glVertex2dv(B);
glVertex2dv(O);
glVertex2dv(C);
glEnd();
//Check For Errors
for (bool ErrorOccured; ;){
switch(glGetError()){
#define OTG_CASE(C) case C: puts("ERROR: "#C); ErrorOccured = true; break;
case GL_NO_ERROR:
if (ErrorOccured){
puts("Failed To Render Quad");
return;
}
goto noerrors;
OTG_CASE(GL_INVALID_ENUM)
OTG_CASE(GL_INVALID_VALUE)
OTG_CASE(GL_INVALID_OPERATION)
OTG_CASE(GL_STACK_OVERFLOW)
OTG_CASE(GL_STACK_UNDERFLOW)
OTG_CASE(GL_OUT_OF_MEMORY)
default: puts("ERROR: Unknown"); ErrorOccured = true; break;
#undef OTG_CASE
}
}
noerrors:
//Swap Buffers
if (!SwapBuffers(DeviceContext)){
printf("Failed To Swap Buffers %lu", GetLastError());
return;
}
system("PAUSE");
}
int wWinMain(HINSTANCE Instance, HINSTANCE, PWSTR, int CmdShow){
HWND Window;
HDC DeviceContext;
HGLRC RenderingContext;
WNDCLASSW WindowClass = {0};
//Register Window Class
WindowClass.lpfnWndProc = DefWindowProcW;
WindowClass.hInstance = Instance;
WindowClass.lpszClassName = L"OTG";
{
ATOM WindowClassAtom;
WindowClassAtom = RegisterClassW(&WindowClass);
if (!WindowClassAtom){
printf("Failed To Register Class %lu", GetLastError());
return -1;
}
SetLastError(NO_ERROR);
}
//Create Window
Window = CreateWindowExW(
0,
WindowClass.lpszClassName,
L"firstwindow",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
Instance,
NULL
);
if (!Window){
printf("Failed To Create Window %lu", GetLastError());
goto unregisterclass;
}
SetLastError(NO_ERROR);
ShowWindow(Window, CmdShow);
//Get Device Context
DeviceContext = GetDC(Window);
if (!DeviceContext){
printf("Failed To Retrieve Device Context %lu", GetLastError());
goto destroywindow;
}
SetLastError(NO_ERROR);
{
//Find A Suitable Pixel Format, Manually
PIXELFORMATDESCRIPTOR PixelFormatDescriptor = {0};
int PixelFormat;
PixelFormat = 1;
for (;;++PixelFormat){
int NumPixelFormats;
printf("Checking Pixel Format %d\n", PixelFormat);
NumPixelFormats = DescribePixelFormat(
DeviceContext,
PixelFormat,
sizeof(PixelFormatDescriptor),
&PixelFormatDescriptor
);
if (!NumPixelFormats){
printf("Failed To Describe PixelFormat %lu", GetLastError());
goto releasedevicecontext;
}
SetLastError(NO_ERROR);
if (
PixelFormatDescriptor.dwFlags & PFD_SUPPORT_OPENGL
&& PixelFormatDescriptor.dwFlags & PFD_DOUBLEBUFFER
&& PixelFormatDescriptor.cDepthBits > 1
)
break;
if (PixelFormat == NumPixelFormats){
puts("All Formats Checked - Cannot Find A Suitable OpenGL Pixel Format");
goto releasedevicecontext;
}
}
puts("Format Is Suitable");
//Set Pixel Format
if (!SetPixelFormat(DeviceContext, PixelFormat, &PixelFormatDescriptor)){
printf("Failed To Set Pixel Format %lu", GetLastError());
goto releasedevicecontext;
}
SetLastError(NO_ERROR);
}
//Create OpenGl Rendering Context
RenderingContext = wglCreateContext(DeviceContext);
if (!RenderingContext){
printf("Failed To Create OpenGL Rendering Context %lu", GetLastError());
goto releasedevicecontext;
}
SetLastError(NO_ERROR);
//Make OpenGl Rendering Context Current
if (!wglMakeCurrent(DeviceContext, RenderingContext)){
printf("Failed To Make OpenGL Rending Context Current %lu", GetLastError());
goto deleterenderingcontext;
}
puts("Initialized OpenGL Rendering Context");
RenderQuad(DeviceContext);
//Make OpenGl Rendering Context Not Current
if(!wglMakeCurrent(NULL, NULL))
printf("\nFailed To Make OpenGL Rendering Context Not Current %lu", GetLastError());
deleterenderingcontext:
SetLastError(NO_ERROR);
if (!wglDeleteContext(RenderingContext))
printf("\nFailed To Delete OpenGL Rendering Context %lu", GetLastError());
releasedevicecontext:
SetLastError(NO_ERROR);
if (!ReleaseDC(Window, DeviceContext))
printf("\nFailed To Release Device Context %lu", GetLastError());
destroywindow:
SetLastError(NO_ERROR);
if (!DestroyWindow(Window))
printf("\nFailed To Destroy Window %lu", GetLastError());
unregisterclass:
SetLastError(NO_ERROR);
if (!UnregisterClassW(WindowClass.lpszClassName, Instance))
printf("\nFailed To Unregister Class %lu", GetLastError());
return 0;
}
...however it keeps drawing a triangle:
Why is a triangle being rendered? How does glBegin(GL_QUADS)
work? How can I fix RenderQuad
such that it produces the expected output?
Your shape is concave. Drawing such shapes with quads or polygons mode may not work properly.
Only convex polygons are guaranteed to be drawn correctly by the GL. If a specified polygon is nonconvex when projected onto the window, then the rendered polygon need only lie within the convex hull of the projected vertices defining its boundary.
The rules given for polygons also apply to each quad generated in a quad strip or from separate quads.
taken from legacy spec .
To get your kite just render two separate triangles.