Trying to display the characters typed on keyboard, I am using the following code:
void myKey(unsigned char key, int x, int y)
{
if (key == 13) // enter key
{
return;
}
glRasterPos2f(xpos, 600);
glColor3f(0.0, 0.0, 1.0); // text color
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, key); // print the color
glFlush();
xpos += 15;
player1[i] = key;
i += 1;
}
It prints the text entered onto the screen but, it doesn't exit as it is supposed to when I press enter. I want the the code to display the player name of the player1 and store it in an array then exit when I press enter and then continue to accept the second player name.
Only do OpenGL stuff in the display callback.
You need to break your text entry into two pieces:
Keyboard/array handling in the glutKeyboardFunc() callback. Once you're done modifying the name list post a redisplay event.
String rendering in the glutDisplayFunc() callback, where you iterate over the name vector and display each string.
Like so:
#include <GL/freeglut.h>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
vector< string > names( 1 );
void keyboard( unsigned char key, int x, int y )
{
if( key == 13 )
{
// enter key
names.push_back( "" );
}
else if( key == 8 )
{
// backspace
names.back().pop_back();
}
else
{
// regular text
names.back().push_back( key );
}
glutPostRedisplay();
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, 0, h, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
for( size_t i = 0; i < names.size(); ++i )
{
ostringstream oss;
oss << ( i + 1 ) << ": " << names[i];
void* font = GLUT_BITMAP_9_BY_15;
const int fontHeight = glutBitmapHeight( font );
glRasterPos2i( 10, h - ( fontHeight * ( i + 1 ) ) );
glutBitmapString( font, (const unsigned char*)( oss.str().c_str() ) );
}
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMainLoop();
return 0;
}
Related
I'm trying to do an animation which ball starts dropping with affects of gravity but unfortunately the ball is too slow. I actually found a way for it which is to change
double dt = (cur - last) / 1000.0;
to
double dt = (cur - last) / 100.0;
but that time, the bug is that position of the ball is kind of wrong because the ball starts dying :). If you work the animation you may understand what I'm trying to say!
The main code is there :
#include <GL/glut.h>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
#include <glm/glm.hpp>
#include <glm/gtx/norm.hpp>
using namespace glm;
int seconds_past = 0;
struct Ball{
int radius;
dvec3 pos;
dvec3 vel;
double acc = -9.8;
bool last, made = false;
dvec3 last_vel;
void Integrate(double cur, double dt){
static int count = 0;
count++;
vel += dvec3{vel[0], acc * dt, 0};
pos = pos + vel * dt;
std::cout << vel[1] << " " << count << std::endl;
}
void HandleCollisions(){
if(pos[1] - 10 < -100){
std::cout << "true" << std::endl;
vel = -vel;
}
}
};
void Integrate( vector< Ball >& particles, double cur, double dt)
{
for( size_t i = 0; i < particles.size(); ++i )
{
particles[i].Integrate( cur, dt );
particles[i].HandleCollisions();
}
}
vector< Ball > particles;
void display()
{
// use last frame time to calculate delta-t
static int last = glutGet( GLUT_ELAPSED_TIME );
int cur = glutGet( GLUT_ELAPSED_TIME );
double dt = ( cur - last ) / 1000.0;
last = cur;
Integrate( particles, cur, dt);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glOrtho( -100 * ar, 100 * ar, -100, 100, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// draw particles
glPointSize( 50 );
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_DOUBLE, sizeof( Ball ), &particles[0].pos[0] );
glDrawArrays( GL_POINTS, 0, particles.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glutSwapBuffers();
}
void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 1000.0/60.0, timer, value );
}
int main(int argc, char **argv)
{
particles.resize(1);
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
I have an assignment to build a 7 segment BCD counter. The idea is to generate binary numbers 000, 001, etc all the way up to 9, and then feed them into a BCD decoder and the display will be a 7 segment display that counts 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, etc. I know this is typically done with an FPGA board, but since we're distance learning the task is to perform this using simple C++ graphics. I had a previous project where the user would input a binary number and the display would display the number in the seven seg, so I built off of that. However, I'm getting a floating point fault and the program crashes and I cannot for the life of me figure out why. Any help would be appreciated.
#include <GL/glut.h>
#include <stdio.h>
#include <string.h>
#include <deque>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include "dec2baser.cpp"
using namespace std;
deque<char>textQ; // holding a message
int bits[100]; // holding bits entered
bool enter = false;
class Point {
public:
float v[2];
Point() { v[0] = v[1] = 0;}
Point( float x0, float y0 ){
v[0] = x0;
v[1] = y0;
}
Point( float v0[] ){
v[0] = v0[0];
v[1] = v0[1];
}
void move ( float dx, float dy )
{
v[0] += dx;
v[1] += dy;
}
};
void aLine ( Point p0, Point p1, int thick ) //modifies width based on what segment is activated
{
if ( !thick ) // thin line
glLineWidth ( 1 );
else // thick line
glLineWidth ( 4 );
glBegin( GL_LINES );
glVertex2fv ( p0.v );
glVertex2fv ( p1.v );
glEnd();
}
void text ( char *s )
{
char *p;
for ( p = s; *p; p++ )
glutBitmapCharacter ( GLUT_BITMAP_TIMES_ROMAN_24, (int) *p );
// glutBitmapCharacter ( GLUT_BITMAP_HELVETICA_18, *p );
}
/*bool getBits()
{
char s[400], s1[400];
float x = -9, y = 9;
int i, n;
static bool first = true;
enter = false;
glColor3f (0, 0, 0);
strcpy ( s, "Press'q' to quit: \n");
if ( first ) {
glRasterPos2f ( x, y );
text ( s );
first = false;
return enter;
}
n = strlen( s );
i = 0;
deque <char> :: iterator it;
for (it = textQ.begin(); it != textQ.end(); ++it) {
if ( i > 100 ) break;
s[i+n] = s1[i] = *it;
if ( s1[i] == '\r' ) {
s[i+n] = s1[i] = 0;
enter = true;
break;
}
i++;
}
s[i+n] = 0;
s1[i] = 0;
glRasterPos2f ( x, y );
text ( s );
if ( enter ) {
glRasterPos2f ( 0, 0 );
text ( s1 );
i = 0;
while ( s1[i] != 0 ) {
bits[i] = s1[i] - '0';
i++;
}
bits[i] = -1; //signals end of bits
textQ.erase(textQ.begin(), textQ.end() );
}
return enter;
}
void printBits()
{
int i = 0;
while ( bits[i] != -1 )
cout << bits[i++];
cout << endl;
}*/
void drawLines()
{
Point p0, p1;
p0 = Point ( -2, 2);
p1 = Point ( 4, 2 );
aLine ( p0, p1, 0 ); // thin horizontal
p0.move ( 0, -1 );
p1.move ( 0, -1 );
aLine ( p0, p1, 1 ); // thick horizontal
p0 = Point ( -2, 0);
p1 = Point ( -2, -5 );
aLine ( p0, p1, 0 ); // thin vertical
p0.move ( 4, 0 );
p1.move ( 4, 0 );
aLine ( p0, p1, 1 ); // thick vertical
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT ); //clear screen
//if ( getBits() ) commented out because user is not inputing any bits
char res[100];
unsigned int microsecond = 1000000;
for ( int i = 0; i < 9; i ++ )
{
binaryGen(res, i, 2);
drawLines();
usleep( 1 * microsecond); //wait for 1 second
}
glFlush(); //send all output to screen
}
void keyboard ( unsigned char key, int mousex, int mousey )
{
switch ( key ) {
case 27: // escape
case 'q':
exit ( -1 );
}
if ( key == '\b' ) // back space
textQ.pop_back();
else
textQ.push_back( key );
glutPostRedisplay();
return;
}
As you can see I have the getbits function commented out because that was for my previous project where the user would input the values and the program would display that value. That's the drawing source code, now here's my main source code.
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
//function call protos
void init(void);
void display (void);
void keyboard ( unsigned char key, int mousex, int mousey );
//modified to initialize our display
void init(void)
{
const char *version;
glClearColor( 1.0, 1.0, 1.0, 0.0 ); //get white background color
glColor3f( 0.0f, 0.0f, 0.0f ); //set drawing color
glPointSize( 4.0 ); //a dot is 4x4
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( -10.0, 10.0, -10.0, 10.0 );
}
/* Main Loop
* Open window with initial window size, title bar,
* RGBA drawLines mode, depth buffer.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv); //initialize toolkit
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB ); //set drawLines mode
glutInitWindowSize(500, 500); //set window size on screen
glutInitWindowPosition( 100, 150 ); //set window position on screen
glutCreateWindow(argv[0]); //open screen widow
init();
glutKeyboardFunc ( keyboard );
glutDisplayFunc (display ); //points to drawLines function
glutMainLoop(); //go into perpetual loop
return 0;
}
Any and all help is appreciated, I'm relatively new to coding so if there's any obvious errors you see let me know. Thank you!
I'm writing a Level Editor and I'm using the GLUT to display text inside an opengl canvas. However, I would like to scale the text with the canvas instead of staying at the given size (18 at this moment).
How am I able to do this? A friend of mine suggested to create my own font but I think that's a bit much.
This is the code I'm using
public void showCharacters(GL gl, String text) {
final GLUT glut = new GLUT();
System.out.println(text);
if (text != null) {
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glRasterPos2f(x + (sizeX / 10), (y - (sizeY)));
glut.glutBitmapString(GLUT.BITMAP_HELVETICA_18, text);
}
}
Use glutStroke*() and GLUT_STROKE_*:
#include <GL/glut.h>
#include <cstring>
int glWidth( void* font, const char* str )
{
int width = 0;
for( size_t i = 0; i < strlen( str ); ++i )
{
width += glutStrokeWidth( font, (int)str[i] );
}
return width;
}
void glPrint( void* font, const char* str )
{
for( size_t i = 0; i < strlen( str ); ++i )
{
glutStrokeCharacter( font, (int)str[i] );
}
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glOrtho( -250 * ar, 250 * ar, -250, 250, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
void* font = GLUT_STROKE_MONO_ROMAN;
const char* str = "Hello";
glTranslatef( -glWidth( font, str ) / 2.0f, 0, 0 );
glPrint( font, str );
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
how can drawing like square or TRIANGLES when clicked on any position on screen show the shape this is my Attempt i do't know what doing
...........................................................................
.......................................................................................
#include <windows.h>
#include <gl/Gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
GLsizei wh=500,ww=500;
GLfloat size=3.0;
void drawsquare( int x, int y)
{
y=wh-y;
glBegin(GL_POLYGON);
glVertex2f(x+size,y+size);
glVertex2f(x-size,y+size);
glVertex2f(x-size,y-size);
glVertex2f(x+size,y-size);
glEnd();
glFlush();
}
void mymose(int button,int state,int x,int y)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
drawsquare(x,y);
//if(button==GLUT_RIGHT_BUTTON_BUTTON && state==GLUT_UP)
// exit();
}
void myInit(){
glViewport(0,0,ww,wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,1.0);
glColor3f(1.0,0.0,0.0);
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(ww,wh);
glutInitWindowPosition(100,100);
glutCreateWindow("GLUT");
glutMouseFunc(mymose);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
You need a vector to store the points in.
Add points in the mouse callback and request a redraw via glutPostRedisplay().
Then in display() you can spin over all the points in the vector and draw quads around them:
#include <GL/glut.h>
#include <vector>
struct Point
{
Point( float x, float y ) : x(x), y(y) {}
float x, y;
};
std::vector< Point > points;
void mouse( int button, int state, int x, int y )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_UP )
{
points.push_back( Point( x, y ) );
}
if( button == GLUT_RIGHT_BUTTON && state == GLUT_UP )
{
points.clear();
}
glutPostRedisplay();
}
void display()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
int w = glutGet( GLUT_WINDOW_WIDTH );
int h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, h, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub( 255, 0, 0 );
glBegin( GL_QUADS );
for( size_t i = 0; i < points.size(); ++i )
{
const unsigned int SIZE = 20;
const Point& pt = points[ i ];
glVertex2i( pt.x - SIZE, pt.y - SIZE );
glVertex2i( pt.x + SIZE, pt.y - SIZE );
glVertex2i( pt.x + SIZE, pt.y + SIZE );
glVertex2i( pt.x - SIZE, pt.y + SIZE );
}
glEnd();
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutMouseFunc( mouse );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
Quick question:
How can I draw value of double using
glutBitmapCharacter
?
I tried many options but none of them works, I don't know how to convert double to char *
#include <GL/glut.h>
#include <sstream>
#include <iomanip>
void glString( const std::string str, void* font = GLUT_BITMAP_8_BY_13 )
{
for( size_t i = 0; i < str.size(); ++i )
{
glutBitmapCharacter( font, str[i] );
}
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, h, 0, -1, 1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub( 255, 255, 255 );
glRasterPos2i( 50, 50 );
double val = 3.14159265358979323846;
std::ostringstream oss;
oss << std::setprecision(17) << val;
glString( oss.str() );
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "Text" );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}