I have a problem with glRotatef() function, I want to pause this function when user press Space, I've googled how to store curent function x,y,z but I've nothing found. There is a function in OpenGL glGet() but it can't get x,y,z coordinates. That's what I've done so far:
glPushMatrix();
if(flag==0)
{
glTranslatef(20,5,-10);
glRotatef(0.8f, 0.8f, 1.0f, 0.5f);
drawCube();
}
else {
glTranslatef(20,5,-10);
drawCube();
}
glPopMatrix();
and for Space event:
case VK_SPACE:
if(flag==0)
flag=1;
else
flag=0;
break;
this work in some way but only not in that way I need. I need to store the position of the cube when user pressed Space and when the user hit again space to continue from curent position.
first thing: old style openGL? please look into upgrading
second create a cubeAngle variable
in your update function increment it with how fast you want to rotate (multiplied by the delay between updates) only if flag==0
then
glPushMatrix();
glTranslatef(20,5,-10);
glRotatef(cubeAngle, 0.8f, 1.0f, 0.5f);
drawCube();
glPopMatrix();
Related
I modified the "Simple example" example in GLFW3.0.4 in Mac OSX 10.8 as an XCode 4.6 project (runs fine when unchanged). I am having a (2D) rectangle drawn with an external library (which draws via shaders). I can see the rectangle but If I draw the sample triangle (immediate drawn) before it, the triangle is seen in the first splash (frame) and then it is lost. If I try to draw it after, the triangle is never seen. I can only see the rectangle and I don't know what settings/states the library is changing!
I tried to inspect the application with OpenGL Profiler. Stopped before CGLFlushDrawable and could not find the triangle in any of the buffers (front, back, depth, stencil).
Am I doing something (prominently) wrong? The profiler allows only gl-function breakpoints. How can I debug this (more efficiently) and find the problem.
Here is (much of the changed parts of) the code:
void glfw2DViewport(GLFWwindow * window) {
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float) height;
glViewport(0, 0, width, height);
glClearColor(0.8, 0.8, 0.8, 1.0); // Lets see if something black is drawn!!
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// eye is at 0,0,0 looking to positive Z, -1(behind) to 1 are clipping planes:
// https://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml
glOrtho(ratio, -ratio, -1.f, 1.f, 1.0f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// ----- 2D settings -----
glfwSwapInterval(1);
glEnable(GL_SMOOTH);
glDisable(GL_DEPTH_TEST);
//glDisable(GL_STENCIL_TEST); // Disabling changed nothing!!
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLineWidth(5.0f);
glEnable(GL_LINE_SMOOTH);
glPointSize(5.0f);
glEnable(GL_POINT_SMOOTH);
}
int main(void) {
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfw2DViewport(window);
//...
while (!glfwWindowShouldClose(window)) {
glMatrixMode(GL_MODELVIEW_MATRIX);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
//drawUnitTriangle(); // can be seen just in the first frame!
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); // A vain attempt?
glPushAttrib(GL_ALL_ATTRIB_BITS); // Another vain attempt??
external_library_identity_matrix();
external_library_rectangle(POS,RED);
external_library_flush();
glPopAttrib();
glPopClientAttrib();
// Other vain attempts:
glfwMakeContextCurrent(window);
glMatrixMode(GL_MODELVIEW_MATRIX);
glLoadIdentity();
drawUnitTriangle(); // Nothing is Drawn!!
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
Are you sure the posted code is exactly what you are building with? If that's true, please check the argument of glMatrixMode() it should be GL_MODELVIEW, not GL_MODELVIEW_MATRIX. There are two places where you set it like this.
Since you already have glfw2DViewport(), why don't you put it in the while loop and delete other model view setting codes?
How can I update Space in chupmunk My Code is:
// left
shape1 = cpSegmentShapeNew(edge, cpvzero, cpv(0.0f, size.height), 0.0f);
shape1->u = 0.1f; // minimal friction on the ground
shape1->e = 0.7f;
cpSpaceAddStaticShape(_space, shape1); // a body can be represented by multiple shapes
// top
shape2 = cpSegmentShapeNew(edge, cpvzero, cpv(size.width, 0.0f), 0.0f);
shape2->u = 0.1f;
shape2->e = 0.7f;
cpSpaceAddStaticShape(_space, shape2);
// right
shape3 = cpSegmentShapeNew(edge, cpv(size.width, 0.0f), cpv(size.width, size.height), 0.0f);
shape3->u = 0.1f;
shape3->e = 0.7f;
cpSpaceAddStaticShape(_space, shape3);
// bottom
shape4 = cpSegmentShapeNew(edge, cpv(0.0f, size.height), cpv(size.width, size.height), 0.0f);
shape4->u = 0.1f;
shape4->e = 0.7f;
cpSpaceAddStaticShape(_space, shape4);
if ball touch the Bottom shape like this ball go up but the bottom shape is remove and display green line that want i do but i dont know how to remove shape from body. anyone suggestions are welcome.
So three things.
1) The cpSpace[Add|Remove]StaticShape() functions are deprecated, and you should be using the cpSpace[Add|Remove]Shape() functions instead.
2) As the last answer stated, cpSpaceAddShape() will add a shape to a space. If you want to remove it you call cpSpaceRemoveShape(). There's really nothing more to it than that.
3) Chipmunk doesn't do any graphics, so if you want to draw a green line you need to use whatever functionality provided by your graphics or rendering library.
cpSpaceRemoveStaticShape(_space, shape4);
This is the code written in the book openGL SuperBible to create a Spring-Shaped Path of Points on the screen:
#include "stdafx.h"
#include <Windows.h>
#include <gl\glut.h>
#include <gl\GLU.h>
#include <gl\GL.h>
#include <math.h>
// Define a constant for the value of PI
#define GL_PI 3.1415f
void ChangeSize(GLsizei , GLsizei );
void SetupRC();
void RenderScene(void);
int main(int argc, CHAR* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Points Example");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();
return 0;
}
// Change viewing volume and viewport. Called when window is resized
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat nRange = 100.0f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// This function does any needed initialization on the rendering context
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
}
// Called to draw scene
void RenderScene(void)
{
GLfloat x,y,z,angle;
int xRot,yRot; // Storage for coordinates and angles
xRot = 45;
yRot = 45;
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT);
// Save matrix state and do the rotation
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
// Call only once for all remaining points
glBegin(GL_POINTS);
z = -50.0f;
for(angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.1f)
{
x = 50.0f*sin(angle);
y = 50.0f*cos(angle);
// Specify the point and move the Z value up a little
glVertex3f(x, y, z);
z += 0.5f;
}
// Done drawing points
glEnd();
// Restore transformations
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
}
In fact by setting xRot=yRot=45 degrees, I have reached this shape.
But in the book it is told:
When this program is run, all you see is a circle
of points because you are initially looking directly down the z-axis. To see the effect, use
the arrow keys to spin the drawing around the x- and y-axes.
This means that we should have some code using arrow keys to increase and decrease the value of xRot and yRot. I have made some effort to do that.
1-Writing a function:
void _cdecl keyboard(int key ,int xRot,int yRot)
{
switch (key)
{
case GLUT_KEY_PAGE_UP:
yRot++;
case GLUT_KEY_PAGE_DOWN:
yRot--;
case GLUT_KEY_HOME:
xRot--;
case GLUT_KEY_END:
xRot++;
}
}
2-Its prototype at top of the code:
void _cdecl keyboard(int,int,int);
3-adding these two lines of code to the body of the function RenderScene:
GLint key = GLUT_KEY_PAGE_UP;
glutSpecialFunc(keyboard(key,xRot,yRot));
But I'm not sure it will work. The code gets the error:
error C2664: 'glutSpecialFunc' : cannot convert parameter 1 from 'void' to 'void (__cdecl *)(int,int,int)'
and I don't know how to return the changed value of xRot and yRot to the caller function because the compiler doesn't let me to define Pass by referrence parameters and the argument of glutSpecialFunc is a pointer to a void function!
Edited section of my question
as jblocksom suggested I changed the code to something like this:
1-defining and initializing global variables just before the main starts:
int xRot = 0;
int yRot = 0;
2- calling glutSpecialFunc somewhere in main
glutSpecialFunc(keyboard);
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
3- altering the code in keyboard function
void keyboard(int keyParam ,int mx,int my)
{
switch (keyParam)
{
case GLUT_KEY_PAGE_UP:
my++;
case GLUT_KEY_PAGE_DOWN:
my--;
case GLUT_KEY_HOME:
mx--;
case GLUT_KEY_END:
mx++;
}
glutPostRedisplay();
}
No compile and run-time error. But it does not work. I think this is because when I call glutSpecialFunc(keyboard), the function uses coordinates of mouse and keypress as the input argument so any increment or decrement is applied on the mouse coordinates not xRot or yRot which will be used in glRotatef(xRot, 1.0f, 0.0f, 0.0f) or glRotatef(yRot, 0.0f, 1.0f, 0.0f) so when calling the two latter the xRot and yRot is still equal to zero and there will be no rotation.I need to pass xRot and yRot to the function keyboard but how???
Even writing the function as:
void keyboard(int keyParam ,int mx,int my)
{
switch (keyParam)
{
case GLUT_KEY_PAGE_UP:
yRot++;
case GLUT_KEY_PAGE_DOWN:
yRot--;
case GLUT_KEY_HOME:
xRot--;
case GLUT_KEY_END:
xRot++;
}
glutPostRedisplay();
}
and calling it in the form glutSpecialFunc(keyboard) will not any difference!!!
glutSpecialFunc registers a callback with GLUT to be called when the user hits one of the arrow keys; the function you give it, keyboard, is not something you would call yourself. This is why you can't return anything from it. To get data out of the callback you'll need to set a global variable.
You'll want to call glutSpecialFunc somewhere in main where the other GLUT callbacks are set (eg glutRenderFunc). To get past the compile error, you'll call it like this:
glutSpecialFunc(keyboard);
which tells GLUT to call keyboard() with the key and mouse position.
Make the xRot and yRot variables referred to in RenderScene global.
Change the function signature of keyboard to not use xRot and yRot as variable names so that it will refer to the global ones:
void _cdecl keyboard(int key, int mx, int my)
You'll also probably need a call to glutPostRedisplay() at the end of keyboard, this will tell GLUT to redraw the scene.
Hopefully after that it should work, good luck!
I am teaching myself about open gl es and vertex buffer (VBO) and I have written code and it is supposed to draw one red triangle but instead it colours the screen black:
- (void)drawRect:(CGRect)rect {
// Draw a red triangle in the middle of the screen:
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
// Setup the vertex data:
typedef struct {
float x;
float y;
} Vertex;
const Vertex vertices[] = {{50,50}, {50,150}, {150,50}};
const short indices[3] = {0,1,2};
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
NSLog(#"drawrect");
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
// The following line does the actual drawing to the render buffer:
glDrawElements(GL_TRIANGLE_STRIP, 3, GL_UNSIGNED_SHORT, indices);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, framebuffer);
[eAGLcontext presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Here vertexBuffer is of type GLuint. What is going wrong? Thanks for your help.
Your vertices dont have a Z component, try {{50,50,-100}, {50,150,-100}, {150,50,-100}}; (your camera by default looks down the Z axis so putting it in the -Z should put it on screen) if you cant see it still try smaller numbers, im not sure what your near and far draw cutoff distance is, and if its not even set i dont know what the default is. This might not be the only issue but its the only one i can see by just looking quickly at it.
You need to add
glViewport(0, 0, 320, 480);
where you create the frame buffer and set up the context.
And replace your call to glDrawElements with
glDrawArrays(GL_TRIANGLE_STRIP, ...);
I've been working with OpenGL for a few months. We have started coding basic shaders in class and we have a Qt+OpenGL project to do. It's a simple one: an interactive 3d scene viewer. We've been given the starting code that loads .obj files, places them in the scene and then lets us rotate with the mouse.
I have a really weird problem here that my teacher hasn't been able to explain. We're using GL_LIGHT0 with its default parameters:
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
This is the only inicialization. The light's direction and position should be the same as the eye's. And this is how it works when I run the program in Ubuntu; i load the model of a cup and as I rotate, light rotates with my eye and I can see all its faces lighted up.
However, under Mac OS X 10.6.8, it's not working. The light stays fixed and all the faces that are facing other directions are black.
I've tried other lights, I've tried loading the identity in MODELVIEW and then specifying position and direction myself, I've tried re-downloading the code, re-compiling it and running it and still the same error.
The program needs some .dylib files that I link using soft links (I don't think this is the problem, though). The problem is not in the code since it works in other systems.
Is it possible that the Mac implementation is different? How can I test this? Thanks!
Edit: Here is a larger piece of code:
void GLWidget::initializeGL() {
glClearColor(0.8f, 0.8f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
resetCamera(); // sets VRP, OBS...
}
void GLWidget::paintGL( void ) {
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
setProjection();
setModelview();
drawAxes();
pscene.render();
}
void drawAxes() {
float L = DRAW_AXES_LENGTH;
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(1,0,0); glVertex3f(0,0,0); glVertex3f(L,0,0); // X
glColor3f(0,1,0); glVertex3f(0,0,0); glVertex3f(0,L,0); // Y
glColor3f(0,0,1); glVertex3f(0,0,0); glVertex3f(0,0,L); // Z
glEnd();
glEnable(GL_LIGHTING);
}
These are the functions related to lighting. As I said, LIGHT0 is set once inside initializeGL. I tried to set its position in paintGL but it didn't work either.
----- EDIT 2 -----
I found a solution. Inside drawAxes, just before returning, add:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GLfloat pos[] = {0.0f, 0.0f, 1.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glPopMatrix();
Why is this? After disabling and re-enabling it stops working?