//Call this first, or every time window is resized
static void setup_opengl( int width, int height )
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
}
//Drawing function gets called every loop
static void draw_screen( void )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glEnable( GL_BLEND );
glColor4f(0.0, 1.0, 0.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex2f( 100, 100);
glVertex2f( 100, 200);
glVertex2f( 200, 200);
glVertex2f( 200, 100);
glEnd();
glPopMatrix();
//Swap buffers here
}
As you can see there aren't any actual glut calls here, so I figured it would work in SDL. However, when calling glVertex2f, it still wants a value between -1 and 1, with 0 being the center of the screen. Anyone know how I can change this?
Oh, and on a side note, if anyone knows... I'm doing this with XCode in Mac OS X, but when I run my program, then exit and it comes back from fullscreen, and I can no longer minimize windows of applications that were running at the same time. I have to restart all my apps. It's pretty weird...
Per Pixel drawing
I'm going to be making a 2D vector-graphics based game in C/OpenGL. I was using GLUT, but I decided to go with SDL as per advice in another thread because it supports USB joysticks. However, I want to be able to plot points on the screen per pixel (relative to the resolution rather than real pixels of course), with point 0, 0 being on the bottom left of the screen (therefor putting my entire view in the first quadrant).
When I was using GLUT, I did this:
Ok i'm kinda tired but if i read that right you basically want to convert something where the ranges are -1 to 1 to 0 to 1?
If thats what you are after then why don't you just do -1 + ( your number between 0 and 1 * 2 )
Hope that helps
Chris
If thats what you are after then why don't you just do -1 + ( your number between 0 and 1 * 2 )
Hope that helps
Chris
Er, that's not quite what I meant. What I'm saying is, if my resolution is 800x600, I want 0,0 to be the lower left corner of the screen, and plotting a point at (800,600) would give me the upper right of the screen, and 400,300 would be the middle. Like working with Java's graphics (although with inversed Y plotting). Basically so I can plot in the range of 0x0 to 800x600 (Or whatever resolution I use) instead of -1 to 1.
Are you sure you want glVertex2f instead of glVertex2i? Also, do you want gluOrtho or do you want glOrtho(0,width,0,height,1.0,1.0)?
Well, you're right that I shouldn't be using that gluOrth2D (I guess glOrtho is GL's equivalent?) I changed that, but it didn't fix my problem. However, using glvertex2i wouldn't make a difference. Perhaps I am making this sound more complicated than it needs to be?
The site that I first learned openGL with GLUT is here: http://onesadcookie.com/Tutorials
He describes the transformation like this:
In OpenGL, you can use whatever coordinate system is useful to
you. One of the most useful for 2D graphics is the projection
where OpenGL units are precisely one pixel.
That is the coordinate system that that same code used to let me use. If you take a look at that tutorial under Pixel-Perfect Projection, maybe you'll see what I mean.
The site that I first learned openGL with GLUT is here: http://onesadcookie.com/Tutorials
He describes the transformation like this:
In OpenGL, you can use whatever coordinate system is useful to
you. One of the most useful for 2D graphics is the projection
where OpenGL units are precisely one pixel.
That is the coordinate system that that same code used to let me use. If you take a look at that tutorial under Pixel-Perfect Projection, maybe you'll see what I mean.
gluOrtho(left, right, bottom, top, near, far) is, IIRC, equivilent to glOrtho(left, right, bottom, top, 1, -1). (ie. it sets the near and far plane for you).
Your code looks ok from a quick glance. I'd try calling setup_opengl at the top of draw_scene and see if that helps - it could be that you're calling setup_opengl too early (before you've got a valid display context) and so they're being ignored.
Your code looks ok from a quick glance. I'd try calling setup_opengl at the top of draw_scene and see if that helps - it could be that you're calling setup_opengl too early (before you've got a valid display context) and so they're being ignored.
Well, I am calling setup_opengl well after I initialize the graphics context. Here's the whole code:
Obviously it's mostly copy and pasted, but it seems like it should work. As I said, it achieves the desired effect when I'm using GLUT, but not SDL... I just don't know
#include <SDL/SDL.h>
#include <OpenGL/gl.h>
#include <stdio.h>
#include <stdlib.h>
SDL_Joystick *joystick;
int width, height;
double d(double f) {
return f/800 * 1.0;
}
static void quit_tutorial( int code )
{
SDL_JoystickClose(joystick);
SDL_Quit( );
exit( code );
}
static void handle_key_down( SDL_keysym* keysym )
{
switch( keysym->sym ) {
case SDLK_ESCAPE:
quit_tutorial( 0 );
break;
case SDLK_SPACE:
break;
default:
break;
}
}
static void process_events( void )
{
SDL_Event event;
while( SDL_PollEvent( &event ) ) {
switch( event.type ) {
case SDL_KEYDOWN:
handle_key_down( &event.key.keysym );
break;
case SDL_QUIT:
/* Handle quit requests (like Ctrl-c). */
quit_tutorial( 0 );
break;
case SDL_JOYAXISMOTION:
if(event.jaxis.value < -3200) {
if(event.jaxis.axis == 0) {
printf("You hit the left button!\n");
}
else if(event.jaxis.axis == 1) {
printf("You hit the down button!\n");
}
}
else if(event.jaxis.value > 3200) {
if(event.jaxis.axis == 0) {
printf("You hit the right button!\n");
}
else if(event.jaxis.axis == 1) {
printf("You hit the up button!\n");
}
}
break;
case SDL_JOYBUTTONDOWN:
if ( event.jbutton.button == 0 )
{
printf("You hit B!\n");
}
else if ( event.jbutton.button == 1 )
{
printf("You hit A!\n");
}
else if ( event.jbutton.button == 2 )
{
printf("You hit Select!\n");
}
else if ( event.jbutton.button == 3 )
{
printf("You hit Start!\n");
}
break;
}
}
}
static void setup_opengl( int width, int height )
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, 1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void draw_screen( void )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glEnable( GL_BLEND );
glColor4f(0.0, 1.0, 0.0, 1.0);
//This works
glBegin(GL_LINE_LOOP);
glVertex2f( -1.0f, -1.0f);
glVertex2f( -1.0f, 0.9f);
glVertex2f( 0.9f, 0.9f);
glVertex2f( 0.9f, -1.0f);
glEnd();
//But I'd like to be able to draw within a larger projection
glBegin(GL_LINE_LOOP);
glVertex2f( 100, 100);
glVertex2f( 100, 200);
glVertex2f( 200, 200);
glVertex2f( 200, 100);
glEnd();
glPopMatrix();
SDL_GL_SwapBuffers( );
}
int main( int argc, char* argv[] )
{
/* Information about the current video settings. */
const SDL_VideoInfo* info = NULL;
/* Color depth in bits of our window. */
int bpp = 0;
/* Flags we will pass into SDL_SetVideoMode. */
int flags = 0;
int error = SDL_Init(SDL_INIT_EVERYTHING);
/* Let's get some video information. */
info = SDL_GetVideoInfo( );
if( !info ) {
fprintf( stderr, "Video query failed: %s\n",
SDL_GetError( ) );
quit_tutorial( 1 );
}
/*
* Set our width/height to 640/480 (you would
* of course let the user decide this in a normal
* app). We get the bpp we will request from
* the display. On X11, VidMode can't change
* resolution, so this is probably being overly
* safe. Under Win32, ChangeDisplaySettings
* can change the bpp.
*/
width = 800;
height = 600;
bpp = info->vfmt->BitsPerPixel;
/* SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );*/
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
/*
* We want to request that SDL provide us
* with an OpenGL window, in a fullscreen
* video mode.
*/
flags = SDL_OPENGL | SDL_FULLSCREEN;
if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
fprintf( stderr, "Video mode set failed: %s\n",
SDL_GetError( ) );
quit_tutorial( 1 );
}
//Use Joystick
SDL_JoystickEventState(SDL_ENABLE);
joystick = SDL_JoystickOpen(0);
setup_opengl( width, height );
//Main loop... process, draw
while( 1 ) {
process_events( );
draw_screen( );
}
return 0;
}
Obviously it's mostly copy and pasted, but it seems like it should work. As I said, it achieves the desired effect when I'm using GLUT, but not SDL... I just don't know
You are passing 1.0 to both the near and far clipping planes in your glOrtho call, change them to -1.0 and 1.0 or use gluOrtho2d(0, width, 0, height).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement