LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-27-2008, 02:43 AM   #1
tanoatlq
Member
 
Registered: Mar 2007
Posts: 157

Rep: Reputation: 30
efficent scroll with SDL and openGL


Hello,
I have an SDL surface representing the audio of a song.
I would like to show on the screen the current portion that is played
as a cursor on the middle and scroll it while music goes on.
I think some openGL function could help me.
Suggestions?
Thanks,
tano
 
Old 08-27-2008, 05:05 AM   #2
resetreset
Senior Member
 
Registered: Mar 2008
Location: Cyberspace
Distribution: Dynebolic, Ubuntu 10.10
Posts: 1,340

Rep: Reputation: 62
i have no idea about the answer to your qusetion, but just wanna say that there are some opengl tuts on nehe.gamedev.net .
 
Old 08-27-2008, 05:42 AM   #3
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
The effect you are talking about is referred to as scrolling see this page for information about it. Using OpenGL you want to adjust the GL_MODELVIEW matrix so that the correct portion of the background is in the buffer.

edit:Sorry I forgot the title of the thread

Last edited by dmail; 08-27-2008 at 05:46 AM.
 
Old 08-27-2008, 07:13 AM   #4
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by tanoatlq View Post
Hello,
I have an SDL surface representing the audio of a song.
I would like to show on the screen the current portion that is played
as a cursor on the middle and scroll it while music goes on.
I think some openGL function could help me.
Suggestions?
Thanks,
tano
It's very easy to do.


Either build surface for entire song and scroll it, or draw surface only for currently visible segment.
Code:
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <wchar.h>
#include <math.h>

const double pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854874462379962749567351885752724891227938183011949129833673362; //:-) 
static int scrWidth = 640;
static int scrHeight = 480;

float song(float pos){
	float result = 0.0f;
	const int numHarmonics = 5;
	for (int i = 0; i < numHarmonics; i++){
		float f = (1 << i);
		result += sinf(pi*pos*f);
	}
	result /= (float)numHarmonics;
	return result;
	//return sinf(pi*pos) + sinf(pi*;
}

int main(int argc, char** argv){
    SDL_Init(SDL_INIT_VIDEO);
	
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	
	if (SDL_SetVideoMode(scrWidth, scrHeight, 32, SDL_OPENGL) == 0){
		fprintf(stderr, "couldn't set mode %dx%d!\n", 640, 480);
		SDL_Quit();
		return -1;
	}
	
	SDL_ShowCursor(SDL_DISABLE);
    
	glClearColor(0.2, 0.2, 0.2, 0.2);
	glClearDepth(1.0);
	
	glEnable(GL_DEPTH_TEST);
	
	bool running = true;
	Uint32 lastTick = SDL_GetTicks();
	Uint32 curTick = lastTick;
	while (running){
		SDL_Event event;
		if (SDL_PollEvent(&event)){
			switch(event.type){
				case SDL_QUIT:
				    running = false;
				    break;
			};
		}
		
		curTick = SDL_GetTicks();
		float delta = float(curTick - lastTick)/1000.0f;
		lastTick = curTick;
		
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluOrtho2D(0, scrWidth, scrHeight/2.0f, -scrHeight/2.0f);
	
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		static float offset = 0;
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		glBegin(GL_LINE_STRIP);
		glColor3f(0, 1, 0);
		offset += delta;
		if (offset > 3.0f)
			offset -= 3.0f;
		float lineOffset = offset - 0.5f;
		float cursorPos = 0.5f;
		if (lineOffset < 0){
			cursorPos = lineOffset+0.5;
			lineOffset = 0;
		}
		if (lineOffset > 2.0f){
			cursorPos = lineOffset - 1.5f;
			lineOffset = 2.0f;
		}
		for (int x = 0; x < scrWidth; x ++)
			glVertex2f(x, scrHeight*song(((float)x/(float)scrWidth)+lineOffset)*0.5f);
		    
		glEnd();
		glBegin(GL_LINE_STRIP);
		glVertex2f(cursorPos*scrWidth, scrHeight*0.5f);
		glVertex2f(cursorPos*scrWidth, -scrHeight*0.5f);
		glEnd();
			
		glDisable(GL_DEPTH_TEST);
		
		glFlush();
		SDL_GL_SwapBuffers();		
	}	
	
    SDL_Quit();
    return 0;
}
With surface it'll be same thing.

--EDIT--
By the way, you can't render SDL_surface with OpenGL. Either make OpenGL texture from that surface and render it, or don't use OpenGL and use SDL_BlitSurface function.

Last edited by ErV; 08-27-2008 at 07:19 AM.
 
Old 08-27-2008, 07:20 AM   #5
tanoatlq
Member
 
Registered: Mar 2007
Posts: 157

Original Poster
Rep: Reputation: 30
Thanks!
I have to look at it one minute, but it seems not to be complex.
 
Old 08-27-2008, 07:53 AM   #6
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
With texture:
Code:
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <wchar.h>
#include <math.h>

const double pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854874462379962749567351885752724891227938183011949129833673362; //:-) 
static int scrWidth = 640;
static int scrHeight = 480;
GLuint texture = 0;

GLuint genTexture(){
	GLuint tex = 0;
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	const int width = 256;
	const int height = 16;
	Uint32 data[height][width];
	for (int x  = 0; x < width; x++)
		for (int y = 0; y < height; y++){
			int color = (x & 1) ^ (y & 1);
			Uint32 color1 = 0xFF000000|(x << 16);
			Uint32 color2 = 0xFF000000|y << 4;
			data[y][x] = color ? color1: color2;
		}
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//_MIPMAP_LINEAR);
	glBindTexture(GL_TEXTURE_2D, 0);
	return tex;
}

int main(int argc, char** argv){
    SDL_Init(SDL_INIT_VIDEO);
	
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	
	if (SDL_SetVideoMode(scrWidth, scrHeight, 32, SDL_OPENGL) == 0){
		fprintf(stderr, "couldn't set mode %dx%d!\n", 640, 480);
		SDL_Quit();
		return -1;
	}
	
	SDL_ShowCursor(SDL_DISABLE);
    
	glClearColor(0.2, 0.2, 0.2, 0.2);
	glClearDepth(1.0);
	
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	texture = genTexture();
	
	bool running = true;
	Uint32 lastTick = SDL_GetTicks();
	Uint32 curTick = lastTick;
	while (running){
		SDL_Event event;
		if (SDL_PollEvent(&event)){
			switch(event.type){
				case SDL_QUIT:
				    running = false;
				    break;
			};
		}
		
		curTick = SDL_GetTicks();
		float delta = float(curTick - lastTick)/1000.0f;
		lastTick = curTick;
		
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluOrtho2D(0, scrWidth, scrHeight/2.0f, -scrHeight/2.0f);
	
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glBindTexture(GL_TEXTURE_2D, texture);
		static float offset = 0;
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		glColor3f(0, 1, 0);
		const int numSegments = 4;
		float segmentSize = 1.0f/(float)numSegments;
		float halfSegment = segmentSize * 0.5f;
		float maxValue = ((float)(numSegments) - 0.5f)*segmentSize;
		float minValue = 0.5f*segmentSize;
		
		offset += delta*segmentSize*0.5f;
		if (offset > 1.0f)
			offset = offset - 1.0f;
		float lineOffset = offset;
		float cursorPos = 0.5f;
		lineOffset -= halfSegment;
		if (lineOffset < 0){
			cursorPos = lineOffset*numSegments + 0.5f;
			lineOffset = 0;
		}
		
		if (lineOffset > (1.0f - segmentSize)){
			cursorPos = (lineOffset - (1.0f - segmentSize))* numSegments + 0.5f;
			lineOffset = (1.0f - segmentSize);
		}

		glColor3f(1, 1, 1);
		glBegin(GL_TRIANGLE_FAN);
		float s1 = lineOffset;
		float s2 = lineOffset + segmentSize;
		glTexCoord2f(s1, 0);
		glVertex2f(0, -scrHeight*0.5f);
		glTexCoord2f(s2, 0);
		glVertex2f(scrWidth, -scrHeight*0.5f);
		glTexCoord2f(s2, 1);
		glVertex2f(scrWidth, scrHeight*0.5f);
		glTexCoord2f(s1, 1);
		glVertex2f(0, scrHeight*0.5f);
		glEnd();
		glBindTexture(GL_TEXTURE_2D, 0);
		glColor3f(0, 1, 0);
		glBegin(GL_LINE_STRIP);
		glVertex2f(cursorPos*scrWidth, scrHeight*0.5f);
		glVertex2f(cursorPos*scrWidth, -scrHeight*0.5f);
		glEnd();
			
		glDisable(GL_DEPTH_TEST);
		
		glFlush();
		SDL_GL_SwapBuffers();		
	}

	glDeleteTextures(1, &texture);	
	
    SDL_Quit();
    return 0;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Java vs OpenGL vs SDL vs ????? LinuxNoob75 Programming 12 12-08-2007 04:30 PM
Using SDL/OpenGL, need help. kornerr Programming 33 11-19-2005 11:19 PM
sdl / opengl - cant press up and right atrain Linux - Games 2 03-27-2005 11:29 PM
Using OpenGL (+SDL) for 2D programs R00ts Programming 4 07-16-2004 12:33 PM
OpenGL lighting with SDL MadCactus Programming 0 09-21-2003 11:52 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:48 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration