Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: rotating cube only rotates when window resized

  1. #1
    Intern Contributor
    Join Date
    Jun 2013
    Posts
    69

    rotating cube only rotates when window resized

    hi i am trying to create a program where a cube rotates, but it only rotates when the window is resized. im 99% positive it has to do with the main while loop in the main function. here is my code:
    Code :
    #include "gl_core_4_3.h"
    #include "matrixfuncs.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <X11/X.h>
    #include <X11/Xlib.h>
    #include <GL/gl.h>
    #include <GL/glx.h>
    #include <GL/glu.h>
    #include <string.h>
    #include <math.h>
     
    GLuint yaxis = 0, xaxis = 0;
     
    GLuint vao, buffers[2], matrixloc;
    GLfloat matrixy[] = {1, 0, 0, 0, 
    0, 1, 0, 0, 
    0, 0, 1, 0, 
    0, 0, 0, 1};
    GLfloat matrixx[] = {1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1};
     
     
    Display                 *dpy;
    Window                  root;
    GLint                   att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
    XVisualInfo             *vi;
    Colormap                cmap;
    XSetWindowAttributes    swa;
    Window                  win;
    GLXContext              glc;
    XWindowAttributes       gwa;
    XEvent                  xev;
     
    void display();
    void init();
    void rotate();
     
    int main(int argc, char **argv) {
     
     dpy = XOpenDisplay(NULL);
     
     if(dpy == NULL) {
            printf("\n\tcannot connect to X server\n\n");
            exit(0);
     }
     
     root = DefaultRootWindow(dpy);
     
     vi = glXChooseVisual(dpy, 0, att);
     
     if(vi == NULL) {
            printf("\n\tno appropriate visual found\n\n");
            exit(0);
     } 
     else {
            printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
     }
     
     
     cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
     
     swa.colormap = cmap;
     swa.event_mask = ExposureMask | KeyPressMask;
     
     win = XCreateWindow(dpy, root, 0, 0, 600, 600, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
     
     XMapWindow(dpy, win);
     XStoreName(dpy, win, "Testing Transformations");
     
     glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
     glXMakeCurrent(dpy, win, glc);
     
    	init(); 
     
     while(1) {
            XNextEvent(dpy, &xev);
     
     
     
            if(xev.type == Expose) {
                    XGetWindowAttributes(dpy, win, &gwa);
                    glViewport(0, 0, gwa.width, gwa.height);
    		rotate();
                    display(); 
                    glXSwapBuffers(dpy, win);
            }
     
            if(xev.type == KeyPress) {
                    glXMakeCurrent(dpy, None, NULL);
                    glXDestroyContext(dpy, glc);
                    XDestroyWindow(dpy, win);
                    XCloseDisplay(dpy);
                    exit(0);
            }
        } /* this closes while(1) { */
    } /* this is the } which closes int main(int argc, char *argv[]) { */
     
    void display()
    {
    	if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
    	    {
    	        printf("error with ogl");
    	        exit(1);
    	    }
     
    	glClear(GL_COLOR_BUFFER_BIT);
     
    	glEnable(GL_PRIMITIVE_RESTART);
    	glPrimitiveRestartIndex(1000);
     
    	glBindVertexArray(vao);
    	glDrawElements(GL_TRIANGLE_STRIP, 17, GL_UNSIGNED_SHORT, NULL);
     
    	glDisable(GL_PRIMITIVE_RESTART);
     
    	glFlush();
    }
     
    void init()
    {
    		if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
    	    {
    	        printf("error with ogl");
    	        exit(1);
    	    }
     
    	glGenVertexArrays(1, &vao);
    	glBindVertexArray(vao);	
     
    	glClearColor(0, 1, 0, 1);
    	const char *fshader =
    	    	    "#version 430 core\n"
    	    		"out vec4 fColor;\n"
    	    		"void main()\n"
    	    	    "{\n"
    	    		"fColor = vec4(1, 0, 0, 1);\n"
    	    	    "}\n";
     
    	    const char *vshader =
    	    	    "#version 430 core\n"
    		"uniform mat4 Matrix;\n"
    	    	    "layout (location = 0) in vec4 vPosition;\n"
    	    		"void main()\n"
    	    	    "{\n"
    	    	    "gl_Position = Matrix * vPosition;\n"
    	    		"}\n";
     
    	    GLuint prog = glCreateProgram();
     
    	    GLuint vert = glCreateShader(GL_VERTEX_SHADER);
    	    GLuint frag = glCreateShader(GL_FRAGMENT_SHADER);
     
    	    GLint vlen = (GLint)strlen(vshader);
    	    GLint flen = (GLint)strlen(fshader);
     
    	    glShaderSource(vert, 1, &vshader, &vlen);
    	    glShaderSource(frag, 1, &fshader, &flen);
    	    glCompileShader(vert);
    	    glCompileShader(frag);
     
     
    	    glAttachShader(prog, vert);
    	    glAttachShader(prog, frag);
    	    glLinkProgram(prog);
    	    glUseProgram(prog);
     
    	matrixloc = glGetUniformLocation(prog, "Matrix");
     
    	GLfloat vertices[] = {
    	-.5, -.5, -.5, 1,
    	-.5, -.5, .5, 1,
    	-.5, .5, -.5, 1,
    	-.5, .5, .5, 1,
    	.5, -.5, -.5, 1,
    	.5, -.5, .5, 1,
    	.5, .5, -.5, 1,
    	.5, .5, .5, 1
    	};
     
    	GLushort cubeindices[] = {
    	0, 1, 2, 3, 6, 7, 4, 5, 
    	1000,
    	2, 6, 0, 4, 1, 5, 3, 7
    	};
     
    	glGenBuffers(2, buffers);
     
    	glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    	glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
     
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof cubeindices, cubeindices, GL_STATIC_DRAW);
     
    	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void *)0);
    	glEnableVertexAttribArray(0);	
    }
     
    void rotate()
    {
    		if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
    	    {
    	        printf("error with ogl");
    	        exit(1);
    	    }
    	GLfloat matrixresult[16];
     
    	matrixy[0] = cos(yaxis);
    	matrixy[2] = sin(yaxis);
    	matrixy[8] = (-1) * sin(yaxis);
    	matrixy[10] = cos(yaxis);
     
    	matrixx[5] = cos(xaxis);
    	matrixx[6] = sin(xaxis);
    	matrixx[9] = (-1) * sin(xaxis);
    	matrixx[10] = cos(xaxis);
     
    	Mult4fv(matrixy, matrixx, matrixresult);
    	glUniformMatrix4fv(matrixloc, 1, GL_FALSE, matrixresult);
    	yaxis += 2;
    	xaxis++;
    }

  2. #2
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    474
    Quote Originally Posted by sandbucket View Post
    hi i am trying to create a program where a cube rotates, but it only rotates when the window is resized. im 99% positive it has to do with the main while loop in the main function.
    XNextEvent() blocks until an event is received. If you aren't receiving events, nothing will be executed.

    My first recommendation is not to try to write an application using raw Xlib. Use GLUT, GLFW, SDL, SFML, GTK, Qt, Motif, wxWidgets or whatever. Failing that, look at the source code for one of those toolkits to see how to write an event loop which can handle timers or other event sources.

    In any case, none of this is specific to OpenGL, so it's off-topic for this forum.

  3. #3
    Advanced Member Frequent Contributor
    Join Date
    Aug 2004
    Location
    munich, germany
    Posts
    659
    i would not say it is off-topic for this forum. this is the linux section, so any problem concerning linux and opengl can be posted here.
    especially this one because, apparently, the program posted above is a linux example from the opengl wiki.

    anyway, there is another source there which is more appropriate for animations:

    http://www.opengl.org/wiki/Programmi...h_GLX_and_Xlib

  4. #4
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    474
    Quote Originally Posted by RigidBody View Post
    anyway, there is another source there which is more appropriate for animations:
    That has exactly the same problem as the original code, i.e. it blocks until an event is received.

    FWIW, the way that freeglut does it is to only call XNextEvent() while XPending() returns non-zero. Then it checks for timers, then runs any idle callback, then (if no idle callback is installed), select()s on the descriptor for the connection to the X server (with a timeout determined by the next timer event).

  5. #5
    Advanced Member Frequent Contributor
    Join Date
    Aug 2004
    Location
    munich, germany
    Posts
    659
    Quote Originally Posted by GClements View Post
    That has exactly the same problem as the original code, i.e. it blocks until an event is received.
    nope, it doesn't. the example i linked uses XCheckWindowEvent (), which doesnt block anything.

  6. #6
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    474
    Quote Originally Posted by RigidBody View Post
    nope, it doesn't. the example i linked uses XCheckWindowEvent (), which doesnt block anything.
    My mistake. I was looking at the program fragment at the top of the page (which, on further reading, is given as an example of the problem).

    Even so, the program itself is also a fairly good example of how not to do event handling with Xlib.

    Realistically, the OpenGL wiki shouldn't be discussing Xlib, with the possible exception of initialisation (visual selection, context creation, etc). I say "possible" because most of the people who actually need to know that stuff already know it.

    About the only people who need to know how to use Xlib are the people writing GUI toolkits (in much the same way that about the only people who need to know assembly language are the people writing compilers).

    Everyone else will get better results with less effort if they just use a toolkit (either a full GUI toolkit such as GTK or Qt, or a "graphics window" toolkit such as GLUT, SDL or GLFW). The code will be more portable and better behaved, it will continue to work if Xlib gets eliminated in favour of XCB (or Wayland, Mir, etc), and so on.

  7. #7
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    Realistically, the OpenGL wiki shouldn't be discussing Xlib, with the possible exception of initialisation (visual selection, context creation, etc).
    Um, why not? As long as it's good information and represents good practice, I see no reason why the wiki shouldn't host a code example of how to use XLib to initialize OpenGL and deal with animation. If the example code has bugs in it, by all means, use the wiki as it's intended: fix them.

    I certainly don't know enough about XLib to do so

    I say "possible" because most of the people who actually need to know that stuff already know it.
    ... that's patently absurd. The people "who actually need to know" are the people who want to know.

    I encourage the use of cross-platform libraries where possible. I've even written several recommendations on the Wiki, discouraging people from manually loading OpenGL functions and linking them directly to several loading libraries. But that doesn't mean I want the knowledge of how to properly handle OpenGL functions to be hidden away. To be something that only those select few "who actually need to know" by some arbitrary metric can actually discover.

    There is absolutely nothing to be gained by hiding this knowledge from the world. Yes, encourage people not to do it, and tell them why they should use cross-platform solutions. But that doesn't mean you actively prevent them from learning the manual approach.

    in much the same way that about the only people who need to know assembly language are the people writing compilers
    Ah, so it's in the way that it's not true at all.

    Most people don't need to write assembly language. But any C/C++ programmer who is interested in low-level performance, at some point, is going to have to be able to read the disassemble of some function and then decide if there are ways to optimize that. Those ways might be to write inline assembly, but they may also be to restructure the C/C++ code to generate better code.

    Which you can't do unless you know that it's generating bad code. Which requires being able to read and understand it.

  8. #8
    Advanced Member Frequent Contributor
    Join Date
    Aug 2004
    Location
    munich, germany
    Posts
    659
    Quote Originally Posted by GClements View Post
    Even so, the program itself is also a fairly good example of how not to do event handling with Xlib.
    and the reason is...?

    Realistically, the OpenGL wiki shouldn't be discussing Xlib,
    because you, personally, don't like xlib or don't use xlib?
    currently, the page http://www.opengl.org/wiki/Programmi...:_GLX_and_Xlib has 95k hits. not all generated by myself.
    in my opinion, that shows that people are interested in xlib. and knowing xlib helps you to understand qt or glut in a better way.

    with the possible exception of initialisation (visual selection, context creation, etc).
    that doesnt make any sense at all. i show you how you can initialise an opengl window, but i dont show you how to use it in a program?

    Everyone else will get better results with less effort if they just use a toolkit (either a full GUI toolkit such as GTK or Qt, or a "graphics window" toolkit such as GLUT, SDL or GLFW).
    i have been thinking about making a qt tutorial for a while, but that would not fit on a single page like the xlib example, and it would need much more work to do it in a comprehensible way.
    we have had that discussion in another thread. qt needs a good amount of c++ knowledge, xlib does not.

    The code will be more portable
    ofc.

    and better behaved,
    how so?

    it will continue to work if Xlib gets eliminated in favour of XCB (or Wayland, Mir, etc), and so on.
    i have not much info about xcb etc. but i would be much surprised if there is no backward compatibility.

  9. #9
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    in my opinion, that shows that people are interested in xlib.
    That could show a lot of things. It should show that people can easily find that page from the wiki. Or that Google led them there when they Googled "Linux OpenGL Programming." Because apparently, that's what you get when you Google that (which is kinda sad). The fact that Google quickly finds a page doesn't mean that the page is necessarily what they wanted.

    Don't confuse popularity with quality.

    and knowing xlib helps you to understand qt or glut in a better way.
    No it doesn't. As someone who understands Qt and GLUT, my understanding of them would not be enhanced in any way by knowing anything about XLib. Nor has my understanding of them been enhanced by knowing Win32. GLUT especially hides both APIs very well.

    A good abstraction makes learning about the lower levels pointless because it abstracts them.

  10. #10
    Advanced Member Frequent Contributor
    Join Date
    Aug 2004
    Location
    munich, germany
    Posts
    659
    Quote Originally Posted by Alfonse Reinheart View Post
    Don't confuse popularity with quality.
    i didnt say anything about quality at all. i was saying that people seem to be *interested* about programming opengl with xlib.
    if someone googles something, it shows clearly that he is interested in that topic. about the wiki page being on top of google-
    well, i wouldn't boast with it, but it doesn't make me sad either. btw, back to quality- when i look at the bottom of the page,
    it seems that it has received more good than bad ratings.

    A good abstraction makes learning about the lower levels pointless because it abstracts them.
    thats completely wrong. even if you program just in plain c, there are some things that you should know, even when
    you don't have to deal with them directly. memory management, for example: you should know that local variables
    are created on the stack. you should know that for example writing to an array beyond its limits doesn't necessarily cause
    a segmentation fault if the array is a local variable and therefore on the stack, but may change other local variables.

    you should know that something as simple as realloc() behaves differently on linux and windows. on linux, you may get
    exactly the same pointer in return, while on windows, the original pointer is *always* free'd, a new pointer is alloc'ed, and
    the original data are memcpy'd to the new pointer, which results in poor performance.

    and, for example, you should know why

    typedef struct
    {
    char c1, c2;
    int i1, i2;
    } S1;

    is better than

    typedef struct
    {
    char c1;
    int i1;
    char c2;
    int i2;
    } S2;

    even though your compiler probably will optimize the structure internally.
    Last edited by RigidBody; 08-04-2013 at 04:16 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •