Ich versuche, Text in sdl-2 zu rendern. Der Text sollte in SDL_Rect destination
im Clip-Bereich SDL_Rect rcTextOutput
angezeigt werden, aber es gibt einen sigabrt Fehler zurück. Ich habe versucht, dies mit valgrind und gdb zu debuggen, aber ich sehe das Problem immer noch nicht.Das Auslösen einer Ausnahme gibt einen Speicherausnahmefehler zurück
Ich werde den gesamten Code am Ende verlassen, aber hier ist der Abschnitt, wo der Text gerendert wird:
SDL_SetRenderDrawColor(gRenderer, 0x40, 0x40, 0x40, 0x40);
gTextSurface = TTF_RenderText_Solid(gFont, "text", gTextColor);
if (gTextSurface == NULL)
{
throw "Unable to render texture! ERROR: ";
}
gTextTexture = SDL_CreateTextureFromSurface(gRenderer, gTextSurface);
if (gTextTexture == NULL)
{
throw "Unable to render texture! ERROR: ";
}
SDL_Rect destination;
destination.x = rcTextOutput.x + rcTextOutput.w - 800;
destination.y = rcTextOutput.y;
destination.w = 800;
destination.h = 20;
SDL_RenderSetClipRect(gRenderer, &rcTextOutput);
SDL_RenderCopy(gRenderer, gTextTexture, NULL, &destination);
SDL_RenderSetClipRect(gRenderer, NULL);
// ...
SDL_RenderPresent(gRenderer);
Ich nahm Kenntnis von SDL_SetClipRect()
von this answer und seinem Beispiel, aber es funktioniert nicht.
Ich habe schon diese Lazy Foo' tutorial angeschaut und der Code scheint in Ordnung zu sein. Ich habe auch gdb darauf laufen und es zurückgegeben:
Starting program: /home/pradana/Projects/sierra/caventure/build/caventure
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7fffeb5f1700 (LWP 25319)]
[New Thread 0x7fffeadf0700 (LWP 25320)]
terminate called after throwing an instance of 'char const*'
Thread 1 "caventure" received signal SIGABRT, Aborted.
0x00007ffff6c92a10 in raise() from /usr/lib/libc.so.6
Ich habe sogar versucht valgrind:
==25239== Memcheck, a memory error detector
==25239== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25239== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==25239== Command: build/./caventure
==25239==
==25239== Syscall param writev(vector[...]) points to uninitialised byte(s)
==25239== at 0x5CF218D: ??? (in /usr/lib/libc-2.25.so)
==25239== by 0x8088BAC: ??? (in /usr/lib/libxcb.so.1.1.0)
==25239== by 0x8088FAC: ??? (in /usr/lib/libxcb.so.1.1.0)
==25239== by 0x808902C: xcb_writev (in /usr/lib/libxcb.so.1.1.0)
==25239== by 0x7D7EF3D: _XSend (in /usr/lib/libX11.so.6.3.0)
==25239== by 0x7D7F431: _XReply (in /usr/lib/libX11.so.6.3.0)
==25239== by 0x7D6A2EE: XInternAtom (in /usr/lib/libX11.so.6.3.0)
==25239== by 0x4EFB79A: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== by 0x4EFC694: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== by 0x4EEB87F: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== by 0x4EEB60E: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== by 0x4E4F1C6: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== Address 0x79c5573 is 35 bytes inside a block of size 16,384 alloc'd
==25239== at 0x4C2CF35: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25239== by 0x7D6F385: XOpenDisplay (in /usr/lib/libX11.so.6.3.0)
==25239== by 0x4EFA84F: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== by 0x4EEB5BB: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== by 0x4E4F1C6: ??? (in /usr/lib/libSDL2-2.0.so.0.4.1)
==25239== by 0x4011F3: init() (in /home/pradana/Projects/sierra/caventure/build/caventure)
==25239== by 0x40148A: main (in /home/pradana/Projects/sierra/caventure/build/caventure)
==25239==
terminate called after throwing an instance of 'char const*'
==25239==
==25239== Process terminating with default action of signal 6 (SIGABRT): dumping core
==25239== at 0x5C41A10: raise (in /usr/lib/libc-2.25.so)
==25239== by 0x5C43139: abort (in /usr/lib/libc-2.25.so)
==25239== by 0x53ED4EC: __gnu_cxx::__verbose_terminate_handler() (vterminate.cc:95)
==25239== by 0x53EB2A5: __cxxabiv1::__terminate(void (*)()) (eh_terminate.cc:47)
==25239== by 0x53EB2F0: std::terminate() (eh_terminate.cc:57)
==25239== by 0x53EB507: __cxa_throw (eh_throw.cc:87)
==25239== by 0x4013FC: loadMedia() (in /home/pradana/Projects/sierra/caventure/build/caventure)
==25239== by 0x40148F: main (in /home/pradana/Projects/sierra/caventure/build/caventure)
==25239==
==25239== HEAP SUMMARY:
==25239== in use at exit: 13,232,031 bytes in 33,989 blocks
==25239== total heap usage: 76,191 allocs, 42,202 frees, 50,434,525 bytes allocated
==25239==
==25239== LEAK SUMMARY:
==25239== definitely lost: 16 bytes in 1 blocks
==25239== indirectly lost: 176 bytes in 4 blocks
==25239== possibly lost: 4,143,500 bytes in 29,652 blocks
==25239== still reachable: 9,088,339 bytes in 4,332 blocks
==25239== suppressed: 0 bytes in 0 blocks
==25239== Rerun with --leak-check=full to see details of leaked memory
==25239==
==25239== For counts of detected and suppressed errors, rerun with: -v
==25239== Use --track-origins=yes to see where uninitialised values come from
==25239== ERROR SUMMARY: 5 errors from 1 contexts (suppressed: 0 from 0)
Hier ist der Rest des Skripts (irrelevant Code entfernt wird):
#include <stdio.h>
#include <string>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
// Screen dimensions, constants
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 900; // 600 for ground, 280 for output, 20 for input
SDL_Surface* gScreenSurface = NULL; // The surface contained by the window
SDL_Surface* gCurrentSurface = NULL; // Current displayed image
SDL_Surface* gTextSurface = NULL; // SDL_Surface for the text.
SDL_Texture* gTextTexture = NULL; // SDL_Texture for the text.
TTF_Font* gFont = NULL; // Font pointer.
SDL_Color gTextColor = { 0, 0, 0, 0xFF }; // Text color, white.
SDL_Renderer* gRenderer = NULL; // The renderer we'll be using
SDL_Rect rcGround, rcSprite, rcTextInput, rcTextOutput;
void init();
void loadMedia();
void quit();
void init()
{
if (SDL_Init(SDL_INIT_VIDEO) > 0)
{
throw "SDL failed to initialise! ERROR: ";
}
else
{
// CODE REDACTED: gWindow and gRenderer is initialised
if (TTF_Init() > 0)
{
throw "TTF could not be initialised! ERROR: ";
}
}
}
void loadMedia()
{
// Ground rendering
rcGround.x = 0;
rcGround.y = 0;
rcGround.w = 800;
rcGround.h = 600;
// Sprite rendering
rcSprite.x = 400;
rcSprite.y = 300;
rcSprite.w = 4;
rcSprite.h = 4;
// TextOutput box rendering
rcTextOutput.x = 0;
rcTextOutput.y = 600;
rcTextOutput.w = 800;
rcTextOutput.h = 280;
// TextInput box rendering
rcTextInput.x = 0;
rcTextInput.y = 880;
rcTextInput.w = 800;
rcTextInput.h = 20;
gFont = TTF_OpenFont("resources/consolas.ttf", 14);
if (gFont == NULL)
{
throw "Font load error";
}
}
void quit()
{
// Destroy window
SDL_DestroyWindow(gWindow);
SDL_DestroyRenderer(gRenderer);
SDL_DestroyTexture(gTextTexture);
SDL_FreeSurface(gTextSurface);
TTF_CloseFont(gFont);
gWindow = NULL;
gRenderer = NULL;
gFont = NULL;
// Quit SDL subsystems
TTF_Quit();
SDL_Quit();
}
int main()
{
try
{
init();
loadMedia();
bool quit = false;
SDL_Event event;
while(!quit)
{
// CODE REDACTED: event & sprite movement
}
if (rcSprite.x < 0 || rcSprite.y < 0 || rcSprite.y > rcGround.h || rcSprite.x > rcGround.w)
{
rcSprite.x = 400;
rcSprite.y = 300;
}
SDL_SetRenderDrawColor(gRenderer, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(gRenderer);
SDL_RenderFillRect(gRenderer, &rcGround);
SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, &rcGround);
SDL_RenderFillRect(gRenderer, &rcTextInput);
SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, &rcTextInput);
SDL_SetRenderDrawColor(gRenderer, 0x40, 0x40, 0x40, 0x40);
gTextSurface = TTF_RenderText_Solid(gFont, "text", gTextColor);
if (gTextSurface == NULL)
{
throw "Unable to render texture! ERROR: ";
}
gTextTexture = SDL_CreateTextureFromSurface(gRenderer, gTextSurface);
if (gTextTexture == NULL)
{
throw "Unable to render texture! ERROR: ";
}
SDL_Rect destination;
destination.x = rcTextOutput.x + rcTextOutput.w - 800;
destination.y = rcTextOutput.y;
destination.w = 800;
destination.h = 20;
SDL_RenderSetClipRect(gRenderer, &rcTextOutput);
SDL_RenderCopy(gRenderer, gTextTexture, NULL, &destination);
SDL_RenderSetClipRect(gRenderer, NULL);
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderDrawLine(gRenderer, 0, 600, 800, 600);
SDL_RenderDrawLine(gRenderer, 0, 880, 800, 880);
SDL_RenderFillRect(gRenderer, &rcSprite);
SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, &rcSprite);
SDL_RenderPresent(gRenderer);
}
}
catch (const std::string& msg)
{
printf("%s", msg.c_str());
if (SDL_GetError() != NULL)
{
printf("%s", SDL_GetError());
}
else if (TTF_GetError() != NULL)
{
printf("%s", TTF_GetError());
}
else
{
printf("%s", "NULL");
}
quit();
exit(EXIT_FAILURE);
}
quit();
return 0;
}
Huh. Anscheinend war das das Problem. Nun, danke. Ich fand den Fehler, der Dateipfad für 'TTF_OpenFont()' war falsch, dann funktionierte es. Lustig genug, als ich es lief, wurde "rcTextOutput" schwarz und ich kann keinen Text sehen. –