2013-12-22 86 views
0

我的程序沒有在屏幕上顯示任何東西。我嘗試了幾件事,但沒有成功。OpenGL根本沒有渲染任何東西

這裏是我的源代碼,頂點和片段着色器:

Renderer.cpp:

#include "Renderer.h" 

Renderer::Renderer(Camera& camera, float w, float h) 
    : 
cam(camera), 
winW(w), 
winH(h) 
{} 

Renderer::~Renderer() 
{ 
    glDeleteBuffers(1, &quad); 
    glDeleteBuffers(1, &color); 
    glDeleteBuffers(1, &UV); 
    glDeleteVertexArrays(1, &vao); 
} 

void Renderer::load() 
{ 
    projectionMatrix = glm::mat4(1.0f); 
    projectionMatrix = glm::perspective<float>(45.0f, (float) winW/(float) winH, 0.01f, 100.0f); 

    shader.loadAndCompile("Res/Shaders/std.vs", "Res/Shaders/std.fs"); 

    texture.loadTexture("Res/Tex/sheet.png"); 
    texture.bind(); 

    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    Vertex quadArray[] = { 
     { -0.5, -0.5, 0.0 }, 
     { -0.5, 0.5, 0.0 }, 
     { 0.5, -0.5, 0.0 }, 
     { 0.5, -0.5, 0.0 }, 
     { 0.5, 0.5, 0.0 }, 
     { -0.5, 0.5, 0.0 } 
    }; 

    glUseProgram(shader.getProgram()); 

    MVPLocation = glGetUniformLocation(shader.getProgram(), "MVP"); 

    glGenBuffers(1, &quad); 
    glBindBuffer(GL_ARRAY_BUFFER, quad); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(quadArray), quadArray, GL_STATIC_DRAW); 

    glGenBuffers(1, &color); 
    glBindBuffer(GL_ARRAY_BUFFER, color); 
    glBufferData(GL_ARRAY_BUFFER, 48, NULL, GL_STREAM_DRAW); 

    glGenBuffers(1, &UV); 
    glBindBuffer(GL_ARRAY_BUFFER, UV); 
    glBufferData(GL_ARRAY_BUFFER, 48, NULL, GL_STREAM_DRAW); 
} 

void Renderer::translate(glm::vec3 pos) 
{ 
    this->transMatrix = glm::translate(glm::mat4(1.0f), pos); 
} 

void Renderer::translate(float x, float y, float z) 
{ 
    translate(glm::vec3(x, y, z)); 
} 

void Renderer::rotate(float angle, glm::vec3 axis) 
{ 
    this->rotationMatrix = glm::rotate(glm::mat4(1.0f), angle, axis); 
} 

void Renderer::scale(glm::vec3 scale) 
{ 
    this->scaleMatrix = glm::scale(glm::mat4(1.0f), scale); 
} 

void Renderer::scale(float x, float y, float z) 
{ 
    scale(glm::vec3(x, y, z)); 
} 

void Renderer::drawSpriteBillboarded(glm::vec3 pos, glm::vec3 lookAtPos, int w, int h, int uP, int vP, glm::vec4 col) 
{ 
    int texW = texture.getWidth(), texH = texture.getHeight(); 

    float u = (float) uP/(float) texW, v = (float) vP/(float) texH, uEnd = (float) (uP + w)/(float) texW, vEnd = (float) (vP + h)/(float) texH; 

    Color colArray[] = { 
     { col.r, col.g, col.b, col.a }, 
     { col.r, col.g, col.b, col.a }, 
     { col.r, col.g, col.b, col.a }, 
     { col.r, col.g, col.b, col.a }, 
     { col.r, col.g, col.b, col.a }, 
     { col.r, col.g, col.b, col.a } 
    }; 

    Vertex uvArray[] = { 
     { u, v }, 
     { u, vEnd }, 
     { uEnd, v }, 
     { uEnd, v }, 
     { uEnd, vEnd }, 
     { u, vEnd } 
    }; 

    translate(pos); 

    glm::vec2 dist = glm::vec2(lookAtPos.x, lookAtPos.z) - glm::vec2(pos.x, pos.z); 

    rotate(atan2f(dist.y, dist.x), glm::vec3(0, 1, 0)); 

    scale(w/16 * 1.0, h/16 * 1.0, 1.0); 

    modelMatrix = transMatrix * rotationMatrix * scaleMatrix; 

    camTransMatrix = glm::translate(glm::mat4(1.0f), cam.getPos()); 
    camRotationMatrix = glm::rotate(camRotationMatrix, cam.getRotX(), glm::vec3(1, 0, 0)); 
    camRotationMatrix = glm::rotate(camRotationMatrix, cam.getRotY(), glm::vec3(0, 1, 0)); 
    camRotationMatrix = glm::rotate(camRotationMatrix, cam.getRotZ(), glm::vec3(0, 0, 1)); 
    viewMatrix = camTransMatrix * camRotationMatrix; 

    modelViewProjectionMatrix = projectionMatrix * viewMatrix * modelMatrix; 

    glUniformMatrix4fv(MVPLocation, 1, GL_FALSE, &modelViewProjectionMatrix[ 0 ][ 0 ]); 

    glBindBuffer(GL_ARRAY_BUFFER, quad); 

    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); 

    glBindBuffer(GL_ARRAY_BUFFER, color); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(colArray), colArray, GL_STREAM_DRAW); 

    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0); 

    glBindBuffer(GL_ARRAY_BUFFER, UV); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(uvArray), uvArray, GL_STREAM_DRAW); 

    glEnableVertexAttribArray(2); 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); 

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); 
} 

void Renderer::drawSprite(glm::vec3 pos, int w, int h, int uP, int vP, glm::vec4 col) 
{} 

頂點着色器

#version 330 core 

layout(location = 0) in vec3 vertPosition; 
layout(location = 1) in vec4 color; 
layout(location = 2) in vec2 in_UV; 

uniform mat4 MVP; 

out vec4 col; 
out vec2 uv; 

void main(void) 
{ 
    gl_Position = MVP * vec4(vertPosition, 1.0); 

    col = color; 
    uv = in_UV; 
} 

片段着色器

#version 330 core 

in vec4 col; 
in vec2 uv; 

out vec4 color; 

uniform sampler2D tex; 

void main(void) 
{ 
    vec4 Color = texture2D(tex, uv) * col; 

    color = Color; 
} 

我叫drawSprit eBillboarded功能從我的遊戲類,像這樣:

drawSpriteBillboarded(glm::vec3(0, 0, -5), cam.getPos(), 16, 16, 0, 0, glm::vec3(255, 255, 255, 255)); 

攝像機的位置爲0,0,0

我試着改變頂點着色器不被MVP矩陣相乘,並試圖改變片段着色器:

#version 330 core 

in vec4 col; 
in vec2 uv; 

out vec4 color; 

void main(void) 
{ 
    color = vec4(1.0, 1.0, 1.0, 1.0); 
} 

但它也沒有顯示任何東西。 我也試過將GL_TRIANGLES更改爲GL_POINTS,但沒有任何結果。

編輯

我還添加了loadAndCompile()函數:

void Shader::loadAndCompile(const char* vertPath, const char* fragPath) 
{ 
    std::string vsCode = ""; 
    std::ifstream vsStream(vertPath, std::ios::in); 

    fprintf(stdout, "loading vertex shader %s\n", vertPath); 

    if(vsStream.is_open()) 
    { 
     std::string line; 
     while(std::getline(vsStream, line)) 
      vsCode += line + '\n'; 
     vsStream.close(); 
    } 
    else 
    { 
     fprintf(stderr, "Error: could not find vertex shader %s\n", vertPath); 
     return; 
    } 

    std::string fsCode = ""; 
    std::ifstream fsStream(fragPath, std::ios::in); 

    fprintf(stdout, "loading fragment shader %s\n", fragPath); 

    if(fsStream.is_open()) 
    { 
     std::string line; 
     while(std::getline(fsStream, line)) 
      fsCode += line + '\n'; 
     fsStream.close(); 
    } 
    else 
    { 
     fprintf(stderr, "Error: could not find fragment shader %s\n", fragPath); 
     return; 
    } 

    fprintf(stdout, "Compiling vertexShader %s\n", vertPath); 

    const char* vertCode = vsCode.c_str(); 
    GLuint vertShader = glCreateShader(GL_VERTEX_SHADER); 

    glShaderSource(vertShader, 1, &vertCode, NULL); 
    glCompileShader(vertShader); 

    GLint result = GL_FALSE; 
    int infoLogLength; 

    glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result); 
    glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &infoLogLength); 

    if(infoLogLength > 0) 
    { 
     std::vector<char> errorMsg(infoLogLength); 
     glGetShaderInfoLog(vertShader, infoLogLength, NULL, &errorMsg[ 0 ]); 
     fprintf(stderr, "%s\n", &errorMsg[ 0 ]); 
    } 

    fprintf(stdout, "Compiling fragmentShader %s\n", fragPath); 

    const char* fragCode = fsCode.c_str(); 
    GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER); 

    glShaderSource(fragShader, 1, &fragCode, NULL); 
    glCompileShader(fragShader); 

    glGetShaderiv(fragShader, GL_COMPILE_STATUS, &result); 
    glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &infoLogLength); 

    if(infoLogLength > 0) 
    { 
     std::vector<char> errorMsg(infoLogLength); 
     glGetShaderInfoLog(fragShader, infoLogLength, NULL, &errorMsg[ 0 ]); 
     fprintf(stderr, "%s\n", &errorMsg[ 0 ]); 
    } 

    fprintf(stdout, "Linking program...\n"); 

    GLuint tmpProgID = glCreateProgram(); 

    glAttachShader(tmpProgID, vertShader); 
    glAttachShader(tmpProgID, fragShader); 
    glLinkProgram(tmpProgID); 

    glGetProgramiv(tmpProgID, GL_LINK_STATUS, &result); 
    glGetProgramiv(tmpProgID, GL_INFO_LOG_LENGTH, &infoLogLength); 
    if(infoLogLength > 0) 
    { 
     std::vector<char> errorMsg(infoLogLength); 
     glGetProgramInfoLog(tmpProgID, infoLogLength, NULL, &errorMsg[ 0 ]); 
     fprintf(stderr, "%s\n", &errorMsg[ 0 ]); 
    } 

    glDeleteShader(vertShader); 
    glDeleteShader(fragShader); 

    this->programID = tmpProgID; 
} 

所以我基本上是問你檢查我的代碼,看看我做了(傻)的錯誤。

+0

它是否至少顯示白屏?你得到什麼輸出_do_?你有沒有嘗試檢查你的着色日誌,以確保他們正在加載? – zero298

+0

是的,他們正在加載他們應該的方式。我得到clearcolor背景屏幕 – Potte

+0

你的函數是否只調用'loadAndCompile(...)'**加載並編譯**或者是否也***鏈接***着色器?因爲校服在鏈接之前不會有位置,如果您嘗試使用尚未鏈接的程序執行此操作,'glUseProgram(...)'也會產生錯誤。 –

回答

0

解決! - 構造函數被調用時,winW和winH變量未被初始化。 我也必須將glDrawElements(...)更改爲glDrawArrays(...)