📄 oglkernel.cpp
字号:
#include "oglfunc.hpp"#include "oglcontext.hpp"#include "oglcheckgl.hpp"#include "ogltexture.hpp"#include "oglwindow.hpp"#include "nvcontext.hpp"using namespace brook;static const char passthrough_vertex[] = "not used";static const char passthrough_pixel[] ="!!ARBfp1.0\n""ATTRIB tex0 = fragment.texcoord[0];\n""OUTPUT oColor = result.color;\n""TEX oColor, tex0, texture[0], RECT;\n""END\n";OGLPixelShader::OGLPixelShader(unsigned int _id, const char * program_string): id(_id), largest_constant(0) { unsigned int i; for (i=0; i<(unsigned int) MAXCONSTANTS; i++) { constants[i] = float4(0.0f, 0.0f, 0.0f, 0.0f); } if (NVContext::isVendorContext()) {//only they rely on named constants if (strstr(program_string,"#profile fp30")) { while (*program_string&&(program_string=strstr(program_string,"#semantic main."))!=NULL) { const char *name; unsigned int len=0; program_string += strlen("#semantic main."); /* set name to the ident */ name = program_string; do{program_string++; len++;}while (*program_string!='\0'&&*program_string != ' '); std::string const_name(name,len); do program_string++; while (*program_string !=':'); do program_string++; while (*program_string ==' '); if (*program_string!='C') continue; program_string++; char * ptr=NULL; unsigned int constreg = strtol (program_string,&ptr,10); if(ptr){ if (constreg > (unsigned int)MAXCONSTANTS) { fprintf (stderr, "NV30GL: Too many constant registers\n"); exit(1); } program_string=ptr; constant_names[constreg] = const_name; } } } } } GPUContext::VertexShaderHandle OGLContext::getPassthroughVertexShader(void) {#if 0 if (!_passthroughVertexShader) { GLuint id; glGenProgramsARB(1, &id); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, id); glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(passthrough_vertex), (GLubyte *) passthrough_vertex); CHECK_GL(); _passthroughVertexShader = (GPUContext::VertexShaderHandle) id; } return _passthroughVertexShader;#else return (GPUContext::VertexShaderHandle) 1;#endif}GPUContext::PixelShaderHandle OGLContext::getPassthroughPixelShader() { //fprintf (stderr, "getPassthroughPixelShader: this=0x%p\n", this); if (!_passthroughPixelShader) { GLuint id; //fprintf (stderr, "Calling glGenProgramsARB...\n"); glGenProgramsARB(1, &id); //fprintf (stderr, "Calling glBindProgramARB...\n"); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, id); //fprintf (stderr, "Loading String: \n"); //fprintf (stderr, "%s\n", passthrough_pixel); glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(passthrough_pixel), (GLubyte *) passthrough_pixel); //fprintf (stderr, "Mallocing PixelShader\n"); _passthroughPixelShader = new OGLPixelShader(id,passthrough_pixel); //fprintf (stderr, "Checking GL\n"); CHECK_GL(); } //fprintf (stderr, " returning 0x%p\n ", _passthroughPixelShader); return (GPUContext::PixelShaderHandle) _passthroughPixelShader;}GPUContext::PixelShaderHandleOGLContext::createPixelShader( const char* shader ) { unsigned int id; // Allocate ids glGenProgramsARB(1, &id); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, id); // Try loading the program glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(shader), (GLubyte *) shader); /* Check for program errors */ if (glGetError() == GL_INVALID_OPERATION) { GLint pos; int i; int line, linestart; char *progcopy; progcopy = strdup (shader); glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos); line = 1; linestart = 0; for (i=0; i<pos; i++) { if (progcopy[i] == '\n') { line++; linestart = i+1; } } fprintf ( stderr, "GL: Program Error on line %d\n", line); for (i=linestart; progcopy[i] != '\0' && progcopy[i] != '\n'; i++); progcopy[i] = '\0'; fprintf ( stderr, "%s\n", progcopy+linestart); for (i=linestart; i<pos; i++) fprintf ( stderr, " "); for (;progcopy[i] != '\0' && progcopy[i] != '\n'; i++) fprintf ( stderr, "^"); fprintf ( stderr, "\n"); free(progcopy); fprintf ( stderr, "%s\n", glGetString(GL_PROGRAM_ERROR_STRING_ARB)); fflush(stderr); assert(0); exit(1); } return (GPUContext::PixelShaderHandle) new OGLPixelShader(id,shader);}void OGLContext::bindConstant( PixelShaderHandle ps, unsigned int inIndex, const float4& inValue ) { OGLPixelShader *oglps = (OGLPixelShader *) ps; GPUAssert(oglps, "Missing shader"); bindPixelShader(ps); glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, inIndex, (const float *) &inValue); CHECK_GL(); std::string::size_type len=oglps->constant_names[inIndex].length(); if (len){ glProgramNamedParameter4fvNV(oglps->id, len, (const GLubyte *)oglps->constant_names[inIndex].c_str(), &inValue.x); GLenum err=glGetError(); //errors come if a constant is passed into a kernel but optimized out of that kernel. // they are "safe" to ignore assert (err==GL_NO_ERROR||err==GL_INVALID_VALUE); } GPUAssert(inIndex < (unsigned int) OGLPixelShader::MAXCONSTANTS, "Too many constants used in kernel"); if (inIndex >= oglps->largest_constant) oglps->largest_constant = inIndex+1; oglps->constants[inIndex] = inValue;}void OGLContext::bindTexture( unsigned int inIndex, TextureHandle inTexture ) { OGLTexture *oglTexture = (OGLTexture *) inTexture; GPUAssert(oglTexture, "Null Texture"); GPUAssert(inIndex < _slopTextureUnit, "Too many bound textures"); glActiveTextureARB(GL_TEXTURE0_ARB+inIndex); glBindTexture(GL_TEXTURE_RECTANGLE_NV, oglTexture->id()); _boundTextures[inIndex] = oglTexture; CHECK_GL();}void OGLContext::bindOutput( unsigned int inIndex, TextureHandle inTexture ) { OGLTexture *oglTexture = (OGLTexture *) inTexture; GPUAssert(oglTexture, "Null Texture"); GPUAssert(inIndex <= _maxOutputCount , "Backend does not support more than" " four shader output."); _outputTextures[inIndex] = oglTexture;}void OGLContext::bindPixelShader( GPUContext::PixelShaderHandle inPixelShader ) { OGLPixelShader *ps = (OGLPixelShader *) inPixelShader; GPUAssert(ps, "Null pixel shader"); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ps->id); CHECK_GL(); _boundPixelShader = ps;}void OGLContext::bindVertexShader( GPUContext::VertexShaderHandle inVertexShader ) {#if 0 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, (unsigned int) inVertexShader); CHECK_GL();#endif}void OGLContext::disableOutput( unsigned int inIndex ) { GPUAssert(inIndex <= 4, "Backend does not support more than" " four shader outputs."); _outputTextures[inIndex] = NULL;}voidOGLContext::get1DInterpolant( const float4 &start, const float4 &end, const unsigned int w, GPUInterpolant &interpolant) const { if (w == 1) { interpolant.vertices[0] = start; interpolant.vertices[1] = start; interpolant.vertices[2] = start; return; } float4 f1, f2; float bias = 0.00001f; float x1 = start.x; float y1 = start.y; float z1 = start.z; float w1 = start.w; float x2 = end.x; float y2 = end.y; float z2 = end.z; float w2 = end.w; float sx = x2-x1; float sy = y2-y1; float sz = z2-z1; float sw = w2-w1; float ratiox = sx / w; float ratioy = sy / w; float ratioz = sz / w; float ratiow = sw / w; float shiftx = ratiox * 0.5f; float shifty = ratioy * 0.5f; float shiftz = ratioz * 0.5f; float shiftw = ratiow * 0.5f; f1.x = x1 - shiftx + bias; f1.y = y1 - shifty + bias; f1.z = z1 - shiftz + bias; f1.w = w1 - shiftw + bias; f2.x = (x1+2*sx) - shiftx + bias; f2.y = (y1+2*sy) - shifty + bias; f2.z = (z1+2*sz) - shiftz + bias; f2.w = (w1+2*sw) - shiftw + bias; interpolant.vertices[0] = f1; interpolant.vertices[1] = f2; interpolant.vertices[2] = f1;}voidOGLContext::get2DInterpolant( const float2 &start, const float2 &end, const unsigned int w, const unsigned int h, GPUInterpolant &interpolant) const { float2 f1, f2; float x1 = start.x; float y1 = start.y; float x2 = end.x; float y2 = end.y; float bias = 0.00001f; if (w==1 && h==1) { float4 v (start.x, start.y, 0.0f, 1.0f); interpolant.vertices[0] = v; interpolant.vertices[1] = v; interpolant.vertices[2] = v; return; } float sx = x2-x1; float sy = y2-y1; float ratiox = sx / w; float ratioy = sy / h;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -