Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 16

Thread: rotating cube only rotates when window resized

Hybrid View

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

    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
    490
    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
    490
    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
    490
    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.

Posting Permissions

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