2013-05-17 1 views
0

적절한 그리기 사각형에 문제가 있습니다. Windows 7 x64에서 glut과 glew를 사용하고 있습니다.OpenGL 2.0 직사각형 그리기 직교 투영

오른쪽 상단 모서리에 검정색 사각형 (내 앱에서 벽) 만 보입니다.

나는 정사각형으로 미로를 그려 나가려고하고있다. 쉐이더없이

내 소스 코드 :

#define GL_GLEXT_PROTOTYPES 1 
#define FREEGLUT_LIB_PRAGMAS 1 
#define FREEGLUT_STATIC 1 
#include <gl/glew.h> 
#include <gl/freeglut.h> 
#include <stdlib.h> 
#include <gl/glext.h> 
#include "Shaders.h" 
#include <iostream> 
using namespace std; 
GLuint buf_v; 
GLuint buf_c; 
#define FOR(i,s,t) for(int i = (s); i < (t);i++) 
int width = 480; 
int height = 800; 
const int N = 24; 
const int WALL = 9999; 
int map[N][N]; 
GLfloat arrQuad[12]; 
GLfloat color[] ={ 1.0,1.0,1.0,1.0}; 
Shaders shaders; 
Matrix w, v, p, wvp; 
void drawQuad(float x, float y, int isWALL = 9999){//from top left corner 
    glUseProgram(shaders.program); 
    glBindBuffer(GL_ARRAY_BUFFER, buf_v); 
    GLvoid *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); 
    arrQuad[0] = x; 
    arrQuad[1] = y; 
    arrQuad[2] = x; 
    arrQuad[3] = y + 1.0; 
    arrQuad[4] = x + 1.0; 
    arrQuad[5] = y; 

    arrQuad[6] = x; 
    arrQuad[7] = y + 1.0; 
    arrQuad[8] = x + 1.0; 
    arrQuad[9] = y; 
    arrQuad[10] = x + 1.0; 
    arrQuad[11] = y + 1.0; 
    FOR(i,0,12){ 
     arrQuad[i]*=(GLfloat)width; 
     arrQuad[i]/=(GLfloat)N; 
    } 
    printf("%f, %f %f %f \n",arrQuad[3],arrQuad[4], arrQuad[10],arrQuad[11]); 
    printf("%f, %f %f %f \n\n",arrQuad[0],arrQuad[1], arrQuad[8],arrQuad[9]); 

    memcpy(buf, arrQuad, sizeof(arrQuad)); 
    glUnmapBuffer(GL_ARRAY_BUFFER); 
    if(isWALL == WALL){ 
     color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f; 
    } 
    else 
    { 
     color[0] = 0.0; color[1] = 0.0; color[2] = 0.0; 
    } 
    if(shaders.positionAttribute != -1) 
    { 
     glEnableVertexAttribArray(shaders.positionAttribute); 
     glVertexAttribPointer(shaders.positionAttribute, 2, GL_FLOAT, GL_FALSE, 0, 0);; 
    }else{ perror("err pos attr"); } 

    if(shaders.colorUniform != -1) 
    { 
     glUniform4fv(shaders.colorUniform, 1, color); 
    }else{ perror ("err col atr"); } 
    GLfloat mat_wvp_16[16] = { 
     wvp[0], wvp[1], wvp[2], wvp[3], 
     wvp[4], wvp[5], wvp[6], wvp[7], 
     wvp[8], wvp[9], wvp[10], wvp[11], 
     wvp[12], wvp[13], wvp[14], wvp[15], 
    };      

    if(shaders.mat_wvp != -1) 
    { 
     glUniformMatrix4fv(shaders.mat_wvp, 1, GL_FALSE, mat_wvp_16); 
    }else{ 
     //perror ("err mat atr"); 
    } 
    glBindBuffer(GL_ARRAY_BUFFER, buf_v); 
    glDrawArrays(GL_TRIANGLES, 0, 6); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 
void reshape(int w, int h) 
{ 
    glViewport(0,0,(GLsizei)w,(GLsizei)h); 
} 
void init(){ 
    shaders.HasGLSLSupport(); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_COLOR_ARRAY); 
    glGenBuffers(1, &buf_v); 
    glBindBuffer(GL_ARRAY_BUFFER, buf_v); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(arrQuad), arrQuad, GL_DYNAMIC_DRAW); 

    glGenBuffers(1, &buf_c); 
    glBindBuffer(GL_ARRAY_BUFFER, buf_c); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_DYNAMIC_DRAW); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    if(shaders.Init("vert.vs","frag.frg") != 0) 
     perror("shader initialization error"); 
    wvp.loadOrthoMatrix(0.0, width, 0, height, 0.0, 100.0); 

    wvp = wvp * w; 
} 
void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    FOR(i, 0, N) 
     FOR(j, 0, N) 
    { 
     drawQuad(i, j, map[i][j]); 
    } 

    glutSwapBuffers(); 
} 
void timer(int i = 0) 
{ 
    glutPostRedisplay(); 
    FOR(i, 0, N) 
     FOR(j, 0, N) 
    { 
     if(rand() % 4 == 0) 
      map[i][j] = WALL; 
     else 
      map[i][j] = -1; 
    } 
    display(); 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 
    glutInitWindowSize(width, height); 
    glutCreateWindow("Hi, wave!"); 
    glClearColor(1.0,1.0,1.0,1.0); 
    glViewport(0,0,(GLfloat)width, (GLfloat)height); 
    GLenum err = glewInit(); 
    if (GLEW_OK != err) 
    { 
     cout << "glewInit failed, aborting." << endl; 
     exit (1); 
    } 
    init(); 

    glutTimerFunc(17,timer,0); 
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutMainLoop(); 

    return 0; 
} 

uniform mat4 u_wvp; 
attribute vec4 a_pos; 
void main() 
{ 
    gl_Position = (u_wvp * a_pos); 
} 

vert.vs frag.frg

precision mediump float; 
uniform vec4 u_color; 

void main(){ 
    gl_FragColor = u_color; 
} 
+1

셰이더는 단순히 값을 가져와 비디오 카드로 보냅니다. 업데이트를 참조하십시오. – SevenDays

+0

'# version' 지시어는 어디에 있습니까? – genpfault

+1

#version 110을 설정할 때 아무 것도 변경되지 않습니다. GLSL은 기본적으로 2.0을 지원해야한다고 생각합니다. – SevenDays

답변

1

이 시도 :

#include <GL/glew.h> 
#include <GL/glut.h> 
#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp> 
#include <iostream> 
#include <vector> 
using namespace std; 

// RAII vertex attribute wrapper 
struct Attrib 
{ 
    Attrib 
     ( 
     const char* name, const GLint size, const GLsizei stride, const GLvoid* pointer, 
     const GLenum type = GL_FLOAT, const GLboolean normalized = GL_FALSE, const GLuint prog = GetProgram() 
     ) 
    { 
     mLoc = glGetAttribLocation(prog, name); 
     if(mLoc < 0) return; 
     glVertexAttribPointer(mLoc, size, type, normalized, stride, pointer); 
     glEnableVertexAttribArray(mLoc); 
    } 

    ~Attrib() 
    { 
     if(mLoc < 0) return; 
     glDisableVertexAttribArray(mLoc); 
    } 

    GLint mLoc; 

private: 
    static GLuint GetProgram() 
    { 
     GLint program = 0; 
     glGetIntegerv(GL_CURRENT_PROGRAM, &program); 
     return program; 
    } 
}; 

// GLSL shader program loader 
struct Program 
{ 
    static GLuint Load(const char* vert, const char* geom, const char* frag) 
    { 
     GLuint prog = glCreateProgram(); 
     if(vert) AttachShader(prog, GL_VERTEX_SHADER, vert); 
     if(geom) AttachShader(prog, GL_GEOMETRY_SHADER, geom); 
     if(frag) AttachShader(prog, GL_FRAGMENT_SHADER, frag); 
     glLinkProgram(prog); 
     CheckStatus(prog); 
     return prog; 
    } 

private: 
    static void CheckStatus(GLuint obj) 
    { 
     GLint status = GL_FALSE, len = 10; 
     if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status); 
     if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status); 
     if(status == GL_TRUE) return; 
     if(glIsShader(obj)) glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len); 
     if(glIsProgram(obj)) glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len); 
     std::vector<char> log(len, 'X'); 
     if(glIsShader(obj)) glGetShaderInfoLog(obj, len, NULL, &log[0]); 
     if(glIsProgram(obj)) glGetProgramInfoLog(obj, len, NULL, &log[0]); 
     std::cerr << &log[0] << std::endl; 
     exit(-1); 
    } 

    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 

const char* vert = GLSL 
(
    110, 
    uniform mat4 u_wvp; 
    attribute vec2 a_pos; 
    void main() 
    { 
     gl_Position = (u_wvp * vec4(a_pos, 0.0, 1.0)); 
    } 
); 

const char* frag = GLSL 
(
    110, 
    uniform vec4 u_color; 
    void main(){ 
     gl_FragColor = u_color; 
    } 
); 

GLuint buf_v; 
GLuint buf_c; 
#define FOR(i,s,t) for(int i = (s); i < (t);i++) 
int width = 480; 
int height = 800; 
const int N = 24; 
const int WALL = 9999; 
int map[N][N]; 
GLfloat arrQuad[12]; 
GLfloat color[] ={ 1.0,1.0,1.0,1.0}; 

glm::mat4 proj; 
glm::mat4 modelview; 
glm::mat4 wvp; 

GLuint program; 
void drawQuad(float x, float y, int isWALL = 9999) 
{ 
    //from top left corner 
    glUseProgram(program); 
    glBindBuffer(GL_ARRAY_BUFFER, buf_v); 
    GLvoid *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); 
    arrQuad[0] = x; 
    arrQuad[1] = y; 
    arrQuad[2] = x; 
    arrQuad[3] = y + 1.0; 
    arrQuad[4] = x + 1.0; 
    arrQuad[5] = y; 

    arrQuad[6] = x; 
    arrQuad[7] = y + 1.0; 
    arrQuad[8] = x + 1.0; 
    arrQuad[9] = y; 
    arrQuad[10] = x + 1.0; 
    arrQuad[11] = y + 1.0; 
    FOR(i,0,12) 
    { 
     arrQuad[i]*=(GLfloat)width; 
     arrQuad[i]/=(GLfloat)N; 
    } 
    memcpy(buf, arrQuad, sizeof(arrQuad)); 
    glUnmapBuffer(GL_ARRAY_BUFFER); 

    if(isWALL == WALL) 
    { 
     color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f; 
    } 
    else 
    { 
     color[0] = 0.0; color[1] = 0.0; color[2] = 0.0; 
    } 

    glUniformMatrix4fv(glGetUniformLocation(program, "u_wvp"), 1, GL_FALSE, glm::value_ptr(wvp)); 
    glUniform4fv(glGetUniformLocation(program, "u_color"), 1, color); 
    { 
     glBindBuffer(GL_ARRAY_BUFFER, buf_v); 
     Attrib a1("a_pos", 2, 0, 0); 
     glDrawArrays(GL_TRIANGLES, 0, 6); 
     glBindBuffer(GL_ARRAY_BUFFER, 0);   
    } 
} 

void init() 
{ 
    glGenBuffers(1, &buf_v); 
    glBindBuffer(GL_ARRAY_BUFFER, buf_v); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(arrQuad), arrQuad, GL_DYNAMIC_DRAW); 

    glGenBuffers(1, &buf_c); 
    glBindBuffer(GL_ARRAY_BUFFER, buf_c); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_DYNAMIC_DRAW); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    program = Program::Load(vert, NULL, frag); 

    glm::mat4 proj = glm::ortho(0.0f, (float)width, 0.0f, (float)height, 0.0f, 100.0f); 
    glm::mat4 modelview = glm::mat4(1.0f); 
    wvp = proj * modelview; 
} 

void display() 
{ 
    FOR(i, 0, N) 
     FOR(j, 0, N) 
    { 
     if(rand() % 4 == 0) 
      map[i][j] = WALL; 
     else 
      map[i][j] = -1; 
    } 

    glClearColor(1.0,1.0,1.0,1.0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    FOR(i, 0, N) 
     FOR(j, 0, N) 
    { 
     drawQuad(i, j, map[i][j]); 
    } 

    glutSwapBuffers(); 
} 

void timer(int i = 0) 
{ 
    glutPostRedisplay(); 
    glutTimerFunc(17, timer, 0); 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 
    glutInitWindowSize(width, height); 
    glutCreateWindow("Hi, wave!"); 
    GLenum err = glewInit(); 
    if (GLEW_OK != err) 
    { 
     cout << "glewInit failed, aborting." << endl; 
     exit (1); 
    } 
    init(); 

    glutTimerFunc(0,timer,0); 
    glutDisplayFunc(display); 
    glutMainLoop(); 

    return 0; 
} 
+0

코드가 작동하지만 위의 코드에서 잘못된 점을 파악할 수 없습니다. – SevenDays