Not able to draw a rectangle in openGl - c

I am trying to draw a sqaure . I have given the co ordinates rightly. But I am
not getting a sqaure but a 5 sided polygon as shown in this figure.
I have given the following vertices
glVertex2f(-249, -249);
glVertex2f(-249,-209);
glVertex2f(-209,-249);
glVertex2f(-209, -209);
Here is My code:-
#include<GL/glut.h>
#include<stdio.h>
int x, y;
int rFlag = 0;
void draw_pixel(float x1, float y1)
{
glColor3f(0.0, 0.0, 1.0);
glPointSize(5.0);
glBegin(GL_POINTS);
glVertex2f(x1, y1);
glEnd();
}
void triangle()
{
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(-249, -249);
glVertex2f(-249,-209);
glVertex2f(-209,-249);
glVertex2f(-209, -209);
glEnd();
}
float th = 0.0;
float trX = 0.0, trY = 0.0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
if (rFlag == 1) //Rotate Around origin
{
trX = 0.0;
trY = 0.0;
th += 0.1;
draw_pixel(0.0, 0.0);
}
if (rFlag == 2) //Rotate Around Fixed Point
{
trX = x;
trY = y;
th += 0.1;
draw_pixel(x, y);
}
triangle();
glutPostRedisplay();
glutSwapBuffers();
}
void myInit()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-500.0, 500.0, -500.0, 500.0);
glMatrixMode(GL_MODELVIEW);
}
void rotateMenu(int option)
{
if (option == 1)
rFlag = 1;
if (option == 2)
rFlag = 2;
if (option == 3)
rFlag = 3;
}
int main(int argc, char** argv)
{
printf("Enter Fixed Points (x,y) for Rotation:\n");
scanf_s("%d %d", &x, &y);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Create and Rotate Triangle");
myInit();
glutDisplayFunc(display);
glutCreateMenu(rotateMenu);
glutAddMenuEntry("Rotate around ORIGIN", 1);
glutAddMenuEntry("Rotate around FIXED POINT", 2);
glutAddMenuEntry("Stop Rotation", 3);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
}

The order of the vertices is wrong. Change the order and draw the vertices either clockwise or counter clockwise:
glBegin(GL_POLYGON);
glVertex2f(-249, -249);
glVertex2f(-209, -249)
glVertex2f(-209, -209);
glVertex2f(-249, -209);
glEnd();

Related

more than one instance of overloaded function "abs" matches the argument list

The below code is for dynamic sort in visual code but getting an overload in line 116
if ( (abs(initial_x1 - cc2->x) < 0.3 && abs(initial_x2 - cc1->x) < 0.3) ) //set this to speed of animation
**Please note: the same code runs with no error on a mac which I am confused **
I have tried everything adding fabs, labs
according to the research I did but the errors keep piling up
any help will be appreciated
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<glut.h>
#include<conio.h>
#include<string.h>
#define MAX 10
int k = 0;
typedef struct circle
{
GLfloat x; //x axis of center
GLfloat y; //y axis of center
GLfloat r; // radius
}circle;
circle c[MAX]; //array of circles to store the center and radius of each circle
int a[MAX]; // int array for sorting algo
int initial[MAX] = { 10,4,8,6,3,7,9,1,5,2 }; //int array to restore random values after sorting
GLfloat initial_x1, initial_x2; //to set the destiniation for swapping
int global_i = 0, global_j = 0; //i and j values for bubble-sort
int swapping = 0; //flag to check if circle are being swapped
int sorting = 0; //start sorting only after user input
void initialise()
{
global_i = global_j = swapping = 0; //reset all globals
for (int i = 0; i < MAX; i++)
{
a[i] = initial[i]; //if a[] is sorted restore from initial[]
c[i].r = a[i] * 4.0; //4 because to fit 10 circles in screen
c[i].y = 300.0; //vertical center of window
if (i == 0)
c[i].x = 45.0; // first circle starts from 45 offset
else
c[i].x = c[i - 1].x + 90.0;//(c[i-1].r+c[i].r+10.0); //distance between circles = sum of 2 max readii
printf("%f - %f - %f\n", c[i].x, c[i].y, c[i].r); //for testing purpose don worry
}
}
//func to display text on screen char by char
void bitmap_output(int x, int y, const char* string, void* font)
{
int len, i;
glRasterPos2f(x, y);
len = (int)strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}
//function to integer to string
void int_str(int rad, char r[])
{
switch (rad)
{
case 1: strcpy(r, "1"); break;
case 2: strcpy(r, "2"); break;
case 3: strcpy(r, "3"); break;
case 4: strcpy(r, "4"); break;
case 5: strcpy(r, "5"); break;
case 6: strcpy(r, "6"); break;
case 7: strcpy(r, "7"); break;
case 8: strcpy(r, "8"); break;
case 9: strcpy(r, "9"); break;
case 10: strcpy(r, "10"); break;
}
}
//draw circle by drawing consecutive triangle fans
void circle_draw(circle c)
{
float i;
glBegin(GL_TRIANGLE_FAN);
glVertex2f(c.x, c.y); //center of circle
for (i = 0; i < 360; i += 1)
glVertex2f(c.x + sin(i) * c.r, c.y + cos(i) * c.r);
glEnd();
//display the value of circle below
int x = c.x - 2;
int y = c.y - (c.r + 10);
int rad = c.r / 4;
char r[3] = "";
int_str(rad, r);
glColor3f(0.0, 0.0, 0.0);
bitmap_output(x, y, r, GLUT_BITMAP_TIMES_ROMAN_10);
}
// swaps circles cc1 and cc2 by changing their centers
void swap_circles(circle* cc1, circle* cc2)
{
if (swapping == 0) //if circles are not being swapped set destination for each circles
{
initial_x1 = cc1->x; //center of circle in left
initial_x2 = cc2->x; //center of circle in right
swapping = 1; //means cicle are being swapped
printf("%f - %f\n", cc1->r, cc2->r);
}
if (initial_x1 <= cc2->x) //decrease the center of circle in right till its > center of left circle
cc2->x -= 1.0; //speed of animation
if (initial_x2 >= cc1->x)//increase the center of circle in left till its < center of right circle
cc1->x += 1.0;
printf("one %f - %f\n", initial_x1, cc2->x);
printf("two %f - %f\n", initial_x2, cc1->x);
// if difference between destination and center < 0.3 then cicles are swapped
if (abs(initial_x1 - cc2->x) < 0.3 && abs(initial_x2 - cc1->x) < 0.3) //set this to speed of animation
{
swapping = 0;
int temp = cc1->x;
cc1->x = cc2->x;
cc2->x = temp;
temp = cc1->y;
cc1->y = cc2->y;
cc2->y = temp;
temp = cc1->r;
cc1->r = cc2->r;
cc2->r = temp;
}
}
void sort() //bubble sort algo
{
if (!swapping) //if not in process of swappin 2 circles only then get 2 new circles to swap
{
while (global_i < 10)
{
global_j = global_i;
while (global_j < 9)
{
if (a[global_j] > a[global_j + 1])
{
printf("%d %d\n", global_j, a[global_j]);
int temp = a[global_j];
a[global_j] = a[global_j + 1];
a[global_j + 1] = temp;
goto SWAP;
}
global_j++;
}
global_i++;
}
}
SWAP:
printf("swapping --> %d - %d\n", global_j, global_j + 1);
bitmap_output(10, 375, "Swapping ->", GLUT_BITMAP_9_BY_15);
char r[3] = "";
int_str(a[global_j], r);
bitmap_output(150, 375, r, GLUT_BITMAP_9_BY_15);
int_str(a[global_j + 1], r);
bitmap_output(175, 375, r, GLUT_BITMAP_9_BY_15);
swap_circles(&c[global_j], &c[global_j + 1]);
}
void display_text()
{
bitmap_output(200, 565, "DYNAMIC SORTING ALGORITHM VISUALISER", GLUT_BITMAP_TIMES_ROMAN_24);//title larger font
glBegin(GL_LINE_LOOP); //to underline the title
glVertex2f(180, 560);
glVertex2f(750, 560);
glEnd();
//other text small font
bitmap_output(10, 525, "This program sorts a random set of numbers in ascending order displaying them graphically as ", GLUT_BITMAP_9_BY_15);
bitmap_output(10, 505, "circles with varying radii.", GLUT_BITMAP_9_BY_15);
if (sorting == 0)//if not sorting display menu
{
bitmap_output(10, 455, "MENU", GLUT_BITMAP_9_BY_15);
bitmap_output(10, 435, "Press s to SORT", GLUT_BITMAP_9_BY_15);
bitmap_output(10, 415, "Press r to RANDOMISE", GLUT_BITMAP_9_BY_15);
bitmap_output(10, 395, "Esc to QUIT", GLUT_BITMAP_9_BY_15);
}
else if (sorting == 1)
{
glColor3f(0.5, 0.5, 0.5);
bitmap_output(10, 455, "Sorting in progress...", GLUT_BITMAP_9_BY_15);
bitmap_output(10, 435, "Please do not quit", GLUT_BITMAP_9_BY_15);
glColor3f(0.0, 0.0, 0.0);
}
}
void front()
{
glColor3f(0.0, 0.0, 1.0);
bitmap_output(390, 565, "WELCOME!", GLUT_BITMAP_TIMES_ROMAN_24);
glBegin(GL_LINE_LOOP);
glVertex2f(388, 560);
glVertex2f(524, 560);
glEnd();
bitmap_output(440, 535, "TO", GLUT_BITMAP_TIMES_ROMAN_24);
glBegin(GL_LINE_LOOP);
glVertex2f(438, 531);
glVertex2f(475, 531);
glEnd();
bitmap_output(200, 495, "DYNAMIC SORTING ALGORITHM VISUALISER", GLUT_BITMAP_TIMES_ROMAN_24);
glBegin(GL_LINE_LOOP);
glVertex2f(198, 490);
glVertex2f(731, 490);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_QUADS);
glVertex2f(594, 120.0); glVertex2f(594, 145); glVertex2f(836, 145); glVertex2f(836, 120.0);
glEnd();
glColor3f(0.0, 1.0, 0.0);
bitmap_output(600, 125, "Press Enter to continue.......", GLUT_BITMAP_HELVETICA_18);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
if (k == 0)
front();
else
{
display_text();
glPointSize(2.0);
for (int i = 0; i < MAX; i++)
{
glColor3f(1.0, 0.0, 0.0);
circle_draw(c[i]);
}
if (global_j + 1 < MAX && sorting == 1) // call sort only on key press
sort();
else
sorting = 0;
}
glFlush();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
if (key == 13)
k = 1;
if (k == 1)
{
switch (key)
{
case 27: exit(0); //27 is the ascii code for the ESC key
case 's': sorting = 1; break;
case 'r': initialise(); break;
}
}
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-2.0, 2.0, -2.0 * (GLfloat)h / (GLfloat)w, 2.0 * (GLfloat)h / (GLfloat)w, -10.0, 10.0);
else
glOrtho(-2.0 * (GLfloat)w / (GLfloat)h, 2.0 * (GLfloat)w / (GLfloat)h, -2.0, 2.0, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 900.0, 0.0, 600.0);
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(50, 50);
glutInitWindowSize(900, 600);
glutCreateWindow("Dynamic Sorting Algorithm Visualiser");
init();
initialise();
glutDisplayFunc(display);
glutIdleFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
}
it was as simple as adding "fabs" instead of "abs"
due to the Foat datatype

Mandelbrot Set not displayed

a Mandelbrot set fractal using C programming and OpenGL. Here is my code. It is only displaying a dot in the center right now. I cannot figure out where I am going wrong. I'm pretty sure my math is correct. Maybe I have something in the wrong loop?
This picture is what Im trying to get
Here is my code so far:
#include <GLUT/glut.h>
#include <math.h>
void init(void);
void display(void);
const int screenWidth = 640;
const int screenHeight = 480;
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(screenWidth, screenHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Mandelbrot");
// glViewport(-320, -320, 320, 320);
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void init(void) {
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-500.0, screenWidth, -500.0, screenHeight);
// A = screenWidth / 4.0;
// B = 0.0;
// C = D = screenHeight / 2.0;
}
void display(void) {
GLdouble x, f, y, xtemp, y0, x0, iteration, maxInteration;
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(1);
glColor3f(0.0, 0.0, 0.0);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (y0 = - 1; y0 < 1.1; y0 = y0 + 0.0025) {
for (x0 = -2.5; x0 < 1.1; x0 = x0 + 0.0025) {
x = 0;
y = 0;
iteration = 0;
maxInteration = 1000;
while (((x * x) + (y * y) < (2 * 2)) && iteration < maxInteration) {
xtemp = (x * x) - (y * y) + x0;
y = (2 * x * y) + y0;
x = xtemp;
iteration = iteration + 1;
if (y <= 2) {
glBegin(GL_POINTS);
glVertex2d(x / 750, y / 750);
glEnd();
}
}
}
}
glFlush();
}
Here is my updated code after fixing suggestions in comments.. It results in the above image.. However, now I am trying to create the grey circles around the object??? Im attempting to do this through the else at the end... any thoughts?
#include <GLUT/glut.h>
#include <math.h>
void init(void);
void display(void);
const int screenWidth = 640;
const int screenHeight = 640;
GLdouble A, B, C, D;
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(screenWidth, screenHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Mandelbrot");
glViewport(-1, 1, -1, 1);
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void init(void) {
//glMatrixMode(GL_PROJECTION);
gluOrtho2D(-3.0, 3.0, -3.0, 3.0);
A = screenWidth / 4.0;
B = 0.0;
C = D = screenHeight / 2.0;
}
void display(void)
{
GLdouble x, f, y, xtemp, y0, x0, iteration, maxInteration;
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(1);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for(y0 = -1; y0< 1.1; y0 = y0 + 0.0025){
for (x0 = -2.5; x0 < 1.1; x0 = x0 + 0.0025) {
x = 0;
y = 0;
iteration = 0;
maxInteration = 200;
while(((x*x) + (y*y) <(2*2)) && iteration <maxInteration){
xtemp = (x*x) - (y*y) + x0;
y = (2*x*y) +y0;
x = xtemp;
iteration = iteration + 1;
}
if(iteration >= maxInteration){
glBegin(GL_POINTS);
glVertex2d(x0 , y0);
glColor3f(0.0, 0.0, 0.0);
glEnd();
}
else{
????
}
}
}
glFlush();
}
First of all, here's some advices regarding to your code:
When working with complex numbers or vectors i'd recommend you to use a proper fast math library so you can avoid operating with individual components, there are very fast cpu math libraries out there which can use SIMD instructions and your code will become more readable
The way your drawing the mandelbrot is really a bad idea. I mean, yeah, it's alright if you just want to dump simple images and learning the basics but that's pretty much. Don't use GL_POINTS and try to render/update textures directly, or even better, use fragment shaders + glsl (recommended way) so your mandelbrot will be rendered very fast even if you're using non-optimized maths.
Coordinate systems, if you still insist on using GL_POINTS the way you're doing, i'd just use directly the window coordinates and going from that space to the mandelbrot math domain ie: [0,0,w,h]<->[-1,-1,1,1]
Here's a little example of what i mean:
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
const int screen_width = 640;
const int screen_height = 480;
float c[4];
float z[4];
float clamp(float x, float vmin, float vmax) {
if (x < vmin) {
return vmin;
} else if (x > vmax) {
return vmax;
}
return x;
}
void dc_add(float *a, float *b, float *res) {
res[0] = a[0] + b[0];
res[1] = a[1] + b[1];
res[2] = a[2] + b[2];
res[3] = a[3] + b[3];
}
void dc_mul(float *a, float *b, float *res) {
res[0] = a[0] * b[0] - a[1] * b[1];
res[1] = a[0] * b[1] + a[1] * b[0];
res[2] = a[0] * b[2] + a[2] * b[0] - a[1] * b[3] - a[3] * b[1];
res[3] = a[0] * b[3] + a[3] * b[0] + a[2] * b[1] + a[1] * b[2];
}
void dc_sqr(float *a, float *res) {
res[0] = a[0] * a[0] - a[1] * a[1];
res[1] = 2.0f * a[0] * a[1];
res[2] = 2.0f * (a[0] * a[2] - a[1] * a[3]);
res[3] = 2.0f * (a[0] * a[3] + a[1] * a[2]);
}
float dot(float x, float y) { return x * x + y * y; }
void init(void) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, screen_width, 0, screen_height);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
for (int y = 0; y < screen_height; y++) {
for (int x = 0; x < screen_width; x++) {
float px = -1.0f + 2.0f * (float)x / (float)screen_width;
float py = -1.0f + 2.0f * (float)y / (float)screen_height;
px *= (float)screen_width / (float)screen_height;
float tz = 0.5f;
float zo = powf(1.2f, 1.2f);
float m2 = 0.0f;
float co = 0.0f;
float temp[4];
c[0] = px * zo; c[1] = py * zo; c[2] = 1.0; c[3] = 0.0;
z[0] = 0.0f; z[1] = 0.0f; z[2] = 0.0f; z[3] = 0.0f;
for (int i = 0; i < 256; i++) {
if (m2 > 1024.0f) continue;
dc_sqr(z, temp);
dc_add(temp, c, z);
m2 = dot(z[0], z[1]);
co += 1.0f;
}
float d = 0.0f;
if (co < 256.0f) {
d = sqrtf((dot(z[0], z[1]) / dot(z[2], z[3]))) *
logf(dot(z[0], z[1]));
}
d = clamp(4.0f * d / zo, 0.0f, 1.0f);
d = powf(d, 0.25f);
glColor3f(d, d, d);
glBegin(GL_POINTS);
glVertex2d(x, y);
glEnd();
}
}
glFlush();
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(screen_width, screen_height);
glutInitWindowPosition(0, 0);
glutCreateWindow("Mandelbrot");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
And here's the output:
Maths of the above example are based on this shadertoy.
The above code is terrible unefficient and slow but it serves the main purpose to prove you the way you shouldn't ever code a proper mandelbrot.
Happy coding.
There is a simple problem in you code: you use a division instead of a multiplication to compute the pixel coordinates: change glVertex2d(x / 750, y / 750); to
glVertex2d(x * 750, y * 750);
However, this is not the correct method to compute the Mandelbrot set. You should instead compute the number of iterations for the squared module to exceed 4.0, and then set the color of the pixel at (x0 * 300, y0 * 300) to that number as a palette entry or a gray level.

Draw doesn't works with OpenGL while drawing sphere

I'm first in OpenGL, and i want to draw a sphere with 3D graphical view.
For first step, i just want to draw a belt that contained to result sphere.
But there's no result, all of my result window is cleared with white.
Is there any problem in my code?
Here is my Code :
void init();
void display();
void drawPath(int pi, int theta);
void drawQuad(int pi, int theta);
int we = -80; // - 파이
int kyong = -180; // - 세타
int main(int argc, const char * argv[]) {
glutInit(&argc, (char**)argv);
glutInitWindowSize(500, 500);
glutCreateWindow("Prog09 - Goo");
glutDisplayFunc(display);
init();
glutMainLoop();
return 0;
}
void init(){
glClearColor(1, 1, 1, 1);
glOrtho(0, 50, 0, 50, -50, 50);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
}
void display(){
glColor3f(1.0, 1.0, 1.0);
drawPath(0, 0);
}
void drawPath(int pi, int theta){
drawQuad(pi, theta);
}
void drawQuad(pi, theta){
int i;
GLfloat x[4],y[4],z[4];
// theta = (theta * 3.14)/180;
// pi = (pi * 3.14)/180;
x[0] = sin(theta)*cos(pi);
y[0] = cos(theta)*sin(pi);
z[0] = sin(pi);
x[1] = sin(theta)*cos(pi+20);
y[1] = cos(theta)*sin(pi+20);
z[1] = sin(pi+20);
x[2] = sin(theta+20)*cos(pi+20);
y[2] = cos(theta+20)*sin(pi+20);
z[2] = sin(pi+20);
x[3] = sin(theta+20)*cos(pi);
y[3] = cos(theta+20)*sin(pi);
z[3] = sin(pi);
for (i = 0; i < 4; i++) {
glBegin(GL_POLYGON);
glVertex3f(x[i]*10, y[i]*10, z[i]*10);
glEnd();
}
glFlush();
for (i = 0; i < 4; i++) {
printf("%d. %f %f %f\n",i+1, x[i], y[i], z[i]);
}
printf("WHY?\n");
}
I know it's a basic question, but i have know idea why my codes doesn't work.
Thanks for your helps.
You are drawing a number of polygons, were each polygon contains exactly one point:
for (i = 0; i < 4; i++) {
glBegin(GL_POLYGON);
glVertex3f(x[i]*10, y[i]*10, z[i]*10);
glEnd();
}
If you want to draw one polygon with all the points, then you'll have to do something like:
glBegin(GL_POLYGON);
for (i = 0; i < 4; i++) {
glVertex3f(x[i]*10, y[i]*10, z[i]*10);
}
glEnd();

Drawing multiple objects in OpenGL using C

I have an OpenGL program to draw a circle by mouse click. The program works fine except when I try to draw multiple circles the previous circle disappears. Here is the code:
#include <GL/glut.h>
#include<math.h>
#include<stdio.h>
struct position
{
float x;
float y;
};
typedef struct position Position;
Position start;
Position finish;
void setPixel(int x, int y)
{
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
}
void circle(int a0, int b0, int a1, int b1)
{
int i, x, y, x1, y1, r, p;
x1 = (a0+a1)/2;
y1 = (b0+b1)/2;
r = sqrt((((a1-x1)*(a1-x1))+((b1-y1)*(b1-y1))));
p = (5/4-r);
x = 0;
y = r;
while(x <= y)
{
setPixel( x+x1, y+y1);
setPixel( x+x1, -y+y1);
setPixel(-x+x1, -y+y1);
setPixel(-x+x1, y+y1);
setPixel( y+x1, x+y1);
setPixel( y+x1, -x+y1);
setPixel(-y+x1, -x+y1);
setPixel(-y+x1, x+y1);
x = x+1;
if (p<0)
p = p+2*x+1;
else {
y = y-1;
p = p+2*x-2*y+1;
}
}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glPushMatrix();
circle(start.x, start.y, finish.x, finish.y);
glPopMatrix();
glutSwapBuffers();
}
void reshape( int w, int h)
{
glViewport( 0, 0, w, h);
glMatrixMode( GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, w, h, 0, -1, 1);
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN)
{
start.x = x; //x1
start.y = y; //y1
}
if(state == GLUT_UP)
{
finish.x = x; //x2
finish.y = y; //y2
}
break;
glutPostRedisplay();
}
}
void motion( int x, int y)
{
finish.x = x;
finish.y = y;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("");
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
How can I display multiple images together?
If you want to draw multiple things, then draw multiple things. You're only drawing one circle. If you change the position of that circle, it will just be drawn in a different place.
However I really wouldn't recommend drawing like this in GL. Using the fixed-function pipeline to draw individual pixels as GL_POINTS is exceedingly inefficient. GL is not designed as a raster drawing API.

how to convert simple opengl line plotting code to use vertex array

I wrote a simple opengl application in C which plots sin(x). This is my current draw function which runs very slow. How do I have to convert this code to make use of the faster 'vertex array' mode?
list of variables and functions used:
N = total number of points
x1 = min(x)
x2 = max(x)
y1 = min(y)
y2 = max(y)
func(x) = sin(x)
and here's the entire code:
/* to compile, do:
$ gcc -o out simple.c -lglut
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <time.h>
float xmin = -10, xmax = 10, ymin = -5, ymax = 5;
int nPoints = 3000;
/* function to calculate each data point */
float func(float x)
{
return sin(x);
}
/* plotting function - very slow */
void draw(float (* func)(float x), float x1, float x2, float y1, float y2, int N)
{
float x, dx = 1.0/N;
glPushMatrix();
glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
glTranslatef(-x1, -y1, 0.0);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for(x = x1; x < x2; x += dx)
{
glVertex2f(x, func(x));
}
glEnd();
glPopMatrix();
};
/* Redrawing func */
void redraw(void)
{
clock_t start = clock();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// -x, +x, -y, +y, number points
draw(func, xmin, xmax, ymin, ymax, nPoints);
glutSwapBuffers();
printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
};
/* Idle proc. Redisplays, if called. */
void idle(void)
{
// shift 'xmin' & 'xmax' by one.
xmin++;
xmax++;
glutPostRedisplay();
};
/* Key press processing */
void key(unsigned char c, int x, int y)
{
if(c == 27) exit(0);
};
/* Window reashape */
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
};
/* Main function */
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Graph plotter");
glutReshapeWindow(1024, 800);
glutPostRedisplay(); // This call may or may not be necessary
/* Register GLUT callbacks. */
glutDisplayFunc(redraw);
glutKeyboardFunc(key);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
/* Init the GL state */
glLineWidth(2.0);
/* Main loop */
glutMainLoop();
return 0;
}
In terms of LodePNG's C-style vector struct/functions:
// shared
vector pts;
vector_init( &pts, sizeof( float ) );
// whenever x1, x2, or N changes
vector_cleanup( &pts );
float x, dx = 1.0/N;
for(x = x1; x < x2; x += dx)
{
vector_resize( &pts, pts.size + 2 );
*(float*)vector_get( &pts, pts.size-2 ) = x;
*(float*)vector_get( &pts, pts.size-1 ) = func(x);
}
// whenever you want to draw
glPushMatrix();
glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
glTranslatef(-x1, -y1, 0.0);
glColor3f(1.0, 1.0, 1.0);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, (float*)pts.data );
glDrawArrays( GL_LINE_STRIP, 0, pts.size / 2 );
glDisableClientState( GL_VERTEX_ARRAY );
glPopMatrix();
EDIT: Complete code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <time.h>
typedef struct vector /*dynamic vector of void* pointers. This one is used only by the deflate compressor*/
{
void* data;
size_t size; /*in groups of bytes depending on type*/
size_t allocsize; /*in bytes*/
unsigned typesize; /*sizeof the type you store in data*/
} vector;
static unsigned vector_resize(vector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
{
if(size * p->typesize > p->allocsize)
{
size_t newsize = size * p->typesize * 2;
void* data = realloc(p->data, newsize);
if(data)
{
p->allocsize = newsize;
p->data = data;
p->size = size;
}
else return 0;
}
else p->size = size;
return 1;
}
static void vector_cleanup(void* p)
{
((vector*)p)->size = ((vector*)p)->allocsize = 0;
free(((vector*)p)->data);
((vector*)p)->data = NULL;
}
static void vector_init(vector* p, unsigned typesize)
{
p->data = NULL;
p->size = p->allocsize = 0;
p->typesize = typesize;
}
static void* vector_get(vector* p, size_t index)
{
return &((char*)p->data)[index * p->typesize];
}
float xmin = -10, xmax = 10, ymin = -5, ymax = 5;
int nPoints = 3000;
vector pts;
/* function to calculate each data point */
float func(float x)
{
return sin(x);
}
void update(float (* func)(float x), float x1, float x2, int N)
{
float x, dx = 1.0/N;
vector_cleanup( &pts );
for(x = x1; x < x2; x += dx)
{
vector_resize( &pts, pts.size + 2 );
*(float*)vector_get( &pts, pts.size-2 ) = x;
*(float*)vector_get( &pts, pts.size-1 ) = func(x);
}
}
/* plotting function - very slow */
void draw(float x1, float x2, float y1, float y2)
{
glPushMatrix();
glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
glTranslatef(-x1, -y1, 0.0);
glColor3f(1.0, 1.0, 1.0);
if( pts.size > 0 )
{
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, (float*)pts.data );
glDrawArrays( GL_LINE_STRIP, 0, pts.size / 2 );
glDisableClientState( GL_VERTEX_ARRAY );
}
glPopMatrix();
};
/* Redrawing func */
void redraw(void)
{
clock_t start = clock();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// -x, +x, -y, +y, number points
draw(xmin, xmax, ymin, ymax);
glutSwapBuffers();
printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
};
/* Idle proc. Redisplays, if called. */
void idle(void)
{
// shift 'xmin' & 'xmax' by one.
xmin++;
xmax++;
update(func, xmin, xmax, nPoints);
glutPostRedisplay();
};
/* Key press processing */
void key(unsigned char c, int x, int y)
{
if(c == 27) exit(0);
};
/* Window reashape */
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
};
/* Main function */
int main(int argc, char **argv)
{
vector_init( &pts, sizeof( float ) );
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Graph plotter");
glutReshapeWindow(1024, 800);
glutPostRedisplay(); // This call may or may not be necessary
/* Register GLUT callbacks. */
glutDisplayFunc(redraw);
glutKeyboardFunc(key);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
/* Init the GL state */
glLineWidth(2.0);
/* Main loop */
glutMainLoop();
return 0;
}

Resources