It might sound a little strange, but I can't correctly use the Draw_Pixel() and Draw_Line() functions of SDL_Draw.h
I've googled and people state: It's very simple to use, but unfortunately... not for me.
I've written a very simple piece of code but it doesn't show me the pixel, I tried also with a line, but nothing as well.
The simple code is:
#include <SDL.h>
#include "SDL_draw.h"
int main(int argc, char** argv)
{
SDL_Surface* surf;
if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
return -1;
}
if((surf = SDL_SetVideoMode(WIDTH, HEIGTH, BBP, FLAGS)) == NULL) {
return -1;
}
Uint32 myColor = SDL_MapRGB( surf->format, 255, 25, 23); //this is the red color
Draw_Pixel(surf, 45, 45, myColor);
Draw_Line(surf, 45, 20, 90, 100, myColor);
SDL_Quit();
return 1;
}
The x,y coordinates are just random. I'm trying to see the result with breakpoints in Visual Studio.
Can anyone tell me where I'm mistaking?
You have to update your surface by calling SDL_Flip( SDL_Surface * screen) ;
And add a delay before exiting the program, otherwise you wont see the window.
Related
I am trying to develop a little Linux application to perform measurements directly on the screen i.e. to measure distances and angles in images, documents etc.
To this end I was inspired by How to listen for mouse events in Linux?
and thought I could use XNextEvent or XPeekEvent and possibly XPutBackEvent.
This program responds nicely to mouse events but since it uses XNextEvent the bucket stops there and the event is not sent to the target window and the mouse becomes useless and if I use XPutBackEvent the same event comes back again.
To fix this I replaced XNextEvent with XPeekEvent, which is supposed to send the event up the ladder. This didn't help but made things worse sending an endless stream of the same event, filtering
out equal events didn't help either.
Thanks in advance for any tip to solve this problem.
The problem is basically that the events do not disappear and I don't know how to get rid of them in order to be able to use the mouse. The code below is copied from
How to listen for mouse events in Linux? and somewhat modified.
#include <stdio.h>
#include <X11/Xlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
char *key_name[] = {
"first",
"second (or middle)",
"third",
"fourth", // :D
"fivth" // :|
};
int main(int argc, char **argv)
{
Display *display;
XEvent xevent,oldevent;
Window window;
long unsigned int buttontime=0;
if( (display = XOpenDisplay(NULL)) == NULL )
return -1;
window = DefaultRootWindow(display);
XAllowEvents(display, AsyncBoth, CurrentTime);
XGrabPointer(display,
window,
1,
//PointerMotionMask |
ButtonPressMask | ButtonReleaseMask ,
GrabModeAsync,
GrabModeAsync,
None,
None,
CurrentTime);
while(1)
{
XNextEvent(display, &xevent);
//XPeekEvent(display, &xevent);
switch (xevent.type) {
/*case MotionNotify:
printf("Mouse move : [%d, %d]\n", xevent.xmotion.x_root, xevent.xmotion.y_root);
break;*/
case ButtonPress:
//if ((buttontime <= xevent.xbutton.time))
{
printf("Button pressed : %s\n", key_name[xevent.xbutton.button - 1]);
printf("timevent %lu\n",xevent.xbutton.time);
printf("timeold %lu\n",buttontime);
buttontime = xevent.xbutton.time;
buttontime++;
}
break;
case ButtonRelease:
printf("Button released : %s\n", key_name[xevent.xbutton.button - 1]);
break;
}
// XPutBackEvent(display, &xevent);
sleep(1);
}
return 0;
}
I've been testing ncurses, I tried doing a simple code using windows, by reading the code from the tutorials it seemed to me like calling wrefresh() was enough if changes were made just to one window. So I tried the following code, but it doesn't work, does anyone know why?
#include <ncurses.h>
int main (void) {
int ch;
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
WINDOW *my_window = newwin(10, 20, 3, 4);
box(my_window, 0, 0);
wrefresh(my_window);
while ((ch=getch()) != 'q');
endwin();
return 0;
}
If I add an extra call to refresh() before wrefresh() everything works fine.
#include <ncurses.h>
int main (void) {
int ch;
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
WINDOW *my_window = newwin(10, 20, 3, 4);
box(my_window, 0, 0);
refresh();
wrefresh(my_window);
while ((ch=getch()) != 'q');
endwin();
return 0;
}
I've tried several things, for instance calling refresh() after wrefresh() doesn't work either, using only refresh() also does not work. Also example 7 in this guide shows after calling refresh() once, it is enough to just call wrefresh() in the while loop.
Is it always mandatory to make a call to refresh() at least once after initscr()? the documentation does not seem to mention this.
Calling getch is the same as wgetch(stdscr). When you call wgetch, it refreshes the window that it uses as a parameter. If you are trying to refresh a different window (such as my_window), then you should use that window as the parameter.
In your example, there is nothing interesting that is written to stdscr. So you can omit the plain refresh() call.
With those changes, the program is
#include <ncurses.h>
int main (void) {
int ch;
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
WINDOW *my_window = newwin(10, 20, 3, 4);
box(my_window, 0, 0);
while ((ch=wgetch(my_window)) != 'q');
endwin();
return 0;
}
For a more interesting demo, you could write into the window. That is best done with a subwindow, so that it can be scrolled, e.g.,
#include <ncurses.h>
int main (void) {
WINDOW *my_window;
WINDOW *my_scroller;
int ch;
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
if ((my_window = newwin(10, 20, 3, 4)) != 0) {
box(my_window, 0, 0);
wrefresh(my_window);
if ((my_scroller = derwin(my_window, 8, 18, 1, 1)) != 0) {
scrollok(my_scroller, TRUE);
while ((ch=wgetch(my_scroller)) != 'q') {
wprintw(my_scroller, "%#x - %s\n", ch, keyname(ch));
}
}
}
endwin();
return 0;
}
I have created a simple OpenGL window with SDL2. I'm running this on Linux and my WM is xfwm4.
My problem is that if I change workspace (with ctrl+alt+arrows) while window is not focused, it will raise itself. This makes the window appear on the new workspace, or (depending on the WM settings) immediately switches the workspace back. Is there way to prevent this?
Here's a testcase that demonstrates this behavior:
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 200, 200, SDL_WINDOW_OPENGL);
SDL_GLContext glcontext = SDL_GL_CreateContext(window);
glEnable(GL_SCISSOR_TEST);
while (1)
{
SDL_Event e;
SDL_PollEvent(&e);
if (e.type == SDL_QUIT || e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)
break;
// a small opengl effect, please don't mind
int bs = (rand() % 50) + 50; int bo = (200-bs)/2;
float t = SDL_GetTicks()*0.001f; glScissor(0, cos(t*18.92623f)*bo+bo,200,bs);
float g = sin(t)*0.5f+0.5f; glClearColor(2.0f*g,1.5f*g,0.8f*g,0.f); glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
}
SDL_GL_DeleteContext(glcontext);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
#include "stdafx.h"
#include <gl/glut.h>
void resizeEvent(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void displayEvent()
{
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers();
char text[] = "Hello World!";
glRasterPos2d(110, 110);
glColor3f(1, 0, 0);
for(int i=0; text[i] != '\0'; i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, text[i]);
}
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 300);
glutInitWindowPosition(0, 0);
glutCreateWindow("Hello");
glutDisplayFunc(displayEvent);
glutReshapeFunc(resizeEvent);
glutMainLoop();
return 0;
}
I learn from a ppt,and think it will print a string.But it does not work .I search from google,but no answer. I don't know why it can't print a string.
if glutBitmapCharacter is wrong ?
All the commands in opengl, renders on the frame buffer only when flush or finish call happens, so all your commands are still in queue and yet to be displayed on frame buffer. You need to call glFlush/glFinish at the end, glut provides glutSwapBuffers, so in the end of your displayEvent function you need to call glutSwapBuffers to see the effect of your displayEvent function.
thank you for you time in advance.
Very new to MFC and attempting to finish a cs project before Sunday. We are to create a simple program that displays polygons in a grid. Rectangles are working great, but as I begin to add triangles, I cannot for the of me figure out why the triangle dialog box refuses to display. Here is some code:
CEquilDialog.h:
#include <afxwin.h>
class CEquilDialog : public CDialog {
public:
CEquilDialog();
afx_msg void OnOK();
afx_msg void OnCancel();
int m_nSideLength;
COLORREF m_Color;
private:
DECLARE_MESSAGE_MAP()
};
CEquilDialog.cpp:
#include "CEquilDialog.h"
#include "CEquilateralIds.h"
const int TEXT_MAX = 20;
CEquilDialog::CEquilDialog() : CDialog("Equilateral Traingle") {
m_nSideLength = 0;
}
afx_msg void CEquilDialog::OnOK() {
char editText[TEXT_MAX + 1];
CEdit* SideLengthEdit = (CEdit* )(GetDlgItem(IDC_SideLength));
SideLengthEdit->GetWindowText(editText,TEXT_MAX);
m_nSideLength = atoi(editText);
if (m_nSideLength <= 0) {
EndDialog(!IDOK);
return;
}
int color = GetCheckedRadioButton(IDC_Red, IDC_Blue);
switch(color) {
case IDC_Red:
m_Color = RGB(255,0,0);
break;
case IDC_Yellow:
m_Color = RGB(255,255,0);
break;
case IDC_Blue:
m_Color = RGB(0,0,255);
break;
default:
m_Color = RGB(255,255,255);
}
EndDialog(IDOK);
}
afx_msg void CEquilDialog::OnCancel() {
m_nSideLength = 0;
EndDialog(!IDOK);
}
BEGIN_MESSAGE_MAP(CEquilDialog, CDialog)
ON_COMMAND(IDC_OK, OnOK)
ON_COMMAND(IDC_Cancel, OnCancel)
END_MESSAGE_MAP()
CEquilateralIds.h
#define IDC_OK 2000
#define IDC_Cancel 2011
#define IDC_SideLength 2012
#define IDC_Red 2013
#define IDC_Yellow 2014
#define IDC_Blue 2015
Equilateral.rc (resource file)
#include <afxres.h>
#include "CEquilateralIds.h"
Equilateral DIALOG 50,50,150,150
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Create Triangle"
{
LTEXT "Enter Side Length", IDC_STATIC, 10, 5, 50, 8
EDITTEXT IDC_SideLength, 25, 15, 60, 16
GROUPBOX "Select color", IDC_STATIC, 10, 70, 60+15, 50
AUTORADIOBUTTON "Red", IDC_Red, 25, 80, 50, 16, WS_GROUP
AUTORADIOBUTTON "Yellow", IDC_Yellow, 25, 91, 50, 16
AUTORADIOBUTTON "Blue", IDC_Blue, 25, 102, 50, 16
PUSHBUTTON "OK", IDC_OK, 10, 125, 30, 15, NOT WS_TABSTOP
PUSHBUTTON "Cancel", IDC_Cancel, 10+60+15, 125, 30, 15, NOT WS_TABSTOP
}
All of this code is identical to my rectangle files (same files just with rectangle instead of equil, also with height and width instead of just SideLength) -- and here is the CShapesWin.cpp (where the dialog box gets called):
#include <afxwin.h>
#include "CShapesWin.h"
#include "CRectDialog.h"
#include "CEquilDialog.h"
#include "CRectangleIds.h"
#include "CEquilateralIds.h"
CShapesWin::CShapesWin() {
Create(NULL, "DrawShapes");
}
afx_msg void CShapesWin::OnPaint() {
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
m_doc.Paint(dc, rect);
}
afx_msg void CShapesWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
CRectDialog rectDialog;
CEquilDialog equilDialog;
switch(nChar) {
case 38: // Up arrow
case 40: // Down arrow
// Pop up a dialog box and get the response
if (rectDialog.DoModal() == IDOK) {
if (m_doc.Add(new CRectangle(rectDialog.m_nHeight,
rectDialog.m_nWidth, rectDialog.m_Color)) == TRUE) {
Invalidate(TRUE);
}
}
break;
case 39: // Right arrow
case 37: // Left arrow
if (equilDialog.DoModal() == IDOK) {
if (m_doc.Add(new CEquilateral(equilDialog.m_nSideLength,
equilDialog.m_Color)) == TRUE) {
Invalidate(TRUE);
}
}
else {
MessageBox("Whoops, no dialoge box... :(");
}
break;
default:
MessageBox("Key not recognized");
}
}
BEGIN_MESSAGE_MAP(CShapesWin, CFrameWnd)
ON_WM_PAINT()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
With debugging, I have seen the call to equilDialog.DoModel() attempt to be called, but it fails everytime, whereas my rect.Dialog.DoModel() never fails.... I am at a complete lost, if anyone could help I would be so grateful!
EDIT: Thank you Brian, It seems I forgot how to use a computer! Here is a public link with the zip file: http://dl.dropbox.com/u/1734050/SO%20Polygon%20Project.zip
EDIT 2: Martin, Thank you so much, The only thing I had to do was make sure that the string in the CEquilDialog.cpp file matched in the resource file. Once I did that, the dialog box worked like a charm.
FOR ANYONE new to MFC and having Dialog box issues, please remeber the following:
In any of your dialog.cpp files when you declare the constructor:
CYourDialog::CYourDialog() : CDialog("StringToMatchInResourceFile") {
m_nSomeVariable = 0;
}
the "StringToMatchInResourceFile" must also be in the .rc file:
#include <afxres.h>
#include "CEquilateralIds.h"
StringToMatchInResourceFile DIALOG 50,50,150,150
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
...
What I did was have "Equilateral Triangle" in the dialog.cpp and then "Equilateral" in the .rc file. MFC Newbies, *take note!*a
Your dialog resource can't be found. When you call the base class constructor :CDialog("Equilateral Triangles"), you're telling MFC and the dialog manager that you have a dialog template resource with the string id "Equilateral Triangles". But your rc file doesn't have that. It has a dialog resource with the id Equilateral (which I don't see you define anywhere). Instead add IDD_EQUILATERAL as 101 to equilateralids.h and refer to it in the CDialog constructor.
It probably works right for the other case because your ID and its string match.
As an added point, without special mechanics you only get one .rc file per project. So if by chance you have two rc files, merge them into one file. This may also be going wrong because the second RC file isn't going anywhere at all.
Martyn