OpenGL in Ubuntu (C Language) saying things are undeclared - c

So I just started learning OpenGL and I'm doing so Ubuntu with the C language.
I have done a few examples from my lecturers notes and they worked however this one is giving me errors.
callbackexample.c: In function ‘main’:
callbackexample.c:17:18: error: ‘displays’ undeclared (first use in this function)
callbackexample.c:17:18: note: each undeclared identifier is reported only once for each function it appears in
and so on for every method in my file.
I followed his notes word for word and I'm getting this so I'm not sure whats going wrong.
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#define DEG_TO_RAD 0.017453
int singleb, doubleb; //window ids
GLfloat theta = 0.0;
int main(int argc, char **argv){
glutInit(&argc, argv);
//create single buffered window
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
singleb = glutCreateWindow("single_buffered");
glutDisplayFunc(displays);
glutReshapeFunc(myReshape);
glutIdleFunc(spinDisplay);
glutMouseFunc(mouse);
glutKeyboardFunc(mykey);
//create double buffered window
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(400,0); //create window to the right
doubleb = glutCreateWindow("double_buffered");
glutDisplayFunc(displayd);
glutReshapeFunc(myReshape);
glutIdleFunc(spinDisplay);
glutMouseFunc(mouse);
glutCreateMenu(quit_menu);
glutAddMenuEntry("quit", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
}
void displays() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f ( cos(DEG_TO_RAD * theta),
sin(DEG_TO_RAD * theta));
glVertex2f ( -sin(DEG_TO_RAD * theta),
cos(DEG_TO_RAD * theta));
glVertex2f ( -cos(DEG_TO_RAD * theta),
-sin(DEG_TO_RAD * theta));
glVertex2f ( sin(DEG_TO_RAD * theta),
-cos(DEG_TO_RAD * theta));
glEnd();
glFlush();
}
This is just some code of the main method and the first method after it which I get an error on. By undeclared I guess it means that the methods aren't declared but I followed his code so I'm not sure

You try to use the displays method in the main function, before declaring it. You need to either move the entire function before the main function or add the stub to the top:
void displays();
int main(int argc, char **argv){
...
}
void displays(){
...
}
C parses everything in the order it sees it - you cannot use a method that hasn't been declared in its entirety, or at least had a declaration that it will exist at some point.
In regards to your comments:
The cannot find -l* stuff you are getting implies that you either haven't installed the development libraries for OpenGL or have them set up strangely - this is saying that it cannot find the library files to link against.
Additionally, the mykey problem implies that you either haven;t declared a mykey function or are not declaring it as per the prototype:
void mykey(unsigned char key, int x, int y)

Related

DDA Line Drawing Algorithm has errors

Why am I getting an error saying 'setPixel not defined' with this code?
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include<GL/glut.h>
inline int round(const float a)
{
return int (a+0.5);
}
void init(void)
{
glClearColor(0.0f,0.0f,1.0f,1.0f);
gluOrtho2D(0.0,200.0,0.0,200.0);
glMatrixMode(GL_PROJECTION);
}
void LineSegment(int xa, int ya,int xb,int yb)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
printf("Enter the initial value");
scanf("%d%d",&xa,&ya);
printf("Enter the final value");
scanf("%d%d",&xb,&yb);
int dx=xb-xa;
int dy=yb-ya;
int steps,k;
float xIncrement,yIncrement,x=xa,y=ya;
if(fabs(dx)>fabs(dy))
steps=fabs(dx);
else
steps=fabs(dy);
xIncrement=dx/(float)steps;
yIncrement=dy/(float)steps;
setPixel(round(x),round(y));
for(k=0;k<steps;k++);
{
x += xIncrement;
y += yIncrement;
setPixel(round(x),round(y));
}
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA);
glutCreateWindow("DDA Line Algorithm");
glutDisplayFunc(LineSegment);
init();
glutMainLoop();
return 0;
}
Because there is no setPixel method in OpenGL or GLUT and as far as I can see from your code, you do not define one either. OpenGL deals with rendering primitives like points, lines, triangels etc, but not directly with setting single pixels on the screen. Since it is unclear what you want to achieve some suggestions:
If you want to draw a line in OpenGL, use the appropriate methods like glBegin(GL_LINES), etc. (although they are deprecated and should not be used anymore.) or glDrawArrays(GL_LINES, ....
If the goal is to implement a dda software rasterizer, then you might have to write the pixels to a texture and then display this texture.
Because you haven't defined setPixel anywhere. It's not an OpenGL call. You need to write it yourself, and it should set pixels on a buffer (if you're using double buffering) which you then later use as an argument to glDrawPixels(), or a call to the display buffer using glVertex2i(x,y). You can see an example of both approaches here and here.
Also, your LineSegment function is broken. In OpenGL you call glutDisplayFunc to specify a function which is called as fast as possible to render the display. However, in this function you call scanf() to prompt the user for data - this is broken. You should prompt them once at the start, and then pass that data into the function (which will then run as often as possible once glutMainLoop is called).

Accessing custom XResources colors with X11

I'm just starting my first ever program using the X11 library. To start, I'm just trying to access the colors from the user's color-scheme as defined in xrdb. For example, in my ~/.Xresources I have things like:
*color8: #073642
*color0: #002b36
I've also verified that these colors show up when I run xrdb -query. In my C program so far I have:
#include <X11/Xlib.h>
#include <X11/Xresource.h>
int main (int argc, char *argv[])
{
Display* display = XOpenDisplay (0);
XrmDatabase xrdb = XrmGetDatabase (display);
XrmValue v;
Colormap cmap = DefaultColormap (display, DefaultScreen (display));
XColor screenColor;
XColor exactColor;
if (! XAllocNamedColor (display, cmap "color0", &screenColor, &exactColor))
printf ("ERROR\n");
printf ("%u %u %u\n", screenColor.red, screenColor.green, screenColor.blue);
return 0;
}
But this errors. So what am I missing? Is there a better way to do what I'm trying to do? Thanks!
When you want to access parameters set in an Xresource file loaded by xrdb, you need to
xrdb = XrmGetStringDatabase(XResourceManagerString(display));
instead of XrmGetDatabase(...). Hope that addresses (lately) your question.

How to extern SDL_Surface array in C?

I want to extern a SDL_Surface array from one function (load_level) to another (initialize_balls). I have to say that the SDL_Surface (brickim) is a dynamic pointer-struct which is defined inside of load_level function via malloc function and declared as SDL_Surface **brickim as well. I got a segmentation fault when I try to access brickim[0]->w in the initialize_balls function but not in the load_level function. This is the piece of code I hope you could help me to fix.
file1.c
#include <stdio.h>
#include <SDL.h>
SDL_Surface **brickim; /*as global*/
SDL_Surface* load_map(char *map_name , int tran );
void load_level(int stage){
int n;
SDL_Surface **brickim=( SDL_Surface **)malloc(sizeof(SDL_Surface)*input.N);
for (n=0;n < input.N;n++){
**brickim[n]=load_map("brick1.bmp",1); /*load SDL_Surfaces*/**
printf("%d\n",brickim[n]->w); /***access succesfully (returns 100 N times)***/
}
...
}}
SDL_Surface* load_map(char *map_name , int tran ){
SDL_Surface *temp,*map;
Uint32 colorkey;
printf("Loading bit map %s %d...\n",map_name,tran);
temp = SDL_LoadBMP(map_name);
if (temp == NULL){
printf("Unable to load bitmap: %s\n", SDL_GetError());
SDL_FreeSurface(temp);
exit(0);
}else{
map = SDL_DisplayFormat(temp);
colorkey = SDL_MapRGB( map -> format, 132, 0, 12);
if ( tran==1 ) SDL_SetColorKey( map, SDL_SRCCOLORKEY, colorkey );
SDL_FreeSurface(temp);
}
return map;
}
file2.c
#include <SDL.h>
#include <stdlib.h>
#include <stdio.h>
extern SDL_Surface **brickim;/*brings brickim to this function*/
void initialize_balls()
{
printf("Into initialization :)\n ");
printf("%d \n",brickim[0]->w); /***returns segmentation fault***/
}
$./kuranes
Loading bit map brick1.bmp 1...
level image:) 100 (x10 times)
Into initialization :)
Violación de segmento (`core' generado)
Everything was running ok when I used a single SDL_Surface compiled with gcc but I need to do it dynamically. I think something very basic is missing.
Your problem seems to be here. You declare a global brickim, this will be what the extern declaration finds. You then, in load_level, declare a local brickim variable. You can declare a variable with the same name in different scopes, but the global brickim will not be used within load_level, the local one will. Therefore, while you do malloc into the local brickim, you don't ever assign into the global brickim - and therefore if you access it via extern, it will be NULL and you'll segfault.
SDL_Surface **brickim; /*as global*/
SDL_Surface* load_map(char *map_name , int tran );
void load_level(int stage){
int n;
SDL_Surface **brickim=( SDL_Surface **)malloc(sizeof(SDL_Surface)*input.N);
for (n=0;n < input.N;n++){
**brickim[n]=load_map("brick1.bmp",1); /*load SDL_Surfaces*/**
printf("%d\n",brickim[n]->w); /***access succesfully (returns 100 N times)***/
}
...
}}
edit: you might want to check that whole allocation in general. I'm not familiar with the SDL_Surface struct, but i assume it's not a pointer type (it's a generic struct). Your allocation is actually allocating N structures, but you're casting as if you're allocating N pointers to SDL_Surface structures. Don't cast malloc.
If you want N SDL_Surface structures, you only need to have:
SDL_Surface * brickim = malloc(sizeof(SDL_Surface) * N)
If you want N pointers to SDL_Surface structures, you would need:
SDL_Surface ** brickim = malloc(sizeof(SDL_Surface *) * N)
for( i = 0; i < N; i++){
// you've only allocated an array of pointers so far, you now need
// allocate N structures
brickim[0] = malloc(sizeof(SDL_Surface));
}

How to implement functions that work on turtle graphics in C?

So i've been trying to get this function to draw a red box using turtle graphics but it seems like the function is being ignored. Here is my code:
int main(int agrc, char*argc[])
{
create_turtle_world();
void draw_red();
return (p1world_shutdown());
}
void draw_red()
{
pen_colour(RED);
forward(150);
turn(90);
forward(50);
turn(90);
forward(150)
turn(90);
forward(50);
turn(90);
turn(-90);
}
I don't know what I did wrong here, it's compiled correctly, just not drawing a box.
In main(), instead of
void draw_red(); //function declaration
you've to use
draw_red(); //function call

screenshot using openGL and/or X11

i am trying to get a screenshot of the screen or a window. I tried using functions from X11
and it works fine. The problem is that getting the pixels from XImage takes a lot of time.
Than i tried to look for some answers on how to do it using openGL. Here's what i've got:
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
int main(int argc, char **argv)
{
int width=1200;
int height=800;
//_____________________________----
Display *dpy;
Window root;
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi;
GLXContext glc;
dpy = XOpenDisplay(NULL);
if ( !dpy ) {
printf("\n\tcannot connect to X server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);
if (!vi) {
printf("\n\tno appropriate visual found\n\n");
exit(0);
}
glXMakeCurrent(dpy, root, glc);
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));
//____________________________________________
glXMakeCurrent(dpy, root, glc);
glEnable(GL_DEPTH_TEST);
GLubyte* pixelBuffer = new GLubyte[sizeof(GLubyte)*width*height*3*3];
glReadBuffer(GL_FRONT);
GLint ReadBuffer;
glGetIntegerv(GL_READ_BUFFER,&ReadBuffer);
glPixelStorei(GL_READ_BUFFER,GL_RGB);
GLint PackAlignment;
glGetIntegerv(GL_PACK_ALIGNMENT,&PackAlignment);
glPixelStorei(GL_PACK_ALIGNMENT,1);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_INT, pixelBuffer);
int i;
for (i=0;i<100;i++) printf("%u\n",((unsigned int *)pixelBuffer)[i]);
return 0;
}
when i run the program it returns an error:
X Error of failed request: BadAccess (attempt to access private resource denied)
Major opcode of failed request: 199 ()
Minor opcode of failed request: 26
Serial number of failed request: 20
Current serial number in output stream: 20
if i comment the line with glXMakeCurrent(dpy, root, glc); before glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); it returns no erros, but all the pixels are 0.
How should i go about this problem? I am new to openGL and maybe i am missing something important here. Maybe also another way of getting pixels from the screen or specific window exists?
I don't think what you are trying to do is possible. You can't use OpenGL to read pixels from window you don't own and which probably don't even use OpenGL. You need to stick to X11.
If you have XImage you can get raw pixels from ximage->data. Just make sure you are reading it in correct format.
http://tronche.com/gui/x/xlib/graphics/images.html
You can use XShmGetImage, but you have to query the extensions of the X11 server first, to make sure MIT-SHM extension is available. You also need to know how to setup and use a shared memory segment for this.
Querying the Extension:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l224
Getting the image:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l537
The following runs once at 140 fps on my platform. xcb_image_get() (called with XCB_IMAGE_FORMAT_Z_PIXMAP) will store all pixels in ximg->data, pixel by pixel. On my platform, each pixel is 32 bits, each channel is 8 bits, and there's 3 channels (to 8 bits per pixel are unused).
/*
gcc ss.c -o ss -lxcb -lxcb-image && ./ss
*/
#include <stdio.h>
#include <xcb/xcb_image.h>
xcb_screen_t* xcb_get_screen(xcb_connection_t* connection){
const xcb_setup_t* setup = xcb_get_setup(connection); // I think we don't need to free/destroy this!
return xcb_setup_roots_iterator(setup).data;
}
void xcb_image_print(xcb_image_t* ximg){
printf("xcb_image_print() Printing a (%u,%u) `xcb_image_t` of %u bytes\n\n", ximg->height, ximg->width, ximg->size);
for(int i=0; i < ximg->size; i += 4){
printf(" ");
printf("%02x", ximg->data[i+3]);
printf("%02x", ximg->data[i+2]);
printf("%02x", ximg->data[i+1]);
printf("%02x", ximg->data[i+0]);
}
puts("\n");
}
int main(){
// Connect to the X server
xcb_connection_t* connection = xcb_connect(NULL, NULL);
xcb_screen_t* screen = xcb_get_screen(connection);
// Get pixels!
xcb_image_t* ximg = xcb_image_get(connection, screen->root, 0, 0, screen->width_in_pixels, screen->height_in_pixels, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
// ... Now all pixels are in ximg->data!
xcb_image_print(ximg);
// Clean-up
xcb_image_destroy(ximg);
xcb_disconnect(connection);
}

Resources