Creatin a "main" window with ncurses for a game - window

I'm trying to creat a window to be as a border for my entire game. So it will be the "main" window. I found out that the best way to do it is to create a "ghost" window and another, the real one which you'll use, inside of it with slighty less dimensions.
But I still can't proprely craate it: Heres my best solution yet.
#include <ncurses.h>
WINDOW* createWindow(int, int, int, int);
WINDOW* createRealWindow(int, int, int, int);
int main ()
{
initscr();
cbreak();
char str[50];
WINDOW *back_window, *real_window;
int height=12, width=80;
int x=(COLS-width)/2, y=(LINES-height)/2;
back_window = createWindow(x, y, width, height);
real_window = createRealWindow(x+1, y+1, width, height);
wprintw(real_window, "Type: ");
wgetstr(real_window, str);
wrefresh(real_window);
wprintw(real_window, "You typed %s.", str);
wrefresh(real_window);
napms(5000);
endwin();
return 0;
}
WINDOW* createWindow(int x, int y, int height, int width)
{
WINDOW *local;
local = newwin(width, height, y, x);
box(local, 0, 0);
wrefresh(local);
return local;
}
WINDOW* createRealWindow(int x, int y, int height, int width)
{
WINDOW *local;
local = newwin(width-2, height-2, y+1, x+1);
box(local, ' ', ' ');
wrefresh(local);
return local;
}
Here is my output:
my output
Thanks guys!
Edit: I've found the solution with the code down below, but I don't know how this will behave in others people computers with different resolutions. Ideas? PS: I use 1920 x 1080.
int main ()
{
initscr();
cbreak();
char str[50];
WINDOW *back_window, *real_window;
int height=22, width=78;
int x=(COLS-width-1)/2, y=(LINES-height-2)/2;
back_window = createWindow(x, y, width, height);
real_window = createRealWindow(x+1, y+1, width, height);
wprintw(real_window, "Type: ");
wgetstr(real_window, str);
wrefresh(real_window);
wprintw(real_window, "You typed %s.", str);
wrefresh(real_window);
napms(5000);
endwin();
return 0;
}
WINDOW* createWindow(int x, int y, int height, int width)
{
WINDOW *local;
local = newwin(width+2, height+2, y, x);
box(local, 0, 0);
wrefresh(local);
return local;
}
WINDOW* createRealWindow(int x, int y, int height, int width)
{
WINDOW *local;
local = newwin(width, height, y, x);
wrefresh(local);
return local;
}

The back_window did not show up because the real_window obscured it (due to size/position). But using subwin is the preferred way to do this:
#include <ncurses.h>
int main ()
{
initscr();
cbreak();
char str[50];
WINDOW *back_window, *real_window;
int height=12, width=80;
int x=(COLS-width)/2, y=(LINES-height)/2;
back_window = newwin(height, width, y, x);
box(back_window, 0, 0);
wrefresh(back_window);
real_window = subwin(back_window, height-2, width-2, y+1, x+1);
wprintw(real_window, "Type: ");
wgetstr(real_window, str);
wrefresh(real_window);
wprintw(real_window, "You typed %s.", str);
wrefresh(real_window);
napms(5000);
endwin();
return 0;
}

Related

Visual Studio, GLUT error - The following is a new check for GLUT 3.0; update your code. redisplay needed for window 1, but no display callback

The code is building successfully but when I run the code I have the following error -
The following is a new check for GLUT 3.0; update your code.
GLUT: Fatal Error in D:\6th Sem\4. CG UCS505\EasyAlgo\Project1\Debug\Project1.exe: redisplay needed for window 1, but no display callback.
I've tried everything but am not able to figure it out, am new with open gl and vs. Thank you for your help.
Here is the .cpp file code -
source.cpp
#include <GL/glut.h>
#include <debug.hpp>
#include <config.hpp>
#include <blobs.hpp>
#include <fonts.hpp>
#include <draw.hpp>
#include <highlight.hpp>
#include <animation.hpp>
#include <unistd.h>
#include <iostream>
using namespace std;
unsigned short mainWindow, subWindow1, subWindow2;
void Init(float, float, float);
void Init(float, float, float, int, int);
void mainInit();
void display();
void onClick(int, int, int, int);
void keyPress(unsigned char, int, int);
int main(int argc, char** argv)
{
#ifdef DEBUG
mode = "InsertionSort";
b1.bv.resize(7, blobs());
int rad[7] = { 28,32,20,28,36,45,31 };
for (int p = 0; p < 7; p++)
b1.bv[p].radius = (float)rad[p];
b1.min = 20;
b1.max = 45;
#endif
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(WindowWidth, WindowHeight);
std::string title = "AlgoLucidator " + AL_VERSION;
mainWindow = glutCreateWindow(title.c_str());
glutPositionWindow(WIN_POS_X, WIN_POS_Y);
mainInit();
glutMouseFunc(onClick);
glutKeyboardFunc(keyPress);
subWindow1 = glutCreateSubWindow(mainWindow, 0, 0, WindowWidth / 4, WindowHeight);
Init(0.80f, 0.80f, 0.60f);
glutKeyboardFunc(keyPress);
glutDisplayFunc(display);
subWindow2 = glutCreateSubWindow(mainWindow, WindowWidth / 4, 0, 3 * WindowWidth / 4, WindowHeight);
Init(0.65f, 0.75f, 0.70f);
std::string mainInstruct = "Press 1. InsertionSort 2. BubbleSort 3. Dijkstra";
printText(0, 0, 0, -(5 * mainInstruct.size()), 540, mainInstruct);
glutMouseFunc(onClick);
glutKeyboardFunc(keyPress);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void Init(float r, float g, float b)
{
int CurrWindowWidth = glutGet(GLUT_WINDOW_WIDTH);
int CurrWindowHeight = glutGet(GLUT_WINDOW_HEIGHT);
glClearColor(r, g, b, 1);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-CurrWindowWidth, CurrWindowWidth, -CurrWindowHeight, CurrWindowHeight);
drawTitle(CurrWindowWidth, CurrWindowHeight);
}
void Init(float r, float g, float b, int width, int height)
{
glClearColor(r, g, b, 1);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-width, width, -height, height);
drawTitle(width, height);
}
void mainInit()
{
int CurrWindowWidth = glutGet(GLUT_WINDOW_WIDTH);
int CurrWindowHeight = glutGet(GLUT_WINDOW_HEIGHT);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0, CurrWindowWidth, 0, CurrWindowHeight);
glClearColor(0, 0, 0, 0.80f);
glClear(GL_COLOR_BUFFER_BIT);
}
void display()
{
glFlush();
}
void onClick(int button, int state, int oldx, int oldy)
{}
void keyPress(unsigned char key, int x, int y)
{
int activeWindow = glutGetWindow();
switch (key)
{
case 13: if (b1.pushreq)
{
b1.bv.push_back(blobs((float)base_radius));
}
if (activeWindow != subWindow2)
glutSetWindow(subWindow2);
if (mode == "InsertionSort")
{
drawInsertionSort();
}
else if (mode == "BubbleSort")
{
drawBubbleSort();
}
break;
case 27: glutDestroyWindow(mainWindow); //Esc
break;
case 49: mode = "InsertionSort";
b1.reset();
glutSetWindow(subWindow2);
glutMouseFunc(onClick2);
Init2(0.65f, 0.75f, 0.70f);
drawTitle3(960, 640);
break;
case 50: mode = "BubbleSort";
glutSetWindow(subWindow2);
glutMouseFunc(onClick3);
glutIdleFunc(display);
Init3(0.65f, 0.75f, 0.70f);
drawTitle4(960, 640);
break;
default:;
}
}
The error message is pretty much exactly telling what's wrong and how to fix it (QFT):
The following is a new check for GLUT 3.0; update your code. GLUT: Fatal Error in (…) Project1.exe: redisplay needed for window 1, but no display callback.
For first window you create, window one, the one created with glutCreateWindow you don't specify a display callback:
mainWindow = glutCreateWindow(title.c_str());
glutPositionWindow(WIN_POS_X, WIN_POS_Y);
mainInit();
glutMouseFunc(onClick);
glutKeyboardFunc(keyPress);
/// <<<<<<<< something is missing here
subWindow1 = glutCreateSubWindow(mainWindow, 0, 0, WindowWidth / 4, WindowHeight);
Give that first window you create a display callback and the error will go away.
On a second note: Nothing of what's happening in the …Init functions is initialization at all. OpenGL is a state machine, and everything done in …Init is state prepration that ought to happen at the start of rendering a frame.

SDL2 function that erases lines?

I am making a program that creates lines, how can I erase a line? Is there a function for it?
I have already tried using SDL_RenderClear() but it did not work.
(please note that i am a beginner and that im NOT native american, also i only am 10 years old so explain in a simple way.)
Here is my line creating code:
#include <iostream>
#include <SDL.h>
using namespace std;
int main( int argc, char * argv[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *janela = NULL;
SDL_Renderer *renderer = NULL;
bool roda = true;
SDL_Event evento;
int x;
int y;
int x2;
int y2;
janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);
while (roda) {
SDL_Event evento;
while (SDL_PollEvent(&evento)) {
switch(evento.type){
case SDL_QUIT:
roda = false;
break;
case SDL_MOUSEBUTTONDOWN:{
x = evento.motion.x;
y = evento.motion.y;
break;}
case SDL_MOUSEBUTTONUP:
while(roda){
x2 = evento.motion.x;
y2 = evento.motion.y;
SDL_SetRenderDrawColor(renderer , 255 , 0 , 0 , 255);
SDL_SetRenderDrawColor(renderer , 125 , 234 , 253 , 255);
SDL_RenderDrawLine(renderer , x , y , x2 , y2);
SDL_RenderPresent(renderer);
break;}
case SDL_KEYDOWN:{
switch(evento.key.keysym.sym){
case SDLK_b:{
SDL_RenderClear(renderer);
}
}
}
}
}
}
SDL_DestroyWindow(janela);
janela = NULL;
SDL_DestroyRenderer(renderer);
renderer = NULL;
SDL_Quit();
return 1;
}
What I expect is the lines to be erased but it did not happen.
Typical main loop is basically this:
while(!quit) {
while(pool_event()) {
// change state to react to event
}
clear_previous_frame();
for each line {
draw_line();
}
present();
}
So you should always clear and redraw your lines, adding new line state if events says so (but not drawing it yet - event processing shouldn't do that, or it becomes very compilcated). It is problemmatic to keep previous frame's contents and just add more lines; short explaination is because SDL_RenderPresent documentation says The backbuffer should be considered invalidated after each present (and long explaination is basically a list of reasons why it says so).
To keep track of lines to draw you need to save them somewhere. std::vector could be a simple option, if your requirements aren't against it.
To sum it up, your question's modified code with a bit of comments:
#include <vector>
#include <SDL.h>
struct line {
int x0, y0, x1, y1;
};
int main( int argc, char * argv[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *janela = NULL;
SDL_Renderer *renderer = NULL;
bool roda = true;
int x;
int y;
janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);
std::vector<line> lines;
while (roda) {
SDL_Event evento;
while (SDL_PollEvent(&evento)) {
switch(evento.type){
case SDL_QUIT:
roda = false;
break;
case SDL_MOUSEBUTTONDOWN:
// save starting coordinates
x = evento.motion.x;
y = evento.motion.y;
break;
case SDL_MOUSEBUTTONUP: {
// add new line to draw
line l = { x, y, evento.motion.x, evento.motion.y };
lines.push_back(l);
} break;
case SDL_KEYDOWN:
if(evento.key.keysym.sym == SDLK_b) {
// drop lines
lines.resize(0);
}
break;
}
}
// clear previous contents - in most cases, screen content is
// invalidated after RenderPresent and you need to draw again
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // your 'clear' colour
SDL_RenderClear(renderer);
// draw all accumulated lines
SDL_SetRenderDrawColor(renderer, 125, 234, 253, 255); // your lines colour
for(const line &l : lines) {
SDL_RenderDrawLine(renderer, l.x0, l.y0, l.x1, l.y1);
}
// all drawn - present
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(janela);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0; // 0 is 'success' return code, non-0 is failure
}

FFMPEG RGB to YUV420P : Warning: data is not aligned! This can lead to a speedloss [duplicate]

This question already has answers here:
Pixel format conversion issue [FFMPEG]
(2 answers)
Closed 4 years ago.
I am trying to convert a standard RGB color space to YUV420P. I am struggling to figure out why I keep getting 'Warning: data is not aligned! This can lead to a speedloss' when executing the code. I have looked at a multitude of examples.
int ImageDecoder::rgb2yuv(uint8_t *src,
uint8_t *dest,
uint32_t width,
uint32_t height)
{
struct SwsContext *imgCtx = NULL;
AVFrame *pFrameYUV;
enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_RGB24;
enum AVPixelFormat dst_pix_fmt = AV_PIX_FMT_YUV420P;
int ret;
int size;
const int RGBLinesize[1] = { 3 * (int)width };
pFrameYUV = av_frame_alloc();
pFrameYUV->width = width;
pFrameYUV->height = height;
pFrameYUV->format = dst_pix_fmt;
// Initialize pFrameYUV linesize
ret = av_image_alloc(pFrameYUV->data, pFrameYUV->linesize, pFrameYUV->width, pFrameYUV->height, AV_PIX_FMT_YUV420P, 1);
getLogger()->info("ImageDecoder:{} width={} height={} linesize[0]={} linesize[1]={} linesize[2]={}",
__func__, pFrameYUV->width, pFrameYUV->height, pFrameYUV->linesize[0], pFrameYUV->linesize[1], pFrameYUV->linesize[2]);
size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pFrameYUV->width, pFrameYUV->height, 1);
imgCtx = sws_getCachedContext(imgCtx,
width,
height,
AV_PIX_FMT_RGB24,
pFrameYUV->width,
pFrameYUV->height,
AV_PIX_FMT_YUV420P,
SWS_BICUBIC, 0, 0, 0);
if( imgCtx == NULL)
{
getLogger()->error("ERROR: ImageDecoder: {} Cannot initialize the conversion context", __func__);
}
sws_scale(imgCtx,
(const uint8_t* const*)&src,
RGBLinesize,
0,
height,
pFrameYUV->data,
pFrameYUV->linesize);
memcpy(dest, &pFrameYUV->data[0], size);
sws_freeContext(imgCtx);
av_free(pFrameYUV);
}
I hope it helps you.
I am converting YUV444 decoded frames to RGBA format.
AVFrame* RGBFrame = av_frame_alloc();
RGBFrame->width = YUV_frame->width; RGBFrame->format = AV_PIX_FMT_RGBA;
RGBFrame->height = YUV_frame->height;
int ret = av_image_alloc(RGBFrame->data, RGBFrame->linesize, RGBFrame->width, RGBFrame->height, AV_PIX_FMT_RGBA, YUV_frame->pict_type);
if (ret < 0)
return false;
SwsContext* sws_Context = NULL;
sws_Context = sws_getCachedContext(sws_Context, YUV_frame->width, YUV_frame->height, pVideoCodecCtx->pix_fmt,
YUV_frame->width, YUV_frame->height, AV_PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
if (sws_Context == NULL) return false;
int result = sws_scale(sws_Context, YUV_frame->data, YUV_frame->linesize, 0, (int)YUV_frame->height, RGBFrame->data, RGBFrame->linesize);
if (result < 0) return false;
if (RGBFrame == NULL) {
av_frame_unref(RGBFrame);
return false;
}
sws_freeContext(sws_Context);
int ImageDecoder::rgb2yuv(uint8_t *src,
uint8_t *dest,
uint32_t *outBufferSize,
uint32_t width,
uint32_t height)
{
struct SwsContext *imgCtx = NULL;
uint8_t * RGBData[1] = {src};
const int RGBLinesize[1] = {3 * (int) width};
uint8_t * YUVData[] = {dest,
YUVData[0] + ((int) width * (int) height),
YUVData[1] + (((int) width * (int) height) / 4)};
const int YUVLinesize[] = {(int) width, (int) width / 2, (int) width / 2};
int size;
size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, width, height, 1);
*outBufferSize = size;
imgCtx = sws_getCachedContext(imgCtx,
width,
height,
AV_PIX_FMT_RGB24,
width,
height,
AV_PIX_FMT_YUV420P,
SWS_BICUBIC, 0, 0, 0);
if (imgCtx == NULL)
{
getLogger()->error("ERROR: ImageDecoder: {} Cannot initialize the conversion context", __func__);
return -1;
}
sws_scale(imgCtx,
RGBData,
RGBLinesize,
0,
height,
YUVData,
YUVLinesize);
sws_freeContext(imgCtx);
return 0;
}

glutMainLoop in mac osx Lion freezes application

I'm trying to run an example GLUT program, but it only creates a white window and then freezes the application. I found it freezes when calling glutMainLoop (same if I call glutCheckLoop in a loop). Something I may be missing?
Here's the the sample code I found:
#include <stdlib.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// Question 1: In a GLUT program, how is control passed
// back to the programmer? How is this set up during
// initialization?
int win_width = 512;
int win_height = 512;
void display( void )
{
glClear( GL_COLOR_BUFFER_BIT );
glutSwapBuffers();
}
void reshape( int w, int h )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
// Question 3: What do the calls to glOrtho()
// and glViewport() accomplish?
glOrtho( 0., 1., 0., 1., -1., 1. );
glViewport( 0, 0, w, h );
win_width = w;
win_height = h;
glutPostRedisplay();
}
void keyboard( unsigned char key, int x, int y ) {
switch(key) {
case 27: // Escape key
exit(0);
break;
}
}
int main (int argc, char *argv[]) {
glutInit( &argc, argv );
// Question 2: What does the parameter to glutInitDisplayMode()
// specify?
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( win_width, win_height );
glutCreateWindow( "Intro Graphics Assignment 1" );
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutKeyboardFunc( keyboard );
glutMainLoop();
return 0;
}
int main is not where you want glutMainLoop(), mate.
You should have that in your init method ie initGlutDisplay().
#include <stdlib.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// Question 1: In a GLUT program, how is control passed
// back to the programmer? How is this set up during
// initialization?
int win_width = 512;
int win_height = 512;
void display( void )
{
glClear( GL_COLOR_BUFFER_BIT );
glutSwapBuffers();
}
void reshape( int w, int h )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
// Question 3: What do the calls to glOrtho()
// and glViewport() accomplish?
glOrtho( 0., 1., 0., 1., -1., 1. );
glViewport( 0, 0, w, h );
win_width = w;
win_height = h;
glutPostRedisplay();
}
void keyboard( unsigned char key, int x, int y ) {
switch(key) {
case 27: // Escape key
exit(0);
break;
}
}
int initGlutDisplay(int argc, char* argv[]){
glutInit( &argc, argv );
// Question 2: What does the parameter to glutInitDisplayMode()
// specify?
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( win_width, win_height );
glutCreateWindow( "Intro Graphics Assignment 1" );
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutKeyboardFunc( keyboard );
glutMainLoop();
return 0;
}
int main (int argc, char *argv[]) {
int win_width = 512;
int win_height = 512;
initGlutDisplay(argc, argv);
}
The above code should work perfectly.
EDIT
According to opengl
AGL is the old Carbon-based API with C bindings. The Carbon part
needed for windowing and event handling are not thread-safe. There is
no 64 bit version of this API.
I wonder if this is your issue. I would review the opengl Programming guide by apple to see if you missed any steps that might solve your problem.
It was a bug in the compiler (works now with gcc)

Showing size grip in CDialog?

I have seen code which handles the drawing of this thing (DFCS_SCROLLSIZEGRIP), but surely there is a window style which I can apply to get it "for free". Right?
In lieu of a better answer, I will post the code I have that draws the size grip and handles the hit-testing. You also need to invalidate the appropriate area during OnSize in order to get it repainted.
BOOL CMyDialog::OnEraseBkgnd(CDC* pDC)
{
if (CDialog::OnEraseBkgnd(pDC))
{
// draw size grip
CRect r;
GetClientRect(&r);
int size = GetSystemMetrics(SM_CXVSCROLL);
r.left = r.right - size;
r.top = r.bottom - size;
pDC->DrawFrameControl(&r, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
return TRUE;
}
else
{
return FALSE;
}
}
-
LRESULT CMyDialog::OnNcHitTest(CPoint point)
{
// return HTBOTTOMRIGHT for sizegrip area
CRect r;
GetClientRect(&r);
int size = GetSystemMetrics(SM_CXVSCROLL);
r.left = r.right - size;
r.top = r.bottom - size;
ScreenToClient(&point);
if (r.PtInRect(point))
{
return HTBOTTOMRIGHT;
}
else
return CDialog::OnNcHitTest(point);
}
Source: http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.ui/2006-01/msg00103.html
In addition to OnEraseBkgnd and OnNcHitTest mentioned by the above you will need to invalidate the grip area when the window sized, otherwise it will leave marks when enlarged:
void CMyDialog::OnSize(UINT nType, INT cx, INT cy)
{
CRect rc;
int iSize=GetSystemMetrics(SM_CXVSCROLL);
GetClientRect(rc);
InvalidateRect(CRect(rc.left-iSize, rc.bottom-iSize, rc.right, rc.bottom), FALSE);
CDialog::OnSize(nType, cx, cy);
}
I don't think there is a default style to get this functionality for free. You have to create a new child window with class name Scrollbar and control style SBS_SIZEGRIP

Resources