SDL_CreateRGBSurface

Started by
27 comments, last by LordSputnik 15 years, 9 months ago
from post above
Quote:One
Scale the surface up to a power of two create a texture and apply it to a polygon.
Then scale the polygon back to the correct size when you draw it.

Two
use glTexSubImage2D
It does exactly what you are trying to do with SDL_BlitSurface but does not suffer from slow downs with alpha channels (for and example see void Sprockets::CreateTexture in my post above)


The first way can also be used with DirectX.
The second (as far as I can tell )works only with Opengl. I have yet to find a function in DirectX that does the same thing as glTexSubImage2D.


Option Two is the only true alternative i know for SDL_BlitSurface.
Option one will get the job done just a different way.


From my post above.
void CreateTexture(SDL_Surface * _baseSurface,SDL_Surface * _image){		int h=NearestPowerOfTwo(_image->h);		int w=NearestPowerOfTwo(_image->w);	if(_baseSurface && _image)	{		glGenTextures(1, &m_GLTexture);		glBindTexture(GL_TEXTURE_2D, m_GLTexture);		//SDL_LockSurface(temp);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  GL_LINEAR);		glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, _baseSurface->pixels);		glTexSubImage2D(GL_TEXTURE_2D,0,0,0,_image->w,_image->h,GL_BGRA,GL_UNSIGNED_BYTE,_image->pixels);		m_iTextureH=h;		m_iTextureW=w;	}	return;}


This function will do the job that SDL_BlitSurface does.
you are welcome to use my function if you want.
Through you mite need to change this GL_BGRA to this GL_RGBA to work with your code
Black CloakEpee Engine.
Advertisement
I tried using that, but now I'm getting this sort of output:

Sorry about that here is code to repace that other code I posted
this is code to replace the SDL_BlitSurface in your SDL_GL_RenderText funtion that is in the demo code you posted. (I tested this new code it with your demo code and it work)

 //======================SDL_BlitSurface Replacment========================       SDL_Surface * tempalpha = NULL;	   tempalpha = SDL_DisplayFormatAlpha(initial);		glGenTextures(1, &texture);		glBindTexture(GL_TEXTURE_2D, texture);		//SDL_LockSurface(temp);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  GL_LINEAR);		glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary->pixels);		glTexSubImage2D(GL_TEXTURE_2D,0,0,0,tempalpha->w,tempalpha->h,GL_RGBA,GL_UNSIGNED_BYTE,tempalpha->pixels);				SDL_FreeSurface(tempalpha);//======================End SDL_BlitSurface Replacment========================



though there is still a lag I will look into it an let you know
Black CloakEpee Engine.
ok I narrow down the lag to glflush() the code below has timers built in to it.
in this case since the are very few text boxes on the screen using SDL_BlitSurface over glTexSubImage2D does not make a diffreance, but the more alpha you but on the screen eventually SDL_BlitSurface will become a problem.

sorry for the long code post.

// Includes#include "SDL.h"#include "SDL_mixer.h"#include "SDL_opengl.h"#include "SDL_ttf.h"//#include <glu.h>#include <string>using namespace std;//Chat Loop Variablesstring tempchar;string chatbuffer;int done = 0;int stringpos = 0;SDL_Event event;//Resolution Settingsfloat resmultiplierx;float resmultipliery;int bpp;//Font variablesTTF_Font *font;int t_height = 0;int t_width = 0;enum textquality {solid, shaded, blended};//Sets the window size, and quad size multipliers.void setresstats(float& xmult, float& ymult,int resolution){     switch(resolution)     {         case 1:             xmult = 0.625;             ymult = 0.625;             break;         case 2:             xmult = 0.78125;             ymult = 0.78125;             break;         case 3:             xmult = 1;             ymult = 1;             break;         case 4:             xmult = 1.125;             ymult = 1.125;             break;         case 5:             xmult = 1.25;             ymult = 1.25;             break;         case 6:             xmult = 1.25;             ymult = 1.3333333333;             break;         default:             xmult = 1;             ymult = 1;             break;     }}//Initialises Simple DirectMedia Layer, OpenGL, Font engine and sound mixer.void initSDL(){    printf("Setting resolution!");    setresstats(resmultiplierx,resmultipliery,1);    bpp = 32;    printf("Resolution set: X: %f Y: %f  BPP: %i - Setting sound!",resmultiplierx,resmultipliery,bpp);    printf("Sound set - Initializing SDL!");     //Change this to load resolution from config file...         if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)    {        printf("Unable to initialize SDL!: %s \n", SDL_GetError());    }    //Set the window caption    SDL_WM_SetCaption( "Thanks for your help!", NULL );    printf("SDL initialised!\n");    if (TTF_Init() == -1)    {      printf("Unable to initialize SDL_ttf: %s \n", TTF_GetError());    }printf("Fonts initialised!\n");SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);	  SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0);	//SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1);	SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE,32);//Move video back to second in initialisation when debugged.    if(SDL_SetVideoMode((1024*resmultiplierx), (768*resmultipliery), bpp, SDL_OPENGL | SDL_HWSURFACE) == NULL)    {       printf("Unable to initialize SDL Video!: %s \n", SDL_GetError());    }printf("Video initialised!\n");    atexit(SDL_Quit);}void initGL(){    glEnable( GL_TEXTURE_2D );    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );    glViewport( 0, 0, (1024*resmultiplierx), (768*resmultipliery) );    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);    glClear( GL_COLOR_BUFFER_BIT );    glMatrixMode( GL_PROJECTION );    glLoadIdentity();    gluOrtho2D(0, (1024*resmultiplierx), (768*resmultipliery), 0);    glMatrixMode( GL_MODELVIEW );    glLoadIdentity();    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);    printf("GL initialised!\n");}//Sets RGB of a color.SDL_Color SetRGB(int r,int g,int b){    SDL_Color tempcolor;    tempcolor.r = r;    tempcolor.g = g;    tempcolor.b = b;    return tempcolor;}//Loads a font into memory from a file.TTF_Font* loadfont(char* file, int ptsize){  TTF_Font* tmpfont;  tmpfont = TTF_OpenFont(file, ptsize);  if (tmpfont == NULL){    printf("Unable to load font: %s %s \n", file, TTF_GetError());    // Handle the error here.  }  return tmpfont;}//Function to draw textured quads, with alpha transparency support.void DrawRect(int x,int y,int xe,int ye){    glEnable(GL_BLEND);    glBegin( GL_QUADS );    	//Top-left vertex (corner)        glColor4f(1.0f,1.0f,1.0f,1.0f);    	glTexCoord2i( 0, 0 );    	glVertex3f((x*resmultiplierx),(y*resmultipliery), 0.0f );    	//Bottom-left vertex (corner)        glColor4f(1.0f,1.0f,1.0f,1.0f);    	glTexCoord2i( 1, 0 );    	glVertex3f((xe*resmultiplierx), (y*resmultipliery), 0 );    	//Bottom-right vertex (corner)        glColor4f(1.0f,1.0f,1.0f,1.0f);    	glTexCoord2i( 1, 1 );    	glVertex3f((xe*resmultiplierx),(ye*resmultipliery), 0 );    	//Top-right vertex (corner)        glColor4f(1.0f,1.0f,1.0f,1.0f);    	glTexCoord2i( 0, 1 );    	glVertex3f( (x*resmultiplierx),(ye*resmultipliery), 0 );    glEnd();    glDisable(GL_BLEND);}void DrawRectColor(int x,int y,int xe,int ye,int r,int g,int b,float a){glEnable(GL_BLEND);glBegin( GL_QUADS );printf("Drawing Rect at %i,%i to %i,%i, with the color: %i,%i,%i,%i\n",x,y,xe,ye,r,b,g,a);	//Top-left vertex (corner)    glColor4f(r,g,b,a);	glVertex3f((x*resmultiplierx),(y*resmultipliery), 0.0f );	//Bottom-left vertex (corner)    glColor4f(r,g,b,a);	glVertex3f((xe*resmultiplierx), (y*resmultipliery), 0 );	//Bottom-right vertex (corner)    glColor4f(r,g,b,a);	glVertex3f((xe*resmultiplierx),(ye*resmultipliery), 0 );	//Top-right vertex (corner)    glColor4f(r,g,b,a);	glVertex3f( (x*resmultiplierx),(ye*resmultipliery), 0 );glEnd();glDisable(GL_BLEND);}void SDL_GL_RenderText(string text,                      TTF_Font *font,                      SDL_Color color,                      SDL_Color bgcolor,                      SDL_Rect *location,                      int alignment,int transp,textquality quality/*,int wrapwidth*/){	SDL_Surface *initial;	SDL_Surface *intermediary;	SDL_Rect rect;	char* textc;	int w,h;	GLuint texture; Uint32 TimeStart=SDL_GetTicks();    textc = new char[text.size()+1];    strcpy (textc, text.c_str());	/* Use SDL_TTF to render our text */    if (quality == solid)    {        initial = TTF_RenderText_Solid(font, textc, color);    }    else if (quality == shaded)    {        initial = TTF_RenderText_Shaded(font, textc, color, bgcolor);    }    else if (quality == blended)    {        initial = TTF_RenderText_Blended(font, textc, color);    }  printf("SDL_GL_RenderText 1: %i\n",SDL_GetTicks()-TimeStart);    TimeStart=SDL_GetTicks();    /* Convert the rendered text to a known format */    w = initial->w;    h = initial->h;    t_width = initial->w;    printf("SDL_GL_RENDER_TEXT: Text Height: %i Width: %i\n",h,w);    if((quality == shaded) && (transp = 1))    {        printf("Error: Cannot render shaded text as transparent!");    } printf("SDL_GL_RenderText 2: %i\n",SDL_GetTicks()-TimeStart); TimeStart=SDL_GetTicks();    //I Think That It's Crashing HERE.    intermediary = SDL_CreateRGBSurface(0, w, h, 32,    		0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);    //SDL_BlitSurface(initial, NULL, intermediary, NULL);    //======================SDL_BlitSurface Replacment========================       SDL_Surface * tempalpha = NULL;	   tempalpha = SDL_DisplayFormatAlpha(initial);		glGenTextures(1, &texture);		glBindTexture(GL_TEXTURE_2D, texture);		//SDL_LockSurface(temp);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  GL_LINEAR);		glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary->pixels);		glTexSubImage2D(GL_TEXTURE_2D,0,0,0,tempalpha->w,tempalpha->h,GL_RGBA,GL_UNSIGNED_BYTE,tempalpha->pixels);		SDL_FreeSurface(tempalpha);//======================End SDL_BlitSurface Replacment======================== printf("SDL_GL_RenderText 3: %i\n",SDL_GetTicks()-TimeStart); TimeStart=SDL_GetTicks();    /* Tell GL about our new texture */   //=========================UNcomment To use SDL_BlitSurface=============   /* glGenTextures(1, &texture);    glBindTexture(GL_TEXTURE_2D, texture);    glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA,    		GL_UNSIGNED_BYTE, intermediary->pixels );    //GL_NEAREST looks horrible, if scaled...    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    /* prepare to render our texture */    //=========================UNcomment To use SDL_BlitSurface=============    glEnable(GL_TEXTURE_2D);    glBindTexture(GL_TEXTURE_2D, texture);    glColor3f(1.0f, 1.0f, 1.0f); printf("SDL_GL_RenderText 4: %i\n",SDL_GetTicks()-TimeStart);  TimeStart=SDL_GetTicks();	/* Draw a quad at location */	switch(alignment)	{        case 0: //Left            DrawRect(location->x,location->y,(location->x + w),(location->y + h));            break;        case 1: //Center            DrawRect((location->x - (w/2)),location->y,(location->x + (w/2)),location->y + h);            break;        case 2: //Right            DrawRect((location->x + w),(location->y + h),location->x,location->y);            break;    } printf("SDL_GL_RenderText 6: %i\n",SDL_GetTicks()-TimeStart); TimeStart=SDL_GetTicks();	/* Bad things happen if we delete the texture before it finishes */	glFinish();printf("SDL_GL_RenderText 7: %i\n",SDL_GetTicks()-TimeStart);TimeStart=SDL_GetTicks();	/* return the deltas in the unused w,h part of the rect */	location->w = initial->w;	location->h = initial->h;	/* Clean up */	SDL_FreeSurface(initial);	SDL_FreeSurface(intermediary);	glDeleteTextures(1, &texture);	 printf("SDL_GL_RenderText 8: %i\n",SDL_GetTicks()-TimeStart);}void PrintChat(string print,TTF_Font *printfont,int fr,int fg,int fb,int br,int bg,int bb,int x,int y,int align,int wrap){    Uint32 TimeStart=SDL_GetTicks();    SDL_Rect printloc;    char* printline;    int linesz = 0;    t_height = 0;    printloc.x = x;    printloc.y = y;    printf("Printing: %s",print.c_str());    int i;    if(print.compare((print.length()-(int)strlen("\n")),(int)strlen("\n"),"\n") == 0)    {        print = print.substr(0,(print.length()-(int)strlen("\n")));    }    char* printc = new char[print.size()+1];    strcpy (printc, print.c_str());    printline = strtok(printc, "\n");    while(printline != NULL && (print.compare((linesz+(int)strlen(printline)),(int)strlen("\n"),"\n") == 0))    {        linesz += ((int)strlen(printline)+(int)strlen("\n"));        printloc.y += TTF_FontLineSkip(printfont);        SDL_GL_RenderText(printline,printfont,SetRGB(fr,fg,fb),SetRGB(br,bg,bb),&printloc,align,1,solid);        printline = strtok(NULL,"\n");    }    if(printline != NULL)    {        linesz += (int)strlen("\n");    }    printline = new char [(print.length()-linesz)+1];    strcpy (printline,(print.substr(linesz-1,(print.length()-linesz)+1)).c_str());    printf("PRINTCHAT: Loop Done! Printing: '%s'. LineSZ: %i\n",printline,linesz);    printloc.y += TTF_FontLineSkip(printfont);    printf("PRINTCHAT: Rendering!\n");     printf("PrintChat %i\n",SDL_GetTicks()-TimeStart);    SDL_GL_RenderText(printline,printfont,SetRGB(fr,fg,fb),SetRGB(br,bg,bb),&printloc,align,1,solid);    printf("T_Width: %i",t_width);    printf("PRINTCHAT: Render Sucessful!\n");    SDL_GL_SwapBuffers();}int main(int argc, char *argv[]){initSDL();initGL();glClear( GL_COLOR_BUFFER_BIT );font = loadfont("C:\\WINDOWS\\Fonts\\ARIAL.TTF",32);PrintChat("This text is being rendered using PrintChat.\nType below to see the problem:",font,255,255,255,0,0,0,10,10,0,0);PrintChat("Thanks for your help!",font,255,255,255,0,0,0,10,600,0,0);SDL_GL_SwapBuffers();SDL_EnableUNICODE( SDL_ENABLE );while(!done){    printf("Loop entering!\n");    SDL_PollEvent(&event);    if(event.key.keysym.sym == SDLK_ESCAPE)    {        done = 1;        break;    }    if(event.type == SDL_QUIT)    {        done = 1;        break;    }    if(event.key.keysym.unicode >= (Uint16)' ' && event.key.keysym.unicode <= (Uint16)'~' )    {        /** This is either an upper or lowwer case letter,        *  add it to the buffer, This check can obviously        *  be easily modified to allow for numbers and more.        *  But it is important to pro_event the ASCII values        *  of control keys or others from being nonsensically        *  added to your buffer.        */        tempchar = (char)event.key.keysym.unicode;       Uint32 TimeStart=SDL_GetTicks();        chatbuffer.insert(stringpos,tempchar);       printf("Insert Time %i\n",SDL_GetTicks()-TimeStart);        stringpos++;        printf("Printing!\n");        PrintChat(chatbuffer,font,255,255,255,0,0,0,50,150,0,0);    }SDL_GL_SwapBuffers();}SDL_EnableUNICODE( SDL_DISABLE );return 1;}

run this and then look at the stdout.txt
look at SDL_GL_RenderText 8:
this line is in SDL_GL_RenderText
watch how it grows over time
I am not sure what is causing this

(note this code does seem to exit for no reason some times in code::blocks but not Visual studios not sure why)

Sorry i could not be any more help today

Hope you find some of this usefully
Black CloakEpee Engine.
Won't be able to run the updated demo code tonight, but I fixed the blit replacement code, and it works again...

I'll test the new demo code tomorrow, and post the results. :) Thanks for all the help you've given me so far!
Hey :)

I tested and ran the code, but I only ever get SDL_GL_RenderText 8: 0. :S
Sorry I meant SDL_GL_RenderText 7
my bad

One last thing (this donned on me last night)
You don't need glflush if you are calling SDL_GL_SwapBuffers() it does it for you. This mite be part of the lag issue since every time you call glflush you are sending information down the bus and then sending it again with SDL_GL_SwapBuffers(). So the glflush calls are a waste of cpu cycles.


Hope this helps


[Edited by - blackcloak on July 25, 2008 2:05:07 PM]
Black CloakEpee Engine.
Ok... I changed the font file, but I'm still getting the crash... does it work for you? :/
Awesome news guys! It wasn't anything to do with SDL!!! I was thinking about what blackcloak said, about deleting where I'd used new, and I found two un-deleted chars in PrintChat. I deleted them before SDL_GL_SwapBuffers, and it didn't crash anymore :P

Thanks guys for all your help over the past few days, especially blackcloak, who's helped me with all my other problems since I joined last week :P And thanks for the tips on lag too ;)

This topic is closed to new replies.

Advertisement