Sign in to follow this  
Timptation

OpenGL Help with the basics...

Recommended Posts

Why am I not seeing a red triangle on my blue screen?

 
 
#pragma comment(linker, "/subsystem:windows")
 
#include <windows.h>
#pragma comment (lib, "openGL32")
#include <gl/gl.h>
#include <gl/glu.h>
 
 
HDC g_HDC;
bool fullScreen = true;
 
void Render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
 
 
glColor4f(1.0f, 0.0f, 0.0f, 0.0f);
 
glPushMatrix();
glLoadIdentity();

glBegin(GL_POLYGON);
 
float zPos = -10.0f;
 
glVertex3f(100.0f, 100.0f, zPos);
glVertex3f(200.0f, 200.0f, zPos);
glVertex3f(300.0f, 100.0f, zPos);
 
glEnd();
    glPopMatrix();
 
    glFlush();
 
    // Bring back buffer to foreground
    SwapBuffers(g_HDC);
}
 
void SetupPixelFormat(HDC hDC)
{
    int nPixelFormat;
 
    static PIXELFORMATDESCRIPTOR pfd = {
            sizeof(PIXELFORMATDESCRIPTOR),          //size of structure
            1,                                      //default version
            PFD_DRAW_TO_WINDOW |                    //window drawing support
            PFD_SUPPORT_OPENGL |                    //opengl support
            PFD_DOUBLEBUFFER,                       //double buffering support
            PFD_TYPE_RGBA,                          //RGBA color mode
            32,                                     //32 bit color mode
            0, 0, 0, 0, 0, 0,                       //ignore color bits
            0,                                      //no alpha buffer
            0,                                      //ignore shift bit
            0,                                      //no accumulation buffer
            0, 0, 0, 0,                             //ignore accumulation bits
            16,                                     //16 bit z-buffer size
            0,                                      //no stencil buffer
            0,                                      //no aux buffer
            PFD_MAIN_PLANE,                         //main drawing plane
            0,                                      //reserved
            0, 0, 0 };                              //layer masks ignored
 
    nPixelFormat = ChoosePixelFormat(hDC, &pfd);

    SetPixelFormat(hDC, nPixelFormat, &pfd);
}
 
void InitOpenGL()
{

GLint iViewport[4];
    glGetIntegerv( GL_VIEWPORT, iViewport );
glViewport(0, 0, iViewport[2], iViewport[3]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
    glOrtho( iViewport[0], iViewport[0]+iViewport[2], iViewport[1], iViewport[1]+iViewport[3], -100.0f, 100.0f );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
 
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CW);
//glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_CULL_FACE);
 
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//glEnable(GL_BLEND);
 
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
}
 
/*      Windows Event Procedure Handler */
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    //      Rendering and Device Context variables are declared here.
    static HGLRC hRC;
    static HDC hDC;
 
    //      Width and Height for the window our robot is to be displayed in.
    int width, height;
 
    switch(message)
    {
            case WM_CREATE: //window being created
{
                    hDC = GetDC(hwnd);  //get current windows device context
                    g_HDC = hDC;
 
SetupPixelFormat(hDC); //call our pixel format setup function
 
                    //      Create rendering context and make it current
                    hRC = wglCreateContext(hDC);
                    wglMakeCurrent(hDC, hRC);
 
InitOpenGL();
 
                    return 0;
                    break;
}
            case WM_CLOSE:  //window is closing
{
                    /*      Deselect rendering context and delete it*/
                    wglMakeCurrent(hDC, NULL);
                    wglDeleteContext(hRC);
 
                    /*      Send quit message to queue*/
                    PostQuitMessage(0);
 
                    return 0;
                    break;
}
            case WM_SIZE:
{
                    /*      Retrieve width and height*/
                    height = HIWORD(lParam);
                    width = LOWORD(lParam);
 
                    /*      Don't want a divide by 0*/
                    if (height == 0)
                            height = 1;
 
                    /*      Reset the viewport to new dimensions*/
                    glViewport(0, 0, width, height);
 
                    /*      Set current Matrix to projection and load in the orthographic matrix*/
                    //glMatrixMode(GL_PROJECTION);
                    //glLoadIdentity(); //reset projection matrix
//glOrtho(...
 
                    //glMatrixMode(GL_MODELVIEW); //set modelview matrix
                    //glLoadIdentity(); //reset modelview matrix
 
                    return 0;
                    break;
}
            default:
{
                    break;
}
    }
 
    return (DefWindowProc(hwnd, message, wParam, lParam));
}
 
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
// Getting rid of unused variable warnings.
(nCmdShow);
(lpCmdLine);
(hPrevInstance);
 
    WNDCLASSEX windowClass;         //window class
    HWND    hwnd;                   //window handle
    MSG     msg = MSG();            //message
    bool    done;                   //flag for completion of app
    DWORD   dwExStyle;              //window extended style
    DWORD   dwStyle;                //window style
    RECT    windowRect;
 
    /*      Screen/display attributes*/
    int width = 2880;
    int height = 1800;
    int bits = 32;
 
    windowRect.left =(long)0;               //set left value to 0
    windowRect.right =(long)width; //set right value to requested width
    windowRect.top =(long)0;                //set top value to 0
    windowRect.bottom =(long)height; //set bottom value to requested height
 
    /*      Fill out the window class structure*/
    windowClass.cbSize              = sizeof(WNDCLASSEX);
    windowClass.style               = CS_HREDRAW | CS_VREDRAW;
    windowClass.lpfnWndProc         = WndProc;
    windowClass.cbClsExtra          = 0;
    windowClass.cbWndExtra          = 0;
    windowClass.hInstance           = hInstance;
    windowClass.hIcon               = LoadIcon(NULL, IDI_APPLICATION);
    windowClass.hCursor             = LoadCursor(NULL, IDC_ARROW);
    windowClass.hbrBackground       = NULL;
    windowClass.lpszMenuName        = NULL;
    windowClass.lpszClassName       = "MyClass";
    windowClass.hIconSm             = LoadIcon(NULL, IDI_WINLOGO);
 
    /*      Register window class*/
    if (!RegisterClassEx(&windowClass))
            return 0;
 
    /*      Check if fullscreen is on*/
    if (fullScreen)
    {
        DEVMODE dmScreenSettings;
        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
        dmScreenSettings.dmSize = sizeof(dmScreenSettings);
        dmScreenSettings.dmPelsWidth = width;   //screen width
        dmScreenSettings.dmPelsHeight = height; //screen height
        dmScreenSettings.dmBitsPerPel = bits;   //bits per pixel
        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
 
        if( ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN != DISP_CHANGE_SUCCESSFUL) )
        {
            /*      Setting display mode failed, switch to windowed*/
            MessageBox(NULL, "Display mode failed", NULL, MB_OK);
            fullScreen = false;
        }
    }
 
    /*      Check if fullscreen is still on*/
    if (fullScreen)
    {
        dwExStyle = WS_EX_APPWINDOW;    // window extended style
        dwStyle = WS_POPUP;             // windows style
        ShowCursor(FALSE);              // hide mouse pointer
    }
    else
    {
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; //window extended style
        dwStyle = WS_OVERLAPPEDWINDOW;                  //windows style
    }
 
    AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);
 
    /*      Class registerd, so now create our window*/
    hwnd = CreateWindowEx(NULL, "MyClass", //class name
"2D_Project", //app name
dwStyle |
WS_CLIPCHILDREN |
WS_CLIPSIBLINGS,
0, 0, //x and y coords
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top, //width, height
NULL, //handle to parent
NULL, //handle to menu
hInstance, //application instance
NULL); //no xtra params
 
    /*      Check if window creation failed (hwnd = null ?)*/
    if (!hwnd)
return 0;
 
    ShowWindow(hwnd, SW_SHOW);      //display window
    UpdateWindow(hwnd);             //update window
 
    done = false;   //initialize loop condition variable
 
    /*      Main message loop*/
    while (!done)
    {
        PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);
 
        if (msg.message == WM_QUIT)     //did we receive a quit message?
        {
done = true;
}
        else
        {
            Render();
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    if (fullScreen)
    {
        ChangeDisplaySettings(NULL, 0);
        ShowCursor(TRUE);
    }
 
    return msg.wParam;
}

Share this post


Link to post
Share on other sites
I tried using <code></code>, but that didn't seem to do the trick. I can't seem to find the tags you're referring to. If you'll show me, I'll be more than happy to add the tags.

I thought the alpha channel was the other way around? Higher value for higher transparency. I haven't enabled GL_BLEND, so that shouldn't be an issue anyway, correct? I tried it with a 1, and I've verified glDisable(GL_BLEND) doesn't help either.

The only thing I see right now is a blue screen (the clear color). On occasion I can see red, but its not what I expect it to be in terms of size, then I keep messing around with code/values and lose it again... I feel like my ortho setup or camera knowledge is lacking somewher....

Share this post


Link to post
Share on other sites
WHAAAAT? That's really frustrating. I wonder if it has something to do with my machine. I'll try it on another one. I'm currently trying it on a dual booted macbook pro retina. Maybe apple's drivers aren't up to par or something...?

Share this post


Link to post
Share on other sites
Your screenshot gave me an idea.

Ok, I tried using

glVertex3f(0.0f, 200.0f, zPos);
glVertex3f(1600.0f, 900.0f, zPos);
glVertex3f(2800.0f, 200.0f, zPos);

because I have a 2800x1600 display. That way I had a better chance of seeing the triangle, since it would be larger, and I would expect to see the tip of the top be at my center screen, and bottom edges meet properly near the bottom edge of the screen. What I actually see (I'd post a screenshot if I knew the capture button...) is that the triangle tip is appearing roughly in the bottom right quadrant of my screen. Somewhere I must be getting bad values for screen size/viewport size/resolution/whatever.

Share this post


Link to post
Share on other sites
Also of note is that the thumbnail image of the program on my taskbar appears to be correct (maybe slightly off, but certainly different than what the fullscreen image is showing... A fullscreen issue then?

Share this post


Link to post
Share on other sites

The triangle appears where I'd expect it on my computer based on your projection matrix, vertex data and the screen resolution I am running. Try setting your projection matrix to identity (i.e. comment out the gOrtho line in InitOpenGL) and change your polygon draw calls to the following:

 

glVertex3f(-1.0f, -1.0f, 0);
glVertex3f(1.0f, -1.0f, 0);
glVertex3f(0.0f, 1.0f, 0);

You should see a big red triangle covering the entire screen (regardless of resolution) like this:

 

http://imgur.com/THV9H

Share this post


Link to post
Share on other sites
Doing that, I get a triangle with top at center screen, and bottom corners on the bottom of the screen at 1/4 and 3/4 screen width. The thumbnail image appears to have the triangle positioned such that the bottom left corner is at the bottom left of the image (as if at 0,0), top at (1/3 width, 2/3 height), and the bottom right corner at (2/3 width, 0). I'm still attempting to get this going on another machine too.....

Share this post


Link to post
Share on other sites
Ok, I just verified that everything is fine on another machine. I can only assume the issue has to do with apple's retina display tech. I know they have some kind of new resolution independence code that messes with how the drawing for the new display works. I won't claim to fully understand it, but it must be something to do with it. Their windows drivers must be doing something similar and keeping me from seeing what I expect to see.

The issue only appears in fullscreen mode. Development on this macbook will have to happen in windowed mode. If anyone has a solution, or even explanation, that would be great.

Thanks a bunch for your help GeneralQuery! Edited by fstim82

Share this post


Link to post
Share on other sites

Last I checked when researching some Wordpress graphics was that the retina technology takes an image with double the resolution (200% of the original) and reduces it, so you have more pixels per inch (I guess that would mean 4 pixels in the space 1 pixel normally takes up).

Share this post


Link to post
Share on other sites

Oh, I forgot to mention. Re: code tags. The correct usage is using square brackets rather than angle brackets, i.e.:

 

 

 
[code]type your code here[/code]
 

I wouldn't worry so much about it for your OP but it's useful to keep in mind for future posts as people with short attention spans (such as myself!) tend to zone out and hit the back button when confronted with a wall of unformatted code wink.png

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Announcements

  • Forum Statistics

    • Total Topics
      628320
    • Total Posts
      2982072
  • Similar Content

    • By mellinoe
      Hi all,
      First time poster here, although I've been reading posts here for quite a while. This place has been invaluable for learning graphics programming -- thanks for a great resource!
      Right now, I'm working on a graphics abstraction layer for .NET which supports D3D11, Vulkan, and OpenGL at the moment. I have implemented most of my planned features already, and things are working well. Some remaining features that I am planning are Compute Shaders, and some flavor of read-write shader resources. At the moment, my shaders can just get simple read-only access to a uniform (or constant) buffer, a texture, or a sampler. Unfortunately, I'm having a tough time grasping the distinctions between all of the different kinds of read-write resources that are available. In D3D alone, there seem to be 5 or 6 different kinds of resources with similar but different characteristics. On top of that, I get the impression that some of them are more or less "obsoleted" by the newer kinds, and don't have much of a place in modern code. There seem to be a few pivots:
      The data source/destination (buffer or texture) Read-write or read-only Structured or unstructured (?) Ordered vs unordered (?) These are just my observations based on a lot of MSDN and OpenGL doc reading. For my library, I'm not interested in exposing every possibility to the user -- just trying to find a good "middle-ground" that can be represented cleanly across API's which is good enough for common scenarios.
      Can anyone give a sort of "overview" of the different options, and perhaps compare/contrast the concepts between Direct3D, OpenGL, and Vulkan? I'd also be very interested in hearing how other folks have abstracted these concepts in their libraries.
    • By aejt
      I recently started getting into graphics programming (2nd try, first try was many years ago) and I'm working on a 3d rendering engine which I hope to be able to make a 3D game with sooner or later. I have plenty of C++ experience, but not a lot when it comes to graphics, and while it's definitely going much better this time, I'm having trouble figuring out how assets are usually handled by engines.
      I'm not having trouble with handling the GPU resources, but more so with how the resources should be defined and used in the system (materials, models, etc).
      This is my plan now, I've implemented most of it except for the XML parts and factories and those are the ones I'm not sure of at all:
      I have these classes:
      For GPU resources:
      Geometry: holds and manages everything needed to render a geometry: VAO, VBO, EBO. Texture: holds and manages a texture which is loaded into the GPU. Shader: holds and manages a shader which is loaded into the GPU. For assets relying on GPU resources:
      Material: holds a shader resource, multiple texture resources, as well as uniform settings. Mesh: holds a geometry and a material. Model: holds multiple meshes, possibly in a tree structure to more easily support skinning later on? For handling GPU resources:
      ResourceCache<T>: T can be any resource loaded into the GPU. It owns these resources and only hands out handles to them on request (currently string identifiers are used when requesting handles, but all resources are stored in a vector and each handle only contains resource's index in that vector) Resource<T>: The handles given out from ResourceCache. The handles are reference counted and to get the underlying resource you simply deference like with pointers (*handle).  
      And my plan is to define everything into these XML documents to abstract away files:
      Resources.xml for ref-counted GPU resources (geometry, shaders, textures) Resources are assigned names/ids and resource files, and possibly some attributes (what vertex attributes does this geometry have? what vertex attributes does this shader expect? what uniforms does this shader use? and so on) Are reference counted using ResourceCache<T> Assets.xml for assets using the GPU resources (materials, meshes, models) Assets are not reference counted, but they hold handles to ref-counted resources. References the resources defined in Resources.xml by names/ids. The XMLs are loaded into some structure in memory which is then used for loading the resources/assets using factory classes:
      Factory classes for resources:
      For example, a texture factory could contain the texture definitions from the XML containing data about textures in the game, as well as a cache containing all loaded textures. This means it has mappings from each name/id to a file and when asked to load a texture with a name/id, it can look up its path and use a "BinaryLoader" to either load the file and create the resource directly, or asynchronously load the file's data into a queue which then can be read from later to create the resources synchronously in the GL context. These factories only return handles.
      Factory classes for assets:
      Much like for resources, these classes contain the definitions for the assets they can load. For example, with the definition the MaterialFactory will know which shader, textures and possibly uniform a certain material has, and with the help of TextureFactory and ShaderFactory, it can retrieve handles to the resources it needs (Shader + Textures), setup itself from XML data (uniform values), and return a created instance of requested material. These factories return actual instances, not handles (but the instances contain handles).
       
       
      Is this a good or commonly used approach? Is this going to bite me in the ass later on? Are there other more preferable approaches? Is this outside of the scope of a 3d renderer and should be on the engine side? I'd love to receive and kind of advice or suggestions!
      Thanks!
    • By nedondev
      I 'm learning how to create game by using opengl with c/c++ coding, so here is my fist game. In video description also have game contain in Dropbox. May be I will make it better in future.
      Thanks.
    • By Abecederia
      So I've recently started learning some GLSL and now I'm toying with a POM shader. I'm trying to optimize it and notice that it starts having issues at high texture sizes, especially with self-shadowing.
      Now I know POM is expensive either way, but would pulling the heightmap out of the normalmap alpha channel and in it's own 8bit texture make doing all those dozens of texture fetches more cheap? Or is everything in the cache aligned to 32bit anyway? I haven't implemented texture compression yet, I think that would help? But regardless, should there be a performance boost from decoupling the heightmap? I could also keep it in a lower resolution than the normalmap if that would improve performance.
      Any help is much appreciated, please keep in mind I'm somewhat of a newbie. Thanks!
    • By test opty
      Hi,
      I'm trying to learn OpenGL through a website and have proceeded until this page of it. The output is a simple triangle. The problem is the complexity.
      I have read that page several times and tried to analyse the code but I haven't understood the code properly and completely yet. This is the code:
       
      #include <glad/glad.h> #include <GLFW/glfw3.h> #include <C:\Users\Abbasi\Desktop\std_lib_facilities_4.h> using namespace std; //****************************************************************************** void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow *window); // settings const unsigned int SCR_WIDTH = 800; const unsigned int SCR_HEIGHT = 600; const char *vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "void main()\n" "{\n" " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" "}\0"; const char *fragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "void main()\n" "{\n" " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" "}\n\0"; //******************************* int main() { // glfw: initialize and configure // ------------------------------ glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // glfw window creation GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "My First Triangle", nullptr, nullptr); if (window == nullptr) { cout << "Failed to create GLFW window" << endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // glad: load all OpenGL function pointers if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { cout << "Failed to initialize GLAD" << endl; return -1; } // build and compile our shader program // vertex shader int vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr); glCompileShader(vertexShader); // check for shader compile errors int success; char infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog); cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << endl; } // fragment shader int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr); glCompileShader(fragmentShader); // check for shader compile errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog); cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << endl; } // link shaders int shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog); cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // set up vertex data (and buffer(s)) and configure vertex attributes float vertices[] = { -0.5f, -0.5f, 0.0f, // left 0.5f, -0.5f, 0.0f, // right 0.0f, 0.5f, 0.0f // top }; unsigned int VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); // bind the Vertex Array Object first, then bind and set vertex buffer(s), //and then configure vertex attributes(s). glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // note that this is allowed, the call to glVertexAttribPointer registered VBO // as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind glBindBuffer(GL_ARRAY_BUFFER, 0); // You can unbind the VAO afterwards so other VAO calls won't accidentally // modify this VAO, but this rarely happens. Modifying other // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind // VAOs (nor VBOs) when it's not directly necessary. glBindVertexArray(0); // uncomment this call to draw in wireframe polygons. //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // render loop while (!glfwWindowShouldClose(window)) { // input // ----- processInput(window); // render // ------ glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // draw our first triangle glUseProgram(shaderProgram); glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to // bind it every time, but we'll do so to keep things a bit more organized glDrawArrays(GL_TRIANGLES, 0, 3); // glBindVertexArray(0); // no need to unbind it every time // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) glfwSwapBuffers(window); glfwPollEvents(); } // optional: de-allocate all resources once they've outlived their purpose: glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // glfw: terminate, clearing all previously allocated GLFW resources. glfwTerminate(); return 0; } //************************************************** // process all input: query GLFW whether relevant keys are pressed/released // this frame and react accordingly void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); } //******************************************************************** // glfw: whenever the window size changed (by OS or user resize) this callback function executes void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } As you see, about 200 lines of complicated code only for a simple triangle. 
      I don't know what parts are necessary for that output. And also, what the correct order of instructions for such an output or programs is, generally. That start point is too complex for a beginner of OpenGL like me and I don't know how to make the issue solved. What are your ideas please? What is the way to figure both the code and the whole program out correctly please?
      I wish I'd read a reference that would teach me OpenGL through a step-by-step method. 
  • Popular Now