简体   繁体   English

使用GLSL在OpenGL中进行简单的2D矩阵旋转不会产生任何输出

[英]Simple 2D matrix rotation in OpenGL with GLSL produces no output

I'm starting to learn about OpenGL and doing some early examples to understand the API how to use it. 我开始学习OpenGL,并做一些早期的例子来了解API如何使用它。 The I'm currently stuck on, is with a rotation example. 我目前坚持使用的是旋转示例。 The code, (provided bellow) is supposed to create a 2D square from 4 vertices and apply a rotation of 30º around the Z axis. 该代码(提供的波纹管)应该是从4个顶点创建一个2D正方形,并绕Z轴旋转30º。 Apparently, the code seems fine and I've seen it running in my professor's machine and it works. 显然,该代码看起来不错,而且我已经看到它在教授的机器上运行并且可以运行。 If I draw the square without applying the rotation inside the shader, the program draws the square, but with no rotation, of course. 如果在不应用着色器内部旋转的情况下绘制正方形,则程序当然会绘制正方形,但不旋转。

Could this be caused by some bad configuration? 这可能是由于某些错误的配置引起的吗? All the other examples seems to work fine. 所有其他示例似乎工作正常。

Here is the code: 这是代码:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Angel.h"

glm::vec2 vertices[4] = {
    glm::vec2( -0.5, -0.5 ),
    glm::vec2(  0.5, -0.5 ),
    glm::vec2(  0.5,  0.5 ),
    glm::vec2( -0.5,  0.5 ),
};

const int NumPoints = 6;
glm::vec2 points[NumPoints];

void square( ){
    points[0] = vertices[0];
    points[1] = vertices[1];
    points[2] = vertices[2];
    points[3] = vertices[0];
    points[4] = vertices[2];
    points[5] = vertices[3];
}

GLuint matRot;
void init( void ){
    square();
    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    GLuint buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

    GLuint program = InitShader( "vshader1.glsl", "fshader1.glsl" );
    glUseProgram( program );

    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0,
                           BUFFER_OFFSET(0) );

    matRot = glGetUniformLocation( program, "rot" );

    glClearColor( 1.0, 1.0, 1.0, 1.0 ); 
}

void display( void ){
    glClear( GL_COLOR_BUFFER_BIT );    

    glm::mat4 rotZ; 
    rotZ = glm::rotate(rotZ, glm::radians(30.0f), glm::vec3(0.0f,0.0f,1.0f));
    glUniformMatrix4fv(matRot,1,GL_FALSE, glm::value_ptr(rotZ)); 

    glDrawArrays( GL_TRIANGLES, 0, NumPoints );  
    glFlush();
}

int main( int argc, char **argv ){
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
    glutInitWindowSize( 512, 512 );
    glutInitWindowPosition(0,0);
    glutCreateWindow( "square rotation" );

    glewInit(); 

    init();

    glutDisplayFunc( display );

    glutMainLoop();
    return 0;
}

The Angel.h is an additional resource that helps with some management of all those libraries. Angel.h是有助于对所有这些库进行某种管理的附加资源。 It can be found here and the InitShader implementation is here 可以在这里找到并且InitShader实现在这里

The vertex shader: 顶点着色器:

#version 130

in vec4 vPosition;
uniform mat4 rot;

void main()
{
    gl_Position = rot * vPosition;
}

If I don't multiply rot * vPosition , the "un-rotated" square is drawn 如果我不乘以rot * vPosition ,则会绘制“未旋转”的正方形

And the fragments shadder: 和片段阴影:

#version 130

out vec4 fColor;

void main()
{
    fColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}

Workin' fine on my machine with FreeGLUT, GLUT_DOUBLE , & GLM 0.9.8.4: 使用FreeGLUT, GLUT_DOUBLE和GLM 0.9.8.4在我的机器上可以正常工作:

旋转正方形的屏幕截图

#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <cstdarg>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

struct Program
{
    static GLuint Load( const char* shader, ... )
    {
        GLuint prog = glCreateProgram();
        va_list args;
        va_start( args, shader );
        while( shader )
        {
            const GLenum type = va_arg( args, GLenum );
            AttachShader( prog, type, shader );
            shader = va_arg( args, const char* );
        }
        va_end( args );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static void CheckStatus( GLuint obj )
    {
        GLint status = GL_FALSE;
        if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        GLchar log[ 1 << 15 ] = { 0 };
        if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
        if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
        std::cerr << log << std::endl;
        exit( EXIT_FAILURE );
    }

    static void AttachShader( GLuint program, GLenum type, const char* src )
    {
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};

#define GLSL(version, shader) "#version " #version "\n" #shader

glm::vec2 vertices[4] =
{
    glm::vec2( -0.5, -0.5 ),
    glm::vec2(  0.5, -0.5 ),
    glm::vec2(  0.5,  0.5 ),
    glm::vec2( -0.5,  0.5 ),
};

const int NumPoints = 6;
glm::vec2 points[NumPoints];

void square( )
{
    points[0] = vertices[0];
    points[1] = vertices[1];
    points[2] = vertices[2];
    points[3] = vertices[0];
    points[4] = vertices[2];
    points[5] = vertices[3];
}

GLuint matRot;
void init( void )
{
    square();
    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    GLuint buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

    const char* vert = GLSL
    (
        130,
        in vec4 vPosition;
        uniform mat4 rot;

        void main()
        {
            gl_Position = rot * vPosition;
        }
    );

    const char* frag = GLSL
    (
        130,
        out vec4 fColor;

        void main()
        {
            fColor = vec4( 1.0, 0.0, 0.0, 1.0 );
        }
    );
    GLuint program = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
    glUseProgram( program );

    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );

    matRot = glGetUniformLocation( program, "rot" );

    glClearColor( 1.0, 1.0, 1.0, 1.0 ); 
}


void display()
{
    glClear( GL_COLOR_BUFFER_BIT );    

    glm::mat4 rotZ; 
    rotZ = glm::rotate(rotZ, glm::radians(30.0f), glm::vec3(0.0f,0.0f,1.0f));
    glUniformMatrix4fv(matRot,1,GL_FALSE, glm::value_ptr(rotZ)); 

    glDrawArrays( GL_TRIANGLES, 0, NumPoints );  

    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 600, 600 );
    glutCreateWindow( "GLUT" );

    glewExperimental = GL_TRUE;
    glewInit();

    init();

    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM