Я пытаюсь сделать 3 вещи:
Каждый из них прекрасно работает сам по себе, но их объединение каким-то образом нарушает AntTweakBar, в зависимости от комбинации:
Вот (грязный) исходный код для этого тестового приложения. res_path.h
а также cleanup.h
может быть найден Вот а также Вот (но не должно иметь значения).
#include <iostream>
#include <SDL2/SDL.h>
#include "res_path.h"#include "cleanup.h"#include "SDL2/SDL2_gfxPrimitives.h"#include <AntTweakBar.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
bool quit = false;
bool tex = false;
bool circ = false;
//-----------------------------------------------------------------------
/**
* Log an SDL error with some error message to the output stream of our choice
* @param os The output stream to write the message to
* @param msg The error message to write, format will be msg error: SDL_GetError()
*/
void logSDLError(std::ostream &os, const std::string &msg)
{
os << msg << " error: " << SDL_GetError() << std::endl;
}
/**
* Loads a BMP image into a texture on the rendering device
* @param file The BMP image file to load
* @param ren The renderer to load the texture onto
* @return the loaded texture, or nullptr if something went wrong.
*/
SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren)
{
//Initialize to nullptr to avoid dangling pointer issues
SDL_Texture *texture = nullptr;
//Load the image
SDL_Surface *loadedImage = SDL_LoadBMP(file.c_str());
//If the loading went ok, convert to texture and return the texture
if (loadedImage != nullptr){
texture = SDL_CreateTextureFromSurface(ren, loadedImage);
SDL_FreeSurface(loadedImage);
//Make sure converting went ok too
if (texture == nullptr){
logSDLError(std::cout, "CreateTextureFromSurface");
}
}
else {
logSDLError(std::cout, "LoadBMP");
}
return texture;
}/**
* Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving
* the texture's width and height
* @param tex The source texture we want to draw
* @param ren The renderer we want to draw to
* @param x The x coordinate to draw to
* @param y The y coordinate to draw to
*/
void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y)
{
//Setup the destination rectangle to be at the position we want
SDL_Rect dst;
dst.x = x;
dst.y = y;
//Query the texture to get its width and height to use
SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
SDL_RenderCopy(ren, tex, NULL, &dst);
}
void TW_CALL RunCA(void * /*clientData*/)
{
std::cout << "button 1 clicked" << std::endl;
tex = !tex;
}
void TW_CALL RunCB(void * /*clientData*/)
{
std::cout << "button 2 clicked" << std::endl;
circ = !circ;
}
//---------------------------------------
int main()
{
int size=10;
int alpha=100;
std::cout << "Resource path is: " << getResourcePath() << std::endl;
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
logSDLError(std::cout, "SDL_Init");
return 1;
}
SDL_Window *window = SDL_CreateWindow("Lesson 2", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (window == nullptr){
logSDLError(std::cout, "CreateWindow");
SDL_Quit();
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
if (renderer == nullptr){
logSDLError(std::cout, "CreateRenderer");
cleanup(window);
SDL_Quit();
return 1;
}const std::string resPath = getResourcePath();
SDL_Texture *image = loadTexture(resPath + "image.bmp", renderer);
if (image == nullptr){
cleanup(image, renderer, window);
SDL_Quit();
return 1;
}TwInit(TW_OPENGL, NULL);
TwWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
TwBar *myBar;
myBar = TwNewBar("TestBar");
TwDefine(" GLOBAL help='example help' "); // Message added to the help bar.
TwAddButton(myBar, "Switch Texture", RunCA, NULL, " label='texture' ");
TwAddButton(myBar, "Switch Circle", RunCB, NULL, " label='circle' ");
TwAddVarRW(myBar, "width", TW_TYPE_INT32, &size, " keyIncr=w, keyDecr=s ");
TwAddVarRW(myBar, "alpha", TW_TYPE_INT32, &alpha, " ");
// Add 'quit' to 'bar': this is a modifiable (RW) variable of type TW_TYPE_BOOL32
// (a boolean stored in a 32 bits integer). Its shortcut is [ESC].
TwAddVarRW(myBar, "Quit", TW_TYPE_BOOL32, &quit,
" label='Quit?' true='+' false='-' key='ESC' help='Quit program.' ");
// main loop
while( !quit )
{
SDL_Event event;
int handled=1;
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
if(tex)
renderTexture(image, renderer, 50, 50);
if(circ)
filledCircleRGBA(renderer,
100, 100,
size,
0, 255, 0, alpha);TwDraw(); // draw the tweak bar(s)SDL_RenderPresent(renderer);
while(SDL_PollEvent(&event))
{
handled = TwEventSDL(&event, SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
if( !handled )
{
//If user closes the window
if (event.type == SDL_QUIT){
std::cout << "window closed" << std::endl;
quit = true;
}
//If user presses any key
if (event.type == SDL_KEYDOWN){
std::cout << "key down" << std::endl;
}
//If user clicks the mouse
if (event.type == SDL_MOUSEBUTTONDOWN){
std::cout << "mouse clicked" << std::endl;
}
}
}
// SDL_Delay(10);} // end of main loop//cleanup
cleanup(image, renderer, window);
// Terminate AntTweakBar
TwTerminate();
SDL_Quit();
return 0;
}
Кто-нибудь знает, что происходит и как это можно исправить или избежать? Если нет, возможно, кто-то мог бы порекомендовать другой подход для рендеринга простых геометрических фигур и GUI (для настройки некоторых параметров) в SDL2 / C ++ без особых усилий.
Я справился с этим, изменив среду разработки с OSX (10.11.1) на Linux (Ubuntu 14.04-3). Конечно, это не «РЕАЛЬНОЕ» решение, но, возможно, эта информация все еще может кому-то помочь.
Других решений пока нет …