Reputation: 49
EDIT........ So I've gotten rid of all the crap and just have an SSCE now (hopefully I understand what one is now). For anyone who hasn't seen this problem already, I want to maintain the aspect ratio when resizing, but the window behaves as though I had commented out anything to do with resizing (it stretches). I have checked the projection matrix along all points and it changes at the points you'd expect and stays the same at the points you'd expect.
I stripped out the stuff that relies on other files, so it should compile for you, except the shader files, I will post their code too (they are very short). I'm sorry it doesn't look very nicely formatted, it is hard to keep the formatting having to put 4 spaces in front of most of the lines.
The wire cube does not appear by the way. But when copying verbatim my first answerer's suggestion and compiling it, it does appear. Not sure if that is related to my problem.
#define GLEW_STATIC
#include "glew.h"
#include "glut.h"
#include <Windows.h>
#include <iostream>
//#include "TgaParser.h"
//#include "Vertex.h"
//#include "ObjParser.h"
//#include "Car.h"
//#include "Floor.h"
//#include "BitmapParser.h"
using namespace std;
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"glut32.lib")
#pragma comment(lib, "glew32s.lib")
/*GLOBALS*/
int g_ScreenWidth = 800;
int g_ScreenHeight = 800;
int g_Program = 0;
int g_PositionHandle = 0;
int g_TextureCoordhandle = 0;
int g_ModelMatrixHandle = 0;
//Car* g_pCar = 0;
//Floor* g_pFloor = 0;
void error(char * error)
{
printf(error);
system("pause");
exit(0);
}
static void checkGlError(const char* op)
{
for (GLint error = glGetError(); error; error
= glGetError())
{
const GLubyte* sError = gluErrorString(error);
printf("Shader error %s\n",sError);
}
}
GLuint loadShader(GLenum shaderType, const char* pSource)
{
GLuint shader = glCreateShader(shaderType);
if (shader)
{
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
checkGlError("createVertexShader");
if (!compiled)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen)
{
char* buf = (char*) malloc(infoLen);
if (buf)
{
glGetShaderInfoLog(shader, infoLen, NULL, buf);
printf(buf);
free(buf);
}
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
GLuint createProgram(const char* pVertexSource, const char* pFragmentSource)
{
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
checkGlError("createVertexShader");
if (!vertexShader)
{
return 0;
}
GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
if (!pixelShader)
{
return 0;
}
GLuint program = glCreateProgram();
g_Program=program;
if (program)
{
glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE)
{
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength)
{
char* buf = (char*) malloc(bufLength);
if (buf)
{
glGetProgramInfoLog(program, bufLength, NULL, buf);
free(buf);
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
void forward_display()
{
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)g_ScreenWidth/(GLfloat)g_ScreenHeight, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0, -0.5, 1, 0, 0, -1, 0, 1, 0);
//glPushMatrix ();
//glRotatef(timeGetTime()*0.05,0,1,0);
//g_pCar->Draw(g_ModelMatrixHandle, g_PositionHandle, g_TextureCoordhandle);
//glPopMatrix ();
glTranslatef(0, 0, -2);
glColor3f(1,0,0);
glRotatef( 45, 1, 1, 0 );
glutWireCube(1);
glutSwapBuffers();
}
void forward_animate()
{
forward_display();
}
/*Reads in all of the data contents automatically allocating memory for the content*/
char* readFileData (char * fileName)
{
FILE *fp = fopen(fileName,"r");
if (fp==0)
{
error("Why is all rum gone!!\n");
return 0;
}
fseek(fp, 0L, SEEK_END);
int sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char * data = new char[sz+1];
memset(data,0,sz+1);
fread(data,1,sz,fp);
fclose(fp);
return data;
}
void init()
{
char * vertexShaderBuffer = readFileData("../resources/shaders/IntroToShaders.vs");
char * pixelShaderBuffer = readFileData("../resources/shaders/IntroToShaders.ps");
g_Program = createProgram (vertexShaderBuffer, pixelShaderBuffer);
//We have finished compiling the shader now delete the char arrays with the source code
delete [] vertexShaderBuffer;
delete [] pixelShaderBuffer;
g_PositionHandle = glGetAttribLocation(g_Program, "vPosition");
g_TextureCoordhandle = glGetAttribLocation(g_Program, "vTextureCoord");
g_ModelMatrixHandle = glGetUniformLocation(g_Program, "modelview_matrix");
if (g_PositionHandle == -1)
{
printf("g_PositionHandle is bad\n");
}
if (g_TextureCoordhandle == -1)
{
printf("g_TextureCoordhandle is bad\n");
}
if (g_ModelMatrixHandle == -1)
{
printf("g_ModelMatrixHandle is bad\n");
}
glUseProgram(g_Program);
//g_pCar = new Car();
//g_pCar->Initialise ();
//g_pFloor = new Floor ();
//g_pFloor->Initialise ();
//g_pCar->InitTextures();
//g_pFloor->InitTextures ();
//g_pCar->LoadTextures ();
//g_pFloor->LoadTextures ();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void reshape(int w, int h)
{
g_ScreenWidth = w;
g_ScreenHeight = h;
glViewport(0, 0, w, h);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(g_ScreenWidth, g_ScreenHeight);
glutCreateWindow("Assignment 1");
glewInit();
init ();
glutDisplayFunc(forward_display);
glutIdleFunc(forward_animate);
glutReshapeFunc(reshape);
glutMainLoop();
/*
DONT DO THINGS HERE
*/
return 0;
}
IntroToShaders.ps:
varying vec2 vTexCoord;
uniform sampler2D myTexture;
void main (void)
{
gl_FragColor = texture2D(myTexture, vTexCoord);
}
IntroToShaders.vs:
attribute vec3 vPosition;
attribute vec2 vTextureCoord;
varying vec2 vTexCoord;
uniform mat4 modelview_matrix;
void main(void)
{
vTexCoord = vTextureCoord;
gl_Position = modelview_matrix*vec4(vPosition,1.0);
}
Upvotes: 0
Views: 642
Reputation: 49
gluPerspective does not work when you have shaders, unless you pass the projection matrix handle to the shader.
So have a global int g_ProjectionMatrixHandle = 0 at the beginning with your other globals.
Then get the handle in your init phase:
g_ProjectionMatrixHandle = glGetUniformLocation(g_Program, "projection_matrix");
Then send the handle to the shader in your drawing phase:
GLfloat p[16];
glGetFloatv(GL_PROJECTION_MATRIX, p);
glUniformMatrix4fv(g_ProjectionMatrixHandle, 1, GL_FALSE, p);
Then collect the handle in the shader and use it:
attribute vec3 vPosition;
attribute vec2 vTextureCoord;
varying vec2 vTexCoord;
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
void main(void)
{
vTexCoord = vTextureCoord;
gl_Position = projection_matrix * modelview_matrix * vec4(vPosition,1.0);
}
I will also figure out why I can't draw shapes soon and edit this answer later on in case anyone else is having problems.
By the way if you are just drawing regular shapes (lines, polygons etc) instead of arrays for coordinates and textures, and are using shaders for some reason, refer to genpfault's code for your shader.
Upvotes: 0
Reputation: 52084
I'm not entirely sure what you hoped to accomplish without a glutInit()
call.
Try this:
#include <GL/glut.h>
void forward_display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(60, w / h, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef( 0, 0, -2 );
glColor3ub(255, 0, 0);
glRotatef( 45, 1, 1, 0 );
glutWireCube( 1 );
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutCreateWindow("Intro to shading");
glutDisplayFunc(forward_display);
glutMainLoop();
return 0;
}
EDIT: Given the code in (as of this writing) the most recent revision, give this a shot:
#include <GL/glew.h>
#include <GL/glut.h>
#include <cstdio>
/*GLOBALS*/
int g_Program = 0;
int g_ProjectionMatrixHandle = 0;
int g_ModelMatrixHandle = 0;
static void checkGlError(const char* op)
{
for (GLint error = glGetError(); error; error
= glGetError())
{
const GLubyte* sError = gluErrorString(error);
printf("Shader error %s\n",sError);
}
}
GLuint loadShader(GLenum shaderType, const char* pSource)
{
GLuint shader = glCreateShader(shaderType);
if (shader)
{
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
checkGlError("createVertexShader");
if (!compiled)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen)
{
char* buf = (char*) malloc(infoLen);
if (buf)
{
glGetShaderInfoLog(shader, infoLen, NULL, buf);
printf(buf);
free(buf);
}
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
GLuint createProgram(const char* pVertexSource, const char* pFragmentSource)
{
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
checkGlError("createVertexShader");
if (!vertexShader)
{
return 0;
}
GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
if (!pixelShader)
{
return 0;
}
GLuint program = glCreateProgram();
g_Program=program;
if (program)
{
glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE)
{
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength)
{
char* buf = (char*) malloc(bufLength);
if (buf)
{
glGetProgramInfoLog(program, bufLength, NULL, buf);
free(buf);
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
void forward_display()
{
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(60, w / h, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -2);
glColor3f(1,0,0);
glRotatef( 45, 1, 1, 0 );
GLfloat projection[16];
glGetFloatv( GL_PROJECTION_MATRIX, projection );
glUniformMatrix4fv( g_ProjectionMatrixHandle, 1, GL_FALSE, projection );
GLfloat modelview[16];
glGetFloatv( GL_MODELVIEW_MATRIX, modelview );
glUniformMatrix4fv( g_ModelMatrixHandle, 1, GL_FALSE, modelview );
glutWireCube(1);
glutSwapBuffers();
}
void forward_timer( int extra )
{
glutTimerFunc( 16, forward_timer, 0 );
glutPostRedisplay();
}
#define GLSL(version, shader) "#version " #version "\n" #shader
const char * vertexShaderBuffer = GLSL
(
120,
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
varying vec4 vColor;
void main(void)
{
vColor = gl_Color;
gl_Position = projection_matrix * modelview_matrix * gl_Vertex;
}
);
const char * pixelShaderBuffer = GLSL
(
120,
varying vec4 vColor;
void main (void)
{
gl_FragColor = vColor;
}
);
void init()
{
g_Program = createProgram (vertexShaderBuffer, pixelShaderBuffer);
glUseProgram(g_Program);
g_ProjectionMatrixHandle = glGetUniformLocation(g_Program, "projection_matrix");
if (g_ProjectionMatrixHandle == -1)
{
printf("g_ProjectionMatrixHandle is bad\n");
}
g_ModelMatrixHandle = glGetUniformLocation(g_Program, "modelview_matrix");
if (g_ModelMatrixHandle == -1)
{
printf("g_ModelMatrixHandle is bad\n");
}
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutCreateWindow("Assignment 1");
glewInit();
init ();
glutDisplayFunc(forward_display);
glutTimerFunc( 0, forward_timer, 0 );
glutMainLoop();
return 0;
}
Upvotes: 3