0

编辑........所以我已经摆脱了所有的废话,现在只有一个 SSCE(希望我明白现在是什么)。对于尚未看到此问题的任何人,我想在调整大小时保持纵横比,但窗口的行为就像我已注释掉与调整大小有关的任何内容(它会拉伸)。我已经检查了所有点的投影矩阵,它在您期望的点处发生变化,并在您期望的点处保持不变。

我去掉了依赖其他文件的东西,所以它应该为你编译,除了着色器文件,我也会发布他们的代码(它们很短)。很抱歉,它的格式看起来不是很好,很难保持格式必须在大多数行前放置 4 个空格。

顺便说一句,电线立方体没有出现。但是当逐字复制我的第一个回答者的建议并编译它时,它确实出现了。不确定这是否与我的问题有关。

#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);
}
4

2 回答 2

3

我不完全确定您希望在没有glutInit()电话的情况下完成什么。

尝试这个:

#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;
}

编辑:鉴于(在撰写本文时)最新版本中的代码,试一试:

#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;
}
于 2013-04-26T14:49:29.477 回答
0

当您有着色器时,gluPerspective 不起作用,除非您将投影矩阵句柄传递给着色器。

所以在你的其他全局变量的开头有一个全局 int g_ProjectionMatrixHandle = 0 。

然后在初始化阶段获取句柄:

g_ProjectionMatrixHandle = glGetUniformLocation(g_Program, "projection_matrix");

然后在绘图阶段将句柄发送到着色器:

GLfloat p[16];
glGetFloatv(GL_PROJECTION_MATRIX, p);
glUniformMatrix4fv(g_ProjectionMatrixHandle, 1, GL_FALSE, p);

然后在着色器中收集句柄并使用它:

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);
}

我还将弄清楚为什么我不能很快绘制形状并稍后编辑这个答案,以防其他人遇到问题。

顺便说一句,如果您只是绘制常规形状(线、多边形等)而不是用于坐标和纹理的数组,并且出于某种原因使用着色器,请参阅 genpfault 的着色器代码。

于 2013-05-10T02:18:23.117 回答